diff options
-rw-r--r-- | Makefile.inc1 | 3 | ||||
-rw-r--r-- | contrib/binutils/include/elf/common.h | 4 | ||||
-rw-r--r-- | contrib/gcc/config/arm/freebsd.h | 1 | ||||
-rw-r--r-- | contrib/gcc/config/arm/unwind-arm.h | 4 | ||||
-rw-r--r-- | contrib/gdb/gdb/osabi.c | 14 | ||||
-rw-r--r-- | contrib/libstdc++/libsupc++/unwind-cxx.h | 20 | ||||
-rw-r--r-- | lib/Makefile | 10 | ||||
-rw-r--r-- | lib/libcxxrt/Version.map | 26 | ||||
-rw-r--r-- | sbin/recoverdisk/recoverdisk.c | 5 | ||||
-rw-r--r-- | sys/arm/arm/vm_machdep.c | 9 | ||||
-rw-r--r-- | sys/dev/uart/uart_bus_pci.c | 12 | ||||
-rw-r--r-- | sys/kern/kern_ktr.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_malloc.c | 11 | ||||
-rw-r--r-- | sys/netgraph/ng_ether.c | 8 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_lookup.c | 1 | ||||
-rw-r--r-- | sys/vm/vm_kern.c | 11 | ||||
-rw-r--r-- | usr.bin/bmake/Makefile.config | 21 | ||||
-rw-r--r-- | usr.bin/bmake/unit-tests/Makefile | 2 | ||||
-rw-r--r-- | usr.bin/join/join.c | 2 | ||||
-rw-r--r-- | usr.sbin/crunch/crunchide/exec_elf32.c | 224 |
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: |