summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2013-02-04 22:10:01 +0000
committerattilio <attilio@FreeBSD.org>2013-02-04 22:10:01 +0000
commitd3b7ec3a087fe017933d12d65a35cae1d1a00914 (patch)
treeab3d468dc0be6c80a1fb354da0786f9b3853ac34
parent0d3b58aee00948d85d75a9d3d222deb454afc98e (diff)
parentcfd3c02e72a8574bd02f57cd649cc2a4138d83ef (diff)
downloadFreeBSD-src-d3b7ec3a087fe017933d12d65a35cae1d1a00914.zip
FreeBSD-src-d3b7ec3a087fe017933d12d65a35cae1d1a00914.tar.gz
MFC
-rw-r--r--Makefile.inc13
-rw-r--r--contrib/binutils/include/elf/common.h4
-rw-r--r--contrib/gcc/config/arm/freebsd.h1
-rw-r--r--contrib/gcc/config/arm/unwind-arm.h4
-rw-r--r--contrib/gdb/gdb/osabi.c14
-rw-r--r--contrib/libstdc++/libsupc++/unwind-cxx.h20
-rw-r--r--lib/Makefile10
-rw-r--r--lib/libcxxrt/Version.map26
-rw-r--r--sbin/recoverdisk/recoverdisk.c5
-rw-r--r--sys/arm/arm/vm_machdep.c9
-rw-r--r--sys/dev/uart/uart_bus_pci.c12
-rw-r--r--sys/kern/kern_ktr.c3
-rw-r--r--sys/kern/kern_malloc.c11
-rw-r--r--sys/netgraph/ng_ether.c8
-rw-r--r--sys/ufs/ufs/ufs_lookup.c1
-rw-r--r--sys/vm/vm_kern.c11
-rw-r--r--usr.bin/bmake/Makefile.config21
-rw-r--r--usr.bin/bmake/unit-tests/Makefile2
-rw-r--r--usr.bin/join/join.c2
-rw-r--r--usr.sbin/crunch/crunchide/exec_elf32.c224
20 files changed, 272 insertions, 119 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1
index 34369a8..771f852 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -1733,7 +1733,8 @@ NOFUN=-DNO_FSCHG -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT \
XDDIR=${XDEV_ARCH}-freebsd
XDTP=/usr/${XDDIR}
-CDBENV=MAKEOBJDIRPREFIX=${MAKEOBJDIRPREFIX}/${XDDIR}
+CDBENV=MAKEOBJDIRPREFIX=${MAKEOBJDIRPREFIX}/${XDDIR} \
+ INSTALL="sh ${.CURDIR}/tools/install.sh"
CDENV= ${CDBENV} \
_SHLIBDIRPREFIX=${XDTP} \
TOOLS_PREFIX=${XDTP}
diff --git a/contrib/binutils/include/elf/common.h b/contrib/binutils/include/elf/common.h
index bb50a5c..f2e5022 100644
--- a/contrib/binutils/include/elf/common.h
+++ b/contrib/binutils/include/elf/common.h
@@ -435,6 +435,10 @@
#define NT_FREEBSD_ABI_TAG 1
+/* Values for FreeBSD .note.tag notes. Note name is "FreeBSD". */
+
+#define NT_FREEBSD_TAG 2
+
/* These three macros disassemble and assemble a symbol table st_info field,
which contains the symbol binding and symbol type. The STB_ and STT_
defines identify the binding and type. */
diff --git a/contrib/gcc/config/arm/freebsd.h b/contrib/gcc/config/arm/freebsd.h
index 04be692..8b03615 100644
--- a/contrib/gcc/config/arm/freebsd.h
+++ b/contrib/gcc/config/arm/freebsd.h
@@ -85,6 +85,7 @@
while (false)
#else
/* Default it to use ATPCS with soft-VFP. */
+#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_APCS_FRAME \
| TARGET_ENDIAN_DEFAULT)
diff --git a/contrib/gcc/config/arm/unwind-arm.h b/contrib/gcc/config/arm/unwind-arm.h
index a3040d7..0811f2c 100644
--- a/contrib/gcc/config/arm/unwind-arm.h
+++ b/contrib/gcc/config/arm/unwind-arm.h
@@ -87,7 +87,7 @@ extern "C" {
struct _Unwind_Control_Block
{
- char exception_class[8];
+ unsigned exception_class __attribute__((__mode__(__DI__)));
void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *);
/* Unwinder cache, private fields for the unwinder's use */
struct
@@ -186,7 +186,7 @@ extern "C" {
/* Support functions for the PR. */
#define _Unwind_Exception _Unwind_Control_Block
- typedef char _Unwind_Exception_Class[8];
+ typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
void * _Unwind_GetLanguageSpecificData (_Unwind_Context *);
_Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *);
diff --git a/contrib/gdb/gdb/osabi.c b/contrib/gdb/gdb/osabi.c
index 3acfc70..4e43df5 100644
--- a/contrib/gdb/gdb/osabi.c
+++ b/contrib/gdb/gdb/osabi.c
@@ -463,6 +463,20 @@ generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d",
return;
}
+
+ /* .note.tag notes, used by FreeBSD. */
+ if (strcmp (name, ".note.tag") == 0)
+ {
+ /* FreeBSD. */
+ if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_TAG))
+ {
+ /* There is no need to check the version yet. */
+ *osabi = GDB_OSABI_FREEBSD_ELF;
+ return;
+ }
+
+ return;
+ }
/* .note.netbsd.ident notes, used by NetBSD. */
if (strcmp (name, ".note.netbsd.ident") == 0
diff --git a/contrib/libstdc++/libsupc++/unwind-cxx.h b/contrib/libstdc++/libsupc++/unwind-cxx.h
index c5636556..523c054 100644
--- a/contrib/libstdc++/libsupc++/unwind-cxx.h
+++ b/contrib/libstdc++/libsupc++/unwind-cxx.h
@@ -173,7 +173,7 @@ __get_exception_header_from_ue (_Unwind_Exception *exc)
return reinterpret_cast<__cxa_exception *>(exc + 1) - 1;
}
-#ifdef __ARM_EABI_UNWINDER__
+#if defined(__ARM_EABI_UNWINDER__) && !defined(__FreeBSD__)
static inline bool
__is_gxx_exception_class(_Unwind_Exception_Class c)
{
@@ -200,13 +200,7 @@ __GXX_INIT_EXCEPTION_CLASS(_Unwind_Exception_Class c)
c[6] = '+';
c[7] = '\0';
}
-
-static inline void*
-__gxx_caught_object(_Unwind_Exception* eo)
-{
- return (void*)eo->barrier_cache.bitpattern[0];
-}
-#else // !__ARM_EABI_UNWINDER__
+#else // !__ARM_EABI_UNWINDER__ || __FreeBSD__
// This is the exception class we report -- "GNUCC++\0".
const _Unwind_Exception_Class __gxx_exception_class
= ((((((((_Unwind_Exception_Class) 'G'
@@ -223,8 +217,16 @@ __is_gxx_exception_class(_Unwind_Exception_Class c)
{
return c == __gxx_exception_class;
}
-
#define __GXX_INIT_EXCEPTION_CLASS(c) c = __gxx_exception_class
+#endif
+
+#ifdef __ARM_EABI_UNWINDER__
+static inline void*
+__gxx_caught_object(_Unwind_Exception* eo)
+{
+ return (void*)eo->barrier_cache.bitpattern[0];
+}
+#else // !__ARM_EABI_UNWINDER__
// GNU C++ personality routine, Version 0.
extern "C" _Unwind_Reason_Code __gxx_personality_v0
diff --git a/lib/Makefile b/lib/Makefile
index 132302e..1447002 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -177,6 +177,11 @@ _libiconv_modules= libiconv_modules
_libipx= libipx
.endif
+.if ${MK_LIBCPLUSPLUS} != "no"
+_libcxxrt= libcxxrt
+_libcplusplus= libc++
+.endif
+
.if ${MK_LIBTHR} != "no"
_libthr= libthr
.endif
@@ -221,11 +226,6 @@ _librtld_db= librtld_db
_libmp= libmp
.endif
-.if ${MK_LIBCPLUSPLUS} != "no"
-_libcxxrt= libcxxrt
-_libcplusplus= libc++
-.endif
-
.if ${MK_PMC} != "no"
_libpmc= libpmc
.endif
diff --git a/lib/libcxxrt/Version.map b/lib/libcxxrt/Version.map
index 1fdda27..f7e12e1 100644
--- a/lib/libcxxrt/Version.map
+++ b/lib/libcxxrt/Version.map
@@ -208,7 +208,6 @@ CXXABI_1.3 {
"typeinfo name for __cxxabiv1::__vmi_class_type_info";
"std::type_info::type_info(std::type_info const&)";
- "std::type_info::type_info(std::type_info const&)";
"std::type_info::operator=(std::type_info const&)";
@@ -238,18 +237,16 @@ CXXRT_1.0 {
"std::type_info::operator!=(std::type_info const&) const";
"std::bad_cast::bad_cast(std::bad_cast const&)";
"std::bad_cast::bad_cast()";
- "std::bad_cast::bad_cast(std::bad_cast const&)";
- "std::bad_cast::bad_cast()";
"std::bad_cast::operator=(std::bad_cast const&)";
- "std::exception::exception(std::exception const&)";
- "std::exception::exception()";
+ "std::bad_typeid::bad_typeid(std::bad_typeid const&)";
+ "std::bad_typeid::bad_typeid()";
+ "std::bad_typeid::operator=(std::bad_typeid const&)";
"std::exception::exception(std::exception const&)";
"std::exception::exception()";
"std::exception::operator=(std::exception const&)";
-
-
-
-
+ "std::bad_alloc::bad_alloc(std::bad_alloc const&)";
+ "std::bad_alloc::bad_alloc()";
+ "std::bad_alloc::operator=(std::bad_alloc const&)";
};
__cxa_allocate_dependent_exception;
@@ -281,15 +278,16 @@ GLIBCXX_3.4 {
"std::type_info::~type_info()";
"std::bad_cast::~bad_cast()";
+ "std::bad_typeid::~bad_typeid()";
"std::exception::~exception()";
+ "std::bad_alloc::~bad_alloc()";
+
+ "std::exception::what() const";
std::set_new_handler*;
std::set_terminate*;
std::set_unexpected*;
- std::exception*;
- std::bad_alloc;
- std::bad_typeid;
- std::type_info*;
+ std::type_info::__*;
"vtable for std::bad_alloc";
"vtable for std::bad_cast";
@@ -299,10 +297,10 @@ GLIBCXX_3.4 {
"typeinfo for std::bad_alloc";
"typeinfo for std::bad_typeid";
- "typeinfo for std::exception";
"typeinfo for std::bad_cast";
"typeinfo for std::exception";
"typeinfo for std::type_info";
+ "typeinfo name for std::bad_alloc";
"typeinfo name for std::bad_typeid";
"typeinfo name for std::bad_cast";
"typeinfo name for std::exception";
diff --git a/sbin/recoverdisk/recoverdisk.c b/sbin/recoverdisk/recoverdisk.c
index 3a92d1d..caa8ebd 100644
--- a/sbin/recoverdisk/recoverdisk.c
+++ b/sbin/recoverdisk/recoverdisk.c
@@ -156,6 +156,7 @@ main(int argc, char * const argv[])
int error, state;
u_char *buf;
u_int sectorsize;
+ u_int stripesize;
time_t t1, t2;
struct stat sb;
u_int n, snapshot = 60;
@@ -201,6 +202,10 @@ main(int argc, char * const argv[])
if (error < 0)
err(1, "DIOCGSECTORSIZE failed");
+ error = ioctl(fdr, DIOCGSTRIPESIZE, &stripesize);
+ if (error == 0 && stripesize > sectorsize)
+ sectorsize = stripesize;
+
minsize = sectorsize;
bigsize = (bigsize / sectorsize) * sectorsize;
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 22a209b..9326546 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -362,8 +362,8 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
{
struct trapframe *tf = td->td_frame;
- tf->tf_usr_sp = ((int)stack->ss_sp + stack->ss_size
- - sizeof(struct trapframe)) & ~7;
+ tf->tf_usr_sp = STACKALIGN((int)stack->ss_sp + stack->ss_size
+ - sizeof(struct trapframe));
tf->tf_pc = (int)entry;
tf->tf_r0 = (int)arg;
tf->tf_spsr = PSR_USR32_MODE;
@@ -396,14 +396,13 @@ cpu_thread_alloc(struct thread *td)
{
td->td_pcb = (struct pcb *)(td->td_kstack + td->td_kstack_pages *
PAGE_SIZE) - 1;
- td->td_frame = (struct trapframe *)
- ((u_int)td->td_kstack + USPACE_SVC_STACK_TOP - sizeof(struct pcb)) - 1;
/*
* Ensure td_frame is aligned to an 8 byte boundary as it will be
* placed into the stack pointer which must be 8 byte aligned in
* the ARM EABI.
*/
- td->td_frame = (struct trapframe *)((u_int)td->td_frame & ~7);
+ td->td_frame = (struct trapframe *)STACKALIGN((u_int)td->td_kstack +
+ USPACE_SVC_STACK_TOP - sizeof(struct pcb) - 1);
#ifdef __XSCALE__
#ifndef CPU_XSCALE_CORE3
pmap_use_minicache(td->td_kstack, td->td_kstack_pages * PAGE_SIZE);
diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c
index 4237fa4..c382669 100644
--- a/sys/dev/uart/uart_bus_pci.c
+++ b/sys/dev/uart/uart_bus_pci.c
@@ -52,7 +52,7 @@ static device_method_t uart_pci_methods[] = {
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
DEVMETHOD(device_resume, uart_bus_resume),
- { 0, 0 }
+ DEVMETHOD_END
};
static driver_t uart_pci_driver = {
@@ -71,7 +71,7 @@ struct pci_id {
int rclk;
};
-static struct pci_id pci_ns8250_ids[] = {
+static const struct pci_id pci_ns8250_ids[] = {
{ 0x1028, 0x0008, 0xffff, 0, "Dell Remote Access Card III", 0x14,
128 * DEFAULT_RCLK },
{ 0x1028, 0x0012, 0xffff, 0, "Dell RAC 4 Daughter Card Virtual UART", 0x14,
@@ -134,8 +134,8 @@ static struct pci_id pci_ns8250_ids[] = {
{ 0xffff, 0, 0xffff, 0, NULL, 0, 0}
};
-static struct pci_id *
-uart_pci_match(device_t dev, struct pci_id *id)
+const static struct pci_id *
+uart_pci_match(device_t dev, const struct pci_id *id)
{
uint16_t device, subdev, subven, vendor;
@@ -160,7 +160,7 @@ static int
uart_pci_probe(device_t dev)
{
struct uart_softc *sc;
- struct pci_id *id;
+ const struct pci_id *id;
sc = device_get_softc(dev);
@@ -178,4 +178,4 @@ uart_pci_probe(device_t dev)
return (uart_bus_probe(dev, 0, id->rclk, id->rid, 0));
}
-DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, 0, 0);
+DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, NULL, NULL);
diff --git a/sys/kern/kern_ktr.c b/sys/kern/kern_ktr.c
index 5b9d7aa..a11c76c 100644
--- a/sys/kern/kern_ktr.c
+++ b/sys/kern/kern_ktr.c
@@ -198,7 +198,7 @@ SYSCTL_PROC(_debug_ktr, OID_AUTO, mask, CTLTYPE_UINT|CTLFLAG_RW, 0, 0,
sysctl_debug_ktr_mask, "IU",
"Bitmask of KTR event classes for which logging is enabled");
-#if KTR_ENTRIES != KTR_BOOT_ENTRIES
+#if KTR_ENTRIES > KTR_BOOT_ENTRIES
/*
* A simplified version of sysctl_debug_ktr_entries.
* No need to care about SMP, scheduling, etc.
@@ -213,6 +213,7 @@ ktr_entries_initializer(void *dummy __unused)
ktr_mask = 0;
ktr_buf = malloc(sizeof(*ktr_buf) * KTR_ENTRIES, M_KTR,
M_WAITOK | M_ZERO);
+ memcpy(ktr_buf, ktr_buf_init, sizeof(ktr_buf_init));
ktr_entries = KTR_ENTRIES;
ktr_mask = mask;
}
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 1186e36..05fd5e5 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -186,16 +186,6 @@ struct {
*/
static uma_zone_t mt_zone;
-static vm_offset_t vm_min_kernel_address = VM_MIN_KERNEL_ADDRESS;
-SYSCTL_ULONG(_vm, OID_AUTO, min_kernel_address, CTLFLAG_RD,
- &vm_min_kernel_address, 0, "Min kernel address");
-
-#ifndef __sparc64__
-static vm_offset_t vm_max_kernel_address = VM_MAX_KERNEL_ADDRESS;
-#endif
-SYSCTL_ULONG(_vm, OID_AUTO, max_kernel_address, CTLFLAG_RD,
- &vm_max_kernel_address, 0, "Max kernel address");
-
u_long vm_kmem_size;
SYSCTL_ULONG(_vm, OID_AUTO, kmem_size, CTLFLAG_RDTUN, &vm_kmem_size, 0,
"Size of kernel memory");
@@ -592,7 +582,6 @@ free(void *addr, struct malloc_type *mtp)
panic("free: address %p(%p) has not been allocated.\n",
addr, (void *)((u_long)addr & (~UMA_SLAB_MASK)));
-
if (!(slab->us_flags & UMA_SLAB_MALLOC)) {
#ifdef INVARIANTS
struct malloc_type **mtpp = addr;
diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c
index 6266f40..df2dff5 100644
--- a/sys/netgraph/ng_ether.c
+++ b/sys/netgraph/ng_ether.c
@@ -410,11 +410,17 @@ static void
ng_ether_ifnet_arrival_event(void *arg __unused, struct ifnet *ifp)
{
char name[IFNAMSIZ];
- node_p node = IFP2NG(ifp);
+ node_p node;
+
+ /* Only ethernet interfaces are of interest. */
+ if (ifp->if_type != IFT_ETHER
+ && ifp->if_type != IFT_L2VLAN)
+ return;
/*
* Just return if it's a new interface without an ng_ether companion.
*/
+ node = IFP2NG(ifp);
if (node == NULL)
return;
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index d72278d..02fda9f 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -1434,7 +1434,6 @@ ufs_checkpath(ino_t source_ino, ino_t parent_ino, struct inode *target, struct u
return (0);
if (target->i_number == ROOTINO)
return (0);
- error = 0;
for (;;) {
error = ufs_dir_dd_ino(vp, cred, &dd_ino);
if (error != 0)
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index f731895..4d789ce 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -94,6 +94,17 @@ vm_map_t buffer_map=0;
const void *zero_region;
CTASSERT((ZERO_REGION_SIZE & PAGE_MASK) == 0);
+SYSCTL_ULONG(_vm, OID_AUTO, min_kernel_address, CTLFLAG_RD,
+ NULL, VM_MIN_KERNEL_ADDRESS, "Min kernel address");
+
+SYSCTL_ULONG(_vm, OID_AUTO, max_kernel_address, CTLFLAG_RD,
+#ifdef __sparc64__
+ &vm_max_kernel_address, 0,
+#else
+ NULL, VM_MAX_KERNEL_ADDRESS,
+#endif
+ "Max kernel address");
+
/*
* kmem_alloc_nofault:
*
diff --git a/usr.bin/bmake/Makefile.config b/usr.bin/bmake/Makefile.config
new file mode 100644
index 0000000..e4c4d3d
--- /dev/null
+++ b/usr.bin/bmake/Makefile.config
@@ -0,0 +1,21 @@
+# This is a generated file, do NOT edit!
+# See contrib/bmake/bsd.after-import.mk
+#
+# $FreeBSD$
+
+SRCTOP?= ${.CURDIR:H:H}
+
+# things set by configure
+
+prefix= /usr
+srcdir= ${SRCTOP}/contrib/bmake
+CC?= gcc
+DEFAULT_SYS_PATH= .../share/mk:/usr/share/mk
+
+CPPFLAGS+=
+CFLAGS+= ${CPPFLAGS} -DHAVE_CONFIG_H
+LDFLAGS=
+LIBOBJS= ${LIBOBJDIR}stresep$U.o
+LDADD=
+USE_META= yes
+FILEMON_H= /usr/include/dev/filemon/filemon.h
diff --git a/usr.bin/bmake/unit-tests/Makefile b/usr.bin/bmake/unit-tests/Makefile
index 8b2f514..0b9db1e 100644
--- a/usr.bin/bmake/unit-tests/Makefile
+++ b/usr.bin/bmake/unit-tests/Makefile
@@ -79,10 +79,12 @@ TOOL_TR?= tr
TOOL_DIFF?= diff
DIFF_FLAGS?= -u
+.if defined(.PARSEDIR)
# ensure consistent results from sort(1)
LC_ALL= C
LANG= C
.export LANG LC_ALL
+.endif
# The driver.
# We always pretend .MAKE was called 'make'
diff --git a/usr.bin/join/join.c b/usr.bin/join/join.c
index 97bb4cf..afa7cbc 100644
--- a/usr.bin/join/join.c
+++ b/usr.bin/join/join.c
@@ -516,7 +516,7 @@ static void
outfield(LINE *lp, u_long fieldno, int out_empty)
{
if (needsep++)
- (void)printf("%lc", *tabchar);
+ (void)printf("%lc", (wint_t)*tabchar);
if (!ferror(stdout)) {
if (lp->fieldcnt <= fieldno || out_empty) {
if (empty != NULL)
diff --git a/usr.sbin/crunch/crunchide/exec_elf32.c b/usr.sbin/crunch/crunchide/exec_elf32.c
index 9274f89..752007f 100644
--- a/usr.sbin/crunch/crunchide/exec_elf32.c
+++ b/usr.sbin/crunch/crunchide/exec_elf32.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <errno.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -82,11 +83,9 @@ __FBSDID("$FreeBSD$");
#define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x))
#define htoxe32(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x))
-struct listelem {
- struct listelem *next;
- void *mem;
- off_t file;
- size_t size;
+struct shlayout {
+ Elf_Shdr *shdr;
+ void *bufp;
};
static ssize_t
@@ -235,87 +234,154 @@ int
ELFNAMEEND(hide)(int fd, const char *fn)
{
Elf_Ehdr ehdr;
- Elf_Shdr *shdrp = NULL, *symtabshdr, *strtabshdr;
+ struct shlayout *layoutp = NULL;
+ Elf_Shdr *shdrp = NULL, *symtabshdr, *strtabshdr, *shstrtabshdr;
+ Elf_Shdr shdrshdr;
Elf_Sym *symtabp = NULL;
- char *strtabp = NULL;
- Elf_Size nsyms, ewi;
+ char *shstrtabp = NULL, *strtabp = NULL;
+ Elf_Size nsyms, ewi;
+ Elf_Off off;
ssize_t shdrsize;
- int rv, i, weird;
- size_t nstrtab_size, nstrtab_nextoff, fn_size;
+ int rv, i, weird, l, m, r, strtabidx;
+ size_t nstrtab_size, nstrtab_nextoff, fn_size, size;
char *nstrtabp = NULL;
unsigned char data;
- Elf_Off maxoff, stroff;
const char *weirdreason = NULL;
+ void *buf;
+ Elf_Half shnum;
rv = 0;
if (xreadatoff(fd, &ehdr, 0, sizeof ehdr, fn) != sizeof ehdr)
goto bad;
data = ehdr.e_ident[EI_DATA];
+ shnum = xe16toh(ehdr.e_shnum);
- shdrsize = xe16toh(ehdr.e_shnum) * xe16toh(ehdr.e_shentsize);
+ shdrsize = shnum * xe16toh(ehdr.e_shentsize);
if ((shdrp = xmalloc(shdrsize, fn, "section header table")) == NULL)
goto bad;
if (xreadatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) !=
shdrsize)
goto bad;
- symtabshdr = strtabshdr = NULL;
+ symtabshdr = strtabshdr = shstrtabshdr = NULL;
weird = 0;
- maxoff = stroff = 0;
- for (i = 0; i < xe16toh(ehdr.e_shnum); i++) {
- if (xewtoh(shdrp[i].sh_offset) > maxoff)
- maxoff = xewtoh(shdrp[i].sh_offset);
+ for (i = 0; i < shnum; i++) {
switch (xe32toh(shdrp[i].sh_type)) {
case SHT_SYMTAB:
- if (symtabshdr != NULL)
+ if (symtabshdr != NULL) {
weird = 1;
+ weirdreason = "multiple symbol tables";
+ }
symtabshdr = &shdrp[i];
strtabshdr = &shdrp[xe32toh(shdrp[i].sh_link)];
-
- /* Check whether the string table is the last section */
- stroff = xewtoh(shdrp[xe32toh(shdrp[i].sh_link)].sh_offset);
- if (!weird && xe32toh(shdrp[i].sh_link) != (xe16toh(ehdr.e_shnum) - 1)) {
- weird = 1;
- weirdreason = "string table not last section";
- }
+ break;
+ case SHT_STRTAB:
+ if (i == xe16toh(ehdr.e_shstrndx))
+ shstrtabshdr = &shdrp[i];
break;
}
}
- if (! weirdreason)
- weirdreason = "unsupported";
if (symtabshdr == NULL)
goto out;
- if (strtabshdr == NULL)
+ if (strtabshdr == NULL) {
weird = 1;
- if (!weird && stroff != maxoff) {
+ weirdreason = "string table does not exist";
+ }
+ if (shstrtabshdr == NULL) {
weird = 1;
- weirdreason = "string table section not last in file";
- }
+ weirdreason = "section header string table does not exist";
+ }
+ if (weirdreason == NULL)
+ weirdreason = "unsupported";
if (weird) {
fprintf(stderr, "%s: weird executable (%s)\n", fn, weirdreason);
goto bad;
}
/*
+ * sort section layout table by offset
+ */
+ layoutp = xmalloc((shnum + 1) * sizeof(struct shlayout),
+ fn, "layout table");
+ if (layoutp == NULL)
+ goto bad;
+
+ /* add a pseudo entry to represent the section header table */
+ shdrshdr.sh_offset = ehdr.e_shoff;
+ shdrshdr.sh_size = htoxew(shdrsize);
+ shdrshdr.sh_addralign = htoxew(ELFSIZE / 8);
+ layoutp[shnum].shdr = &shdrshdr;
+
+ /* insert and sort normal section headers */
+ for (i = shnum; i-- != 0;) {
+ l = i + 1;
+ r = shnum;
+ while (l <= r) {
+ m = ( l + r) / 2;
+ if (xewtoh(shdrp[i].sh_offset) >
+ xewtoh(layoutp[m].shdr->sh_offset))
+ l = m + 1;
+ else
+ r = m - 1;
+ }
+
+ if (r != i) {
+ memmove(&layoutp[i], &layoutp[i + 1],
+ sizeof(struct shlayout) * (r - i));
+ }
+
+ layoutp[r].shdr = &shdrp[i];
+ layoutp[r].bufp = NULL;
+ }
+ ++shnum;
+
+ /*
* load up everything we need
*/
- /* symbol table */
- if ((symtabp = xmalloc(xewtoh(symtabshdr->sh_size), fn, "symbol table"))
- == NULL)
+ /* load section string table for debug use */
+ if ((shstrtabp = xmalloc(xewtoh(shstrtabshdr->sh_size), fn,
+ "section string table")) == NULL)
goto bad;
- if ((size_t)xreadatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset),
- xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size))
+ if ((size_t)xreadatoff(fd, shstrtabp, xewtoh(shstrtabshdr->sh_offset),
+ xewtoh(shstrtabshdr->sh_size), fn) != xewtoh(shstrtabshdr->sh_size))
goto bad;
- /* string table */
- if ((strtabp = xmalloc(xewtoh(strtabshdr->sh_size), fn, "string table"))
- == NULL)
- goto bad;
- if ((size_t)xreadatoff(fd, strtabp, xewtoh(strtabshdr->sh_offset),
- xewtoh(strtabshdr->sh_size), fn) != xewtoh(strtabshdr->sh_size))
- goto bad;
+ /* we need symtab, strtab, and everything behind strtab */
+ strtabidx = INT_MAX;
+ for (i = 0; i < shnum; i++) {
+ if (layoutp[i].shdr == &shdrshdr) {
+ /* not load section header again */
+ layoutp[i].bufp = shdrp;
+ continue;
+ }
+ if (layoutp[i].shdr == shstrtabshdr) {
+ /* not load section string table again */
+ layoutp[i].bufp = shstrtabp;
+ continue;
+ }
+
+ if (layoutp[i].shdr == strtabshdr)
+ strtabidx = i;
+ if (layoutp[i].shdr == symtabshdr || i >= strtabidx) {
+ off = xewtoh(layoutp[i].shdr->sh_offset);
+ size = xewtoh(layoutp[i].shdr->sh_size);
+ layoutp[i].bufp = xmalloc(size, fn,
+ shstrtabp + xewtoh(layoutp[i].shdr->sh_name));
+ if (layoutp[i].bufp == NULL)
+ goto bad;
+ if ((size_t)xreadatoff(fd, layoutp[i].bufp, off, size, fn) !=
+ size)
+ goto bad;
+
+ /* set symbol table and string table */
+ if (layoutp[i].shdr == symtabshdr)
+ symtabp = layoutp[i].bufp;
+ else if (layoutp[i].shdr == strtabshdr)
+ strtabp = layoutp[i].bufp;
+ }
+ }
nstrtab_size = 256;
nstrtabp = xmalloc(nstrtab_size, fn, "new string table");
@@ -365,28 +431,62 @@ ELFNAMEEND(hide)(int fd, const char *fn)
strtabshdr->sh_size = htoxew(nstrtab_nextoff);
/*
- * write new tables to the file
+ * update section header table in ascending order of offset
*/
- if (xwriteatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) !=
- shdrsize)
- goto bad;
- if ((size_t)xwriteatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset),
- xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size))
- goto bad;
- /* write new symbol table strings */
- if ((size_t)xwriteatoff(fd, nstrtabp, xewtoh(strtabshdr->sh_offset),
- xewtoh(strtabshdr->sh_size), fn) != xewtoh(strtabshdr->sh_size))
- goto bad;
+ for (i = strtabidx + 1; i < shnum; i++) {
+ Elf_Off off, align;
+ off = xewtoh(layoutp[i - 1].shdr->sh_offset) +
+ xewtoh(layoutp[i - 1].shdr->sh_size);
+ align = xewtoh(layoutp[i].shdr->sh_addralign);
+ off = (off + (align - 1)) & ~(align - 1);
+ layoutp[i].shdr->sh_offset = htoxew(off);
+ }
+
+ /*
+ * write data to the file in descending order of offset
+ */
+ for (i = shnum; i-- != 0;) {
+ if (layoutp[i].shdr == strtabshdr) {
+ /* new string table */
+ buf = nstrtabp;
+ } else
+ buf = layoutp[i].bufp;
+
+ if (layoutp[i].shdr == &shdrshdr ||
+ layoutp[i].shdr == symtabshdr || i >= strtabidx) {
+ if (buf == NULL)
+ goto bad;
+
+ /*
+ * update the offset of section header table in elf
+ * header if needed.
+ */
+ if (layoutp[i].shdr == &shdrshdr &&
+ ehdr.e_shoff != shdrshdr.sh_offset) {
+ ehdr.e_shoff = shdrshdr.sh_offset;
+ off = (ELFSIZE == 32) ? 32 : 44;
+ size = sizeof(Elf_Off);
+ if ((size_t)xwriteatoff(fd, &ehdr.e_shoff, off, size,
+ fn) != size)
+ goto bad;
+ }
+
+ off = xewtoh(layoutp[i].shdr->sh_offset);
+ size = xewtoh(layoutp[i].shdr->sh_size);
+ if ((size_t)xwriteatoff(fd, buf, off, size, fn) != size)
+ goto bad;
+ }
+ }
out:
- if (shdrp != NULL)
- free(shdrp);
- if (symtabp != NULL)
- free(symtabp);
- if (strtabp != NULL)
- free(strtabp);
- if (nstrtabp != NULL)
- free(nstrtabp);
+ if (layoutp != NULL) {
+ for (i = 0; i < shnum; i++) {
+ if (layoutp[i].bufp != NULL)
+ free(layoutp[i].bufp);
+ }
+ free(layoutp);
+ }
+ free(nstrtabp);
return (rv);
bad:
OpenPOWER on IntegriCloud