summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
Diffstat (limited to 'ldso')
-rw-r--r--ldso/include/dl-auxvt.h9
-rw-r--r--ldso/include/dl-syscall.h6
-rwxr-xr-xldso/include/ldso.h3
-rw-r--r--ldso/ldso/Makefile.in5
-rw-r--r--ldso/ldso/aarch64/dl-sysdep.h25
-rw-r--r--ldso/ldso/arm/dl-sysdep.h69
-rw-r--r--ldso/ldso/dl-elf.c2
-rw-r--r--ldso/ldso/dl-startup.c6
-rwxr-xr-xldso/ldso/dl-vdso.c12
-rw-r--r--ldso/ldso/i386/dl-sysdep.h27
-rwxr-xr-xldso/ldso/ldso.c2
-rw-r--r--ldso/ldso/m68k/elfinterp.c4
-rw-r--r--ldso/ldso/riscv32/dl-sysdep.h22
-rw-r--r--ldso/ldso/x86_64/dl-sysdep.h45
-rw-r--r--ldso/libdl/libdl.c4
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) {