From 70709408336e483de74947eb53e9ba01ef4ab140 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Tue, 10 Feb 2004 09:26:57 +0000 Subject: Rework file naming, aiming for at least a vague level of consistancy --- ldso/Makefile | 6 +- ldso/include/dl-elf.h | 2 +- ldso/include/dl-string.h | 7 - ldso/include/dl-syscall.h | 2 +- ldso/include/ld_elf.h | 104 ----- ldso/include/ld_hash.h | 103 ----- ldso/include/ld_string.h | 281 ------------ ldso/include/ld_syscall.h | 132 ------ ldso/include/ldso.h | 8 +- ldso/ldso/.cvsignore | 2 +- ldso/ldso/Makefile | 12 +- ldso/ldso/arm/boot1_arch.h | 25 -- ldso/ldso/arm/ld_syscalls.h | 19 - ldso/ldso/arm/ld_sysdep.h | 124 ------ ldso/ldso/cris/boot1_arch.h | 16 - ldso/ldso/cris/dl-sysdep.h | 2 +- ldso/ldso/cris/ld_syscalls.h | 7 - ldso/ldso/cris/ld_sysdep.h | 112 ----- ldso/ldso/dl-startup.c | 4 +- ldso/ldso/hash.c | 262 ------------ ldso/ldso/i386/boot1_arch.h | 7 - ldso/ldso/i386/ld_syscalls.h | 7 - ldso/ldso/i386/ld_sysdep.h | 81 ---- ldso/ldso/ldso.c | 6 +- ldso/ldso/m68k/boot1_arch.h | 7 - ldso/ldso/m68k/ld_syscalls.h | 174 -------- ldso/ldso/m68k/ld_sysdep.h | 88 ---- ldso/ldso/mips/README | 4 +- ldso/ldso/mips/boot1_arch.h | 37 -- ldso/ldso/mips/ld_syscalls.h | 7 - ldso/ldso/mips/ld_sysdep.h | 136 ------ ldso/ldso/powerpc/boot1_arch.h | 20 - ldso/ldso/powerpc/ld_syscalls.h | 244 ----------- ldso/ldso/powerpc/ld_sysdep.h | 127 ------ ldso/ldso/readelflib1.c | 926 ---------------------------------------- ldso/ldso/sh/boot1_arch.h | 21 - ldso/ldso/sh/ld_syscalls.h | 7 - ldso/ldso/sh/ld_sysdep.h | 144 ------- ldso/ldso/sh64/boot1_arch.h | 25 -- ldso/ldso/sh64/ld_syscalls.h | 9 - ldso/ldso/sh64/ld_sysdep.h | 170 -------- ldso/ldso/sparc/boot1_arch.h | 7 - ldso/ldso/sparc/ld_syscalls.h | 156 ------- ldso/ldso/sparc/ld_sysdep.h | 112 ----- ldso/ldso/sparc/resolve.S | 2 +- ldso/ldso/startup.c | 583 ------------------------- ldso/libdl/Makefile | 14 +- ldso/libdl/dlib.c | 644 ---------------------------- ldso/libdl/libdl.c | 6 +- 49 files changed, 35 insertions(+), 4966 deletions(-) delete mode 100644 ldso/include/ld_elf.h delete mode 100644 ldso/include/ld_hash.h delete mode 100644 ldso/include/ld_string.h delete mode 100644 ldso/include/ld_syscall.h delete mode 100644 ldso/ldso/arm/boot1_arch.h delete mode 100644 ldso/ldso/arm/ld_syscalls.h delete mode 100644 ldso/ldso/arm/ld_sysdep.h delete mode 100644 ldso/ldso/cris/boot1_arch.h delete mode 100644 ldso/ldso/cris/ld_syscalls.h delete mode 100644 ldso/ldso/cris/ld_sysdep.h delete mode 100644 ldso/ldso/hash.c delete mode 100644 ldso/ldso/i386/boot1_arch.h delete mode 100644 ldso/ldso/i386/ld_syscalls.h delete mode 100644 ldso/ldso/i386/ld_sysdep.h delete mode 100644 ldso/ldso/m68k/boot1_arch.h delete mode 100644 ldso/ldso/m68k/ld_syscalls.h delete mode 100644 ldso/ldso/m68k/ld_sysdep.h delete mode 100644 ldso/ldso/mips/boot1_arch.h delete mode 100644 ldso/ldso/mips/ld_syscalls.h delete mode 100644 ldso/ldso/mips/ld_sysdep.h delete mode 100644 ldso/ldso/powerpc/boot1_arch.h delete mode 100644 ldso/ldso/powerpc/ld_syscalls.h delete mode 100644 ldso/ldso/powerpc/ld_sysdep.h delete mode 100644 ldso/ldso/readelflib1.c delete mode 100644 ldso/ldso/sh/boot1_arch.h delete mode 100644 ldso/ldso/sh/ld_syscalls.h delete mode 100644 ldso/ldso/sh/ld_sysdep.h delete mode 100644 ldso/ldso/sh64/boot1_arch.h delete mode 100644 ldso/ldso/sh64/ld_syscalls.h delete mode 100644 ldso/ldso/sh64/ld_sysdep.h delete mode 100644 ldso/ldso/sparc/boot1_arch.h delete mode 100644 ldso/ldso/sparc/ld_syscalls.h delete mode 100644 ldso/ldso/sparc/ld_sysdep.h delete mode 100644 ldso/ldso/startup.c delete mode 100644 ldso/libdl/dlib.c diff --git a/ldso/Makefile b/ldso/Makefile index 1c9fc8fef..3836a01d3 100644 --- a/ldso/Makefile +++ b/ldso/Makefile @@ -38,9 +38,9 @@ endif headers: $(LN) -fs $(TOPDIR)../include/elf.h include/ - $(LN) -fs ../ldso/$(TARGET_ARCH)/boot1_arch.h include/ - $(LN) -fs ../ldso/$(TARGET_ARCH)/ld_syscalls.h include/ - $(LN) -fs ../ldso/$(TARGET_ARCH)/ld_sysdep.h include/ + $(LN) -fs ../ldso/$(TARGET_ARCH)/dl-startup.h include/ + $(LN) -fs ../ldso/$(TARGET_ARCH)/dl-syscalls.h include/ + $(LN) -fs ../ldso/$(TARGET_ARCH)/dl-sysdep.h include/ clean: set -e ; for d in $(ALL_SUBDIRS) ; do $(MAKE) -C $$d $@ ; done diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h index 04c450fc5..4cab5505f 100644 --- a/ldso/include/dl-elf.h +++ b/ldso/include/dl-elf.h @@ -1,7 +1,7 @@ #ifndef LINUXELF_H #define LINUXELF_H -#include /* before elf.h to get ELF_USES_RELOCA right */ +#include /* before elf.h to get ELF_USES_RELOCA right */ #include #include diff --git a/ldso/include/dl-string.h b/ldso/include/dl-string.h index 6fd266fc2..cbb867010 100644 --- a/ldso/include/dl-string.h +++ b/ldso/include/dl-string.h @@ -1,13 +1,6 @@ #ifndef _LINUX_STRING_H_ #define _LINUX_STRING_H_ -extern void *_dl_malloc(int size); -extern char *_dl_getenv(const char *symbol, char **envp); -extern void _dl_unsetenv(const char *symbol, char **envp); -extern char *_dl_strdup(const char *string); -extern void _dl_dprintf(int, const char *, ...); - - static size_t _dl_strlen(const char * str); static char *_dl_strcat(char *dst, const char *src); static char * _dl_strcpy(char * dst,const char *src); diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h index 344a93039..0dd3f593d 100644 --- a/ldso/include/dl-syscall.h +++ b/ldso/include/dl-syscall.h @@ -2,7 +2,7 @@ #define _LD_SYSCALL_H_ /* Pull in the arch specific syscall implementation */ -#include +#include /* For MAP_ANONYMOUS -- differs between platforms */ #include /* Pull in whatever this particular arch's kernel thinks the kernel version of diff --git a/ldso/include/ld_elf.h b/ldso/include/ld_elf.h deleted file mode 100644 index 04c450fc5..000000000 --- a/ldso/include/ld_elf.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef LINUXELF_H -#define LINUXELF_H - -#include /* before elf.h to get ELF_USES_RELOCA right */ -#include -#include - -#ifdef DEBUG -# define LDSO_CONF "../util/ld.so.conf" -# define LDSO_CACHE "../util/ld.so.cache" -# define LDSO_PRELOAD "../util/ld.so.preload" -#else -# define LDSO_CONF UCLIBC_RUNTIME_PREFIX "etc/ld.so.conf" -# define LDSO_CACHE UCLIBC_RUNTIME_PREFIX "etc/ld.so.cache" -# define LDSO_PRELOAD UCLIBC_RUNTIME_PREFIX "etc/ld.so.preload" -#endif - - -#define LIB_ANY -1 -#define LIB_DLL 0 -#define LIB_ELF 1 -#define LIB_ELF64 0x80 -#define LIB_ELF_LIBC5 2 -#define LIB_ELF_LIBC6 3 -#define LIB_ELF_LIBC0 4 - -/* Forward declarations for stuff defined in ld_hash.h */ -struct dyn_elf; -struct elf_resolve; - - -/* Definitions and prototypes for cache stuff */ -#ifdef USE_CACHE -extern int _dl_map_cache(void); -extern int _dl_unmap_cache(void); - -#define LDSO_CACHE_MAGIC "ld.so-" -#define LDSO_CACHE_MAGIC_LEN (sizeof LDSO_CACHE_MAGIC -1) -#define LDSO_CACHE_VER "1.7.0" -#define LDSO_CACHE_VER_LEN (sizeof LDSO_CACHE_VER -1) - -typedef struct { - char magic [LDSO_CACHE_MAGIC_LEN]; - char version [LDSO_CACHE_VER_LEN]; - int nlibs; -} header_t; - -typedef struct { - int flags; - int sooffset; - int liboffset; -} libentry_t; - -#else -static inline void _dl_map_cache(void) { } -static inline void _dl_unmap_cache(void) { } -#endif - - -/* Function prototypes for non-static stuff in readelflib1.c */ -extern int _dl_parse_copy_information(struct dyn_elf *rpnt, - unsigned long rel_addr, unsigned long rel_size, int type); -extern void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, - unsigned long rel_addr, unsigned long rel_size, int type); -extern int _dl_parse_relocation_information(struct dyn_elf *rpnt, - unsigned long rel_addr, unsigned long rel_size, int type); -extern struct elf_resolve * _dl_load_shared_library(int secure, - struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname, - int trace_loaded_objects); -extern struct elf_resolve * _dl_load_elf_shared_library(int secure, - struct dyn_elf **rpnt, char *libname); -extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname, - int trace_loaded_objects); -extern int _dl_linux_resolve(void); -extern int _dl_fixup(struct dyn_elf *rpnt, int flag); - - -/* - * Datatype of a relocation on this platform - */ -#ifdef ELF_USES_RELOCA -# define ELF_RELOC ElfW(Rela) -# define DT_RELOC_TABLE_ADDR DT_RELA -# define DT_RELOC_TABLE_SIZE DT_RELASZ -# define UNSUPPORTED_RELOC_TYPE DT_REL -# define UNSUPPORTED_RELOC_STR "REL" -#else -# define ELF_RELOC ElfW(Rel) -# define DT_RELOC_TABLE_ADDR DT_REL -# define DT_RELOC_TABLE_SIZE DT_RELSZ -# define UNSUPPORTED_RELOC_TYPE DT_RELA -# define UNSUPPORTED_RELOC_STR "RELA" -#endif - - - -/* Convert between the Linux flags for page protections and the - ones specified in the ELF standard. */ -#define LXFLAGS(X) ( (((X) & PF_R) ? PROT_READ : 0) | \ - (((X) & PF_W) ? PROT_WRITE : 0) | \ - (((X) & PF_X) ? PROT_EXEC : 0)) - - -#endif /* LINUXELF_H */ diff --git a/ldso/include/ld_hash.h b/ldso/include/ld_hash.h deleted file mode 100644 index 246ed2608..000000000 --- a/ldso/include/ld_hash.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _LD_HASH_H_ -#define _LD_HASH_H_ - -#ifndef RTLD_NEXT -#define RTLD_NEXT ((void*)-1) -#endif - -struct dyn_elf{ - unsigned long flags; - struct elf_resolve * dyn; - struct dyn_elf * next_handle; /* Used by dlopen et al. */ - struct dyn_elf * next; - struct dyn_elf * prev; -}; - -struct elf_resolve{ - /* These entries must be in this order to be compatible with the interface used - by gdb to obtain the list of symbols. */ - ElfW(Addr) loadaddr; /* Base address shared object is loaded at. */ - char *libname; /* Absolute file name object was found in. */ - ElfW(Dyn) *dynamic_addr; /* Dynamic section of the shared object. */ - struct elf_resolve * next; - struct elf_resolve * prev; - /* Nothing after this address is used by gdb. */ - enum {elf_lib, elf_executable,program_interpreter, loaded_file} libtype; - struct dyn_elf * symbol_scope; - unsigned short usage_count; - unsigned short int init_flag; - unsigned int nbucket; - unsigned long * elf_buckets; - /* - * These are only used with ELF style shared libraries - */ - unsigned long nchain; - unsigned long * chains; - unsigned long dynamic_info[24]; - - unsigned long dynamic_size; - unsigned long n_phent; - Elf32_Phdr * ppnt; - -#if defined(__mips__) - /* Needed for MIPS relocation */ - unsigned long mips_gotsym; - unsigned long mips_local_gotno; - unsigned long mips_symtabno; -#endif - -#ifdef __powerpc__ - /* this is used to store the address of relocation data words, so - * we don't have to calculate it every time, which requires a divide */ - unsigned long data_words; -#endif -}; - -#define COPY_RELOCS_DONE 1 -#define RELOCS_DONE 2 -#define JMP_RELOCS_DONE 4 -#define INIT_FUNCS_CALLED 8 - -extern struct dyn_elf * _dl_symbol_tables; -extern struct elf_resolve * _dl_loaded_modules; -extern struct dyn_elf * _dl_handles; - -extern struct elf_resolve * _dl_check_hashed_files(const char * libname); -extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname, - char * loadaddr, unsigned long * dynamic_info, - unsigned long dynamic_addr, unsigned long dynamic_size); - -enum caller_type{symbolrel=0,copyrel=1,resolver=2}; -extern char * _dl_find_hash(const char * name, struct dyn_elf * rpnt1, - struct elf_resolve * f_tpnt, enum caller_type); - -extern int _dl_linux_dynamic_link(void); - -extern char * _dl_library_path; -extern char * _dl_not_lazy; -extern unsigned long _dl_elf_hash(const char * name); - -static inline int _dl_symbol(char * name) -{ - if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_') - return 0; - return 1; -} - - -#define LD_ERROR_NOFILE 1 -#define LD_ERROR_NOZERO 2 -#define LD_ERROR_NOTELF 3 -#define LD_ERROR_NOTMAGIC 4 -#define LD_ERROR_NOTDYN 5 -#define LD_ERROR_MMAP_FAILED 6 -#define LD_ERROR_NODYNAMIC 7 -#define LD_WRONG_RELOCS 8 -#define LD_BAD_HANDLE 9 -#define LD_NO_SYMBOL 10 - - - -#endif /* _LD_HASH_H_ */ - - diff --git a/ldso/include/ld_string.h b/ldso/include/ld_string.h deleted file mode 100644 index 6fd266fc2..000000000 --- a/ldso/include/ld_string.h +++ /dev/null @@ -1,281 +0,0 @@ -#ifndef _LINUX_STRING_H_ -#define _LINUX_STRING_H_ - -extern void *_dl_malloc(int size); -extern char *_dl_getenv(const char *symbol, char **envp); -extern void _dl_unsetenv(const char *symbol, char **envp); -extern char *_dl_strdup(const char *string); -extern void _dl_dprintf(int, const char *, ...); - - -static size_t _dl_strlen(const char * str); -static char *_dl_strcat(char *dst, const char *src); -static char * _dl_strcpy(char * dst,const char *src); -static int _dl_strcmp(const char * s1,const char * s2); -static int _dl_strncmp(const char * s1,const char * s2,size_t len); -static char * _dl_strchr(const char * str,int c); -static char *_dl_strrchr(const char *str, int c); -static char *_dl_strstr(const char *s1, const char *s2); -static void * _dl_memcpy(void * dst, const void * src, size_t len); -static int _dl_memcmp(const void * s1,const void * s2,size_t len); -static void *_dl_memset(void * str,int c,size_t len); -static char *_dl_get_last_path_component(char *path); -static char *_dl_simple_ltoa(char * local, unsigned long i); -static char *_dl_simple_ltoahex(char * local, unsigned long i); - -#ifndef NULL -#define NULL ((void *) 0) -#endif - -static inline size_t _dl_strlen(const char * str) -{ - register char *ptr = (char *) str; - - while (*ptr) - ptr++; - return (ptr - str); -} - -static inline char *_dl_strcat(char *dst, const char *src) -{ - register char *ptr = dst; - - while (*ptr) - ptr++; - - while (*src) - *ptr++ = *src++; - *ptr = '\0'; - - return dst; -} - -static inline char * _dl_strcpy(char * dst,const char *src) -{ - register char *ptr = dst; - - while (*src) - *dst++ = *src++; - *dst = '\0'; - - return ptr; -} - -static inline int _dl_strcmp(const char * s1,const char * s2) -{ - register unsigned char c1, c2; - - do { - c1 = (unsigned char) *s1++; - c2 = (unsigned char) *s2++; - if (c1 == '\0') - return c1 - c2; - } - while (c1 == c2); - - return c1 - c2; -} - -static inline int _dl_strncmp(const char * s1,const char * s2,size_t len) -{ - register unsigned char c1 = '\0'; - register unsigned char c2 = '\0'; - - while (len > 0) { - c1 = (unsigned char) *s1++; - c2 = (unsigned char) *s2++; - if (c1 == '\0' || c1 != c2) - return c1 - c2; - len--; - } - - return c1 - c2; -} - -static inline char * _dl_strchr(const char * str,int c) -{ - register char ch; - - do { - if ((ch = *str) == c) - return (char *) str; - str++; - } - while (ch); - - return 0; -} - -static inline char *_dl_strrchr(const char *str, int c) -{ - register char *prev = 0; - register char *ptr = (char *) str; - - while (*ptr != '\0') { - if (*ptr == c) - prev = ptr; - ptr++; - } - if (c == '\0') - return(ptr); - return(prev); -} - - -static inline char *_dl_strstr(const char *s1, const char *s2) -{ - register const char *s = s1; - register const char *p = s2; - - do { - if (!*p) { - return (char *) s1;; - } - if (*p == *s) { - ++p; - ++s; - } else { - p = s2; - if (!*s) { - return NULL; - } - s = ++s1; - } - } while (1); -} - -static inline void * _dl_memcpy(void * dst, const void * src, size_t len) -{ - register char *a = dst; - register const char *b = src; - - while (len--) - *a++ = *b++; - - return dst; -} - - -static inline int _dl_memcmp(const void * s1,const void * s2,size_t len) -{ - unsigned char *c1 = (unsigned char *)s1; - unsigned char *c2 = (unsigned char *)s2; - - while (len--) { - if (*c1 != *c2) - return *c1 - *c2; - c1++; - c2++; - } - return 0; -} - -static inline void * _dl_memset(void * str,int c,size_t len) -{ - register char *a = str; - - while (len--) - *a++ = c; - - return str; -} - -static inline char *_dl_get_last_path_component(char *path) -{ - char *s; - register char *ptr = path; - register char *prev = 0; - - while (*ptr) - ptr++; - s = ptr - 1; - - /* strip trailing slashes */ - while (s != path && *s == '/') { - *s-- = '\0'; - } - - /* find last component */ - ptr = path; - while (*ptr != '\0') { - if (*ptr == '/') - prev = ptr; - ptr++; - } - s = prev; - - if (s == NULL || s[1] == '\0') - return path; - else - return s+1; -} - -/* Early on, we can't call printf, so use this to print out - * numbers using the SEND_STDERR() macro */ -static inline char *_dl_simple_ltoa(char * local, unsigned long i) -{ - /* 21 digits plus null terminator, good for 64-bit or smaller ints */ - char *p = &local[22]; - *p-- = '\0'; - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - return p + 1; -} - -static inline char *_dl_simple_ltoahex(char * local, unsigned long i) -{ - /* 21 digits plus null terminator, good for 64-bit or smaller ints */ - char *p = &local[22]; - *p-- = '\0'; - do { - char temp = i % 0x10; - if (temp <= 0x09) - *p-- = '0' + temp; - else - *p-- = 'a' - 0x0a + temp; - i /= 0x10; - } while (i > 0); - *p-- = 'x'; - *p-- = '0'; - return p + 1; -} - - -#if defined(mc68000) || defined(__arm__) || defined(__mips__) || defined(__sh__) || defined(__powerpc__) -/* On some arches constant strings are referenced through the GOT. */ -/* XXX Requires load_addr to be defined. */ -#define SEND_STDERR(X) \ - { const char *__s = (X); \ - if (__s < (const char *) load_addr) __s += load_addr; \ - _dl_write (2, __s, _dl_strlen (__s)); \ - } -#else -#define SEND_STDERR(X) _dl_write(2, X, _dl_strlen(X)); -#endif - -#define SEND_ADDRESS_STDERR(X, add_a_newline) { \ - char tmp[22], *tmp1; \ - _dl_memset(tmp, 0, sizeof(tmp)); \ - tmp1=_dl_simple_ltoahex( tmp, (unsigned long)(X)); \ - _dl_write(2, tmp1, _dl_strlen(tmp1)); \ - if (add_a_newline) { \ - tmp[0]='\n'; \ - _dl_write(2, tmp, 1); \ - } \ -}; - -#define SEND_NUMBER_STDERR(X, add_a_newline) { \ - char tmp[22], *tmp1; \ - _dl_memset(tmp, 0, sizeof(tmp)); \ - tmp1=_dl_simple_ltoa( tmp, (unsigned long)(X)); \ - _dl_write(2, tmp1, _dl_strlen(tmp1)); \ - if (add_a_newline) { \ - tmp[0]='\n'; \ - _dl_write(2, tmp, 1); \ - } \ -}; - - -#endif diff --git a/ldso/include/ld_syscall.h b/ldso/include/ld_syscall.h deleted file mode 100644 index 344a93039..000000000 --- a/ldso/include/ld_syscall.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _LD_SYSCALL_H_ -#define _LD_SYSCALL_H_ - -/* Pull in the arch specific syscall implementation */ -#include -/* For MAP_ANONYMOUS -- differs between platforms */ -#include -/* 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... */ -#define kernel_stat stat -#include -#include - - -/* _dl_open() parameters */ -#define O_RDONLY 0x0000 -#define O_WRONLY 01 -#define O_RDWR 02 -#define O_CREAT 0100 - -/* Encoding of the file mode. */ -#define S_IFMT 0170000 /* These bits determine file type. */ - -/* File types. */ -#define S_IFDIR 0040000 /* Directory. */ -#define S_IFCHR 0020000 /* Character device. */ -#define S_IFBLK 0060000 /* Block device. */ -#define S_IFREG 0100000 /* Regular file. */ -#define S_IFIFO 0010000 /* FIFO. */ -#define S_IFLNK 0120000 /* Symbolic link. */ -#define S_IFSOCK 0140000 /* Socket. */ - -/* Protection bits. */ -#define S_ISUID 04000 /* Set user ID on execution. */ -#define S_ISGID 02000 /* Set group ID on execution. */ -#define S_ISVTX 01000 /* Save swapped text after use (sticky). */ -#define S_IREAD 0400 /* Read by owner. */ -#define S_IWRITE 0200 /* Write by owner. */ -#define S_IEXEC 0100 /* Execute by owner. */ - -/* Stuff for _dl_mmap */ -#if 0 -#define MAP_FAILED ((void *) -1) -#define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED) -#else -#ifndef _dl_MAX_ERRNO -#define _dl_MAX_ERRNO 4096 -#endif -#define _dl_mmap_check_error(__res) \ - (((int)__res) < 0 && ((int)__res) >= -_dl_MAX_ERRNO) -#endif - - - -/* Here are the definitions for some syscalls that are used - by the dynamic linker. The idea is that we want to be able - to call these before the errno symbol is dynamicly linked, so - we use our own version here. Note that we cannot assume any - dynamic linking at all, so we cannot return any error codes. - We just punt if there is an error. */ -#define __NR__dl_exit __NR_exit -static inline _syscall1(void, _dl_exit, int, status); - -#define __NR__dl_close __NR_close -static inline _syscall1(int, _dl_close, int, fd); - -#define __NR__dl_open __NR_open -static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode); - -#define __NR__dl_write __NR_write -static inline _syscall3(unsigned long, _dl_write, int, fd, - const void *, buf, unsigned long, count); - -#define __NR__dl_read __NR_read -static inline _syscall3(unsigned long, _dl_read, int, fd, - const void *, buf, unsigned long, count); - -#define __NR__dl_mprotect __NR_mprotect -static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot); - -#define __NR__dl_stat __NR_stat -static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf); - -#define __NR__dl_munmap __NR_munmap -static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length); - -#define __NR__dl_getuid __NR_getuid -static inline _syscall0(uid_t, _dl_getuid); - -#define __NR__dl_geteuid __NR_geteuid -static inline _syscall0(uid_t, _dl_geteuid); - -#define __NR__dl_getgid __NR_getgid -static inline _syscall0(gid_t, _dl_getgid); - -#define __NR__dl_getegid __NR_getegid -static inline _syscall0(gid_t, _dl_getegid); - -#define __NR__dl_getpid __NR_getpid -static inline _syscall0(gid_t, _dl_getpid); - -#define __NR__dl_readlink __NR_readlink -static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz); - -#if defined(__powerpc__) || defined(__mips__) || defined(__sh__) -/* PowerPC, MIPS and SuperH have a different calling convention for mmap(). */ -#define __NR__dl_mmap __NR_mmap -static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length, - int, prot, int, flags, int, fd, off_t, offset); -#else -#define __NR__dl_mmap_real __NR_mmap -static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer); - -static inline void * _dl_mmap(void * addr, unsigned long size, int prot, - int flags, int fd, unsigned long offset) -{ - unsigned long buffer[6]; - - buffer[0] = (unsigned long) addr; - buffer[1] = (unsigned long) size; - buffer[2] = (unsigned long) prot; - buffer[3] = (unsigned long) flags; - buffer[4] = (unsigned long) fd; - buffer[5] = (unsigned long) offset; - return (void *) _dl_mmap_real(buffer); -} -#endif - - -#endif /* _LD_SYSCALL_H_ */ - diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index 15f76ee80..a23e89355 100644 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -8,10 +8,10 @@ /* Pull in the arch specific type information */ #include /* Now the ldso specific headers */ -#include -#include -#include -#include +#include +#include +#include +#include /* Pull in the arch specific page size */ #include #ifndef PAGE_SIZE diff --git a/ldso/ldso/.cvsignore b/ldso/ldso/.cvsignore index cc73e174c..5fe696107 100644 --- a/ldso/ldso/.cvsignore +++ b/ldso/ldso/.cvsignore @@ -1,2 +1,2 @@ ld-uclibc.so* -_dl_progname.h +dl-progname.h diff --git a/ldso/ldso/Makefile b/ldso/ldso/Makefile index 8b62961fb..bd924b142 100644 --- a/ldso/ldso/Makefile +++ b/ldso/ldso/Makefile @@ -41,7 +41,7 @@ XXFLAGS+=$(shell $(CC) -print-search-dirs | sed -ne "s/install: *\(.*\)/-I\1incl LDFLAGS=$(CPU_LDFLAGS-y) -shared --warn-common --export-dynamic --sort-common \ -z combreloc --discard-locals --discard-all --no-undefined -CSRC= ldso.c startup.c #hash.c readelflib1.c $(TARGET_ARCH)/elfinterp.c +CSRC= ldso.c dl-startup.c COBJS=$(patsubst %.c,%.o, $(CSRC)) ASRC=$(shell ls $(TARGET_ARCH)/*.S) AOBJS=$(patsubst %.S,%.o, $(ASRC)) @@ -68,16 +68,16 @@ XXFLAGS := $(XXFLAGS:-fomit-frame-pointer=) all: lib -lib:: _dl_progname.h $(OBJS) $(DLINK_OBJS) +lib:: dl-progname.h $(OBJS) $(DLINK_OBJS) $(LD) $(LDFLAGS) -e _dl_boot -soname=$(UCLIBC_LDSO) \ -o $(LDSO_FULLNAME) $(OBJS) $(LIBGCC); $(INSTALL) -d $(TOPDIR)lib $(INSTALL) -m 755 $(LDSO_FULLNAME) $(TOPDIR)lib $(LN) -sf $(LDSO_FULLNAME) $(TOPDIR)lib/$(UCLIBC_LDSO) -_dl_progname.h: Makefile - echo "const char *_dl_progname=\""$(UCLIBC_LDSO)"\";" > _dl_progname.h - echo "#include \"$(TARGET_ARCH)/elfinterp.c\"" >> _dl_progname.h +dl-progname.h: Makefile + echo "const char *_dl_progname=\""$(UCLIBC_LDSO)"\";" > dl-progname.h + echo "#include \"$(TARGET_ARCH)/elfinterp.c\"" >> dl-progname.h $(COBJS): %.o : %.c @@ -91,4 +91,4 @@ $(AOBJS): %.o : %.S ldso.o: $(CSRC) clean: - $(RM) $(UCLIBC_LDSO)* $(OBJS) $(LDSO_FULLNAME)* core *.o *.a *.s *.i _dl_progname.h ldso.h *~ + $(RM) $(UCLIBC_LDSO)* $(OBJS) $(LDSO_FULLNAME)* core *.o *.a *.s *.i dl-progname.h ldso.h *~ diff --git a/ldso/ldso/arm/boot1_arch.h b/ldso/ldso/arm/boot1_arch.h deleted file mode 100644 index 383fe4e1f..000000000 --- a/ldso/ldso/arm/boot1_arch.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. */ - -/* Overrive the default _dl_boot function, and replace it with a bit of asm. - * Then call the real _dl_boot function, which is now named _dl_boot2. */ - -asm("" \ -" .text\n" \ -" .globl _dl_boot\n" \ -"_dl_boot:\n" \ -" mov r7, sp\n" \ -" @ldr r0, [sp], #4\n" \ -" mov r0, sp\n" \ -" bl _dl_boot2\n" \ -" mov r6, r0\n" \ -" mov r0, r7\n" \ -" mov pc, r6\n" \ -); - - /* It seems ARM needs an offset here */ -#undef ELFMAGIC -#define ELFMAGIC ELFMAG+load_addr - -#define DL_BOOT(X) static void __attribute__ ((unused)) _dl_boot2 (X) diff --git a/ldso/ldso/arm/ld_syscalls.h b/ldso/ldso/arm/ld_syscalls.h deleted file mode 100644 index dbf1634e0..000000000 --- a/ldso/ldso/arm/ld_syscalls.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Define the __set_errno macro as nothing so that INLINE_SYSCALL - * won't set errno, which is important since we make system calls - * before the errno symbol is dynamicly linked. */ - -#define __set_errno(X) {(void)(X);} - -/* Prepare for the case that `__builtin_expect' is not available. */ -#if __GNUC__ == 2 && __GNUC_MINOR__ < 96 -#define __builtin_expect(x, expected_value) (x) -#endif -#ifndef likely -# define likely(x) __builtin_expect((!!(x)),1) -#endif -#ifndef unlikely -# define unlikely(x) __builtin_expect((!!(x)),0) -#endif - -#include "sys/syscall.h" - diff --git a/ldso/ldso/arm/ld_sysdep.h b/ldso/ldso/arm/ld_sysdep.h deleted file mode 100644 index 04e504eda..000000000 --- a/ldso/ldso/arm/ld_sysdep.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Various assmbly language/system dependent hacks that are required - * so that we can minimize the amount of platform specific code. - */ - -/* - * Define this if the system uses RELOCA. - */ -#undef ELF_USES_RELOCA - -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS) - -/* - * Initialization sequence for a GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -{ \ - GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ - GOT_BASE[1] = (unsigned long) MODULE; \ -} - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch(ELF32_R_TYPE((RELP)->r_info)){ \ - case R_ARM_ABS32: \ - *REL += SYMBOL; \ - break; \ - case R_ARM_PC24: \ - { long newvalue, topbits; \ - unsigned long addend = *REL & 0x00ffffff; \ - if (addend & 0x00800000) addend |= 0xff000000; \ - newvalue=SYMBOL-(unsigned long)REL+(addend<<2); \ - topbits = newvalue & 0xfe000000; \ - if (topbits!=0xfe000000&&topbits!=0x00000000){ \ - newvalue = fix_bad_pc24(REL, SYMBOL) \ - -(unsigned long)REL+(addend<<2); \ - topbits = newvalue & 0xfe000000; \ - if (topbits!=0xfe000000&&topbits!=0x00000000){ \ - SEND_STDERR("R_ARM_PC24 relocation out of range\n");\ - _dl_exit(1); } } \ - newvalue>>=2; \ - SYMBOL=(*REL&0xff000000)|(newvalue & 0x00ffffff); \ - *REL=SYMBOL; \ - } \ - break; \ - case R_ARM_GLOB_DAT: \ - case R_ARM_JUMP_SLOT: \ - *REL = SYMBOL; \ - break; \ - case R_ARM_RELATIVE: \ - *REL += (unsigned long) LOAD; \ - break; \ - case R_ARM_NONE: \ - break; \ - default: \ - SEND_STDERR("Aiieeee!"); \ - _dl_exit(1); \ - } - - -/* - * Transfer control to the user's application, once the dynamic loader - * is done. This routine has to exit the current function, then - * call the _dl_elf_main function. - */ - -#define START() return _dl_elf_main; - - - -/* Here we define the magic numbers that this dynamic loader should accept */ - -#define MAGIC1 EM_ARM -#undef MAGIC2 -/* Used for error messages */ -#define ELF_TARGET "ARM" - -struct elf_resolve; -unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - -static inline unsigned long arm_modulus(unsigned long m, unsigned long p) { - unsigned long i,t,inc; - i=p; t=0; - while(!(i&(1<<31))) { - i<<=1; - t++; - } - t--; - for(inc=t;inc>2;inc--) { - i=p<=i) { - m-=i; - i<<=1; - if(i&(1<<31)) - break; - if(i=p) { - m-=p; - } - return m; -} - -#define do_rem(result, n, base) result=arm_modulus(n,base); - -/* 4096 bytes alignment */ -#define PAGE_ALIGN 0xfffff000 -#define ADDR_ALIGN 0xfff -#define OFFS_ALIGN 0x7ffff000 diff --git a/ldso/ldso/cris/boot1_arch.h b/ldso/ldso/cris/boot1_arch.h deleted file mode 100644 index bf7714539..000000000 --- a/ldso/ldso/cris/boot1_arch.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * This code fix the stack pointer so that the dynamic linker - * can find argc, argv and auxvt (Auxillary Vector Table). - */ -asm("" \ -" .text\n" \ -" .globl _dl_boot\n" \ -" .type _dl_boot,@function\n" \ -"_dl_boot:\n" \ -" move.d $sp,$r10\n" \ -" move.d $pc,$r9\n" \ -" add.d _dl_boot2 - ., $r9\n" \ -" jsr $r9\n" \ -); - -#define DL_BOOT(X) static void __attribute__ ((unused)) _dl_boot2 (X) diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h index c127076ff..7066863f6 100644 --- a/ldso/ldso/cris/dl-sysdep.h +++ b/ldso/ldso/cris/dl-sysdep.h @@ -66,7 +66,7 @@ struct elf_resolve; extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry); -/* Cheap modulo implementation, taken from arm/ld_sysdep.h. */ +/* Cheap modulo implementation, taken from arm/dl-sysdep.h. */ static inline unsigned long cris_mod(unsigned long m, unsigned long p) { diff --git a/ldso/ldso/cris/ld_syscalls.h b/ldso/ldso/cris/ld_syscalls.h deleted file mode 100644 index 651280c18..000000000 --- a/ldso/ldso/cris/ld_syscalls.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Define the __set_errno macro as nothing so that INLINE_SYSCALL - * won't set errno, which is important since we make system calls - * before the errno symbol is dynamicly linked. - */ -#define __set_errno(X) {(void)(X);} -#include "sys/syscall.h" diff --git a/ldso/ldso/cris/ld_sysdep.h b/ldso/ldso/cris/ld_sysdep.h deleted file mode 100644 index c127076ff..000000000 --- a/ldso/ldso/cris/ld_sysdep.h +++ /dev/null @@ -1,112 +0,0 @@ -/* CRIS can never use Elf32_Rel relocations. */ -#define ELF_USES_RELOCA - -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS) - -/* - * Initialization sequence for a GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -{ \ - GOT_BASE[1] = (unsigned long) MODULE; \ - GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ -} - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP, REL, SYMBOL, LOAD, SYMTAB) \ - switch (ELF32_R_TYPE((RELP)->r_info)) { \ - case R_CRIS_GLOB_DAT: \ - case R_CRIS_JUMP_SLOT: \ - case R_CRIS_32: \ - *REL = SYMBOL; \ - break; \ - case R_CRIS_16_PCREL: \ - *(short *) *REL = SYMBOL + (RELP)->r_addend - *REL - 2; \ - break; \ - case R_CRIS_32_PCREL: \ - *REL = SYMBOL + (RELP)->r_addend - *REL - 4; \ - break; \ - case R_CRIS_NONE: \ - break; \ - case R_CRIS_RELATIVE: \ - *REL = (unsigned long) LOAD + (RELP)->r_addend; \ - break; \ - default: \ - _dl_exit(1); \ - break; \ - } - -/* - * Transfer control to the user's application once the dynamic loader - * is done. This routine has to exit the current function, then call - * _dl_elf_main. - */ -#define START() __asm__ volatile ("moveq 0,$r8\n\t" \ - "move $r8,$srp\n\t" \ - "move.d %1,$sp\n\t" \ - "jump %0\n\t" \ - : : "r" (_dl_elf_main), "r" (args)) - -/* Defined some magic numbers that this ld.so should accept. */ -#define MAGIC1 EM_CRIS -#undef MAGIC2 -#define ELF_TARGET "CRIS" - -struct elf_resolve; -extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry); - -/* Cheap modulo implementation, taken from arm/ld_sysdep.h. */ -static inline unsigned long -cris_mod(unsigned long m, unsigned long p) -{ - unsigned long i, t, inc; - - i = p; - t = 0; - - while (!(i & (1 << 31))) { - i <<= 1; - t++; - } - - t--; - - for (inc = t; inc > 2; inc--) { - i = p << inc; - - if (i & (1 << 31)) - break; - - while (m >= i) { - m -= i; - i <<= 1; - if (i & (1 << 31)) - break; - if (i < p) - break; - } - } - - while (m >= p) - m -= p; - - return m; -} - -#define do_rem(result, n, base) result = cris_mod(n, base); - -/* 8192 bytes alignment */ -#define PAGE_ALIGN 0xffffe000 -#define ADDR_ALIGN 0x1fff -#define OFFS_ALIGN 0xffffe000 diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index 6a131633a..f40207996 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -90,7 +90,7 @@ #include "ldso.h" -/* Some arches may need to override this in boot1_arch.h */ +/* Some arches may need to override this in dl-startup.h */ #define ELFMAGIC ELFMAG /* This is a poor man's malloc, used prior to resolving our internal poor man's malloc */ @@ -102,7 +102,7 @@ #define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3)) /* Pull in all the arch specific stuff */ -#include "boot1_arch.h" +#include "dl-startup.h" /* Static declarations */ int (*_dl_elf_main) (int, char **, char **); diff --git a/ldso/ldso/hash.c b/ldso/ldso/hash.c deleted file mode 100644 index c33b329ec..000000000 --- a/ldso/ldso/hash.c +++ /dev/null @@ -1,262 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Program to load an ELF binary on a linux system, and run it - * after resolving ELF shared library symbols - * - * Copyright (C) 2004 by Joakim Tjernlund - * Copyright (C) 2000-2004 by Erik Andersen - * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, - * David Engel, Hongjiu Lu and Mitch D'Souza - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the above contributors may not be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -/* Various symbol table handling functions, including symbol lookup */ - -/* - * This is the start of the linked list that describes all of the files present - * in the system with pointers to all of the symbol, string, and hash tables, - * as well as all of the other good stuff in the binary. - */ -struct elf_resolve *_dl_loaded_modules = NULL; - -/* - * This is the list of modules that are loaded when the image is first - * started. As we add more via dlopen, they get added into other - * chains. - */ -struct dyn_elf *_dl_symbol_tables = NULL; - -/* - * This is the list of modules that are loaded via dlopen. We may need - * to search these for RTLD_GLOBAL files. - */ -struct dyn_elf *_dl_handles = NULL; - - -/* This is the hash function that is used by the ELF linker to generate the - * hash table that each executable and library is required to have. We need - * it to decode the hash table. */ -unsigned long _dl_elf_hash(const char *name) -{ - unsigned long hash = 0; - unsigned long tmp; - - while (*name) { - hash = (hash << 4) + *name++; - if ((tmp = hash & 0xf0000000)) - hash ^= tmp >> 24; - hash &= ~tmp; - }; - return hash; -} - -/* Check to see if a library has already been added to the hash chain. */ -struct elf_resolve *_dl_check_hashed_files(const char *libname) -{ - struct elf_resolve *tpnt; - int len = _dl_strlen(libname); - - for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { - if (_dl_strncmp(tpnt->libname, libname, len) == 0 && - (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.')) - return tpnt; - } - - return NULL; -} - -/* - * We call this function when we have just read an ELF library or executable. - * We add the relevant info to the symbol chain, so that we can resolve all - * externals properly. - */ -struct elf_resolve *_dl_add_elf_hash_table(const char *libname, - char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr, - unsigned long dynamic_size) -{ - unsigned long *hash_addr; - struct elf_resolve *tpnt; - int i; - - if (!_dl_loaded_modules) { - tpnt = _dl_loaded_modules = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve)); - _dl_memset(tpnt, 0, sizeof(struct elf_resolve)); - } else { - tpnt = _dl_loaded_modules; - while (tpnt->next) - tpnt = tpnt->next; - tpnt->next = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve)); - _dl_memset(tpnt->next, 0, sizeof(struct elf_resolve)); - tpnt->next->prev = tpnt; - tpnt = tpnt->next; - }; - - tpnt->next = NULL; - tpnt->init_flag = 0; - tpnt->libname = _dl_strdup(libname); - tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr; - tpnt->dynamic_size = dynamic_size; - tpnt->libtype = loaded_file; - - if (dynamic_info[DT_HASH] != 0) { - hash_addr = (unsigned long *) (intptr_t)(dynamic_info[DT_HASH] + loadaddr); - tpnt->nbucket = *hash_addr++; - tpnt->nchain = *hash_addr++; - tpnt->elf_buckets = hash_addr; - hash_addr += tpnt->nbucket; - tpnt->chains = hash_addr; - } - tpnt->loadaddr = (ElfW(Addr))loadaddr; - for (i = 0; i < 24; i++) - tpnt->dynamic_info[i] = dynamic_info[i]; -#ifdef __mips__ - { - Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr; - - while(dpnt->d_tag) { - if (dpnt->d_tag == DT_MIPS_GOTSYM) - tpnt->mips_gotsym = dpnt->d_un.d_val; - if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO) - tpnt->mips_local_gotno = dpnt->d_un.d_val; - if (dpnt->d_tag == DT_MIPS_SYMTABNO) - tpnt->mips_symtabno = dpnt->d_un.d_val; - dpnt++; - } - } -#endif - return tpnt; -} - - -/* - * This function resolves externals, and this is either called when we process - * relocations or when we call an entry in the PLT table for the first time. - */ -char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1, - struct elf_resolve *f_tpnt, enum caller_type caller_type) -{ - struct elf_resolve *tpnt; - int si; - int pass; - char *strtab; - Elf32_Sym *symtab; - unsigned long elf_hash_number, hn; - char *weak_result; - struct dyn_elf *rpnt, first; - const ElfW(Sym) *sym; - - weak_result = 0; - elf_hash_number = _dl_elf_hash(name); - - /* A quick little hack to make sure that any symbol in the executable - will be preferred to one in a shared library. This is necessary so - that any shared library data symbols referenced in the executable - will be seen at the same address by the executable, shared libraries - and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */ - if (_dl_symbol_tables && rpnt1) { - first = (*_dl_symbol_tables); - first.next = rpnt1; - rpnt1 = (&first); - } - - /* - * The passes are so that we can first search the regular symbols - * for whatever module was specified, and then search anything - * loaded with RTLD_GLOBAL. When pass is 1, it means we are just - * starting the first dlopened module, and anything above that - * is just the next one in the chain. - */ - for (pass = 0; (1 == 1); pass++) { - - /* - * If we are just starting to search for RTLD_GLOBAL, setup - * the pointer for the start of the search. - */ - if (pass == 1) { - rpnt1 = _dl_handles; - } - - /* - * Anything after this, we need to skip to the next module. - */ - else if (pass >= 2) { - rpnt1 = rpnt1->next_handle; - } - - /* - * Make sure we still have a module, and make sure that this - * module was loaded with RTLD_GLOBAL. - */ - if (pass != 0) { - if (rpnt1 == NULL) - break; - //if ((rpnt1->flags & RTLD_GLOBAL) == 0) - //continue; - } - - for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) { - tpnt = rpnt->dyn; - - /* Don't search the executable when resolving a copy reloc. */ - if (tpnt->libtype == elf_executable && caller_type == copyrel) - continue; - - /* - * Avoid calling .urem here. - */ - do_rem(hn, elf_hash_number, tpnt->nbucket); - symtab = (Elf32_Sym *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr); - strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); - - for (si = tpnt->elf_buckets[hn]; si != STN_UNDEF; si = tpnt->chains[si]) { - sym = &symtab[si]; - - if (sym->st_value == 0) - continue; - if (ELF32_ST_TYPE(sym->st_info) > STT_FUNC) - continue; - if (sym->st_shndx == SHN_UNDEF && caller_type != copyrel) - continue; - if (_dl_strcmp(strtab + sym->st_name, name) != 0) - continue; - - switch (ELF32_ST_BIND(sym->st_info)) { - case STB_WEAK: -//Disable this to match current glibc behavior. Of course, -//this doesn't actually work yet and will cause segfaults... -#if 1 - if (!weak_result) - weak_result = (char *)tpnt->loadaddr + sym->st_value; - break; -#endif - case STB_GLOBAL: - return (char*)tpnt->loadaddr + sym->st_value; - default: /* Local symbols not handled here */ - break; - } - } - } - } - return weak_result; -} diff --git a/ldso/ldso/i386/boot1_arch.h b/ldso/ldso/i386/boot1_arch.h deleted file mode 100644 index 42c96a6f5..000000000 --- a/ldso/ldso/i386/boot1_arch.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. See arm/boot1_arch.h for an example of what - * can be done. - */ - -#define DL_BOOT(X) void __attribute__ ((unused)) _dl_boot (X) diff --git a/ldso/ldso/i386/ld_syscalls.h b/ldso/ldso/i386/ld_syscalls.h deleted file mode 100644 index c020832bb..000000000 --- a/ldso/ldso/i386/ld_syscalls.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Define the __set_errno macro as nothing so that INLINE_SYSCALL - * won't set errno, which is important since we make system calls - * before the errno symbol is dynamicly linked. */ - -#define __set_errno(X) {(void)(X);} -#include "sys/syscall.h" - diff --git a/ldso/ldso/i386/ld_sysdep.h b/ldso/ldso/i386/ld_sysdep.h deleted file mode 100644 index f39a1966c..000000000 --- a/ldso/ldso/i386/ld_sysdep.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Various assmbly language/system dependent hacks that are required - * so that we can minimize the amount of platform specific code. - */ - -/* - * Define this if the system uses RELOCA. - */ -#undef ELF_USES_RELOCA - -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) & ARGS) - -/* - * Initialization sequence for a GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -do { \ - GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ - GOT_BASE[1] = (unsigned long) MODULE; \ -} while(0) - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch(ELF32_R_TYPE((RELP)->r_info)){ \ - case R_386_32: \ - *REL += SYMBOL; \ - break; \ - case R_386_PC32: \ - *REL += SYMBOL - (unsigned long) REL; \ - break; \ - case R_386_GLOB_DAT: \ - case R_386_JMP_SLOT: \ - *REL = SYMBOL; \ - break; \ - case R_386_RELATIVE: \ - *REL += (unsigned long) LOAD; \ - break; \ - default: \ - _dl_exit(1); \ - } - - -/* - * Transfer control to the user's application, once the dynamic loader - * is done. This routine has to exit the current function, then - * call the _dl_elf_main function. - */ -#define START() \ - __asm__ volatile ("leave\n\t" \ - "jmp *%%eax\n\t" \ - : "=a" (status) : "a" (_dl_elf_main)) - - - -/* Here we define the magic numbers that this dynamic loader should accept */ - -#define MAGIC1 EM_386 -#undef MAGIC2 -/* Used for error messages */ -#define ELF_TARGET "386" - -struct elf_resolve; -extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - -#define do_rem(result, n, base) result = (n % base) - -/* 4096 bytes alignment */ -#define PAGE_ALIGN 0xfffff000 -#define ADDR_ALIGN 0xfff -#define OFFS_ALIGN 0x7ffff000 diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 064323bf7..0b0cb1389 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -35,7 +35,7 @@ #define ALLOW_ZERO_PLTGOT /* Pull in the value of _dl_progname */ -#include "_dl_progname.h" +#include "dl-progname.h" /* Global variables used within the shared library loader */ char *_dl_library_path = 0; /* Where we look for libraries */ @@ -767,5 +767,5 @@ static int _dl_suid_ok(void) return 0; } -#include "hash.c" -#include "readelflib1.c" +#include "dl-hash.c" +#include "dl-elf.c" diff --git a/ldso/ldso/m68k/boot1_arch.h b/ldso/ldso/m68k/boot1_arch.h deleted file mode 100644 index 42c96a6f5..000000000 --- a/ldso/ldso/m68k/boot1_arch.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. See arm/boot1_arch.h for an example of what - * can be done. - */ - -#define DL_BOOT(X) void __attribute__ ((unused)) _dl_boot (X) diff --git a/ldso/ldso/m68k/ld_syscalls.h b/ldso/ldso/m68k/ld_syscalls.h deleted file mode 100644 index 1fb2cccd2..000000000 --- a/ldso/ldso/m68k/ld_syscalls.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file contains the system call macros and syscall - * numbers used by the shared library loader. - */ - -#define __NR_exit 1 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_getuid 24 -#define __NR_geteuid 49 -#define __NR_getgid 47 -#define __NR_getegid 50 -#define __NR_readlink 85 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_stat 106 -#define __NR_mprotect 125 - - -/* Here are the macros which define how this platform makes - * system calls. This particular variant does _not_ set - * errno (note how it is disabled in __syscall_return) since - * these will get called before the errno symbol is dynamicly - * linked. */ - - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-125)) { \ - /* avoid using res which is declared to be in register d0; \ - errno might expand to a function call and clobber it. */ \ - /* int __err = -(res); \ - errno = __err; */ \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -#define _syscall0(type, name) \ -type name(void) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name) \ - : "cc", "%d0"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - /* errno = -__res; */ \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall1(type, name, atype, a) \ -type name(atype a) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "g" ((long)a) \ - : "cc", "%d0", "%d1"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - /* errno = -__res; */ \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall2(type, name, atype, a, btype, b) \ -type name(atype a, btype b) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %3, %%d2\n\t" \ - "movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "a" ((long)a), \ - "g" ((long)b) \ - : "cc", "%d0", "%d1", "%d2"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - /* errno = -__res; */ \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall3(type, name, atype, a, btype, b, ctype, c) \ -type name(atype a, btype b, ctype c) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %4, %%d3\n\t" \ - "movel %3, %%d2\n\t" \ - "movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "a" ((long)a), \ - "a" ((long)b), \ - "g" ((long)c) \ - : "cc", "%d0", "%d1", "%d2", "%d3"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - /* errno = -__res; */ \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \ -type name(atype a, btype b, ctype c, dtype d) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %5, %%d4\n\t" \ - "movel %4, %%d3\n\t" \ - "movel %3, %%d2\n\t" \ - "movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "a" ((long)a), \ - "a" ((long)b), \ - "a" ((long)c), \ - "g" ((long)d) \ - : "cc", "%d0", "%d1", "%d2", "%d3", \ - "%d4"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - /* errno = -__res; */ \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e)\ -type name(atype a, btype b, ctype c, dtype d, etype e) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %6, %%d5\n\t" \ - "movel %5, %%d4\n\t" \ - "movel %4, %%d3\n\t" \ - "movel %3, %%d2\n\t" \ - "movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "a" ((long)a), \ - "a" ((long)b), \ - "a" ((long)c), \ - "a" ((long)d), \ - "g" ((long)e) \ - : "cc", "%d0", "%d1", "%d2", "%d3", \ - "%d4", "%d5"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - /* errno = -__res; */ \ - __res = -1; \ - } \ - return (type)__res; \ -} - diff --git a/ldso/ldso/m68k/ld_sysdep.h b/ldso/ldso/m68k/ld_sysdep.h deleted file mode 100644 index 2cbc7d46b..000000000 --- a/ldso/ldso/m68k/ld_sysdep.h +++ /dev/null @@ -1,88 +0,0 @@ - -/* Various assmbly language/system dependent hacks that are required - so that we can minimize the amount of platform specific code. */ - -/* Define this if the system uses RELOCA. */ -#define ELF_USES_RELOCA - -/* Get a pointer to the argv array. On many platforms this can be - just the address if the first argument, on other platforms we need - to do something a little more subtle here. */ -#define GET_ARGV(ARGVP, ARGS) ((ARGVP) = ((unsigned int *) &(ARGS))) - -/* Initialization sequence for a GOT. */ -#define INIT_GOT(GOT_BASE,MODULE) \ -{ \ - GOT_BASE[2] = (int) _dl_linux_resolve; \ - GOT_BASE[1] = (int) (MODULE); \ -} - -/* Here is a macro to perform a relocation. This is only used when - bootstrapping the dynamic loader. RELP is the relocation that we - are performing, REL is the pointer to the address we are - relocating. SYMBOL is the symbol involved in the relocation, and - LOAD is the load address. */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch (ELF32_R_TYPE ((RELP)->r_info)) \ - { \ - case R_68K_8: \ - *(char *) (REL) = (SYMBOL) + (RELP)->r_addend; \ - break; \ - case R_68K_16: \ - *(short *) (REL) = (SYMBOL) + (RELP)->r_addend; \ - break; \ - case R_68K_32: \ - *(REL) = (SYMBOL) + (RELP)->r_addend; \ - break; \ - case R_68K_PC8: \ - *(char *) (REL) = ((SYMBOL) + (RELP)->r_addend \ - - (unsigned int) (REL)); \ - break; \ - case R_68K_PC16: \ - *(short *) (REL) = ((SYMBOL) + (RELP)->r_addend \ - - (unsigned int) (REL)); \ - break; \ - case R_68K_PC32: \ - *(REL) = ((SYMBOL) + (RELP)->r_addend \ - - (unsigned int) (REL)); \ - break; \ - case R_68K_GLOB_DAT: \ - case R_68K_JMP_SLOT: \ - *(REL) = (SYMBOL); \ - break; \ - case R_68K_RELATIVE: /* Compatibility kludge */ \ - *(REL) = ((unsigned int) (LOAD) + ((RELP)->r_addend ? : *(REL))); \ - break; \ - default: \ - _dl_exit (1); \ - } - - -/* Transfer control to the user's application, once the dynamic loader - is done. */ - -#define START() \ - __asm__ volatile ("unlk %%a6\n\t" \ - "jmp %0@" \ - : : "a" (_dl_elf_main)); - - - -/* Here we define the magic numbers that this dynamic loader should accept */ - -#define MAGIC1 EM_68K -#undef MAGIC2 -/* Used for error messages */ -#define ELF_TARGET "m68k" - -struct elf_resolve; -extern unsigned int _dl_linux_resolver (int, int, struct elf_resolve *, int); - -/* Define this because we do not want to call .udiv in the library. - Not needed for m68k. */ -#define do_rem(result, n, base) ((result) = (n) % (base)) - -/* 4096 bytes alignment */ -#define PAGE_ALIGN 0xfffff000 -#define ADDR_ALIGN 0xfff -#define OFFS_ALIGN 0x7ffff000 diff --git a/ldso/ldso/mips/README b/ldso/ldso/mips/README index 1cf6301e5..9ca6a869b 100644 --- a/ldso/ldso/mips/README +++ b/ldso/ldso/mips/README @@ -18,7 +18,7 @@ contains the function to perform relocations for objects other than the linker itself. The code was taken from the function 'elf_machine_rel' in 'sysdeps/mips/dl-machine.h'. -ld_syscalls.h +dl-syscalls.h ------------- Used to contain all the macro functions for the system calls as well as the list of system calls supported. We now include @@ -27,7 +27,7 @@ so we can use the same file for the linker as well as userspace. Original code was taken from the Linux kernel source 2.4.17 and can be found in the file 'include/asm-mips/unistd.h'. -ld_sysdep.h +dl-sysdep.h ----------- Contains bootstrap code for the dynamic linker, magic numbers for detecting MIPS target types and some macros. The macro diff --git a/ldso/ldso/mips/boot1_arch.h b/ldso/ldso/mips/boot1_arch.h deleted file mode 100644 index 886f8b8b8..000000000 --- a/ldso/ldso/mips/boot1_arch.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. - */ - -asm("" \ -" .text\n" \ -" .globl _dl_boot\n" \ -"_dl_boot:\n" \ -" .set noreorder\n" \ -" bltzal $0, 0f\n" \ -" nop\n" \ -"0: .cpload $31\n" \ -" .set reorder\n" \ -" la $4, _DYNAMIC\n" \ -" sw $4, -0x7ff0($28)\n" \ -" move $4, $29\n" \ -" la $8, coff\n" \ -" .set noreorder\n" \ -" bltzal $0, coff\n" \ -" nop\n" \ -"coff: subu $8, $31, $8\n" \ -" .set reorder\n" \ -" la $25, _dl_boot2\n" \ -" addu $25, $8\n" \ -" jalr $25\n" \ -" lw $4, 0($29)\n" \ -" la $5, 4($29)\n" \ -" sll $6, $4, 2\n" \ -" addu $6, $6, $5\n" \ -" addu $6, $6, 4\n" \ -" la $7, _dl_elf_main\n" \ -" lw $25, 0($7)\n" \ -" jr $25\n" \ -); - -#define DL_BOOT(X) static void __attribute__ ((unused)) _dl_boot2 (X) diff --git a/ldso/ldso/mips/ld_syscalls.h b/ldso/ldso/mips/ld_syscalls.h deleted file mode 100644 index e4a1ff9c4..000000000 --- a/ldso/ldso/mips/ld_syscalls.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Define the __set_errno macro as nothing so that we don't bother - * setting errno, which is important since we make system calls - * before the errno symbol is dynamicly linked. */ - -#define __set_errno(X) {(void)(X);} -#include "sys/syscall.h" - diff --git a/ldso/ldso/mips/ld_sysdep.h b/ldso/ldso/mips/ld_sysdep.h deleted file mode 100644 index 17ce7cf71..000000000 --- a/ldso/ldso/mips/ld_sysdep.h +++ /dev/null @@ -1,136 +0,0 @@ -/* vi: set sw=4 ts=4: */ - -/* - * Various assmbly language/system dependent hacks that are required - * so that we can minimize the amount of platform specific code. - */ - -/* - * Define this if the system uses RELOCA. - */ -#undef ELF_USES_RELOCA - - -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS) - - -/* - * Initialization sequence for the application/library GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -do { \ - unsigned long i; \ - \ - /* Check if this is the dynamic linker itself */ \ - if (MODULE->libtype == program_interpreter) \ - continue; \ - \ - /* Fill in first two GOT entries according to the ABI */ \ - GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \ - GOT_BASE[1] = (unsigned long) MODULE; \ - \ - /* Add load address displacement to all local GOT entries */ \ - i = 2; \ - while (i < MODULE->mips_local_gotno) \ - GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \ - \ -} while (0) - - -/* - * Here is a macro to perform the GOT relocation. This is only - * used when bootstrapping the dynamic loader. - */ -#define PERFORM_BOOTSTRAP_GOT(got) \ -do { \ - Elf32_Sym *sym; \ - unsigned long i; \ - \ - /* Add load address displacement to all local GOT entries */ \ - i = 2; \ - while (i < tpnt->mips_local_gotno) \ - got[i++] += load_addr; \ - \ - /* Handle global GOT entries */ \ - got += tpnt->mips_local_gotno; \ - sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + \ - load_addr) + tpnt->mips_gotsym; \ - i = tpnt->mips_symtabno - tpnt->mips_gotsym; \ - \ - while (i--) { \ - if (sym->st_shndx == SHN_UNDEF || \ - sym->st_shndx == SHN_COMMON) \ - *got = load_addr + sym->st_value; \ - else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \ - *got != sym->st_value) \ - *got += load_addr; \ - else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) { \ - if (sym->st_other == 0) \ - *got += load_addr; \ - } \ - else \ - *got = load_addr + sym->st_value; \ - \ - got++; \ - sym++; \ - } \ -} while (0) - - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch(ELF32_R_TYPE((RELP)->r_info)) { \ - case R_MIPS_REL32: \ - if (symtab_index) { \ - if (symtab_index < tpnt->mips_gotsym) \ - *REL += SYMBOL; \ - } \ - else { \ - *REL += LOAD; \ - } \ - break; \ - case R_MIPS_NONE: \ - break; \ - default: \ - SEND_STDERR("Aiieeee!"); \ - _dl_exit(1); \ - } - - -/* - * Transfer control to the user's application, once the dynamic loader - * is done. This routine has to exit the current function, then - * call the _dl_elf_main function. For MIPS, we do it in assembly - * because the stack doesn't get properly restored otherwise. Got look - * at boot1_arch.h - */ -#define START() - - -/* Here we define the magic numbers that this dynamic loader should accept */ -#define MAGIC1 EM_MIPS -#define MAGIC2 EM_MIPS_RS3_LE - - -/* Used for error messages */ -#define ELF_TARGET "MIPS" - - -unsigned long _dl_linux_resolver(unsigned long sym_index, - unsigned long old_gpreg); - - -#define do_rem(result, n, base) result = (n % base) - -/* 4096 bytes alignment */ -#define PAGE_ALIGN 0xfffff000 -#define ADDR_ALIGN 0xfff -#define OFFS_ALIGN 0x7ffff000 diff --git a/ldso/ldso/powerpc/boot1_arch.h b/ldso/ldso/powerpc/boot1_arch.h deleted file mode 100644 index 70e494331..000000000 --- a/ldso/ldso/powerpc/boot1_arch.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. */ - -/* Overrive the default _dl_boot function, and replace it with a bit of asm. - * Then call the real _dl_boot function, which is now named _dl_boot2. */ - -asm("" \ -" .text\n" \ -" .globl _dl_boot\n" \ -"_dl_boot:\n" \ -" mr 3,1\n" \ -" li 4,0\n" \ -" addi 1,1,-16\n" \ -" stw 4,0(1)\n" \ -" bl _dl_boot2\n" \ -".previous\n" \ -); - -#define DL_BOOT(X) static void __attribute__ ((unused)) _dl_boot2(X) diff --git a/ldso/ldso/powerpc/ld_syscalls.h b/ldso/ldso/powerpc/ld_syscalls.h deleted file mode 100644 index 3e561d661..000000000 --- a/ldso/ldso/powerpc/ld_syscalls.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * This file contains the system call macros and syscall - * numbers used by the shared library loader. - */ - -#define __NR_exit 1 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_getpid 20 -#define __NR_getuid 24 -#define __NR_geteuid 49 -#define __NR_getgid 47 -#define __NR_getegid 50 -#define __NR_readlink 85 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_stat 106 -#define __NR_mprotect 125 - -/* Here are the macros which define how this platform makes - * system calls. This particular variant does _not_ set - * errno (note how it is disabled in __syscall_return) since - * these will get called before the errno symbol is dynamicly - * linked. */ - -#undef __syscall_return -#define __syscall_return(type) \ - return (__sc_err & 0x10000000 ? /*errno = __sc_ret,*/ __sc_ret = -1 : 0), \ - (type) __sc_ret - -#undef __syscall_clobbers -#define __syscall_clobbers \ - "r9", "r10", "r11", "r12" - //"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" - -#undef _syscall0 -#define _syscall0(type,name) \ -type name(void) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0) \ - : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#undef _syscall1 -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0) \ - : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#undef _syscall2 -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1, type2 arg2) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4) \ - : "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#undef _syscall3 -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1, type2 arg2, type3 arg3) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5) \ - : "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#undef _syscall4 -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_6 = (unsigned long) (arg4); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5), \ - "r" (__sc_6) \ - : "r7", "r8", "r9", "r10", "r11", "r12" ); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#undef _syscall5 -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_6 = (unsigned long) (arg4); \ - __sc_7 = (unsigned long) (arg5); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5), \ - "r" (__sc_6), \ - "r" (__sc_7) \ - : "r8", "r9", "r10", "r11", "r12" ); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - - -#undef _syscall6 -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - register unsigned long __sc_8 __asm__ ("r8"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_6 = (unsigned long) (arg4); \ - __sc_7 = (unsigned long) (arg5); \ - __sc_8 = (unsigned long) (arg6); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5), \ - "r" (__sc_6), \ - "r" (__sc_7), \ - "r" (__sc_8) \ - : "r9", "r10", "r11", "r12" ); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - - diff --git a/ldso/ldso/powerpc/ld_sysdep.h b/ldso/ldso/powerpc/ld_sysdep.h deleted file mode 100644 index 8768c9ac4..000000000 --- a/ldso/ldso/powerpc/ld_sysdep.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Various assmbly language/system dependent hacks that are required - * so that we can minimize the amount of platform specific code. - */ - -/* - * Define this if the system uses RELOCA. - */ -#define ELF_USES_RELOCA - -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1) - -/* - * Initialization sequence for a GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) _dl_init_got(GOT_BASE,MODULE) - -/* Stuff for the PLT. */ -#define PLT_INITIAL_ENTRY_WORDS 18 -#define PLT_LONGBRANCH_ENTRY_WORDS 0 -#define PLT_TRAMPOLINE_ENTRY_WORDS 6 -#define PLT_DOUBLE_SIZE (1<<13) -#define PLT_ENTRY_START_WORDS(entry_number) \ - (PLT_INITIAL_ENTRY_WORDS + (entry_number)*2 \ - + ((entry_number) > PLT_DOUBLE_SIZE \ - ? ((entry_number) - PLT_DOUBLE_SIZE)*2 \ - : 0)) -#define PLT_DATA_START_WORDS(num_entries) PLT_ENTRY_START_WORDS(num_entries) - -/* Macros to build PowerPC opcode words. */ -#define OPCODE_ADDI(rd,ra,simm) \ - (0x38000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff)) -#define OPCODE_ADDIS(rd,ra,simm) \ - (0x3c000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff)) -#define OPCODE_ADD(rd,ra,rb) \ - (0x7c000214 | (rd) << 21 | (ra) << 16 | (rb) << 11) -#define OPCODE_B(target) (0x48000000 | ((target) & 0x03fffffc)) -#define OPCODE_BA(target) (0x48000002 | ((target) & 0x03fffffc)) -#define OPCODE_BCTR() 0x4e800420 -#define OPCODE_LWZ(rd,d,ra) \ - (0x80000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff)) -#define OPCODE_LWZU(rd,d,ra) \ - (0x84000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff)) -#define OPCODE_MTCTR(rd) (0x7C0903A6 | (rd) << 21) -#define OPCODE_RLWINM(ra,rs,sh,mb,me) \ - (0x54000000 | (rs) << 21 | (ra) << 16 | (sh) << 11 | (mb) << 6 | (me) << 1) - -#define OPCODE_LI(rd,simm) OPCODE_ADDI(rd,0,simm) -#define OPCODE_ADDIS_HI(rd,ra,value) \ - OPCODE_ADDIS(rd,ra,((value) + 0x8000) >> 16) -#define OPCODE_LIS_HI(rd,value) OPCODE_ADDIS_HI(rd,0,value) -#define OPCODE_SLWI(ra,rs,sh) OPCODE_RLWINM(ra,rs,sh,0,31-sh) - - -#define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory") -#define PPC_SYNC asm volatile ("sync" : : : "memory") -#define PPC_ISYNC asm volatile ("sync; isync" : : : "memory") -#define PPC_ICBI(where) asm volatile ("icbi 0,%0" : : "r"(where) : "memory") -#define PPC_DIE asm volatile ("tweq 0,0") - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - {int type=ELF32_R_TYPE((RELP)->r_info); \ - Elf32_Addr finaladdr=(SYMBOL)+(RELP)->r_addend;\ - if (type==R_PPC_RELATIVE) { \ - *REL=(Elf32_Word)(LOAD)+(RELP)->r_addend;\ - } else if (type==R_PPC_JMP_SLOT) { \ - Elf32_Sword delta=finaladdr-(Elf32_Word)(REL);\ - *REL=OPCODE_B(delta); \ - } else if (type==R_PPC_ADDR32) { \ - *REL=finaladdr; \ - } else { \ - _dl_exit(100+ELF32_R_TYPE((RELP)->r_info)); \ - } \ - PPC_DCBST(REL); PPC_SYNC; PPC_ICBI(REL); \ - } -/* - * Transfer control to the user's application, once the dynamic loader - * is done. This routine has to exit the current function, then - * call the _dl_elf_main function. - */ - -/* hgb@ifi.uio.no: - * Adding a clobber list consisting of r0 for %1. addi on PowerPC - * takes a register as the second argument, but if the register is - * r0, the value 0 is used instead. If r0 is used here, the stack - * pointer (r1) will be zeroed, and the dynamically linked - * application will seg.fault immediatly when receiving control. - */ -#define START() \ - __asm__ volatile ( \ - "addi 1,%1,0\n\t" \ - "mtlr %0\n\t" \ - "blrl\n\t" \ - : : "r" (_dl_elf_main), "r" (args) \ - : "r0") - - -/* Here we define the magic numbers that this dynamic loader should accept */ - -#define MAGIC1 EM_PPC -#undef MAGIC2 -/* Used for error messages */ -#define ELF_TARGET "powerpc" - -struct elf_resolve; -extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); -void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt); - - -#define do_rem(result, n, base) result = (n % base) - -/* 4096 bytes alignment */ -#define PAGE_ALIGN 0xfffff000 -#define ADDR_ALIGN 0xfff -#define OFFS_ALIGN 0x7ffff000 diff --git a/ldso/ldso/readelflib1.c b/ldso/ldso/readelflib1.c deleted file mode 100644 index 5a1c89230..000000000 --- a/ldso/ldso/readelflib1.c +++ /dev/null @@ -1,926 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * This file contains the helper routines to load an ELF shared - * library into memory and add the symbol table info to the chain. - * - * Copyright (C) 2000-2004 by Erik Andersen - * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, - * David Engel, Hongjiu Lu and Mitch D'Souza - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the above contributors may not be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "ldso.h" - -#ifdef USE_CACHE - -static caddr_t _dl_cache_addr = NULL; -static size_t _dl_cache_size = 0; - -int _dl_map_cache(void) -{ - int fd; - struct stat st; - header_t *header; - libentry_t *libent; - int i, strtabsize; - - if (_dl_cache_addr == (caddr_t) - 1) - return -1; - else if (_dl_cache_addr != NULL) - return 0; - - if (_dl_stat(LDSO_CACHE, &st) - || (fd = _dl_open(LDSO_CACHE, O_RDONLY, 0)) < 0) { - _dl_dprintf(2, "%s: can't open cache '%s'\n", _dl_progname, LDSO_CACHE); - _dl_cache_addr = (caddr_t) - 1; /* so we won't try again */ - return -1; - } - - _dl_cache_size = st.st_size; - _dl_cache_addr = (caddr_t) _dl_mmap(0, _dl_cache_size, PROT_READ, MAP_SHARED, fd, 0); - _dl_close(fd); - if (_dl_mmap_check_error(_dl_cache_addr)) { - _dl_dprintf(2, "%s: can't map cache '%s'\n", - _dl_progname, LDSO_CACHE); - return -1; - } - - header = (header_t *) _dl_cache_addr; - - if (_dl_cache_size < sizeof(header_t) || - _dl_memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN) - || _dl_memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN) - || _dl_cache_size < - (sizeof(header_t) + header->nlibs * sizeof(libentry_t)) - || _dl_cache_addr[_dl_cache_size - 1] != '\0') - { - _dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, - LDSO_CACHE); - goto fail; - } - - strtabsize = _dl_cache_size - sizeof(header_t) - - header->nlibs * sizeof(libentry_t); - libent = (libentry_t *) & header[1]; - - for (i = 0; i < header->nlibs; i++) { - if (libent[i].sooffset >= strtabsize || - libent[i].liboffset >= strtabsize) - { - _dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE); - goto fail; - } - } - - return 0; - -fail: - _dl_munmap(_dl_cache_addr, _dl_cache_size); - _dl_cache_addr = (caddr_t) - 1; - return -1; -} - -int _dl_unmap_cache(void) -{ - if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t) - 1) - return -1; - -#if 1 - _dl_munmap(_dl_cache_addr, _dl_cache_size); - _dl_cache_addr = NULL; -#endif - - return 0; -} -#endif - -/* This function's behavior must exactly match that - * in uClibc/ldso/util/ldd.c */ -static struct elf_resolve * -search_for_named_library(const char *name, int secure, const char *path_list, - struct dyn_elf **rpnt) -{ - int i, count = 1; - char *path, *path_n; - char mylibname[2050]; - struct elf_resolve *tpnt1; - - if (path_list==NULL) - return NULL; - - /* We need a writable copy of this string */ - path = _dl_strdup(path_list); - if (!path) { - _dl_dprintf(2, "Out of memory!\n"); - _dl_exit(0); - } - - - /* Unlike ldd.c, don't bother to eliminate double //s */ - - - /* Replace colons with zeros in path_list and count them */ - for(i=_dl_strlen(path); i > 0; i--) { - if (path[i]==':') { - path[i]=0; - count++; - } - } - - path_n = path; - for (i = 0; i < count; i++) { - _dl_strcpy(mylibname, path_n); - _dl_strcat(mylibname, "/"); - _dl_strcat(mylibname, name); - if ((tpnt1 = _dl_load_elf_shared_library(secure, rpnt, mylibname)) != NULL) - { - return tpnt1; - } - path_n += (_dl_strlen(path_n) + 1); - } - return NULL; -} - -/* Check if the named library is already loaded... */ -struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname, - int trace_loaded_objects) -{ - const char *pnt, *pnt1; - struct elf_resolve *tpnt1; - const char *libname, *libname2; - static const char libc[] = "libc.so."; - static const char aborted_wrong_lib[] = "%s: aborted attempt to load %s!\n"; - - pnt = libname = full_libname; - -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) - _dl_dprintf(_dl_debug_file, "Checking if '%s' is already loaded\n", full_libname); -#endif - /* quick hack to ensure mylibname buffer doesn't overflow. don't - allow full_libname or any directory to be longer than 1024. */ - if (_dl_strlen(full_libname) > 1024) - return NULL; - - /* Skip over any initial initial './' and '/' stuff to - * get the short form libname with no path garbage */ - pnt1 = _dl_strrchr(pnt, '/'); - if (pnt1) { - libname = pnt1 + 1; - } - - /* Make sure they are not trying to load the wrong C library! - * This sometimes happens esp with shared libraries when the - * library path is somehow wrong! */ -#define isdigit(c) (c >= '0' && c <= '9') - if ((_dl_strncmp(libname, libc, 8) == 0) && _dl_strlen(libname) >=8 && - isdigit(libname[8])) - { - /* Abort attempts to load glibc, libc5, etc */ - if ( libname[8]!='0') { - if (!trace_loaded_objects) { - _dl_dprintf(2, aborted_wrong_lib, libname, _dl_progname); - _dl_exit(1); - } - return NULL; - } - } - - /* Critical step! Weed out duplicates early to avoid - * function aliasing, which wastes memory, and causes - * really bad things to happen with weaks and globals. */ - for (tpnt1 = _dl_loaded_modules; tpnt1; tpnt1 = tpnt1->next) { - - /* Skip over any initial initial './' and '/' stuff to - * get the short form libname with no path garbage */ - libname2 = tpnt1->libname; - pnt1 = _dl_strrchr(libname2, '/'); - if (pnt1) { - libname2 = pnt1 + 1; - } - - if (_dl_strcmp(libname2, libname) == 0) { - /* Well, that was certainly easy */ - return tpnt1; - } - } - - return NULL; -} - - -/* Used to return error codes back to dlopen et. al. */ -unsigned long _dl_error_number; -unsigned long _dl_internal_error_number; - -struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt, - struct elf_resolve *tpnt, char *full_libname, int trace_loaded_objects) -{ - char *pnt, *pnt1; - struct elf_resolve *tpnt1; - char *libname; - - _dl_internal_error_number = 0; - libname = full_libname; - - /* quick hack to ensure mylibname buffer doesn't overflow. don't - allow full_libname or any directory to be longer than 1024. */ - if (_dl_strlen(full_libname) > 1024) - goto goof; - - /* Skip over any initial initial './' and '/' stuff to - * get the short form libname with no path garbage */ - pnt1 = _dl_strrchr(libname, '/'); - if (pnt1) { - libname = pnt1 + 1; - } - - /* Critical step! Weed out duplicates early to avoid - * function aliasing, which wastes memory, and causes - * really bad things to happen with weaks and globals. */ - if ((tpnt1=_dl_check_if_named_library_is_loaded(libname, trace_loaded_objects))!=NULL) - return tpnt1; - -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfind library='%s'; searching\n", libname); -#endif - /* If the filename has any '/', try it straight and leave it at that. - For IBCS2 compatibility under linux, we substitute the string - /usr/i486-sysv4/lib for /usr/lib in library names. */ - - if (libname != full_libname) { -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file, "\ttrying file='%s'\n", full_libname); -#endif - tpnt1 = _dl_load_elf_shared_library(secure, rpnt, full_libname); - if (tpnt1) { - return tpnt1; - } - //goto goof; - } - - /* - * The ABI specifies that RPATH is searched before LD_*_PATH or - * the default path of /usr/lib. Check in rpath directories. - */ - for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { - if (tpnt->libtype == elf_executable) { - pnt = (char *) tpnt->dynamic_info[DT_RPATH]; - if (pnt) { - pnt += (unsigned long) tpnt->loadaddr + tpnt->dynamic_info[DT_STRTAB]; -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching RPATH='%s'\n", pnt); -#endif - if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL) - { - return tpnt1; - } - } - } - } - - /* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */ - if (_dl_library_path) { -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching LD_LIBRARY_PATH='%s'\n", _dl_library_path); -#endif - if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path, rpnt)) != NULL) - { - return tpnt1; - } - } - - /* - * Where should the cache be searched? There is no such concept in the - * ABI, so we have some flexibility here. For now, search it before - * the hard coded paths that follow (i.e before /lib and /usr/lib). - */ -#ifdef USE_CACHE - if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t) - 1) { - int i; - header_t *header = (header_t *) _dl_cache_addr; - libentry_t *libent = (libentry_t *) & header[1]; - char *strs = (char *) &libent[header->nlibs]; - -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching cache='%s'\n", LDSO_CACHE); -#endif - for (i = 0; i < header->nlibs; i++) { - if ((libent[i].flags == LIB_ELF || - libent[i].flags == LIB_ELF_LIBC5) && - _dl_strcmp(libname, strs + libent[i].sooffset) == 0 && - (tpnt1 = _dl_load_elf_shared_library(secure, - rpnt, strs + libent[i].liboffset))) - return tpnt1; - } - } -#endif - - /* Look for libraries wherever the shared library loader - * was installed */ -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching ldso dir='%s'\n", _dl_ldsopath); -#endif - if ((tpnt1 = search_for_named_library(libname, secure, _dl_ldsopath, rpnt)) != NULL) - { - return tpnt1; - } - - - /* Lastly, search the standard list of paths for the library. - This list must exactly match the list in uClibc/ldso/util/ldd.c */ -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching full lib path list\n"); -#endif - if ((tpnt1 = search_for_named_library(libname, secure, - UCLIBC_RUNTIME_PREFIX "usr/X11R6/lib:" - UCLIBC_RUNTIME_PREFIX "usr/lib:" - UCLIBC_RUNTIME_PREFIX "lib:" - "/usr/lib:" - "/lib", rpnt) - ) != NULL) - { - return tpnt1; - } - -goof: - /* Well, we shot our wad on that one. All we can do now is punt */ - if (_dl_internal_error_number) - _dl_error_number = _dl_internal_error_number; - else - _dl_error_number = LD_ERROR_NOFILE; -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(2, "Bummer: could not find '%s'!\n", libname); -#endif - return NULL; -} - - -/* - * Read one ELF library into memory, mmap it into the correct locations and - * add the symbol info to the symbol chain. Perform any relocations that - * are required. - */ - -struct elf_resolve *_dl_load_elf_shared_library(int secure, - struct dyn_elf **rpnt, char *libname) -{ - ElfW(Ehdr) *epnt; - unsigned long dynamic_addr = 0; - unsigned long dynamic_size = 0; - Elf32_Dyn *dpnt; - struct elf_resolve *tpnt; - ElfW(Phdr) *ppnt; - char *status, *header; - unsigned long dynamic_info[24]; - unsigned long *lpnt; - unsigned long libaddr; - unsigned long minvma = 0xffffffff, maxvma = 0; - int i, flags, piclib, infile; - - /* If this file is already loaded, skip this step */ - tpnt = _dl_check_hashed_files(libname); - if (tpnt) { - if (*rpnt) { - (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf)); - _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf)); - (*rpnt)->next->prev = (*rpnt); - *rpnt = (*rpnt)->next; - (*rpnt)->dyn = tpnt; - tpnt->symbol_scope = _dl_symbol_tables; - } - tpnt->usage_count++; - tpnt->libtype = elf_lib; -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(2, "file='%s'; already loaded\n", libname); -#endif - return tpnt; - } - - /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD), - we don't load the library if it isn't setuid. */ - - if (secure) { - struct stat st; - - if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID)) - return NULL; - } - - libaddr = 0; - infile = _dl_open(libname, O_RDONLY, 0); - if (infile < 0) { -#if 0 - /* - * NO! When we open shared libraries we may search several paths. - * it is inappropriate to generate an error here. - */ - _dl_dprintf(2, "%s: can't open '%s'\n", _dl_progname, libname); -#endif - _dl_internal_error_number = LD_ERROR_NOFILE; - return NULL; - } - - header = _dl_mmap((void *) 0, PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - if (_dl_mmap_check_error(header)) { - _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname); - _dl_internal_error_number = LD_ERROR_MMAP_FAILED; - _dl_close(infile); - return NULL; - }; - - _dl_read(infile, header, PAGE_SIZE); - epnt = (ElfW(Ehdr) *) (intptr_t) header; - if (epnt->e_ident[0] != 0x7f || - epnt->e_ident[1] != 'E' || - epnt->e_ident[2] != 'L' || - epnt->e_ident[3] != 'F') - { - _dl_dprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname, - libname); - _dl_internal_error_number = LD_ERROR_NOTELF; - _dl_close(infile); - _dl_munmap(header, PAGE_SIZE); - return NULL; - }; - - if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1 -#ifdef MAGIC2 - && epnt->e_machine != MAGIC2 -#endif - )) - { - _dl_internal_error_number = - (epnt->e_type != ET_DYN ? LD_ERROR_NOTDYN : LD_ERROR_NOTMAGIC); - _dl_dprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET - "\n", _dl_progname, libname); - _dl_close(infile); - _dl_munmap(header, PAGE_SIZE); - return NULL; - }; - - ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff]; - - piclib = 1; - for (i = 0; i < epnt->e_phnum; i++) { - - if (ppnt->p_type == PT_DYNAMIC) { - if (dynamic_addr) - _dl_dprintf(2, "%s: '%s' has more than one dynamic section\n", - _dl_progname, libname); - dynamic_addr = ppnt->p_vaddr; - dynamic_size = ppnt->p_filesz; - }; - - if (ppnt->p_type == PT_LOAD) { - /* See if this is a PIC library. */ - if (i == 0 && ppnt->p_vaddr > 0x1000000) { - piclib = 0; - minvma = ppnt->p_vaddr; - } - if (piclib && ppnt->p_vaddr < minvma) { - minvma = ppnt->p_vaddr; - } - if (((unsigned long) ppnt->p_vaddr + ppnt->p_memsz) > maxvma) { - maxvma = ppnt->p_vaddr + ppnt->p_memsz; - } - } - ppnt++; - }; - - maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN; - minvma = minvma & ~0xffffU; - - flags = MAP_PRIVATE /*| MAP_DENYWRITE */ ; - if (!piclib) - flags |= MAP_FIXED; - - status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma), - maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0); - if (_dl_mmap_check_error(status)) { - _dl_dprintf(2, "%s: can't map %s\n", _dl_progname, libname); - _dl_internal_error_number = LD_ERROR_MMAP_FAILED; - _dl_close(infile); - _dl_munmap(header, PAGE_SIZE); - return NULL; - }; - libaddr = (unsigned long) status; - flags |= MAP_FIXED; - - /* Get the memory to store the library */ - ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff]; - - for (i = 0; i < epnt->e_phnum; i++) { - if (ppnt->p_type == PT_LOAD) { - - /* See if this is a PIC library. */ - if (i == 0 && ppnt->p_vaddr > 0x1000000) { - piclib = 0; - /* flags |= MAP_FIXED; */ - } - - - - if (ppnt->p_flags & PF_W) { - unsigned long map_size; - char *cpnt; - - status = (char *) _dl_mmap((char *) ((piclib ? libaddr : 0) + - (ppnt->p_vaddr & PAGE_ALIGN)), (ppnt->p_vaddr & ADDR_ALIGN) - + ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, infile, - ppnt->p_offset & OFFS_ALIGN); - - if (_dl_mmap_check_error(status)) { - _dl_dprintf(2, "%s: can't map '%s'\n", - _dl_progname, libname); - _dl_internal_error_number = LD_ERROR_MMAP_FAILED; - _dl_munmap((char *) libaddr, maxvma - minvma); - _dl_close(infile); - _dl_munmap(header, PAGE_SIZE); - return NULL; - }; - - /* Pad the last page with zeroes. */ - cpnt = (char *) (status + (ppnt->p_vaddr & ADDR_ALIGN) + - ppnt->p_filesz); - while (((unsigned long) cpnt) & ADDR_ALIGN) - *cpnt++ = 0; - - /* I am not quite sure if this is completely - * correct to do or not, but the basic way that - * we handle bss segments is that we mmap - * /dev/zero if there are any pages left over - * that are not mapped as part of the file */ - - map_size = (ppnt->p_vaddr + ppnt->p_filesz + ADDR_ALIGN) & PAGE_ALIGN; - - if (map_size < ppnt->p_vaddr + ppnt->p_memsz) - status = (char *) _dl_mmap((char *) map_size + - (piclib ? libaddr : 0), - ppnt->p_vaddr + ppnt->p_memsz - map_size, - LXFLAGS(ppnt->p_flags), flags | MAP_ANONYMOUS, -1, 0); - } else - status = (char *) _dl_mmap((char *) (ppnt->p_vaddr & PAGE_ALIGN) - + (piclib ? libaddr : 0), (ppnt->p_vaddr & ADDR_ALIGN) + - ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, - infile, ppnt->p_offset & OFFS_ALIGN); - if (_dl_mmap_check_error(status)) { - _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname); - _dl_internal_error_number = LD_ERROR_MMAP_FAILED; - _dl_munmap((char *) libaddr, maxvma - minvma); - _dl_close(infile); - _dl_munmap(header, PAGE_SIZE); - return NULL; - }; - - /* if(libaddr == 0 && piclib) { - libaddr = (unsigned long) status; - flags |= MAP_FIXED; - }; */ - }; - ppnt++; - }; - _dl_close(infile); - - /* For a non-PIC library, the addresses are all absolute */ - if (piclib) { - dynamic_addr += (unsigned long) libaddr; - } - - /* - * OK, the ELF library is now loaded into VM in the correct locations - * The next step is to go through and do the dynamic linking (if needed). - */ - - /* Start by scanning the dynamic section to get all of the pointers */ - - if (!dynamic_addr) { - _dl_internal_error_number = LD_ERROR_NODYNAMIC; - _dl_dprintf(2, "%s: '%s' is missing a dynamic section\n", - _dl_progname, libname); - _dl_munmap(header, PAGE_SIZE); - return NULL; - } - - dpnt = (Elf32_Dyn *) dynamic_addr; - - dynamic_size = dynamic_size / sizeof(Elf32_Dyn); - _dl_memset(dynamic_info, 0, sizeof(dynamic_info)); - -#if defined(__mips__) - { - - int indx = 1; - Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr; - - while(dpnt->d_tag) { - dpnt++; - indx++; - } - dynamic_size = indx; - } -#endif - - { - unsigned long indx; - - for (indx = 0; indx < dynamic_size; indx++) - { - if (dpnt->d_tag > DT_JMPREL) { - dpnt++; - continue; - } - dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val; - if (dpnt->d_tag == DT_TEXTREL) - dynamic_info[DT_TEXTREL] = 1; - dpnt++; - }; - } - - /* If the TEXTREL is set, this means that we need to make the pages - writable before we perform relocations. Do this now. They get set - back again later. */ - - if (dynamic_info[DT_TEXTREL]) { -#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS - ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff]; - for (i = 0; i < epnt->e_phnum; i++, ppnt++) { - if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) - _dl_mprotect((void *) ((piclib ? libaddr : 0) + - (ppnt->p_vaddr & PAGE_ALIGN)), - (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz, - PROT_READ | PROT_WRITE | PROT_EXEC); - } -#else - _dl_dprintf(_dl_debug_file, "Can't modify %s's text section. Use GCC option -fPIC for shared objects, please.\n",libname); - _dl_exit(1); -#endif - } - - tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info, - dynamic_addr, dynamic_size); - - tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff); - tpnt->n_phent = epnt->e_phnum; - - /* - * Add this object into the symbol chain - */ - if (*rpnt) { - (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf)); - _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf)); - (*rpnt)->next->prev = (*rpnt); - *rpnt = (*rpnt)->next; - (*rpnt)->dyn = tpnt; - tpnt->symbol_scope = _dl_symbol_tables; - } - tpnt->usage_count++; - tpnt->libtype = elf_lib; - - /* - * OK, the next thing we need to do is to insert the dynamic linker into - * the proper entry in the GOT so that the PLT symbols can be properly - * resolved. - */ - - lpnt = (unsigned long *) dynamic_info[DT_PLTGOT]; - - if (lpnt) { - lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] + - ((int) libaddr)); - INIT_GOT(lpnt, tpnt); - }; - -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) { - _dl_dprintf(2, "\n\tfile='%s'; generating link map\n", libname); - _dl_dprintf(2, "\t\tdynamic: %x base: %x size: %x\n", - dynamic_addr, libaddr, dynamic_size); - _dl_dprintf(2, "\t\t entry: %x phdr: %x phnum: %d\n\n", - epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent); - - } -#endif - _dl_munmap(header, PAGE_SIZE); - - return tpnt; -} - -int _dl_fixup(struct dyn_elf *rpnt, int flag) -{ - int goof = 0; - struct elf_resolve *tpnt; - - if (rpnt->next) - goof += _dl_fixup(rpnt->next, flag); - tpnt = rpnt->dyn; - -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname); -#endif - - if (unlikely(tpnt->dynamic_info[UNSUPPORTED_RELOC_TYPE])) { -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) { - _dl_dprintf(2, "%s: can't handle %s relocation records\n", - _dl_progname, UNSUPPORTED_RELOC_STR); - } -#endif - goof++; - return goof; - } - - if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]) { - if (tpnt->init_flag & RELOCS_DONE) - return goof; - tpnt->init_flag |= RELOCS_DONE; - goof += _dl_parse_relocation_information(rpnt, - tpnt->dynamic_info[DT_RELOC_TABLE_ADDR], - tpnt->dynamic_info[DT_RELOC_TABLE_SIZE], 0); - } - - if (tpnt->dynamic_info[DT_JMPREL]) { - if (tpnt->init_flag & JMP_RELOCS_DONE) - return goof; - tpnt->init_flag |= JMP_RELOCS_DONE; - if (flag & RTLD_LAZY) { - _dl_parse_lazy_relocation_information(rpnt, - tpnt->dynamic_info[DT_JMPREL], - tpnt->dynamic_info [DT_PLTRELSZ], 0); - } else { - goof += _dl_parse_relocation_information(rpnt, - tpnt->dynamic_info[DT_JMPREL], - tpnt->dynamic_info[DT_PLTRELSZ], 0); - } - } - - if (tpnt->init_flag & COPY_RELOCS_DONE) - return goof; - tpnt->init_flag |= COPY_RELOCS_DONE; - goof += _dl_parse_copy_information(rpnt, - tpnt->dynamic_info[DT_RELOC_TABLE_ADDR], - tpnt->dynamic_info[DT_RELOC_TABLE_SIZE], 0); - -#if defined (__SUPPORT_LD_DEBUG__) - if(_dl_debug) { - _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname); - _dl_dprintf(_dl_debug_file,"; finished\n\n"); - } -#endif - - return goof; -} - -/* Minimal printf which handles only %s, %d, and %x */ -void _dl_dprintf(int fd, const char *fmt, ...) -{ - int num; - va_list args; - char *start, *ptr, *string; - static char *buf; - - buf = _dl_mmap((void *) 0, PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - if (_dl_mmap_check_error(buf)) { - _dl_write(fd, "mmap of a spare page failed!\n", 29); - _dl_exit(20); - } - - start = ptr = buf; - - if (!fmt) - return; - - if (_dl_strlen(fmt) >= (PAGE_SIZE - 1)) { - _dl_write(fd, "overflow\n", 11); - _dl_exit(20); - } - - _dl_strcpy(buf, fmt); - va_start(args, fmt); - - while (start) { - while (*ptr != '%' && *ptr) { - ptr++; - } - - if (*ptr == '%') { - *ptr++ = '\0'; - _dl_write(fd, start, _dl_strlen(start)); - - switch (*ptr++) { - case 's': - string = va_arg(args, char *); - - if (!string) - _dl_write(fd, "(null)", 6); - else - _dl_write(fd, string, _dl_strlen(string)); - break; - - case 'i': - case 'd': - { - char tmp[22]; - num = va_arg(args, int); - - string = _dl_simple_ltoa(tmp, num); - _dl_write(fd, string, _dl_strlen(string)); - break; - } - case 'x': - case 'X': - { - char tmp[22]; - num = va_arg(args, int); - - string = _dl_simple_ltoahex(tmp, num); - _dl_write(fd, string, _dl_strlen(string)); - break; - } - default: - _dl_write(fd, "(null)", 6); - break; - } - - start = ptr; - } else { - _dl_write(fd, start, _dl_strlen(start)); - start = NULL; - } - } - _dl_munmap(buf, PAGE_SIZE); - return; -} - -char *_dl_strdup(const char *string) -{ - char *retval; - int len; - - len = _dl_strlen(string); - retval = _dl_malloc(len + 1); - _dl_strcpy(retval, string); - return retval; -} - -void *(*_dl_malloc_function) (size_t size) = NULL; -void *_dl_malloc(int size) -{ - void *retval; - -#if 0 -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - _dl_dprintf(2, "malloc: request for %d bytes\n", size); -#endif -#endif - - if (_dl_malloc_function) - return (*_dl_malloc_function) (size); - - if (_dl_malloc_addr - _dl_mmap_zero + size > PAGE_SIZE) { -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - _dl_dprintf(2, "malloc: mmapping more memory\n"); -#endif - _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - if (_dl_mmap_check_error(_dl_mmap_zero)) { - _dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname); - _dl_exit(20); - } - } - retval = _dl_malloc_addr; - _dl_malloc_addr += size; - - /* - * Align memory to 4 byte boundary. Some platforms require this, others - * simply get better performance. - */ - _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3)); - return retval; -} - - - diff --git a/ldso/ldso/sh/boot1_arch.h b/ldso/ldso/sh/boot1_arch.h deleted file mode 100644 index d1ca6d985..000000000 --- a/ldso/ldso/sh/boot1_arch.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. */ - -asm("" \ -" .text\n" \ -" .globl _dl_boot\n" \ -"_dl_boot:\n" \ -" mov r15, r4\n" \ -" mov.l .L_dl_boot2, r0\n" \ -" bsrf r0\n" \ -" add #4, r4\n" \ -".jmp_loc:\n" \ -" jmp @r0\n" \ -" mov #0, r4 !call _start with arg == 0\n" \ -".L_dl_boot2:\n" \ -" .long _dl_boot2-.jmp_loc\n" \ -" .previous\n" \ -); - -#define DL_BOOT(X) static void __attribute__ ((unused)) _dl_boot2 (X) diff --git a/ldso/ldso/sh/ld_syscalls.h b/ldso/ldso/sh/ld_syscalls.h deleted file mode 100644 index e4a1ff9c4..000000000 --- a/ldso/ldso/sh/ld_syscalls.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Define the __set_errno macro as nothing so that we don't bother - * setting errno, which is important since we make system calls - * before the errno symbol is dynamicly linked. */ - -#define __set_errno(X) {(void)(X);} -#include "sys/syscall.h" - diff --git a/ldso/ldso/sh/ld_sysdep.h b/ldso/ldso/sh/ld_sysdep.h deleted file mode 100644 index cd110895c..000000000 --- a/ldso/ldso/sh/ld_sysdep.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Various assmbly language/system dependent hacks that are required - * so that we can minimize the amount of platform specific code. - */ - -/* - * Define this if the system uses RELOCA. - */ -#define ELF_USES_RELOCA - -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS) - -/* - * Initialization sequence for a GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -{ \ - GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ - GOT_BASE[1] = (unsigned long) (MODULE); \ -} - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch(ELF32_R_TYPE((RELP)->r_info)){ \ - case R_SH_REL32: \ - *(REL) = (SYMBOL) + (RELP)->r_addend \ - - (unsigned long)(REL); \ - break; \ - case R_SH_DIR32: \ - case R_SH_GLOB_DAT: \ - case R_SH_JMP_SLOT: \ - *(REL) = (SYMBOL) + (RELP)->r_addend; \ - break; \ - case R_SH_RELATIVE: \ - *(REL) = (LOAD) + (RELP)->r_addend; \ - break; \ - case R_SH_NONE: \ - break; \ - default: \ - SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc type "); \ - SEND_NUMBER_STDERR(ELF32_R_TYPE((RELP)->r_info), 1); \ - SEND_STDERR("REL, SYMBOL, LOAD: "); \ - SEND_ADDRESS_STDERR(REL, 0); \ - SEND_STDERR(", "); \ - SEND_ADDRESS_STDERR(SYMBOL, 0); \ - SEND_STDERR(", "); \ - SEND_ADDRESS_STDERR(LOAD, 1); \ - _dl_exit(1); \ - } - - -/* - * Transfer control to the user's application, once the dynamic loader - * is done. This routine has to exit the current function, then - * call the _dl_elf_main function. - */ - -#define START() return _dl_elf_main; - - - -/* Here we define the magic numbers that this dynamic loader should accept */ - -#define MAGIC1 EM_SH -#undef MAGIC2 -/* Used for error messages */ -#define ELF_TARGET "sh" - -struct elf_resolve; -extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - -static __inline__ unsigned int -_dl_urem(unsigned int n, unsigned int base) -{ - int res; - - __asm__ (""\ - "mov #0, r0\n\t" \ - "div0u\n\t" \ - "" \ - "! get one bit from the msb of the numerator into the T\n\t" \ - "! bit and divide it by whats in %2. Put the answer bit\n\t" \ - "! into the T bit so it can come out again at the bottom\n\t" \ - "" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1 ; div1 %2, r0\n\t" \ - "rotcl %1\n\t" - : "=r" (res) - : "0" (n), "r" (base) - : "r0","cc"); - - return n - (base * res); -} - -#define do_rem(result, n, base) ((result) = _dl_urem((n), (base))) - -/* 4096 bytes alignment */ -#define PAGE_ALIGN 0xfffff000 -#define ADDR_ALIGN 0xfff -#define OFFS_ALIGN 0x7ffff000 diff --git a/ldso/ldso/sh64/boot1_arch.h b/ldso/ldso/sh64/boot1_arch.h deleted file mode 100644 index 4c6f3c5e2..000000000 --- a/ldso/ldso/sh64/boot1_arch.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. - */ - -asm("" \ -" .section .text..SHmedia32,\"ax\"\n" \ -" .globl _dl_boot\n" \ -" .type _dl_boot, @function\n" \ -" .align 5\n" \ -"_dl_boot:\n" \ -" ! Set r12 to point to GOT\n" \ -" movi (((datalabel _GLOBAL_OFFSET_TABLE_-(.LZZZ3-.)) >> 16) & 65535), r12\n" \ -" shori ((datalabel _GLOBAL_OFFSET_TABLE_-(.LZZZ3-.)) & 65535), r12\n" \ -".LZZZ3:\n" \ -" ptrel/u r12, tr0\n" \ -" gettr tr0, r12 ! GOT address\n" \ -" add r18, r63, r11 ! save return address - needed?\n" \ -" add r15, r63, r2 ! arg = stack pointer\n" \ -" pt _dl_boot2, tr0 ! should work even if PIC\n" \ -" blink tr0, r18 ! call _dl_boot2 - user EP is in r2\n" \ -); - -#define DL_BOOT(X) static void __attribute__ ((unused)) _dl_boot2 (X) - diff --git a/ldso/ldso/sh64/ld_syscalls.h b/ldso/ldso/sh64/ld_syscalls.h deleted file mode 100644 index 34da5d630..000000000 --- a/ldso/ldso/sh64/ld_syscalls.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Define the __set_errno macro as nothing so that we don't bother - * setting errno, which is important since we make system calls - * before the errno symbol is dynamicly linked. */ - -#include -#undef __set_errno -#define __set_errno(X) {(void)(X);} -#include "sys/syscall.h" - diff --git a/ldso/ldso/sh64/ld_sysdep.h b/ldso/ldso/sh64/ld_sysdep.h deleted file mode 100644 index 241cde93e..000000000 --- a/ldso/ldso/sh64/ld_sysdep.h +++ /dev/null @@ -1,170 +0,0 @@ -/* vi: set sw=8 ts=8: */ -/* - * Various assmbly language/system dependent hacks that are required - * so that we can minimize the amount of platform specific code. - */ - -/* - * Define this if the system uses RELOCA. - */ -#define ELF_USES_RELOCA - -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *)ARGS) - -/* - * Initialization sequence for a GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -{ \ - GOT_BASE[2] = (unsigned long)_dl_linux_resolve; \ - GOT_BASE[1] = (unsigned long)(MODULE); \ -} - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ - -/* - * We need to do this stupidity here as the preprocessor will choke when - * SYMTAB is NULL if we do this in PERFORM_BOOTSTRAP_RELOC(). - */ - -#include - -static inline int __extract_lsb_from_symtab(Elf32_Sym *symtab) -{ - static int lsb = 0; - - /* Check for SHmedia/SHcompact */ - if (symtab) - lsb = symtab->st_other & 4; - - return lsb; -} - -/* - * While on the subject of stupidity, there appear to be some conflicts with - * regards to several relocation types as far as binutils is concerned - * (Barcelona and Madrid both appear to use an out of date elf.h, whereas - * native Catalonia has all of the necessary definitions. As a workaround, - * we'll just define them here for sanity.. - */ -#ifndef R_SH_RELATIVE_LOW16 -# define R_SH_RELATIVE_LOW16 197 -# define R_SH_RELATIVE_MEDLOW16 198 -# define R_SH_IMM_LOW16 246 -# define R_SH_IMM_LOW16_PCREL 247 -# define R_SH_IMM_MEDLOW16 248 -# define R_SH_IMM_MEDLOW16_PCREL 249 -#endif - -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - const unsigned int r_type = ELF32_R_TYPE((RELP)->r_info); \ - int lsb = __extract_lsb_from_symtab(SYMTAB); \ - \ - switch (r_type) { \ - case R_SH_REL32: \ - *(REL) = (SYMBOL) + (RELP)->r_addend \ - - (unsigned long)(REL); \ - break; \ - case R_SH_DIR32: \ - case R_SH_GLOB_DAT: \ - case R_SH_JMP_SLOT: \ - *(REL) = ((SYMBOL) + (RELP)->r_addend) | lsb; \ - break; \ - case R_SH_RELATIVE: \ - *(REL) = (LOAD) + (RELP)->r_addend; \ - break; \ - case R_SH_RELATIVE_LOW16: \ - case R_SH_RELATIVE_MEDLOW16: \ - { \ - unsigned long word, value; \ - \ - word = (unsigned long)(REL) & ~0x3fffc00; \ - value = (LOAD) + (RELP)->r_addend; \ - \ - if (r_type == R_SH_RELATIVE_MEDLOW16) \ - value >>= 16; \ - \ - word |= (value & 0xffff) << 10; \ - *(REL) = word; \ - break; \ - } \ - case R_SH_IMM_LOW16: \ - case R_SH_IMM_MEDLOW16: \ - { \ - unsigned long word, value; \ - \ - word = (unsigned long)(REL) & ~0x3fffc00; \ - value = ((SYMBOL) + (RELP)->r_addend) | lsb; \ - \ - if (r_type == R_SH_IMM_MEDLOW16) \ - value >>= 16; \ - \ - word |= (value & 0xffff) << 10; \ - *(REL) = word; \ - break; \ - } \ - case R_SH_IMM_LOW16_PCREL: \ - case R_SH_IMM_MEDLOW16_PCREL: \ - { \ - unsigned long word, value; \ - \ - word = (unsigned long)(REL) & ~0x3fffc00; \ - value = (SYMBOL) + (RELP)->r_addend \ - - (unsigned long)(REL); \ - \ - if (r_type == R_SH_IMM_MEDLOW16_PCREL) \ - value >>= 16; \ - \ - word |= (value & 0xffff) << 10; \ - *(REL) = word; \ - break; \ - } \ - case R_SH_NONE: \ - break; \ - default: \ - SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc type "); \ - SEND_NUMBER_STDERR(ELF32_R_TYPE((RELP)->r_info), 1); \ - SEND_STDERR("REL, SYMBOL, LOAD: "); \ - SEND_ADDRESS_STDERR(REL, 0); \ - SEND_STDERR(", "); \ - SEND_ADDRESS_STDERR(SYMBOL, 0); \ - SEND_STDERR(", "); \ - SEND_ADDRESS_STDERR(LOAD, 1); \ - _dl_exit(1); \ - } - -/* - * Transfer control to the user's application, once the dynamic loader - * is done. This routine has to exit the current function, then - * call the _dl_elf_main function. - */ - -#define START() return _dl_elf_main; - -/* Here we define the magic numbers that this dynamic loader should accept */ -#define MAGIC1 EM_SH -#undef MAGIC2 -/* Used for error messages */ -#define ELF_TARGET "sh64" - -struct elf_resolve; -extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - -#define do_rem(result, n, base) result = (n % base) - -/* 4096 bytes alignment */ -#define PAGE_ALIGN 0xfffff000 -#define ADDR_ALIGN 0xfff -#define OFFS_ALIGN 0x7ffff000 - diff --git a/ldso/ldso/sparc/boot1_arch.h b/ldso/ldso/sparc/boot1_arch.h deleted file mode 100644 index 42c96a6f5..000000000 --- a/ldso/ldso/sparc/boot1_arch.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. See arm/boot1_arch.h for an example of what - * can be done. - */ - -#define DL_BOOT(X) void __attribute__ ((unused)) _dl_boot (X) diff --git a/ldso/ldso/sparc/ld_syscalls.h b/ldso/ldso/sparc/ld_syscalls.h deleted file mode 100644 index 4222b2468..000000000 --- a/ldso/ldso/sparc/ld_syscalls.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This file contains the system call macros and syscall - * numbers used by the shared library loader. - */ - -#define __NR_exit 1 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_getpid 20 -#define __NR_getuid 24 -#define __NR_getgid 47 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_readlink 58 -#define __NR_mmap 71 -#define __NR_munmap 73 -#define __NR_stat 38 -#define __NR_mprotect 74 - -/* Here are the macros which define how this platform makes - * system calls. This particular variant does _not_ set - * errno (note how it is disabled in __syscall_return) since - * these will get called before the errno symbol is dynamicly - * linked. */ - -#define _syscall0(type,name) \ -type name(void) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res)\ - : "r" (__g1) \ - : "o0", "cc"); \ -if (__res < -255 || __res >= 0) \ - return (type) __res; \ -/*errno = -__res; */\ -return -1; \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res >= 0) \ - return (type) __res; \ -/*errno = -__res;*/ \ -return -1; \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res >= 0) \ - return (type) __res; \ -/*errno = -__res;*/ \ -return -1; \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res>=0) \ - return (type) __res; \ -/*errno = -__res;*/ \ -return -1; \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -register long __o3 __asm__ ("o3") = (long)(arg4); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res>=0) \ - return (type) __res; \ -/*errno = -__res;*/ \ -return -1; \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -register long __o3 __asm__ ("o3") = (long)(arg4); \ -register long __o4 __asm__ ("o4") = (long)(arg5); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res>=0) \ - return (type) __res; \ -/*errno = -__res; */\ -return -1; \ -} diff --git a/ldso/ldso/sparc/ld_sysdep.h b/ldso/ldso/sparc/ld_sysdep.h deleted file mode 100644 index 1930a937f..000000000 --- a/ldso/ldso/sparc/ld_sysdep.h +++ /dev/null @@ -1,112 +0,0 @@ - -/* - * Various assmbly language/system dependent hacks that are required - * so that we can minimize the amount of platform specific code. - */ -#define LINUXBIN - -/* - * Define this if the system uses RELOCA. - */ -#define ELF_USES_RELOCA - -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. We assume that argc is stored - * at the word just below the argvp that we return here. - */ -#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP)); - -/* - * Initialization sequence for a GOT. For the Sparc, this points to the - * PLT, and we need to initialize a couple of the slots. The PLT should - * look like: - * - * save %sp, -64, %sp - * call _dl_linux_resolve - * nop - * .word implementation_dependent - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -{ \ - GOT_BASE[0] = 0x9de3bfc0; /* save %sp, -64, %sp */ \ - GOT_BASE[1] = 0x40000000 | (((unsigned int) _dl_linux_resolve - (unsigned int) GOT_BASE - 4) >> 2); \ - GOT_BASE[2] = 0x01000000; /* nop */ \ - GOT_BASE[3] = (int) MODULE; \ -} - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch(ELF32_R_TYPE((RELP)->r_info)) { \ - case R_SPARC_32: \ - *REL = SYMBOL + (RELP)->r_addend; \ - break; \ - case R_SPARC_GLOB_DAT: \ - *REL = SYMBOL + (RELP)->r_addend; \ - break; \ - case R_SPARC_JMP_SLOT: \ - REL[1] = 0x03000000 | ((SYMBOL >> 10) & 0x3fffff); \ - REL[2] = 0x81c06000 | (SYMBOL & 0x3ff); \ - break; \ - case R_SPARC_NONE: \ - break; \ - case R_SPARC_WDISP30: \ - break; \ - case R_SPARC_RELATIVE: \ - *REL += (unsigned int) LOAD + (RELP)->r_addend; \ - break; \ - default: \ - _dl_exit(1); \ - } - - -/* - * Transfer control to the user's application, once the dynamic loader - * is done. The crt calls atexit with $g1 if not null, so we need to - * ensure that it contains NULL. - */ - -#define START() \ - __asm__ volatile ( \ - "add %%g0,%%g0,%%g1\n\t" \ - "jmpl %0, %%o7\n\t" \ - "restore %%g0,%%g0,%%g0\n\t" \ - : /*"=r" (status) */ : \ - "r" (_dl_elf_main): "g1", "o0", "o1") - - - -/* Here we define the magic numbers that this dynamic loader should accept */ - -#define MAGIC1 EM_SPARC -#undef MAGIC2 -/* Used for error messages */ -#define ELF_TARGET "Sparc" - -#ifndef COMPILE_ASM -extern unsigned int _dl_linux_resolver(unsigned int reloc_entry, - unsigned int * i); -#endif - -/* - * Define this if you want a dynamic loader that works on Solaris. - */ -#define SOLARIS_COMPATIBLE - -#define do_rem(result, n, base) result = (n % base) - -/* - * dbx wants the binder to have a specific name. Mustn't disappoint it. - */ -#ifdef SOLARIS_COMPATIBLE -#define _dl_linux_resolve _elf_rtbndr -#endif - -/* 4096 bytes alignment */ -#define PAGE_ALIGN 0xfffff000 -#define ADDR_ALIGN 0xfff -#define OFFS_ALIGN 0x7ffff000 diff --git a/ldso/ldso/sparc/resolve.S b/ldso/ldso/sparc/resolve.S index 57c4b6804..a21facfbc 100644 --- a/ldso/ldso/sparc/resolve.S +++ b/ldso/ldso/sparc/resolve.S @@ -2,7 +2,7 @@ * These are various helper routines that are needed to run an ELF image. */ #define COMPILE_ASM -#include "ld_sysdep.h" +#include "dl-sysdep.h" .text .align 16 diff --git a/ldso/ldso/startup.c b/ldso/ldso/startup.c deleted file mode 100644 index 6a131633a..000000000 --- a/ldso/ldso/startup.c +++ /dev/null @@ -1,583 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Program to load an ELF binary on a linux system, and run it - * after resolving ELF shared library symbols - * - * Copyright (C) 2000-2004 by Erik Andersen - * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, - * David Engel, Hongjiu Lu and Mitch D'Souza - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the above contributors may not be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * The main trick with this program is that initially, we ourselves are not - * dynamicly linked. This means that we cannot access any global variables or - * call any functions. No globals initially, since the Global Offset Table - * (GOT) is initialized by the linker assuming a virtual address of 0, and no - * function calls initially since the Procedure Linkage Table (PLT) is not yet - * initialized. - * - * There are additional initial restrictions - we cannot use large switch - * statements, since the compiler generates tables of addresses and jumps - * through them. We cannot use normal syscall stubs, because these all - * reference the errno global variable which is not yet initialized. We _can_ - * use all of the local stack variables that we want. We _can_ use inline - * functions, because these do not transfer control to a new address, but they - * must be static so that they are not exported from the modules. - * - * Life is further complicated by the fact that initially we do not want to do - * a complete dynamic linking. We want to allow the user to supply new - * functions to override symbols (i.e. weak symbols and/or LD_PRELOAD). So - * initially, we only perform relocations for variables that start with "_dl_" - * since ANSI specifies that the user is not supposed to redefine any of these - * variables. - * - * Fortunately, the linker itself leaves a few clues lying around, and when the - * kernel starts the image, there are a few further clues. First of all, there - * is Auxiliary Vector Table information sitting on which is provided to us by - * the kernel, and which includes information about the load address that the - * program interpreter was loaded at, the number of sections, the address the - * application was loaded at and so forth. Here this information is stored in - * the array auxvt. For details see linux/fs/binfmt_elf.c where it calls - * NEW_AUX_ENT() a bunch of time.... - * - * Next, we need to find the GOT. On most arches there is a register pointing - * to the GOT, but just in case (and for new ports) I've added some (slow) C - * code to locate the GOT for you. - * - * This code was originally written for SVr4, and there the kernel would load - * all text pages R/O, so they needed to call mprotect a zillion times to mark - * all text pages as writable so dynamic linking would succeed. Then when they - * were done, they would change the protections for all the pages back again. - * Well, under Linux everything is loaded writable (since Linux does copy on - * write anyways) so all the mprotect stuff has been disabled. - * - * Initially, we do not have access to _dl_malloc since we can't yet make - * function calls, so we mmap one page to use as scratch space. Later on, when - * we can call _dl_malloc we reuse this this memory. This is also beneficial, - * since we do not want to use the same memory pool as malloc anyway - esp if - * the user redefines malloc to do something funky. - * - * Our first task is to perform a minimal linking so that we can call other - * portions of the dynamic linker. Once we have done this, we then build the - * list of modules that the application requires, using LD_LIBRARY_PATH if this - * is not a suid program (/usr/lib otherwise). Once this is done, we can do - * the dynamic linking as required, and we must omit the things we did to get - * the dynamic linker up and running in the first place. After we have done - * this, we just have a few housekeeping chores and we can transfer control to - * the user's application. - */ - -#include "ldso.h" - -/* Some arches may need to override this in boot1_arch.h */ -#define ELFMAGIC ELFMAG - -/* This is a poor man's malloc, used prior to resolving our internal poor man's malloc */ -#define LD_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE)) ; REALIGN(); - -/* Make sure that the malloc buffer is aligned on 4 byte boundary. For 64 bit - * platforms we may need to increase this to 8, but this is good enough for - * now. This is typically called after LD_MALLOC. */ -#define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3)) - -/* Pull in all the arch specific stuff */ -#include "boot1_arch.h" - -/* Static declarations */ -int (*_dl_elf_main) (int, char **, char **); - - - - -/* When we enter this piece of code, the program stack looks like this: - argc argument counter (integer) - argv[0] program name (pointer) - argv[1...N] program args (pointers) - argv[argc-1] end of args (integer) - NULL - env[0...N] environment variables (pointers) - NULL - auxvt[0...N] Auxiliary Vector Table elements (mixed types) -*/ -DL_BOOT(unsigned long args) -{ - unsigned int argc; - char **argv, **envp; - unsigned long load_addr; - unsigned long *got; - unsigned long *aux_dat; - int goof = 0; - ElfW(Ehdr) *header; - struct elf_resolve *tpnt; - struct elf_resolve *app_tpnt; - Elf32_auxv_t auxvt[AT_EGID + 1]; - unsigned char *malloc_buffer, *mmap_zero; - Elf32_Dyn *dpnt; - unsigned long *hash_addr; - struct r_debug *debug_addr = NULL; - int indx; -#if defined(__i386__) - int status = 0; -#endif - - - /* WARNING! -- we cannot make _any_ funtion calls until we have - * taken care of fixing up our own relocations. Making static - * inline calls is ok, but _no_ function calls. Not yet - * anyways. */ - - /* First obtain the information on the stack that tells us more about - what binary is loaded, where it is loaded, etc, etc */ - GET_ARGV(aux_dat, args); -#if defined (__arm__) || defined (__mips__) || defined (__cris__) - aux_dat += 1; -#endif - argc = *(aux_dat - 1); - argv = (char **) aux_dat; - aux_dat += argc; /* Skip over the argv pointers */ - aux_dat++; /* Skip over NULL at end of argv */ - envp = (char **) aux_dat; - while (*aux_dat) - aux_dat++; /* Skip over the envp pointers */ - aux_dat++; /* Skip over NULL at end of envp */ - - /* Place -1 here as a checkpoint. We later check if it was changed - * when we read in the auxvt */ - auxvt[AT_UID].a_type = -1; - - /* 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. */ - while (*aux_dat) { - Elf32_auxv_t *auxv_entry = (Elf32_auxv_t *) aux_dat; - - if (auxv_entry->a_type <= AT_EGID) { - _dl_memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t)); - } - aux_dat += 2; - } - - /* locate the ELF header. We need this done as soon as possible - * (esp since SEND_STDERR() needs this on some platforms... */ - load_addr = auxvt[AT_BASE].a_un.a_val; - header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr; - - /* Check the ELF header to make sure everything looks ok. */ - if (!header || header->e_ident[EI_CLASS] != ELFCLASS32 || - header->e_ident[EI_VERSION] != EV_CURRENT -#if !defined(__powerpc__) && !defined(__mips__) && !defined(__sh__) - || _dl_strncmp((void *) header, ELFMAGIC, SELFMAG) != 0 -#else - || header->e_ident[EI_MAG0] != ELFMAG0 - || header->e_ident[EI_MAG1] != ELFMAG1 - || header->e_ident[EI_MAG2] != ELFMAG2 - || header->e_ident[EI_MAG3] != ELFMAG3 -#endif - ) { - SEND_STDERR("Invalid ELF header\n"); - _dl_exit(0); - } -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("ELF header="); - SEND_ADDRESS_STDERR(load_addr, 1); -#endif - - - /* Locate the global offset table. Since this code must be PIC - * we can take advantage of the magic offset register, if we - * happen to know what that is for this architecture. If not, - * we can always read stuff out of the ELF file to find it... */ -#if defined(__i386__) - __asm__("\tmovl %%ebx,%0\n\t":"=a"(got)); -#elif defined(__m68k__) - __asm__("movel %%a5,%0":"=g"(got)); -#elif defined(__sparc__) - __asm__("\tmov %%l7,%0\n\t":"=r"(got)); -#elif defined(__arm__) - __asm__("\tmov %0, r10\n\t":"=r"(got)); -#elif defined(__powerpc__) - __asm__("\tbl _GLOBAL_OFFSET_TABLE_-4@local\n\t":"=l"(got)); -#elif defined(__mips__) - __asm__("\tmove %0, $28\n\tsubu %0,%0,0x7ff0\n\t":"=r"(got)); -#elif defined(__sh__) && !defined(__SH5__) - __asm__( - " mov.l 1f, %0\n" - " mova 1f, r0\n" - " bra 2f\n" - " add r0, %0\n" - " .balign 4\n" - "1: .long _GLOBAL_OFFSET_TABLE_\n" - "2:" : "=r" (got) : : "r0"); -#elif defined(__cris__) - __asm__("\tmove.d $pc,%0\n\tsub.d .:GOTOFF,%0\n\t":"=r"(got)); -#else - /* Do things the slow way in C */ - { - unsigned long tx_reloc; - Elf32_Dyn *dynamic = NULL; - Elf32_Shdr *shdr; - Elf32_Phdr *pt_load; - -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("Finding the GOT using C code to read the ELF file\n"); -#endif - /* Find where the dynamic linking information section is hiding */ - shdr = (Elf32_Shdr *) (header->e_shoff + (char *) header); - for (indx = header->e_shnum; --indx >= 0; ++shdr) { - if (shdr->sh_type == SHT_DYNAMIC) { - goto found_dynamic; - } - } - SEND_STDERR("missing dynamic linking information section \n"); - _dl_exit(0); - -found_dynamic: - dynamic = (Elf32_Dyn *) (shdr->sh_offset + (char *) header); - - /* Find where PT_LOAD is hiding */ - pt_load = (Elf32_Phdr *) (header->e_phoff + (char *) header); - for (indx = header->e_phnum; --indx >= 0; ++pt_load) { - if (pt_load->p_type == PT_LOAD) { - goto found_pt_load; - } - } - SEND_STDERR("missing loadable program segment\n"); - _dl_exit(0); - -found_pt_load: - /* Now (finally) find where DT_PLTGOT is hiding */ - tx_reloc = pt_load->p_vaddr - pt_load->p_offset; - for (; DT_NULL != dynamic->d_tag; ++dynamic) { - if (dynamic->d_tag == DT_PLTGOT) { - goto found_got; - } - } - SEND_STDERR("missing global offset table\n"); - _dl_exit(0); - -found_got: - got = (unsigned long *) (dynamic->d_un.d_val - tx_reloc + - (char *) header); - } -#endif - - /* Now, finally, fix up the location of the dynamic stuff */ - dpnt = (Elf32_Dyn *) (*got + load_addr); -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("First Dynamic section entry="); - SEND_ADDRESS_STDERR(dpnt, 1); -#endif - - - /* Call mmap to get a page of writable memory that can be used - * for _dl_malloc throughout the shared lib loader. */ - mmap_zero = malloc_buffer = _dl_mmap((void *) 0, PAGE_SIZE, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - if (_dl_mmap_check_error(mmap_zero)) { - SEND_STDERR("dl_boot: mmap of a spare page failed!\n"); - _dl_exit(13); - } - - tpnt = LD_MALLOC(sizeof(struct elf_resolve)); - _dl_memset(tpnt, 0, sizeof(struct elf_resolve)); - app_tpnt = LD_MALLOC(sizeof(struct elf_resolve)); - _dl_memset(app_tpnt, 0, sizeof(struct elf_resolve)); - -#ifdef __UCLIBC_PIE_SUPPORT__ - /* Find the runtime load address of the main executable, this may be - * different from what the ELF header says for ET_DYN/PIE executables. - */ - { - ElfW(Phdr) *ppnt; - int i; - - ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr; - for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) - if (ppnt->p_type == PT_PHDR) { - app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr); - break; - } - } - -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("app_tpnt->loadaddr="); - SEND_ADDRESS_STDERR(app_tpnt->loadaddr, 1); -#endif -#endif - - /* - * This is used by gdb to locate the chain of shared libraries that are currently loaded. - */ - debug_addr = LD_MALLOC(sizeof(struct r_debug)); - _dl_memset(debug_addr, 0, sizeof(struct r_debug)); - - /* OK, that was easy. Next scan the DYNAMIC section of the image. - We are only doing ourself right now - we will have to do the rest later */ -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("scanning DYNAMIC section\n"); -#endif - while (dpnt->d_tag) { -#if defined(__mips__) - if (dpnt->d_tag == DT_MIPS_GOTSYM) - tpnt->mips_gotsym = (unsigned long) dpnt->d_un.d_val; - if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO) - tpnt->mips_local_gotno = (unsigned long) dpnt->d_un.d_val; - if (dpnt->d_tag == DT_MIPS_SYMTABNO) - tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val; -#endif - if (dpnt->d_tag < 24) { - tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val; - if (dpnt->d_tag == DT_TEXTREL) { - tpnt->dynamic_info[DT_TEXTREL] = 1; - } - } - dpnt++; - } - - { - ElfW(Phdr) *ppnt; - int i; - - ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr; - for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) - if (ppnt->p_type == PT_DYNAMIC) { -#ifndef __UCLIBC_PIE_SUPPORT__ - dpnt = (Elf32_Dyn *) ppnt->p_vaddr; -#else - dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + app_tpnt->loadaddr); -#endif - while (dpnt->d_tag) { -#if defined(__mips__) - if (dpnt->d_tag == DT_MIPS_GOTSYM) - app_tpnt->mips_gotsym = - (unsigned long) dpnt->d_un.d_val; - if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO) - app_tpnt->mips_local_gotno = - (unsigned long) dpnt->d_un.d_val; - if (dpnt->d_tag == DT_MIPS_SYMTABNO) - app_tpnt->mips_symtabno = - (unsigned long) dpnt->d_un.d_val; - if (dpnt->d_tag > DT_JMPREL) { - dpnt++; - continue; - } - app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val; - -#warning "Debugging threads on mips won't work till someone fixes this..." -#if 0 - if (dpnt->d_tag == DT_DEBUG) { - dpnt->d_un.d_val = (unsigned long) debug_addr; - } -#endif - -#else - if (dpnt->d_tag > DT_JMPREL) { - dpnt++; - continue; - } - app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val; - if (dpnt->d_tag == DT_DEBUG) { - dpnt->d_un.d_val = (unsigned long) debug_addr; - } -#endif - if (dpnt->d_tag == DT_TEXTREL) - app_tpnt->dynamic_info[DT_TEXTREL] = 1; - dpnt++; - } - } - } - -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("done scanning DYNAMIC section\n"); -#endif - - /* Get some more of the information that we will need to dynamicly link - this module to itself */ - - hash_addr = (unsigned long *) (tpnt->dynamic_info[DT_HASH] + load_addr); - tpnt->nbucket = *hash_addr++; - tpnt->nchain = *hash_addr++; - tpnt->elf_buckets = hash_addr; - hash_addr += tpnt->nbucket; - -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("done grabbing link information\n"); -#endif - -#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS - /* Ugly, ugly. We need to call mprotect to change the protection of - the text pages so that we can do the dynamic linking. We can set the - protection back again once we are done */ - - { - ElfW(Phdr) *ppnt; - int i; - -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("calling mprotect on the shared library/dynamic linker\n"); -#endif - - /* First cover the shared library/dynamic linker. */ - if (tpnt->dynamic_info[DT_TEXTREL]) { - header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr; - ppnt = (ElfW(Phdr) *) ((int)auxvt[AT_BASE].a_un.a_ptr + - header->e_phoff); - for (i = 0; i < header->e_phnum; i++, ppnt++) { - if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) { - _dl_mprotect((void *) (load_addr + (ppnt->p_vaddr & PAGE_ALIGN)), - (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz, - PROT_READ | PROT_WRITE | PROT_EXEC); - } - } - } - -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("calling mprotect on the application program\n"); -#endif - /* Now cover the application program. */ - if (app_tpnt->dynamic_info[DT_TEXTREL]) { - ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr; - for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) { - if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) -#ifndef __UCLIBC_PIE_SUPPORT__ - _dl_mprotect((void *) (ppnt->p_vaddr & PAGE_ALIGN), - (ppnt->p_vaddr & ADDR_ALIGN) + - (unsigned long) ppnt->p_filesz, - PROT_READ | PROT_WRITE | PROT_EXEC); -#else - _dl_mprotect((void *) ((ppnt->p_vaddr + app_tpnt->loadaddr) & PAGE_ALIGN), - ((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) + - (unsigned long) ppnt->p_filesz, - PROT_READ | PROT_WRITE | PROT_EXEC); -#endif - } - } - } -#endif - -#if defined(__mips__) -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("About to do MIPS specific GOT bootstrap\n"); -#endif - /* For MIPS we have to do stuff to the GOT before we do relocations. */ - PERFORM_BOOTSTRAP_GOT(got); -#endif - - /* OK, now do the relocations. We do not do a lazy binding here, so - that once we are done, we have considerably more flexibility. */ -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("About to do library loader relocations\n"); -#endif - - goof = 0; - for (indx = 0; indx < 2; indx++) { - unsigned int i; - ELF_RELOC *rpnt; - unsigned long *reloc_addr; - unsigned long symbol_addr; - int symtab_index; - unsigned long rel_addr, rel_size; - - - rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt-> - dynamic_info[DT_RELOC_TABLE_ADDR]); - rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt-> - dynamic_info[DT_RELOC_TABLE_SIZE]); - - if (!rel_addr) - continue; - - /* Now parse the relocation information */ - rpnt = (ELF_RELOC *) (rel_addr + load_addr); - for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) { - reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset); - symtab_index = ELF32_R_SYM(rpnt->r_info); - symbol_addr = 0; - if (symtab_index) { - char *strtab; - char *symname; - Elf32_Sym *symtab; - - symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + load_addr); - strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + load_addr); - symname = strtab + symtab[symtab_index].st_name; - - /* We only do a partial dynamic linking right now. The user - is not supposed to define any symbols that start with a - '_dl', so we can do this with confidence. */ - if (!symname || symname[0] != '_' || - symname[1] != 'd' || symname[2] != 'l' || symname[3] != '_') - { - continue; - } - symbol_addr = load_addr + symtab[symtab_index].st_value; - - if (!symbol_addr) { - /* This will segfault - you cannot call a function until - * we have finished the relocations. - */ - SEND_STDERR("ELF dynamic loader - unable to self-bootstrap - symbol "); - SEND_STDERR(symname); - SEND_STDERR(" undefined.\n"); - goof++; - } -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("relocating symbol: "); - SEND_STDERR(symname); - SEND_STDERR("\n"); -#endif - PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, &symtab[symtab_index]); - } else { - /* Use this machine-specific macro to perform the actual relocation. */ - PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, NULL); - } - } - } - - if (goof) { - _dl_exit(14); - } - -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - /* Wahoo!!! */ - SEND_STDERR("Done relocating library loader, so we can now\n" - "\tuse globals and make function calls!\n"); -#endif - - /* Now we have done the mandatory linking of some things. We are now - free to start using global variables, since these things have all been - fixed up by now. Still no function calls outside of this library , - since the dynamic resolver is not yet ready. */ - _dl_get_ready_to_run(tpnt, app_tpnt, load_addr, hash_addr, - auxvt, envp, debug_addr, malloc_buffer, mmap_zero, argv); - - - /* Transfer control to the application. */ -#ifdef __SUPPORT_LD_DEBUG_EARLY__ - SEND_STDERR("transfering control to application\n"); -#endif - _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_fcn; - START(); -} - diff --git a/ldso/libdl/Makefile b/ldso/libdl/Makefile index 6e4d6a242..b883fc062 100644 --- a/ldso/libdl/Makefile +++ b/ldso/libdl/Makefile @@ -45,9 +45,9 @@ LIBDL_PIC=libdl_pic.a LIBDL_SHARED=libdl.so LIBDL_SHARED_FULLNAME=libdl-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so -CSRC=dlib.c -OBJS=dlib.o -PIC_OBJS=dlib_pic.o +CSRC=libdl.c +OBJS=libdl.o +PIC_OBJS=libdl_pic.o all: $(OBJS) $(LIBDL) shared @@ -61,12 +61,12 @@ ar-target: $(OBJS) $(PIC_OBJS) $(INSTALL) -m 644 $(LIBDL) $(TOPDIR)lib -dlib.o: dlib.c - $(CC) $(XXFLAGS_NOPIC) -c dlib.c -o dlib.o +libdl.o: libdl.c + $(CC) $(XXFLAGS_NOPIC) -c libdl.c -o libdl.o $(STRIPTOOL) -x -R .note -R .comment $*.o -dlib_pic.o: dlib.c - $(CC) $(XXFLAGS) -c dlib.c -o dlib_pic.o +libdl_pic.o: libdl.c + $(CC) $(XXFLAGS) -c libdl.c -o libdl_pic.o $(STRIPTOOL) -x -R .note -R .comment $*.o $(OBJ): Makefile diff --git a/ldso/libdl/dlib.c b/ldso/libdl/dlib.c deleted file mode 100644 index babcbc9c0..000000000 --- a/ldso/libdl/dlib.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - * libdl.c - * - * Functions required for dlopen et. al. - */ - -#include - - -/* The public interfaces */ -void *dlopen(const char *, int) __attribute__ ((__weak__, __alias__ ("_dlopen"))); -int dlclose(void *) __attribute__ ((__weak__, __alias__ ("_dlclose"))); -void *dlsym(void *, const char *) __attribute__ ((__weak__, __alias__ ("_dlsym"))); -const char *dlerror(void) __attribute__ ((__weak__, __alias__ ("_dlerror"))); -int dladdr(void *, Dl_info *) __attribute__ ((__weak__, __alias__ ("_dladdr"))); -void _dlinfo(void); - - -#ifdef __PIC__ -/* This is a real hack. We need access to the dynamic linker, but we -also need to make it possible to link against this library without any -unresolved externals. We provide these weak symbols to make the link -possible, but at run time the normal symbols are accessed. */ -static void __attribute__ ((unused)) foobar(void) -{ - const char msg[]="libdl library not correctly linked\n"; - _dl_write(2, msg, _dl_strlen(msg)); - _dl_exit(1); -} - -static int __attribute__ ((unused)) foobar1 = (int) foobar; /* Use as pointer */ -extern void _dl_dprintf(int, const char *, ...) __attribute__ ((__weak__, __alias__ ("foobar"))); -extern char *_dl_find_hash(const char *, struct dyn_elf *, struct elf_resolve *, enum caller_type) - __attribute__ ((__weak__, __alias__ ("foobar"))); -extern struct elf_resolve * _dl_load_shared_library(int, struct dyn_elf **, struct elf_resolve *, char *, int) - __attribute__ ((__weak__, __alias__ ("foobar"))); -extern struct elf_resolve * _dl_check_if_named_library_is_loaded(const char *, int) - __attribute__ ((__weak__, __alias__ ("foobar"))); -extern int _dl_fixup(struct dyn_elf *rpnt, int lazy) - __attribute__ ((__weak__, __alias__ ("foobar"))); -#ifdef __mips__ -extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt) - __attribute__ ((__weak__, __alias__ ("foobar"))); -#endif -#ifdef USE_CACHE -int _dl_map_cache(void) __attribute__ ((__weak__, __alias__ ("foobar"))); -int _dl_unmap_cache(void) __attribute__ ((__weak__, __alias__ ("foobar"))); -#endif - -extern struct dyn_elf *_dl_symbol_tables __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern struct dyn_elf *_dl_handles __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern struct elf_resolve *_dl_loaded_modules __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern struct r_debug *_dl_debug_addr __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern unsigned long _dl_error_number __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern void *(*_dl_malloc_function)(size_t) __attribute__ ((__weak__, __alias__ ("foobar1"))); -#ifdef __SUPPORT_LD_DEBUG__ -extern char *_dl_debug __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern char *_dl_debug_symbols __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern char *_dl_debug_move __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern char *_dl_debug_reloc __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern char *_dl_debug_detail __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern char *_dl_debug_nofixups __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern char *_dl_debug_bindings __attribute__ ((__weak__, __alias__ ("foobar1"))); -extern int _dl_debug_file __attribute__ ((__weak__, __alias__ ("foobar1"))); -#endif - -#else /* __PIC__ */ - -#ifdef __SUPPORT_LD_DEBUG__ -char *_dl_debug = 0; -char *_dl_debug_symbols = 0; -char *_dl_debug_move = 0; -char *_dl_debug_reloc = 0; -char *_dl_debug_detail = 0; -char *_dl_debug_nofixups = 0; -char *_dl_debug_bindings = 0; -int _dl_debug_file = 2; -#endif -char *_dl_library_path = 0; -char *_dl_ldsopath = 0; -struct r_debug *_dl_debug_addr = NULL; -static unsigned char *_dl_malloc_addr, *_dl_mmap_zero; -#include "../ldso/_dl_progname.h" /* Pull in the name of ld.so */ -#include "../ldso/hash.c" -#define _dl_trace_loaded_objects 0 -#include "../ldso/readelflib1.c" -void *(*_dl_malloc_function) (size_t size); -int _dl_fixup(struct dyn_elf *rpnt, int lazy); -#endif - -static int do_dlclose(void *, int need_fini); - - -static const char *dl_error_names[] = { - "", - "File not found", - "Unable to open /dev/zero", - "Not an ELF file", -#if defined (__i386__) - "Not i386 binary", -#elif defined (__sparc__) - "Not sparc binary", -#elif defined (__mc68000__) - "Not m68k binary", -#else - "Unrecognized binary type", -#endif - "Not an ELF shared library", - "Unable to mmap file", - "No dynamic section", -#ifdef ELF_USES_RELOCA - "Unable to process REL relocs", -#else - "Unable to process RELA relocs", -#endif - "Bad handle", - "Unable to resolve symbol" -}; - -static void __attribute__ ((destructor)) dl_cleanup(void) -{ - struct dyn_elf *d; - - for (d = _dl_handles; d; d = d->next_handle) - if (d->dyn->libtype == loaded_file && d->dyn->dynamic_info[DT_FINI]) { - (* ((int (*)(void)) (d->dyn->loadaddr + d->dyn->dynamic_info[DT_FINI]))) (); - d->dyn->dynamic_info[DT_FINI] = 0; - } -} - -void *_dlopen(const char *libname, int flag) -{ - struct elf_resolve *tpnt, *tfrom, *tcurr; - struct dyn_elf *dyn_chain, *rpnt = NULL; - struct dyn_elf *dpnt; - static int dl_init = 0; - ElfW(Addr) from; - struct elf_resolve *tpnt1; - void (*dl_brk) (void); - - /* A bit of sanity checking... */ - if (!(flag & (RTLD_LAZY|RTLD_NOW))) { - _dl_error_number = LD_BAD_HANDLE; - return NULL; - } - - from = (ElfW(Addr)) __builtin_return_address(0); - - /* Have the dynamic linker use the regular malloc function now */ - if (!dl_init) { - dl_init++; - _dl_malloc_function = malloc; - } - - /* Cover the trivial case first */ - if (!libname) - return _dl_symbol_tables; - - _dl_map_cache(); - - /* - * Try and locate the module we were called from - we - * need this so that we get the correct RPATH. Note that - * this is the current behavior under Solaris, but the - * ABI+ specifies that we should only use the RPATH from - * the application. Thus this may go away at some time - * in the future. - */ - tfrom = NULL; - for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) { - tpnt = dpnt->dyn; - if (tpnt->loadaddr < from - && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) - tfrom = tpnt; - } - - /* Try to load the specified library */ -#ifdef __SUPPORT_LD_DEBUG__ - if(_dl_debug) - _dl_dprintf(_dl_debug_file, "Trying to dlopen '%s'\n", (char*)libname); -#endif - tpnt = _dl_load_shared_library(0, &rpnt, tfrom, (char*)libname, 0); - if (tpnt == NULL) { - _dl_unmap_cache(); - return NULL; - } - - dyn_chain = (struct dyn_elf *) malloc(sizeof(struct dyn_elf)); - _dl_memset(dyn_chain, 0, sizeof(struct dyn_elf)); - dyn_chain->dyn = tpnt; - dyn_chain->flags = flag; - if (!tpnt->symbol_scope) - tpnt->symbol_scope = dyn_chain; - - dyn_chain->next_handle = _dl_handles; - _dl_handles = rpnt = dyn_chain; - - if (tpnt->init_flag & INIT_FUNCS_CALLED) { - /* If the init and fini stuff has already been run, that means - * the dlopen'd library has already been loaded, and nothing - * further needs to be done. */ - return (void *) dyn_chain; - } - - -#ifdef __SUPPORT_LD_DEBUG__ - if(_dl_debug) - _dl_dprintf(_dl_debug_file, "Looking for needed libraries\n"); -#endif - - for (tcurr = tpnt; tcurr; tcurr = tcurr->next) - { - Elf32_Dyn *dpnt; - char *lpntstr; - for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) { - if (dpnt->d_tag == DT_NEEDED) { - - char *name; - lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + - dpnt->d_un.d_val); - name = _dl_get_last_path_component(lpntstr); - -#ifdef __SUPPORT_LD_DEBUG__ - if(_dl_debug) - _dl_dprintf(_dl_debug_file, "Trying to load '%s', needed by '%s'\n", - lpntstr, tcurr->libname); -#endif - - if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, 0))) { - goto oops; - } - - rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf)); - _dl_memset (rpnt->next, 0, sizeof (struct dyn_elf)); - rpnt = rpnt->next; - if (!tpnt1->symbol_scope) tpnt1->symbol_scope = rpnt; - rpnt->dyn = tpnt1; - - } - } - } - - /* - * OK, now attach the entire chain at the end - */ - rpnt->next = _dl_symbol_tables; - -#ifdef __mips__ - /* - * Relocation of the GOT entries for MIPS have to be done - * after all the libraries have been loaded. - */ - _dl_perform_mips_global_got_relocations(tpnt); -#endif - -#ifdef __SUPPORT_LD_DEBUG__ - if(_dl_debug) - _dl_dprintf(_dl_debug_file, "Beginning dlopen relocation fixups\n"); -#endif - /* - * OK, now all of the kids are tucked into bed in their proper addresses. - * Now we go through and look for REL and RELA records that indicate fixups - * to the GOT tables. We need to do this in reverse order so that COPY - * directives work correctly */ - if (_dl_fixup(dyn_chain, dyn_chain->flags)) - goto oops; - - /* TODO: Should we set the protections of all pages back to R/O now ? */ - - - /* Notify the debugger we have added some objects. */ - if (_dl_debug_addr) { - dl_brk = (void (*)(void)) _dl_debug_addr->r_brk; - if (dl_brk != NULL) { - _dl_debug_addr->r_state = RT_ADD; - (*dl_brk) (); - - _dl_debug_addr->r_state = RT_CONSISTENT; - (*dl_brk) (); - } - } - -#if 0 //def __SUPPORT_LD_DEBUG__ - if(_dl_debug) - _dlinfo(); -#endif - -#ifdef __PIC__ - /* Find the last library so we can run things in the right order */ - for (tpnt = dyn_chain->dyn; tpnt->next!=NULL; tpnt = tpnt->next) - ; - - /* Run the ctors and set up the dtors */ - for (; tpnt != dyn_chain->dyn->prev; tpnt=tpnt->prev) - { - /* Apparently crt1 for the application is responsible for handling this. - * We only need to run the init/fini for shared libraries - */ - if (tpnt->libtype == program_interpreter) - continue; - if (tpnt->libtype == elf_executable) - continue; - if (tpnt->init_flag & INIT_FUNCS_CALLED) - continue; - tpnt->init_flag |= INIT_FUNCS_CALLED; - - if (tpnt->dynamic_info[DT_INIT]) { - void (*dl_elf_func) (void); - dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]); - if (dl_elf_func && *dl_elf_func != NULL) { -#ifdef __SUPPORT_LD_DEBUG__ - if(_dl_debug) - _dl_dprintf(2, "running ctors for library %s at '%x'\n", tpnt->libname, dl_elf_func); -#endif - (*dl_elf_func) (); - } - } - if (tpnt->dynamic_info[DT_FINI]) { - void (*dl_elf_func) (void); - dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]); - if (dl_elf_func && *dl_elf_func != NULL) { -#ifdef __SUPPORT_LD_DEBUG__ - if(_dl_debug) - _dl_dprintf(2, "setting up dtors for library %s at '%x'\n", tpnt->libname, dl_elf_func); -#endif - atexit(dl_elf_func); - } - } - } -#endif - return (void *) dyn_chain; - -oops: - /* Something went wrong. Clean up and return NULL. */ - _dl_unmap_cache(); - do_dlclose(dyn_chain, 0); - return NULL; -} - -void *_dlsym(void *vhandle, const char *name) -{ - struct elf_resolve *tpnt, *tfrom; - struct dyn_elf *handle; - ElfW(Addr) from; - struct dyn_elf *rpnt; - void *ret; - - handle = (struct dyn_elf *) vhandle; - - /* First of all verify that we have a real handle - of some kind. Return NULL if not a valid handle. */ - - if (handle == NULL) - handle = _dl_symbol_tables; - else if (handle != RTLD_NEXT && handle != _dl_symbol_tables) { - for (rpnt = _dl_handles; rpnt; rpnt = rpnt->next_handle) - if (rpnt == handle) - break; - if (!rpnt) { - _dl_error_number = LD_BAD_HANDLE; - return NULL; - } - } else if (handle == RTLD_NEXT) { - /* - * Try and locate the module we were called from - we - * need this so that we know where to start searching - * from. We never pass RTLD_NEXT down into the actual - * dynamic loader itself, as it doesn't know - * how to properly treat it. - */ - from = (ElfW(Addr)) __builtin_return_address(0); - - tfrom = NULL; - for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next) { - tpnt = rpnt->dyn; - if (tpnt->loadaddr < from - && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) { - tfrom = tpnt; - handle = rpnt->next; - } - } - } - - ret = _dl_find_hash((char*)name, handle, NULL, copyrel); - - /* - * Nothing found. - */ - if (!ret) - _dl_error_number = LD_NO_SYMBOL; - return ret; -} - -int _dlclose(void *vhandle) -{ - return do_dlclose(vhandle, 1); -} - -static int do_dlclose(void *vhandle, int need_fini) -{ - struct dyn_elf *rpnt, *rpnt1; - struct dyn_elf *spnt, *spnt1; - ElfW(Phdr) *ppnt; - struct elf_resolve *tpnt; - int (*dl_elf_fini) (void); - void (*dl_brk) (void); - struct dyn_elf *handle; - unsigned int end; - int i = 0; - - handle = (struct dyn_elf *) vhandle; - rpnt1 = NULL; - for (rpnt = _dl_handles; rpnt; rpnt = rpnt->next_handle) { - if (rpnt == handle) { - break; - } - rpnt1 = rpnt; - } - - if (!rpnt) { - _dl_error_number = LD_BAD_HANDLE; - return 1; - } - - /* OK, this is a valid handle - now close out the file. - * We check if we need to call fini () on the handle. */ - spnt = need_fini ? handle : handle->next; - for (; spnt; spnt = spnt1) { - spnt1 = spnt->next; - - /* We appended the module list to the end - when we get back here, - quit. The access counts were not adjusted to account for being here. */ - if (spnt == _dl_symbol_tables) - break; - if (spnt->dyn->usage_count == 1 - && spnt->dyn->libtype == loaded_file) { - tpnt = spnt->dyn; - /* Apparently crt1 for the application is responsible for handling this. - * We only need to run the init/fini for shared libraries - */ - - if (tpnt->dynamic_info[DT_FINI]) { - dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + - tpnt->dynamic_info[DT_FINI]); - (*dl_elf_fini) (); - } - } - } - if (rpnt1) - rpnt1->next_handle = rpnt->next_handle; - else - _dl_handles = rpnt->next_handle; - - /* OK, this is a valid handle - now close out the file */ - for (rpnt = handle; rpnt; rpnt = rpnt1) { - rpnt1 = rpnt->next; - - /* We appended the module list to the end - when we get back here, - quit. The access counts were not adjusted to account for being here. */ - if (rpnt == _dl_symbol_tables) - break; - - rpnt->dyn->usage_count--; - if (rpnt->dyn->usage_count == 0 - && rpnt->dyn->libtype == loaded_file) { - tpnt = rpnt->dyn; - /* Apparently crt1 for the application is responsible for handling this. - * We only need to run the init/fini for shared libraries - */ -#if 0 - - /* We have to do this above, before we start closing objects. - * Otherwise when the needed symbols for _fini handling are - * resolved a coredump would occur. Rob Ryan (robr@cmu.edu)*/ - if (tpnt->dynamic_info[DT_FINI]) { - dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]); - (*dl_elf_fini) (); - } -#endif - end = 0; - for (i = 0, ppnt = rpnt->dyn->ppnt; - i < rpnt->dyn->n_phent; ppnt++, i++) { - if (ppnt->p_type != PT_LOAD) - continue; - if (end < ppnt->p_vaddr + ppnt->p_memsz) - end = ppnt->p_vaddr + ppnt->p_memsz; - } - _dl_munmap((void*)rpnt->dyn->loadaddr, end); - /* Next, remove rpnt->dyn from the loaded_module list */ - if (_dl_loaded_modules == rpnt->dyn) { - _dl_loaded_modules = rpnt->dyn->next; - if (_dl_loaded_modules) - _dl_loaded_modules->prev = 0; - } else - for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) - if (tpnt->next == rpnt->dyn) { - tpnt->next = tpnt->next->next; - if (tpnt->next) - tpnt->next->prev = tpnt; - break; - } - free(rpnt->dyn->libname); - free(rpnt->dyn); - } - free(rpnt); - } - - - if (_dl_debug_addr) { - dl_brk = (void (*)(void)) _dl_debug_addr->r_brk; - if (dl_brk != NULL) { - _dl_debug_addr->r_state = RT_DELETE; - (*dl_brk) (); - - _dl_debug_addr->r_state = RT_CONSISTENT; - (*dl_brk) (); - } - } - - return 0; -} - -const char *_dlerror(void) -{ - const char *retval; - - if (!_dl_error_number) - return NULL; - retval = dl_error_names[_dl_error_number]; - _dl_error_number = 0; - return retval; -} - -/* - * Dump information to stderrr about the current loaded modules - */ -static char *type[] = { "Lib", "Exe", "Int", "Mod" }; - -void _dlinfo(void) -{ - struct elf_resolve *tpnt; - struct dyn_elf *rpnt, *hpnt; - - _dl_dprintf(2, "List of loaded modules\n"); - /* First start with a complete list of all of the loaded files. */ - for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { - _dl_dprintf(2, "\t%x %x %x %s %d %s\n", - (unsigned) tpnt->loadaddr, (unsigned) tpnt, - (unsigned) tpnt->symbol_scope, - type[tpnt->libtype], - tpnt->usage_count, tpnt->libname); - } - - /* Next dump the module list for the application itself */ - _dl_dprintf(2, "\nModules for application (%x):\n", - (unsigned) _dl_symbol_tables); - for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next) - _dl_dprintf(2, "\t%x %s\n", (unsigned) rpnt->dyn, rpnt->dyn->libname); - - for (hpnt = _dl_handles; hpnt; hpnt = hpnt->next_handle) { - _dl_dprintf(2, "Modules for handle %x\n", (unsigned) hpnt); - for (rpnt = hpnt; rpnt; rpnt = rpnt->next) - _dl_dprintf(2, "\t%x %s\n", (unsigned) rpnt->dyn, - rpnt->dyn->libname); - } -} - -int _dladdr(void *__address, Dl_info * __dlip) -{ - struct elf_resolve *pelf; - struct elf_resolve *rpnt; - - _dl_map_cache(); - - /* - * Try and locate the module address is in - */ - pelf = NULL; - -#if 0 - _dl_dprintf(2, "dladdr( %x, %x )\n", __address, __dlip); -#endif - - for (rpnt = _dl_loaded_modules; rpnt; rpnt = rpnt->next) { - struct elf_resolve *tpnt; - - tpnt = rpnt; -#if 0 - _dl_dprintf(2, "Module \"%s\" at %x\n", - tpnt->libname, tpnt->loadaddr); -#endif - if (tpnt->loadaddr < (ElfW(Addr)) __address - && (pelf == NULL || pelf->loadaddr < tpnt->loadaddr)) { - pelf = tpnt; - } - } - - if (!pelf) { - return 0; - } - - /* - * Try and locate the symbol of address - */ - - { - char *strtab; - Elf32_Sym *symtab; - int hn, si; - int sf; - int sn = 0; - ElfW(Addr) sa; - - sa = 0; - symtab = (Elf32_Sym *) (pelf->dynamic_info[DT_SYMTAB] + pelf->loadaddr); - strtab = (char *) (pelf->dynamic_info[DT_STRTAB] + pelf->loadaddr); - - sf = 0; - for (hn = 0; hn < pelf->nbucket; hn++) { - for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) { - ElfW(Addr) symbol_addr; - - symbol_addr = pelf->loadaddr + symtab[si].st_value; - if (symbol_addr <= (ElfW(Addr))__address && (!sf || sa < symbol_addr)) { - sa = symbol_addr; - sn = si; - sf = 1; - } -#if 0 - _dl_dprintf(2, "Symbol \"%s\" at %x\n", - strtab + symtab[si].st_name, symbol_addr); -#endif - } - } - - if (sf) { - __dlip->dli_fname = pelf->libname; - __dlip->dli_fbase = (void *)pelf->loadaddr; - __dlip->dli_sname = strtab + symtab[sn].st_name; - __dlip->dli_saddr = (void *)sa; - } - return 1; - } -} diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index babcbc9c0..f7411cd25 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -80,10 +80,10 @@ char *_dl_library_path = 0; char *_dl_ldsopath = 0; struct r_debug *_dl_debug_addr = NULL; static unsigned char *_dl_malloc_addr, *_dl_mmap_zero; -#include "../ldso/_dl_progname.h" /* Pull in the name of ld.so */ -#include "../ldso/hash.c" +#include "../ldso/dl-progname.h" /* Pull in the name of ld.so */ +#include "../ldso/dl-hash.c" #define _dl_trace_loaded_objects 0 -#include "../ldso/readelflib1.c" +#include "../ldso/dl-elf.c" void *(*_dl_malloc_function) (size_t size); int _dl_fixup(struct dyn_elf *rpnt, int lazy); #endif -- cgit v1.2.3