diff options
Diffstat (limited to 'ldso')
30 files changed, 625 insertions, 245 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 b40f58b10..c143b8d45 100644 --- a/ldso/include/dl-syscall.h +++ b/ldso/include/dl-syscall.h @@ -11,8 +11,13 @@ * been dynamicly linked in yet. */ #include "sys/syscall.h" extern int _dl_errno; + +#ifdef UCLIBC_LDSO #undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} +#endif + +#include <linux/version.h> /* Pull in the arch specific syscall implementation */ #include <dl-syscalls.h> @@ -136,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) @@ -163,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 80d5d5dd5..061d8a536 100755 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -191,13 +191,8 @@ 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( uint32_t sys_info_ehdr, char **envp ); - -#ifdef __VDSO_SUPPORT__ -extern void* _dl__vdso_gettimeofday; -#endif +void load_vdso(void *sys_info_ehdr, char **envp ); #endif /* _LDSO_H */ 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-syscalls.h b/ldso/ldso/aarch64/dl-syscalls.h index f40c4fd31..7f3566d6b 100644 --- a/ldso/ldso/aarch64/dl-syscalls.h +++ b/ldso/ldso/aarch64/dl-syscalls.h @@ -1 +1,38 @@ -/* stub for arch-specific syscall issues */ +/* stub for arch-specific syscall issues/specific implementations */ +#ifndef _DL_SYSCALLS_H +#define _DL_SYSCALLS_H + +#ifdef __ARCH_VDSO_GETTIMEOFDAY_NAME +#undef __ARCH_VDSO_GETTIMEOFDAY_NAME +#endif + +#ifdef __ARCH_VDSO_CLOCK_GETTIME_NAME +#undef __ARCH_VDSO_CLOCK_GETTIME_NAME +#endif + +#define __ARCH_VDSO_GETTIMEOFDAY_NAME "__kernel_gettimeofday" +#define __ARCH_VDSO_CLOCK_GETTIME_NAME "__kernel_clock_gettime" + +#if defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) + +#include "../dl-vdso-calls.h" + +static int __attribute__ ((used)) __aarch64_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __aarch64_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return __generic_vdso_clock_gettime(clock_id, tp); +} + +static int __attribute__ ((used)) __aarch64_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz); +static int __attribute__ ((used)) __aarch64_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + return __generic_vdso_gettimeofday(tv, tz); +} + +#define ARCH_VDSO_GETTIMEOFDAY(tv, tz) __aarch64_vdso_gettimeofday(tv, tz) +#define ARCH_VDSO_CLOCK_GETTIME(clock_id, tp) __aarch64_vdso_clock_gettime(clock_id, tp) + +#endif /* defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) */ + +#endif /* _DL_SYSCALLS_H */ + 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/aarch64/elfinterp.c b/ldso/ldso/aarch64/elfinterp.c index 717a76980..9365569cc 100644 --- a/ldso/ldso/aarch64/elfinterp.c +++ b/ldso/ldso/aarch64/elfinterp.c @@ -238,6 +238,12 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, } } break; + case R_AARCH64_TLS_DTPMOD: + *reloc_addr = tls_tpnt->l_tls_modid; + break; + case R_AARCH64_TLS_DTPREL: + *reloc_addr = symbol_addr + rpnt->r_addend; + break; #endif default: return -1; /*call _dl_exit(1) */ diff --git a/ldso/ldso/arm/dl-syscalls.h b/ldso/ldso/arm/dl-syscalls.h index f40c4fd31..5f6f7a883 100644 --- a/ldso/ldso/arm/dl-syscalls.h +++ b/ldso/ldso/arm/dl-syscalls.h @@ -1 +1,28 @@ -/* stub for arch-specific syscall issues */ +/* stub for arch-specific syscall issues/specific implementations */ + +#ifndef _DL_SYSCALLS_H +#define _DL_SYSCALLS_H + +#if defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) + +#include "../dl-vdso-calls.h" + +static int __attribute__ ((used)) __arm_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __arm_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return __generic_vdso_clock_gettime(clock_id, tp); +} + +static int __attribute__ ((used)) __arm_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz); +static int __attribute__ ((used)) __arm_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + return __generic_vdso_gettimeofday(tv, tz); +} + +#define ARCH_VDSO_GETTIMEOFDAY(tv, tz) __arm_vdso_gettimeofday(tv, tz) +#define ARCH_VDSO_CLOCK_GETTIME(clock_id, tp) __arm_vdso_clock_gettime(clock_id, tp) + +#endif /* defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) */ + +#endif /* _DL_SYSCALLS_H */ + 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/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c index 4c268356f..9c9a3e8ca 100644 --- a/ldso/ldso/arm/elfinterp.c +++ b/ldso/ldso/arm/elfinterp.c @@ -92,7 +92,7 @@ unsigned long _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_offet) *got_entry = funcval; #endif - return got_entry; + return (unsigned long)got_entry; } #else unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) @@ -362,7 +362,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, unsigned long reloc_value = *reloc_addr; if (symbol_addr) - reloc_value = (unsigned long) _dl_funcdesc_for(symbol_addr + reloc_value, sym_ref.tpnt->loadaddr.got_value); + reloc_value = (unsigned long) _dl_funcdesc_for((void *)(symbol_addr + reloc_value), sym_ref.tpnt->loadaddr.got_value); else /* Relocation against an undefined weak symbol: @@ -429,7 +429,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, { struct funcdesc_value *dst = (struct funcdesc_value *) reloc_addr; - dst->entry_point = DL_RELOC_ADDR(tpnt->loadaddr, dst->entry_point); + dst->entry_point = (void *)DL_RELOC_ADDR(tpnt->loadaddr, dst->entry_point); dst->got_value = tpnt->loadaddr.got_value; } break; 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 5b992a3a2..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,13 +370,14 @@ 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 DL_GET_READY_TO_RUN_EXTRA_ARGS); - load_vdso(_dl_auxvt[AT_SYSINFO_EHDR].a_un.a_val, envp); + load_vdso((void *)_dl_auxvt[AT_SYSINFO_EHDR].a_un.a_val, envp); /* Transfer control to the application. */ SEND_STDERR_DEBUG("transfering control to application @ "); diff --git a/ldso/ldso/dl-vdso-calls.h b/ldso/ldso/dl-vdso-calls.h new file mode 100644 index 000000000..c72f2dadf --- /dev/null +++ b/ldso/ldso/dl-vdso-calls.h @@ -0,0 +1,68 @@ +#ifndef _DL_VDSO_CALLS_H +#define _DL_VDSO_CALLS_H + +#include <sys/time.h> +#include <sys/syscall.h> +#include <errno.h> +#include <time.h> + +void __attribute__((weak)) *_get__dl__vdso_clock_gettime(void); +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +void __attribute__((weak)) *_get__dl__vdso_clock_gettime64(void); +typedef int (*clock_gettime_func)(clockid_t clock_id, struct __ts64_struct *tp); +#else +typedef int (*clock_gettime_func)(clockid_t clock_id, struct timespec *tp); +#endif + +extern int __libc_clock_gettime(clockid_t clock_id, struct timespec *tp); + +static int __attribute__ ((used)) __generic_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __generic_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + void *impl = NULL; +#if defined(__UCLIBC_USE_TIME64__) + if (&_get__dl__vdso_clock_gettime64 && (impl = _get__dl__vdso_clock_gettime64())) { + struct __ts64_struct __ts64; + int __ret = ((clock_gettime_func)impl)(clock_id, &__ts64); + if (__ret != 0) { + __set_errno(-__ret); + return -1; + } + + if (tp) { + tp->tv_sec = __ts64.tv_sec; + tp->tv_nsec = __ts64.tv_nsec; + } + return 0; + } + + /* fallback to syscall */ + return __libc_clock_gettime(clock_id, tp); +#else + if (&_get__dl__vdso_clock_gettime && (impl = _get__dl__vdso_clock_gettime())) { + int __ret = ((clock_gettime_func)impl)(clock_id, tp); + if (__ret != 0) { + __set_errno(-__ret); + return -1; + } + + return 0; + } + + /* fallback to syscall */ + return __libc_clock_gettime(clock_id, tp); +#endif +} + +static int __attribute__ ((used)) __generic_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + struct timespec ts; + int __res = __generic_vdso_clock_gettime(CLOCK_REALTIME, &ts); + tv->tv_sec = ts.tv_sec; + tv->tv_usec = (suseconds_t)ts.tv_nsec / 1000; + + return __res; +} + +#endif /* _DL_VDSO_CALLS_H */
\ No newline at end of file diff --git a/ldso/ldso/dl-vdso.c b/ldso/ldso/dl-vdso.c index c8d724cd0..01309011d 100755 --- a/ldso/ldso/dl-vdso.c +++ b/ldso/ldso/dl-vdso.c @@ -1,12 +1,16 @@ #include <elf.h> -//#include <stdio.h> #include <string.h> - #include "sys/auxv.h" -//#include <linux/time.h> -//#include <time.h> +#define __ARCH_VDSO_GETTIMEOFDAY_NAME "__vdso_gettimeofday" +#define __ARCH_VDSO_CLOCK_GETTIME_NAME "__vdso_clock_gettime" + +#if defined(__UCLIBC_USE_TIME64__) +#define __ARCH_VDSO_CLOCK_GETTIME64_NAME "__vdso_clock_gettime64" +#endif + +/* Maybe override default vDSO functions names by arch-specific */ #include "ldso.h" #include "generated/autoconf.h" @@ -24,31 +28,44 @@ #ifndef __VDSO_SUPPORT__ - void load_vdso( uint32_t 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; +void *_dl__vdso_clock_gettime = 0; +#if defined(__UCLIBC_USE_TIME64__) +void *_dl__vdso_clock_gettime64 = 0; +#endif - - - -//typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz); -void* _dl__vdso_gettimeofday = 0; - - -//typedef long (*clock_gettime_t)(int clk_id, struct timespec *tp); -void* _dl__vdso_clock_gettime = 0; +void *_get__dl__vdso_clock_gettime(void); +void *_get__dl__vdso_clock_gettime(void) +{ + return _dl__vdso_clock_gettime; +} +#if defined(__UCLIBC_USE_TIME64__) +void *_get__dl__vdso_clock_gettime64(void); +void *_get__dl__vdso_clock_gettime64(void) +{ + return _dl__vdso_clock_gettime64; +} +#endif +void *_get__dl__vdso_gettimeofday(void); +void *_get__dl__vdso_gettimeofday(void) +{ + return _dl__vdso_gettimeofday; +} -typedef struct{ +typedef struct { void* base_addr; @@ -75,7 +92,7 @@ typedef struct{ char* vers_strings[10]; -}elf_infos; +} elf_infos; /* * the raise() dummy function is needed because of divisons in this code @@ -111,13 +128,10 @@ static ELF(Shdr) *vdso_get_sec_header( elf_infos* elf, int index ){ } - -void load_vdso( uint32_t sys_info_ehdr, char **envp ){ +void load_vdso(void *sys_info_ehdr, char **envp ){ elf_infos vdso_infos; - - - + if ( sys_info_ehdr == 0 ){ #ifdef __SUPPORT_LD_DEBUG__ if ( _dl_debug_vdso != 0 ){ @@ -137,22 +151,16 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ #endif return; } - - + _dl_memset( &vdso_infos, 0 , sizeof( elf_infos ) ); - - + vdso_infos.base_addr = (void*)sys_info_ehdr; vdso_infos.hdr = (ELF(Ehdr)*)vdso_infos.base_addr; - - //printf("base : %p\n",vdso_infos.base_addr); - + if ( 0 != vdso_check_elf_header( &vdso_infos ) ){ return; } - - - + ELF(Shdr) *sec_header = vdso_get_sec_header( &vdso_infos, vdso_infos.hdr->e_shstrndx); vdso_infos.section_header_strtab = ( vdso_infos.base_addr + sec_header->sh_offset ); @@ -307,10 +315,7 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC) continue; - - char* name = vdso_infos.dynstr_table + sym->st_name; - char* vers = vdso_infos.vers_strings[ vdso_infos.versym_table[i] ]; void* func_addr = (void*)( vdso_infos.base_addr + sym->st_value ); // the function name is patched to zero if the kernel has no timer which is @@ -324,10 +329,7 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ continue; } - //printf(" %s@@%s\n", name , vers ); - - //print_sym( sym ); - if ( 0 == _dl_strcmp( name, "__vdso_gettimeofday" ) ){ + if ( 0 == _dl_strcmp( name, __ARCH_VDSO_GETTIMEOFDAY_NAME ) ){ _dl__vdso_gettimeofday = func_addr; #ifdef __SUPPORT_LD_DEBUG__ if ( _dl_debug_vdso != 0 ){ @@ -336,8 +338,7 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ #endif continue; } - - if ( 0 == _dl_strcmp( name, "__vdso_clock_gettime" ) ){ + if ( 0 == _dl_strcmp( name, __ARCH_VDSO_CLOCK_GETTIME_NAME ) ){ _dl__vdso_clock_gettime = func_addr; #ifdef __SUPPORT_LD_DEBUG__ if ( _dl_debug_vdso != 0 ){ @@ -346,17 +347,26 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ #endif continue; } + +#if defined(__UCLIBC_USE_TIME64__) + if ( 0 == _dl_strcmp( name, __ARCH_VDSO_CLOCK_GETTIME64_NAME ) ){ + _dl__vdso_clock_gettime64 = func_addr; +#ifdef __SUPPORT_LD_DEBUG__ + if ( _dl_debug_vdso != 0 ){ + _dl_dprintf(2," %s at address %p\n", name, func_addr ); + } +#endif + continue; + } +#endif /* defined(__UCLIBC_USE_TIME64__) */ #ifdef __SUPPORT_LD_DEBUG__ if ( _dl_debug_vdso != 0 ){ _dl_dprintf(2," <%s> not handled\n", name ); } #endif - - - } - + } } #endif // __VDSO_SUPPORT__ diff --git a/ldso/ldso/fdpic/dl-inlines.h b/ldso/ldso/fdpic/dl-inlines.h index 89e7a9a68..6a31ef3e6 100644 --- a/ldso/ldso/fdpic/dl-inlines.h +++ b/ldso/ldso/fdpic/dl-inlines.h @@ -102,7 +102,7 @@ __dl_update_loadaddr_hdr(struct elf32_fdpic_loadaddr loadaddr, void *addr, #if defined (__SUPPORT_LD_DEBUG__) if (_dl_debug) - _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size %x\n", + _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %p), size %x\n", loadaddr.map->nsegs - 1, segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz); #endif @@ -177,7 +177,7 @@ _dl_funcdesc_for (void *entry_point, void *got_value) tpnt->funcdesc_ht = ht; } - entry = htab_find_slot(ht, entry_point, 1, hash_pointer, eq_pointer); + entry = (struct funcdesc_value **)htab_find_slot(ht, entry_point, 1, hash_pointer, eq_pointer); if (entry == NULL) _dl_exit(1); diff --git a/ldso/ldso/fdpic/dl-sysdep.h b/ldso/ldso/fdpic/dl-sysdep.h index 6ab303b37..81694dc76 100644 --- a/ldso/ldso/fdpic/dl-sysdep.h +++ b/ldso/ldso/fdpic/dl-sysdep.h @@ -108,7 +108,7 @@ struct funcdesc_ht; && ELF32_ST_TYPE((SYM)->st_info) == STT_FUNC \ ? _dl_funcdesc_for ((void *)DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value), \ (TPNT)->loadaddr.got_value) \ - : DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value)) + : (void*)DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value)) #define DL_GET_READY_TO_RUN_EXTRA_PARMS \ , struct elf32_fdpic_loadmap *dl_boot_progmap, Elf32_Addr dl_boot_got_pointer diff --git a/ldso/ldso/i386/dl-syscalls.h b/ldso/ldso/i386/dl-syscalls.h index f40c4fd31..8f144ee28 100644 --- a/ldso/ldso/i386/dl-syscalls.h +++ b/ldso/ldso/i386/dl-syscalls.h @@ -1 +1,29 @@ +/* stub for arch-specific syscall issues/specific implementations */ + +#ifndef _DL_SYSCALLS_H +#define _DL_SYSCALLS_H + +#if defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) + +#include "../dl-vdso-calls.h" + +static int __attribute__ ((used)) __x86_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __x86_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return __generic_vdso_clock_gettime(clock_id, tp); +} + +static int __attribute__ ((used)) __x86_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz); +static int __attribute__ ((used)) __x86_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + return __generic_vdso_gettimeofday(tv, tz); +} + +#define ARCH_VDSO_GETTIMEOFDAY(tv, tz) __x86_vdso_gettimeofday(tv, tz) +#define ARCH_VDSO_CLOCK_GETTIME(clock_id, tp) __x86_vdso_clock_gettime(clock_id, tp) + +#endif /* defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) */ + +#endif /* _DL_SYSCALLS_H */ + /* stub for arch-specific syscall issues */ 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_a |