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-defs.h2
-rw-r--r--ldso/include/dl-elf.h41
-rw-r--r--ldso/include/dl-string.h4
-rw-r--r--ldso/include/dl-syscall.h19
-rwxr-xr-x[-rw-r--r--]ldso/include/ldso.h12
-rw-r--r--ldso/ldso/Makefile.in13
-rw-r--r--ldso/ldso/aarch64/dl-syscalls.h39
-rw-r--r--ldso/ldso/aarch64/dl-sysdep.h25
-rw-r--r--ldso/ldso/aarch64/elfinterp.c14
-rw-r--r--ldso/ldso/arc/dl-sysdep.h3
-rw-r--r--ldso/ldso/arc/resolve.S45
-rw-r--r--ldso/ldso/arm/dl-startup.h2
-rw-r--r--ldso/ldso/arm/dl-syscalls.h29
-rw-r--r--ldso/ldso/arm/dl-sysdep.h69
-rw-r--r--ldso/ldso/arm/elfinterp.c6
-rw-r--r--ldso/ldso/dl-elf.c13
-rw-r--r--ldso/ldso/dl-startup.c47
-rw-r--r--ldso/ldso/dl-vdso-calls.h68
-rwxr-xr-xldso/ldso/dl-vdso.c372
-rw-r--r--ldso/ldso/fdpic/dl-inlines.h4
-rw-r--r--ldso/ldso/fdpic/dl-sysdep.h2
-rw-r--r--ldso/ldso/i386/dl-syscalls.h28
-rw-r--r--ldso/ldso/i386/dl-sysdep.h27
-rwxr-xr-x[-rw-r--r--]ldso/ldso/ldso.c53
-rw-r--r--ldso/ldso/m68k/dl-startup.h3
-rw-r--r--ldso/ldso/m68k/dl-sysdep.h2
-rw-r--r--ldso/ldso/m68k/elfinterp.c4
-rw-r--r--ldso/ldso/mips/dl-startup.h3
-rw-r--r--ldso/ldso/mips/dl-syscalls.h29
-rw-r--r--ldso/ldso/powerpc/dl-startup.h4
-rw-r--r--ldso/ldso/riscv32/dl-startup.h92
-rw-r--r--ldso/ldso/riscv32/dl-syscalls.h1
-rw-r--r--ldso/ldso/riscv32/dl-sysdep.h89
-rw-r--r--ldso/ldso/riscv32/elfinterp.c295
-rw-r--r--ldso/ldso/riscv32/resolve.S96
-rw-r--r--ldso/ldso/riscv64/dl-startup.h2
-rw-r--r--ldso/ldso/riscv64/dl-sysdep.h21
-rw-r--r--ldso/ldso/riscv64/elfinterp.c4
-rw-r--r--ldso/ldso/x86_64/dl-syscalls.h29
-rw-r--r--ldso/ldso/x86_64/dl-sysdep.h45
-rw-r--r--ldso/ldso/xtensa/dl-inlines.h1
-rw-r--r--ldso/ldso/xtensa/dl-startup.h104
-rw-r--r--ldso/ldso/xtensa/dl-sysdep.h69
-rw-r--r--ldso/ldso/xtensa/dl-tlsdesc.S10
-rw-r--r--ldso/ldso/xtensa/elfinterp.c114
-rw-r--r--ldso/libdl/libdl.c4
47 files changed, 1689 insertions, 278 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-defs.h b/ldso/include/dl-defs.h
index f27112a11..e900640bb 100644
--- a/ldso/include/dl-defs.h
+++ b/ldso/include/dl-defs.h
@@ -72,7 +72,7 @@ typedef struct {
#endif
#ifdef _LIBC
-#ifndef __ARCH_HAS_NO_SHARED__
+#ifndef __ARCH_HAS_NO_LDSO__
/* arch specific defines */
#include <dl-sysdep.h>
#endif
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index 2b99958d9..832f6b1dd 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -250,5 +250,46 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info
(((X) & PF_W) ? PROT_WRITE : 0) | \
(((X) & PF_X) ? PROT_EXEC : 0))
+/* FDPIC ABI don't use relative relocations */
+#if !defined(__FDPIC__)
+/* Apply relocations in DT_RELR format */
+#define DL_DO_RELOCATE_RELR(load_addr, relr_start, relr_end) \
+ do { \
+ const ElfW(Relr) *relr = 0; \
+ ElfW(Addr) *relr_reloc_addr = 0; \
+ for (relr = relr_start; relr < relr_end; relr++) { \
+ ElfW(Relr) relr_entry = *relr; \
+ if (!(relr_entry & 1)) \
+ { \
+ relr_reloc_addr = (ElfW(Addr) *)DL_RELOC_ADDR(load_addr, relr_entry); \
+ *relr_reloc_addr = (ElfW(Addr))DL_RELOC_ADDR(load_addr, relr_reloc_addr); \
+ relr_reloc_addr++; \
+ } \
+ else \
+ { \
+ for (long int i = 0; (relr_entry >>= 1) != 0; ++i) { \
+ if ((relr_entry & 1) != 0) \
+ relr_reloc_addr[i] = (ElfW(Addr))DL_RELOC_ADDR(load_addr, relr_reloc_addr[i]); \
+ } \
+ relr_reloc_addr += CHAR_BIT * sizeof(ElfW(Relr)) - 1; \
+ } \
+ } \
+ } while (0)
+
+/* The macro to prepare data for the above DL_DO_RELOCATE_RELR */
+#define DL_RELOCATE_RELR(dyn) \
+ do { \
+ if (dyn->dynamic_info[DT_RELRENT]) \
+ _dl_assert(dyn->dynamic_info[DT_RELRENT] == sizeof(ElfW(Relr))); \
+ if (dyn->dynamic_info[DT_RELR] && \
+ dyn->dynamic_info[DT_RELRSZ]) { \
+ ElfW(Relr) *relr_start = (ElfW(Relr) *)((ElfW(Addr))dyn->loadaddr + (ElfW(Addr))dyn->dynamic_info[DT_RELR]); \
+ ElfW(Relr) *relr_end = (ElfW(Relr) *)((const char *)relr_start + dyn->dynamic_info[DT_RELRSZ]); \
+ _dl_if_debug_dprint("Relocating DT_RELR in %s: start:%p, end:%p\n", \
+ dyn->libname, (void *)relr_start, (void *)relr_end); \
+ DL_DO_RELOCATE_RELR(dyn->loadaddr, relr_start, relr_end); \
+ } \
+ } while (0)
+#endif /* __FDPIC__ */
#endif /* _DL_ELF_H */
diff --git a/ldso/include/dl-string.h b/ldso/include/dl-string.h
index bf6997188..4a66161e0 100644
--- a/ldso/include/dl-string.h
+++ b/ldso/include/dl-string.h
@@ -103,7 +103,7 @@ static __always_inline char * _dl_strstr(const char *s1, const char *s2)
do {
if (!*p)
- return (char *) s1;;
+ return (char *) s1;
if (*p == *s) {
++p;
++s;
@@ -257,7 +257,7 @@ static __always_inline char * _dl_simple_ltoahex(char *local, unsigned long i)
/* On some (wierd) arches, none of this stuff works at all, so
* disable the whole lot... */
/* The same applies for ARM FDPIC at least for the moment. */
-#if defined(__mips__) || (__FDPIC__)
+#if defined(__mips__) || defined(__FDPIC__)
# define SEND_STDERR(X)
# define SEND_ADDRESS_STDERR(X, add_a_newline)
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 2e8bb3630..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>
@@ -20,7 +25,7 @@ extern int _dl_errno;
#define _SYS_MMAN_H 1
#include <bits/mman.h>
-#ifdef __ARCH_HAS_DEPRECATED_SYSCALLS__
+#if defined(__ARCH_HAS_DEPRECATED_SYSCALLS__) && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
/* Pull in whatever this particular arch's kernel thinks the kernel version of
* struct stat should look like. It turns out that each arch has a different
* opinion on the subject, and different kernel revs use different names... */
@@ -116,7 +121,7 @@ static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
static __always_inline _syscall3(int, _dl_mprotect, const void *, addr,
unsigned long, len, int, prot)
-#if defined __NR_fstatat64 && !defined __NR_stat
+#if defined __NR_fstatat64 && !defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
# define __NR__dl_fstatat64 __NR_fstatat64
static __always_inline _syscall4(int, _dl_fstatat64, int, fd, const char *,
fn, struct stat *, stat, int, flags)
@@ -126,7 +131,7 @@ static __always_inline int _dl_stat(const char *file_name,
{
return _dl_fstatat64(AT_FDCWD, file_name, buf, 0);
}
-#elif defined __NR_newfstatat && !defined __NR_stat
+#elif defined __NR_newfstatat && !defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
# define __NR__dl_newfstatat __NR_newfstatat
static __always_inline _syscall4(int, _dl_newfstatat, int, fd, const char *,
fn, struct stat *, stat, int, flags)
@@ -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
+#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)
@@ -160,15 +165,15 @@ static __always_inline int _dl_stat(const char *file_name,
}
#endif
-#if defined __NR_fstat64 && !defined __NR_fstat
+#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__
# define __NR__dl_fstatx __NR_statx
-static __always_inline _syscall5(int, _dl_fstatx, int, fd, const char *, file_name, int, flags, unsigned int, mask, struct stat *, buf);
+static __always_inline _syscall5(int, _dl_fstatx, int, fd, const char *, file_name, int, flags, unsigned int, mask, struct statx *, buf);
static __always_inline int _dl_fstat(int fd,
struct stat *buf)
diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h
index f19957d1d..061d8a536 100644..100755
--- a/ldso/include/ldso.h
+++ b/ldso/include/ldso.h
@@ -48,7 +48,7 @@
/* Pull in the MIN macro */
#include <sys/param.h>
/* Pull in the ldso syscalls and string functions */
-#ifndef __ARCH_HAS_NO_SHARED__
+#if !defined(__ARCH_HAS_NO_SHARED__) || !defined(__ARCH_HAS_NO_LDSO__)
#include <dl-syscall.h>
#include <dl-string.h>
/* Now the ldso specific headers */
@@ -109,6 +109,7 @@ extern char *_dl_debug_reloc;
extern char *_dl_debug_detail;
extern char *_dl_debug_nofixups;
extern char *_dl_debug_bindings;
+extern char *_dl_debug_vdso;
extern int _dl_debug_file;
# define __dl_debug_dprint(fmt, args...) \
_dl_dprintf(_dl_debug_file, "%s:%i: " fmt, __func__, __LINE__, ## args);
@@ -148,6 +149,7 @@ extern int _dl_debug_file;
#define NULL ((void *) 0)
#endif
+
extern void *_dl_malloc(size_t size);
extern void *_dl_calloc(size_t __nmemb, size_t __size);
extern void *_dl_realloc(void *__ptr, size_t __size);
@@ -176,7 +178,7 @@ extern void _dl_dprintf(int, const char *, ...);
#endif
extern void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
- ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv
+ char **envp, char **argv
DL_GET_READY_TO_RUN_EXTRA_PARMS);
#ifdef HAVE_DL_INLINES_H
@@ -185,6 +187,12 @@ extern void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE loa
#else /* __ARCH_HAS_NO_SHARED__ */
#include <dl-defs.h>
+#include <dl-elf.h>
+
#endif
+#include <dl-auxvt.h>
+
+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 4f2a18454..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)\"
@@ -38,7 +43,8 @@ CFLAGS-ldso.c += -DLDSO_MULTILIB_DIR=\"$(MULTILIB_DIR)\"
endif
ifeq ($(TARGET_ARCH),arc)
-CFLAGS-ldso.c += -mno-long-calls
+$(eval $(call check-gcc-var,-mno-long-calls))
+CFLAGS-ldso.c += $(CFLAGS_-mno-long-calls)
endif
LDFLAGS-$(UCLIBC_FORMAT_DSBT_ELF)-$(UCLIBC_LDSO_NAME).so := -Wl,--dsbt-index=1
@@ -62,14 +68,15 @@ ldso_FULL_NAME := $(UCLIBC_LDSO_NAME)-$(VERSION).so
$(UCLIBC_LDSO_NAME)_DIR := $(top_srcdir)ldso/ldso
$(UCLIBC_LDSO_NAME)_OUT := $(top_builddir)ldso/ldso
-$(UCLIBC_LDSO_NAME)_CSRC := $($(UCLIBC_LDSO_NAME)_DIR)/ldso.c
+$(UCLIBC_LDSO_NAME)_CSRC := $($(UCLIBC_LDSO_NAME)_DIR)/ldso.c $($(UCLIBC_LDSO_NAME)_DIR)/dl-vdso.c
# prerequesites
$($(UCLIBC_LDSO_NAME)_OUT)/ldso.o $($(UCLIBC_LDSO_NAME)_OUT)/ldso.oS: \
$($(UCLIBC_LDSO_NAME)_DIR)/dl-debug.c \
$($(UCLIBC_LDSO_NAME)_DIR)/dl-startup.c \
$($(UCLIBC_LDSO_NAME)_DIR)/dl-array.c \
$($(UCLIBC_LDSO_NAME)_DIR)/dl-hash.c \
- $($(UCLIBC_LDSO_NAME)_DIR)/dl-elf.c
+ $($(UCLIBC_LDSO_NAME)_DIR)/dl-elf.c \
+ $($(UCLIBC_LDSO_NAME)_DIR)/dl-vdso.c
$(UCLIBC_LDSO_NAME)_COBJ := $(patsubst $($(UCLIBC_LDSO_NAME)_DIR)/%.c,$($(UCLIBC_LDSO_NAME)_OUT)/%.o,$($(UCLIBC_LDSO_NAME)_CSRC))
$(UCLIBC_LDSO_NAME)_SSRC := $(wildcard $($(UCLIBC_LDSO_NAME)_DIR)/$(TARGET_ARCH)/*.S)
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 adabafaad..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) */
@@ -253,6 +259,8 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
return 0;
}
+#undef __AARCH64_LAZY_RELOC_WORKS
+#ifdef __AARCH64_LAZY_RELOC_WORKS
static int
_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
@@ -303,11 +311,17 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
return 0;
}
+#endif
void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
unsigned long rel_addr, unsigned long rel_size)
{
+#ifdef __AARCH64_LAZY_RELOC_WORKS
(void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
+#else
+ _dl_parse_relocation_information(rpnt, &_dl_loaded_modules->symbol_scope,
+ rel_addr, rel_size);
+#endif
}
int _dl_parse_relocation_information(struct dyn_elf *rpnt,
diff --git a/ldso/ldso/arc/dl-sysdep.h b/ldso/ldso/arc/dl-sysdep.h
index ed8b37205..c8915511a 100644
--- a/ldso/ldso/arc/dl-sysdep.h
+++ b/ldso/ldso/arc/dl-sysdep.h
@@ -75,6 +75,9 @@ do { \
#elif defined(__HS__)
#define MAGIC1 EM_ARCV2
#define ELF_TARGET "ARCv2" /* For error messages */
+#elif defined(__ARC64_ARCH32__)
+#define MAGIC1 EM_ARCV3_32
+#define ELF_TARGET "ARCv3_32" /* For error messages */
#endif
#undef MAGIC2
diff --git a/ldso/ldso/arc/resolve.S b/ldso/ldso/arc/resolve.S
index 891f66b97..2b66c69cb 100644
--- a/ldso/ldso/arc/resolve.S
+++ b/ldso/ldso/arc/resolve.S
@@ -4,6 +4,7 @@
* Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
*/
+#include <asm.h>
#include <sysdep.h>
#include <sys/syscall.h>
@@ -12,30 +13,30 @@
; r10-r12 are already clobbered by PLTn, PLT0 thus neednot be saved
.macro SAVE_CALLER_SAVED
- push_s r0
- push_s r1
- push_s r2
- push_s r3
- st.a r4, [sp, -4]
- st.a r5, [sp, -4]
- st.a r6, [sp, -4]
- st.a r7, [sp, -4]
- st.a r8, [sp, -4]
- st.a r9, [sp, -4]
- push_s blink
+ PUSHR_S r0
+ PUSHR_S r1
+ PUSHR_S r2
+ PUSHR_S r3
+ PUSHR r4
+ PUSHR r5
+ PUSHR r6
+ PUSHR r7
+ PUSHR r8
+ PUSHR r9
+ PUSHR_S blink
.endm
.macro RESTORE_CALLER_SAVED_BUT_R0
- ld.ab blink,[sp, 4]
- ld.ab r9, [sp, 4]
- ld.ab r8, [sp, 4]
- ld.ab r7, [sp, 4]
- ld.ab r6, [sp, 4]
- ld.ab r5, [sp, 4]
- ld.ab r4, [sp, 4]
- pop_s r3
- pop_s r2
- pop_s r1
+ POPR blink
+ POPR r9
+ POPR r8
+ POPR r7
+ POPR r6
+ POPR r5
+ POPR r4
+ POPR_S r3
+ POPR_S r2
+ POPR_S r1
.endm
; Upon entry, PLTn, which led us here, sets up the following regs
@@ -53,5 +54,5 @@ ENTRY(_dl_linux_resolve)
RESTORE_CALLER_SAVED_BUT_R0
j_s.d [r0] ; r0 has resolved function addr
- pop_s r0 ; restore first arg to resolved call
+ POPR_S r0 ; restore first arg to resolved call
END(_dl_linux_resolve)
diff --git a/ldso/ldso/arm/dl-startup.h b/ldso/ldso/arm/dl-startup.h
index cacd461e1..d00e7b053 100644
--- a/ldso/ldso/arm/dl-startup.h
+++ b/ldso/ldso/arm/dl-startup.h
@@ -301,3 +301,5 @@ int raise(int sig)
_dl_exit(1);
}
#endif /* __FDPIC__ */
+
+#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR)
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 2bcfcda64..6656acb0f 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -182,7 +182,10 @@ search_for_named_library(const char *name, unsigned int rflags, const char *path
} else {
_dl_strcpy(mylibname, ".");
}
- _dl_strcat(mylibname, "/");
+ plen = _dl_strlen(mylibname);
+ if ((plen == 0) || (mylibname[plen-1] != '/')) {
+ _dl_strcat(mylibname, "/");
+ }
_dl_strcat(mylibname, name);
#ifdef __LDSO_SAFE_RUNPATH__
if (*mylibname == '/')
@@ -897,7 +900,8 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned int rflags,
_dl_memset(*rpnt, 0, sizeof(struct dyn_elf));
}
#endif
-