diff options
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/include/dl-auxvt.h | 9 | ||||
-rw-r--r-- | ldso/include/dl-syscall.h | 6 | ||||
-rwxr-xr-x | ldso/include/ldso.h | 3 | ||||
-rw-r--r-- | ldso/ldso/Makefile.in | 5 | ||||
-rw-r--r-- | ldso/ldso/aarch64/dl-sysdep.h | 25 | ||||
-rw-r--r-- | ldso/ldso/arm/dl-sysdep.h | 69 | ||||
-rw-r--r-- | ldso/ldso/dl-elf.c | 2 | ||||
-rw-r--r-- | ldso/ldso/dl-startup.c | 6 | ||||
-rwxr-xr-x | ldso/ldso/dl-vdso.c | 12 | ||||
-rw-r--r-- | ldso/ldso/i386/dl-sysdep.h | 27 | ||||
-rwxr-xr-x | ldso/ldso/ldso.c | 2 | ||||
-rw-r--r-- | ldso/ldso/m68k/elfinterp.c | 4 | ||||
-rw-r--r-- | ldso/ldso/riscv32/dl-sysdep.h | 22 | ||||
-rw-r--r-- | ldso/ldso/x86_64/dl-sysdep.h | 45 | ||||
-rw-r--r-- | ldso/libdl/libdl.c | 4 |
15 files changed, 84 insertions, 157 deletions
diff --git a/ldso/include/dl-auxvt.h b/ldso/include/dl-auxvt.h new file mode 100644 index 000000000..29eda6eb3 --- /dev/null +++ b/ldso/include/dl-auxvt.h @@ -0,0 +1,9 @@ +#ifndef _DL_AUXVT_H +#define _DL_AUXVT_H + +#define AUX_MAX_AT_ID 40 +extern ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID]; /* Cache frequently accessed auxiliary vector entries */ +extern ElfW(auxv_t) *_dl_auxv_start; /* Start of the auxiliary vector */ + +#endif /* _DL_AUXVT_H */ + diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h index 4f41034ad..c143b8d45 100644 --- a/ldso/include/dl-syscall.h +++ b/ldso/include/dl-syscall.h @@ -17,6 +17,8 @@ extern int _dl_errno; #define __set_errno(X) {(_dl_errno) = (X);} #endif +#include <linux/version.h> + /* Pull in the arch specific syscall implementation */ #include <dl-syscalls.h> /* For MAP_ANONYMOUS -- differs between platforms */ @@ -139,7 +141,7 @@ static __always_inline int _dl_stat(const char *file_name, { return _dl_newfstatat(AT_FDCWD, file_name, buf, 0); } -#elif defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__)) +#elif defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__) || (LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0))) # define __NR__dl_stat __NR_stat static __always_inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf) @@ -166,7 +168,7 @@ static __always_inline int _dl_stat(const char *file_name, #if defined __NR_fstat64 && !defined __NR_fstat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__)) # define __NR__dl_fstat __NR_fstat64 static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf) -#elif defined __NR_fstat +#elif defined __NR_fstat && !defined __UCLIBC_USE_TIME64__ || defined(__sparc__) # define __NR__dl_fstat __NR_fstat static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf) #elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__ diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index a397cce61..061d8a536 100755 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -191,8 +191,7 @@ extern void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE loa #endif -#define AUX_MAX_AT_ID 40 -extern ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID]; +#include <dl-auxvt.h> void load_vdso(void *sys_info_ehdr, char **envp ); diff --git a/ldso/ldso/Makefile.in b/ldso/ldso/Makefile.in index 6e8a0c388..0f8ed140d 100644 --- a/ldso/ldso/Makefile.in +++ b/ldso/ldso/Makefile.in @@ -19,6 +19,11 @@ ifeq ($(TARGET_ARCH),arm) CFLAGS-rtld += -fno-unwind-tables -fno-asynchronous-unwind-tables endif +ifeq ($(TARGET_ARCH),bfin) +# for gcc 10.5.0 and above we need to use -ffreestanding +CFLAGS-rtld += -ffreestanding +endif + CFLAGS-rtld += -I$(top_srcdir)ldso/ldso/$(TARGET_ARCH) -I$(top_srcdir)ldso/include -I$(top_srcdir)ldso/ldso CFLAGS-rtld += -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" diff --git a/ldso/ldso/aarch64/dl-sysdep.h b/ldso/ldso/aarch64/dl-sysdep.h index 6d9d2c1fb..3466920d9 100644 --- a/ldso/ldso/aarch64/dl-sysdep.h +++ b/ldso/ldso/aarch64/dl-sysdep.h @@ -54,28 +54,21 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); || (type) == R_AARCH64_TLSDESC) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_AARCH64_COPY) * ELF_RTYPE_CLASS_COPY)) -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. */ -extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden; -static __always_inline ElfW(Addr) __attribute__ ((unused)) -elf_machine_dynamic (void) -{ - return _GLOBAL_OFFSET_TABLE_[0]; -} - /* Return the run-time load address of the shared object. */ static __always_inline ElfW(Addr) __attribute__ ((unused)) elf_machine_load_address (void) { - /* To figure out the load address we use the definition that for any symbol: - dynamic_addr(symbol) = static_addr(symbol) + load_addr - - _DYNAMIC sysmbol is used here as its link-time address stored in - the special unrelocated first GOT entry. */ + extern const ElfW(Ehdr) __ehdr_start attribute_hidden; + return (ElfW(Addr)) &__ehdr_start; +} - extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; - return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic (); +/* Return the link-time address of _DYNAMIC. */ +static __always_inline ElfW(Addr) __attribute__ ((unused)) +elf_machine_dynamic (void) +{ + extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; + return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h index 0f783e1c4..93e36b694 100644 --- a/ldso/ldso/arm/dl-sysdep.h +++ b/ldso/ldso/arm/dl-sysdep.h @@ -96,43 +96,6 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); | (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY)) #endif /* __FDPIC__ */ -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. We used to use the PIC register to do this - without a constant pool reference, but GCC 4.2 will use a pseudo-register - for the PIC base, so it may not be in r10. */ -static __always_inline Elf32_Addr __attribute__ ((unused)) -elf_machine_dynamic (void) -{ - Elf32_Addr dynamic; -#if !defined __thumb__ - __asm__ ("ldr %0, 2f\n" - "1: ldr %0, [pc, %0]\n" - "b 3f\n" - "2: .word _GLOBAL_OFFSET_TABLE_ - (1b+8)\n" - "3:" : "=r" (dynamic)); -#else - int tmp; - __asm__ (".align 2\n" - "bx pc\n" - "nop\n" - ".arm\n" - "ldr %0, 2f\n" - "1: ldr %0, [pc, %0]\n" - "b 3f\n" - "2: .word _GLOBAL_OFFSET_TABLE_ - (1b+8)\n" - "3:" - ".align 2\n" - "orr %1, pc, #1\n" - "bx %1\n" - ".force_thumb\n" - : "=r" (dynamic), "=&r" (tmp)); -#endif - - return dynamic; -} - -extern char __dl_start[] __asm__("_dl_start"); - #ifdef __FDPIC__ /* We must force strings used early in the bootstrap into the data segment. */ @@ -148,28 +111,16 @@ extern char __dl_start[] __asm__("_dl_start"); static __always_inline Elf32_Addr __attribute__ ((unused)) elf_machine_load_address (void) { -#if defined(__FDPIC__) - return 0; -#else - Elf32_Addr got_addr = (Elf32_Addr) &__dl_start; - Elf32_Addr pcrel_addr; -#if defined __OPTIMIZE__ && !defined __thumb__ - __asm__ ("adr %0, _dl_start" : "=r" (pcrel_addr)); -#else - /* A simple adr does not work in Thumb mode because the offset is - negative, and for debug builds may be too large. */ - int tmp; - __asm__ ("adr %1, 1f\n\t" - "ldr %0, [%1]\n\t" - "add %0, %0, %1\n\t" - "b 2f\n\t" - ".align 2\n\t" - "1: .word _dl_start - 1b\n\t" - "2:" - : "=r" (pcrel_addr), "=r" (tmp)); -#endif - return pcrel_addr - got_addr; -#endif + extern const Elf32_Ehdr __ehdr_start attribute_hidden; + return (Elf32_Addr) &__ehdr_start; +} + +/* Return the link-time address of _DYNAMIC. */ +static __always_inline Elf32_Addr __attribute__ ((unused)) +elf_machine_dynamic (void) +{ + extern Elf32_Dyn _DYNAMIC[] attribute_hidden; + return (Elf32_Addr) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 4f50d62b7..6656acb0f 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -1028,7 +1028,7 @@ int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int now_flag) return goof; } -#if !defined(__FDPIC__) && !defined(__DSBT__) +#if !defined(__FDPIC__) && !defined(__FRV_FDPIC__) && !defined(__DSBT__) /* Process DT_RELR relative relocations */ DL_RELOCATE_RELR(tpnt); #endif diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index e7000bd87..ec6b72a39 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -100,6 +100,7 @@ extern ElfW(Addr) _begin[] attribute_hidden; ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID]; +ElfW(auxv_t) *_dl_auxv_start; #ifdef LDSO_NEED_DPNT ElfW(Dyn) *_dl_saved_dpnt = 0; @@ -131,6 +132,7 @@ DL_START(unsigned long args) struct elf_resolve tpnt_tmp; struct elf_resolve *tpnt = &tpnt_tmp; ElfW(auxv_t) _dl_auxvt_tmp[AUX_MAX_AT_ID]; + ElfW(auxv_t) *_dl_auxv_start_tmp; ElfW(Dyn) *dpnt; uint32_t *p32; @@ -166,6 +168,7 @@ DL_START(unsigned long args) /* The junk on the stack immediately following the environment is * the Auxiliary Vector Table. Read out the elements of the auxvt, * sort and store them in auxvt for later use. */ + _dl_auxv_start_tmp = (ElfW(auxv_t) *)aux_dat; while (*aux_dat) { ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat; @@ -264,7 +267,7 @@ DL_START(unsigned long args) that once we are done, we have considerably more flexibility. */ SEND_EARLY_STDERR_DEBUG("About to do library loader relocations\n"); -#if !defined(__FDPIC__) && !defined(__DSBT__) +#if !defined(__FDPIC__) && !defined(__FRV_FDPIC__) && !defined(__DSBT__) /* Process DT_RELR relative relocations */ DL_RELOCATE_RELR(tpnt); #endif @@ -367,6 +370,7 @@ DL_START(unsigned long args) * now the globals work. so copy the aux vector */ _dl_memcpy( _dl_auxvt, _dl_auxvt_tmp, sizeof( ElfW(auxv_t) ) * AUX_MAX_AT_ID ); + _dl_auxv_start = _dl_auxv_start_tmp; _dl_elf_main = (int (*)(int, char **, char **)) _dl_get_ready_to_run(tpnt, load_addr, envp, argv diff --git a/ldso/ldso/dl-vdso.c b/ldso/ldso/dl-vdso.c index 196cbbb3b..01309011d 100755 --- a/ldso/ldso/dl-vdso.c +++ b/ldso/ldso/dl-vdso.c @@ -28,14 +28,14 @@ #ifndef __VDSO_SUPPORT__ - void load_vdso(void *sys_info_ehdr, char **envp ){ +void load_vdso( void *sys_info_ehdr attribute_unused, + char **envp attribute_unused ){ #ifdef __SUPPORT_LD_DEBUG__ - if ( _dl_debug_vdso != 0 ){ - _dl_dprintf(2,"_dl_vdso support not enabled\n" ); - } - -#endif + if ( _dl_debug_vdso != 0 ){ + _dl_dprintf(2,"_dl_vdso support not enabled\n" ); } +#endif +} #else void *_dl__vdso_gettimeofday = 0; diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h index b95328df4..8fc80a145 100644 --- a/ldso/ldso/i386/dl-sysdep.h +++ b/ldso/ldso/i386/dl-sysdep.h @@ -35,28 +35,21 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent || (type) == R_386_TLS_TPOFF) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY)) -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT, a special entry that is never relocated. */ -extern const Elf32_Addr _GLOBAL_OFFSET_TABLE_[] attribute_hidden; -static __always_inline Elf32_Addr __attribute__ ((unused, const)) -elf_machine_dynamic (void) -{ - /* This produces a GOTOFF reloc that resolves to zero at link time, so in - fact just loads from the GOT register directly. By doing it without - an asm we can let the compiler choose any register. */ - return _GLOBAL_OFFSET_TABLE_[0]; -} - -extern Elf32_Dyn bygotoff[] __asm__ ("_DYNAMIC") attribute_hidden; /* Return the run-time load address of the shared object. */ static __always_inline Elf32_Addr attribute_unused elf_machine_load_address (void) { - /* Compute the difference between the runtime address of _DYNAMIC as seen - by a GOTOFF reference, and the link-time address found in the special - unrelocated first GOT entry. */ - return (Elf32_Addr) &bygotoff - elf_machine_dynamic (); + extern const Elf32_Ehdr __ehdr_start attribute_hidden; + return (Elf32_Addr) &__ehdr_start; +} + +/* Return the link-time address of _DYNAMIC. */ +static __always_inline Elf32_Addr __attribute__ ((unused, const)) +elf_machine_dynamic (void) +{ + extern Elf32_Dyn _DYNAMIC[] attribute_hidden; + return (Elf32_Addr) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 435bd43bc..e866d6418 100755 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -682,7 +682,7 @@ of this helper program; chances are you did not intend to run this program.\n\ */ /* Now cover the application program. */ if (app_tpnt->dynamic_info[DT_TEXTREL]) { - int j; + unsigned int j; ElfW(Phdr) *ppnt_outer = ppnt; _dl_debug_early("calling mprotect on the application program\n"); ppnt = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val; diff --git a/ldso/ldso/m68k/elfinterp.c b/ldso/ldso/m68k/elfinterp.c index 25ea23067..e7fa117da 100644 --- a/ldso/ldso/m68k/elfinterp.c +++ b/ldso/ldso/m68k/elfinterp.c @@ -193,7 +193,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, #endif #if defined (__SUPPORT_LD_DEBUG__) - old_val = *reloc_addr; + old_val = reloc_addr ? *reloc_addr : 0; #endif switch (reloc_type) { @@ -292,7 +292,7 @@ _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, reloc_type = ELF_R_TYPE(rpnt->r_info); #if defined (__SUPPORT_LD_DEBUG__) - old_val = *reloc_addr; + old_val = reloc_addr ? *reloc_addr : 0; #endif switch (reloc_type) { diff --git a/ldso/ldso/riscv32/dl-sysdep.h b/ldso/ldso/riscv32/dl-sysdep.h index e0a59fddd..02296b148 100644 --- a/ldso/ldso/riscv32/dl-sysdep.h +++ b/ldso/ldso/riscv32/dl-sysdep.h @@ -59,22 +59,20 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); | (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY))) -/* Return the link-time address of _DYNAMIC. */ -static inline ElfW(Addr) -elf_machine_dynamic (void) -{ - extern ElfW(Addr) _GLOBAL_OFFSET_TABLE_ __attribute__ ((visibility ("hidden"))); - return _GLOBAL_OFFSET_TABLE_; -} - - /* Return the run-time load address of the shared object. */ static __always_inline ElfW(Addr) __attribute__ ((unused)) elf_machine_load_address (void) { - ElfW(Addr) load_addr; - __asm__ ("lla %0, _DYNAMIC" : "=r" (load_addr)); - return load_addr - elf_machine_dynamic (); + extern const ElfW(Ehdr) __ehdr_start attribute_hidden; + return (ElfW(Addr)) &__ehdr_start; +} + +/* Return the link-time address of _DYNAMIC. */ +static inline ElfW(Addr) +elf_machine_dynamic (void) +{ + extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; + return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/ldso/x86_64/dl-sysdep.h b/ldso/ldso/x86_64/dl-sysdep.h index ccf9a8851..58447a951 100644 --- a/ldso/ldso/x86_64/dl-sysdep.h +++ b/ldso/ldso/x86_64/dl-sysdep.h @@ -52,48 +52,21 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_X86_64_COPY) * ELF_RTYPE_CLASS_COPY)) -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ -static __always_inline Elf64_Addr __attribute__ ((unused)) -elf_machine_dynamic (void) -{ - Elf64_Addr addr; - - /* This works because we have our GOT address available in the small PIC - model. */ - addr = (Elf64_Addr) &_DYNAMIC; - - return addr; -} - /* Return the run-time load address of the shared object. */ static __always_inline Elf64_Addr __attribute__ ((unused)) elf_machine_load_address (void) { - register Elf64_Addr addr, tmp; - - /* The easy way is just the same as on x86: - leaq _dl_start, %0 - leaq _dl_start(%%rip), %1 - subq %0, %1 - but this does not work with binutils since we then have - a R_X86_64_32S relocation in a shared lib. - - Instead we store the address of _dl_start in the data section - and compare it with the current value that we can get via - an RIP relative addressing mode. */ - - __asm__ ("movq 1f(%%rip), %1\n" - "0:\tleaq _dl_start(%%rip), %0\n\t" - "subq %1, %0\n\t" - ".section\t.data\n" - "1:\t.quad _dl_start\n\t" - ".previous\n\t" - : "=r" (addr), "=r" (tmp) : : "cc"); + extern const Elf64_Ehdr __ehdr_start attribute_hidden; + return (Elf64_Addr) &__ehdr_start; +} - return addr; +/* Return the link-time address of _DYNAMIC. */ +static __always_inline Elf64_Addr __attribute__ ((unused)) +elf_machine_dynamic (void) +{ + extern Elf64_Dyn _DYNAMIC[] attribute_hidden; + return (Elf64_Addr) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index 37c4a876e..6e50cb087 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -972,11 +972,11 @@ static int do_dlclose(void *vhandle, int need_fini) end = (end + ADDR_ALIGN) & PAGE_ALIGN; start = start & ~ADDR_ALIGN; if (end > start) { - _dl_if_debug_print("unmapping: %s at %p with length: '%p' until %p\n", tpnt->libname, tpnt->mapaddr, end - start, tpnt->mapaddr + (end - start)); + _dl_if_debug_print("unmapping: %s at %p with length: '%p' until %p\n", tpnt->libname, (void *)tpnt->mapaddr, (void *)(end - start), (void *)(tpnt->mapaddr + (end - start))); DL_LIB_UNMAP (tpnt, end - start); } else { - _dl_if_debug_print("NOT unmapping: %s at %p. start<end ('%p'<'%p')", tpnt->libname, tpnt->mapaddr, start, end); + _dl_if_debug_print("NOT unmapping: %s at %p. start<end ('%p'<'%p')", tpnt->libname, (void *)tpnt->mapaddr, (void *)start, (void *)end); } /* Free elements in RTLD_LOCAL scope list */ for (runp = tpnt->rtld_local; runp; runp = tmp) { |