mirror of
https://git.busybox.net/uClibc
synced 2025-10-14 01:32:00 +08:00
revert fdpic patch so we can merge it in bit by bit
This commit is contained in:
@@ -66,70 +66,4 @@ typedef struct {
|
||||
|
||||
#endif
|
||||
|
||||
/* Machines in which different sections may be relocated by different
|
||||
amounts should define this and LD_RELOC_ADDR. If you change this,
|
||||
make sure you change struct link_map in include/link.h accordingly
|
||||
such that it matches a prefix of struct elf_resolve. */
|
||||
#ifndef DL_LOADADDR_TYPE
|
||||
# define DL_LOADADDR_TYPE ElfW(Addr)
|
||||
#endif
|
||||
|
||||
/* When DL_LOADADDR_TYPE is not a scalar value, or some different
|
||||
computation is needed to relocate an address, define this. */
|
||||
#ifndef DL_RELOC_ADDR
|
||||
# define DL_RELOC_ADDR(ADDR, LOADADDR) \
|
||||
((void*)((intptr_t)(ADDR) + (intptr_t)(LOADADDR)))
|
||||
#endif
|
||||
|
||||
/* Define if any declarations/definitions of local variables are
|
||||
needed in a function that calls DT_INIT_LOADADDR or
|
||||
DL_INIT_LOADADDR_HDR. Declarations must be properly terminated
|
||||
with a semicolon, and non-declaration statements are forbidden. */
|
||||
#ifndef DL_INIT_LOADADDR_EXTRA_DECLS
|
||||
# define DL_INIT_LOADADDR_EXTRA_DECLS /* int i; */
|
||||
#endif
|
||||
|
||||
/* Prepare a DL_LOADADDR_TYPE data structure for incremental
|
||||
initialization with DL_INIT_LOADADDR_HDR, given pointers to a base
|
||||
load address and to program headers. */
|
||||
#ifndef DL_INIT_LOADADDR
|
||||
# define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
|
||||
((LOADADDR) = (BASEADDR))
|
||||
#endif
|
||||
|
||||
/* Convert a DL_LOADADDR_TYPE to an identifying pointer. Used mostly
|
||||
for debugging. */
|
||||
#ifndef DL_LOADADDR_BASE
|
||||
# define DL_LOADADDR_BASE(LOADADDR) (LOADADDR)
|
||||
#endif
|
||||
|
||||
/* Initialize a LOADADDR representing the loader itself. It's only
|
||||
called from DL_BOOT, so additional arguments passed to it may be
|
||||
referenced. */
|
||||
#ifndef DL_INIT_LOADADDR_BOOT
|
||||
# define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
|
||||
((LOADADDR) = (BASEADDR))
|
||||
#endif
|
||||
|
||||
/* Initialize a LOADADDR representing the program. It's called from
|
||||
DL_BOOT only. */
|
||||
#ifndef DL_INIT_LOADADDR_PROG
|
||||
# define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
|
||||
((LOADADDR) = (BASEADDR))
|
||||
#endif
|
||||
|
||||
/* Test whether a given ADDR is more likely to be within the memory
|
||||
region mapped to TPNT (a struct elf_resolve *) than to TFROM.
|
||||
Everywhere that this is used, TFROM is initially NULL, and whenever
|
||||
a potential match is found, it's updated. One might want to walk
|
||||
the chain of elf_resolve to locate the best match and return false
|
||||
whenever TFROM is non-NULL, or use an exact-matching algorithm
|
||||
using additional information encoded in DL_LOADADDR_TYPE to test
|
||||
for exact containment. */
|
||||
#ifndef DL_ADDR_IN_LOADADDR
|
||||
# define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
|
||||
((void*)(TPNT)->loadaddr < (void*)(ADDR) \
|
||||
&& (! (TFROM) || (TFROM)->loadaddr < (TPNT)->loadaddr))
|
||||
#endif
|
||||
|
||||
#endif /* _LD_DEFS_H */
|
||||
|
@@ -94,12 +94,10 @@ extern void _dl_protect_relro (struct elf_resolve *l);
|
||||
|
||||
#define DYNAMIC_SIZE (DT_NUM+OS_NUM+ARCH_NUM)
|
||||
|
||||
extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr,
|
||||
DL_LOADADDR_TYPE load_off);
|
||||
extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off);
|
||||
|
||||
static __always_inline
|
||||
void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr,
|
||||
DL_LOADADDR_TYPE load_off)
|
||||
void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off)
|
||||
{
|
||||
for (; dpnt->d_tag; dpnt++) {
|
||||
if (dpnt->d_tag < DT_NUM) {
|
||||
@@ -141,8 +139,7 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void
|
||||
#define ADJUST_DYN_INFO(tag, load_off) \
|
||||
do { \
|
||||
if (dynamic_info[tag]) \
|
||||
dynamic_info[tag] = (unsigned long)DL_RELOC_ADDR (dynamic_info[tag], \
|
||||
load_off); \
|
||||
dynamic_info[tag] += load_off; \
|
||||
} while(0)
|
||||
ADJUST_DYN_INFO(DT_HASH, load_off);
|
||||
ADJUST_DYN_INFO(DT_PLTGOT, load_off);
|
||||
|
@@ -28,7 +28,7 @@ struct dyn_elf{
|
||||
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. */
|
||||
DL_LOADADDR_TYPE loadaddr; /* Base address shared object is loaded at. */
|
||||
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;
|
||||
@@ -77,7 +77,7 @@ extern struct elf_resolve * _dl_loaded_modules;
|
||||
extern struct dyn_elf * _dl_handles;
|
||||
|
||||
extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname,
|
||||
DL_LOADADDR_TYPE loadaddr, unsigned long * dynamic_info,
|
||||
char * loadaddr, unsigned long * dynamic_info,
|
||||
unsigned long dynamic_addr, unsigned long dynamic_size);
|
||||
|
||||
extern char * _dl_find_hash(const char * name, struct dyn_elf * rpnt1,
|
||||
|
@@ -88,7 +88,7 @@ extern void _dl_unsetenv(const char *symbol, char **envp);
|
||||
extern char *_dl_strdup(const char *string);
|
||||
extern void _dl_dprintf(int, const char *, ...);
|
||||
|
||||
extern void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
extern void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
|
||||
ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv);
|
||||
|
||||
#endif /* _LDSO_H_ */
|
||||
|
@@ -118,10 +118,10 @@ int _dl_unmap_cache(void)
|
||||
void
|
||||
_dl_protect_relro (struct elf_resolve *l)
|
||||
{
|
||||
ElfW(Addr) base = (ElfW(Addr)) DL_RELOC_ADDR (l->relro_addr,
|
||||
l->loadaddr);
|
||||
ElfW(Addr) start = (base & ~(_dl_pagesize - 1));
|
||||
ElfW(Addr) end = ((base + l->relro_size) & ~(_dl_pagesize - 1));
|
||||
ElfW(Addr) start = ((l->loadaddr + l->relro_addr)
|
||||
& ~(_dl_pagesize - 1));
|
||||
ElfW(Addr) end = ((l->loadaddr + l->relro_addr + l->relro_size)
|
||||
& ~(_dl_pagesize - 1));
|
||||
_dl_if_debug_dprint("RELRO protecting %s: start:%x, end:%x\n", l->libname, start, end);
|
||||
if (start != end &&
|
||||
_dl_mprotect ((void *) start, end - start, PROT_READ) < 0) {
|
||||
@@ -262,8 +262,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
|
||||
#ifdef __LDSO_RUNPATH__
|
||||
pnt = (tpnt ? (char *)tpnt->dynamic_info[DT_RUNPATH] : NULL);
|
||||
if (pnt) {
|
||||
pnt += (intptr_t) DL_RELOC_ADDR (tpnt->dynamic_info[DT_STRTAB],
|
||||
tpnt->loadaddr);
|
||||
pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB];
|
||||
_dl_if_debug_dprint("\tsearching RUNPATH='%s'\n", pnt);
|
||||
if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL)
|
||||
return tpnt1;
|
||||
@@ -353,8 +352,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
|
||||
ElfW(Addr) relro_addr = 0;
|
||||
size_t relro_size = 0;
|
||||
struct stat st;
|
||||
DL_LOADADDR_TYPE lib_loadaddr;
|
||||
DL_INIT_LOADADDR_EXTRA_DECLS
|
||||
|
||||
libaddr = 0;
|
||||
infile = _dl_open(libname, O_RDONLY, 0);
|
||||
@@ -470,10 +467,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
|
||||
}
|
||||
libaddr = (unsigned long) status;
|
||||
flags |= MAP_FIXED;
|
||||
DL_INIT_LOADADDR (lib_loadaddr, libaddr,
|
||||
(Elf32_Phdr *)& header[epnt->e_phoff],
|
||||
epnt->e_phnum);
|
||||
|
||||
|
||||
/* Get the memory to store the library */
|
||||
ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
|
||||
|
||||
@@ -553,8 +547,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
|
||||
|
||||
/* For a non-PIC library, the addresses are all absolute */
|
||||
if (piclib) {
|
||||
dynamic_addr = (unsigned long) DL_RELOC_ADDR (dynamic_addr,
|
||||
lib_loadaddr);
|
||||
dynamic_addr += (unsigned long) libaddr;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -574,7 +567,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
|
||||
|
||||
dpnt = (ElfW(Dyn) *) dynamic_addr;
|
||||
_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
|
||||
_dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr);
|
||||
_dl_parse_dynamic_info(dpnt, dynamic_info, NULL, libaddr);
|
||||
/* 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. */
|
||||
@@ -595,14 +588,13 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
|
||||
#endif
|
||||
}
|
||||
|
||||
tpnt = _dl_add_elf_hash_table(libname, lib_loadaddr, dynamic_info,
|
||||
tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info,
|
||||
dynamic_addr, 0);
|
||||
tpnt->relro_addr = relro_addr;
|
||||
tpnt->relro_size = relro_size;
|
||||
tpnt->st_dev = st.st_dev;
|
||||
tpnt->st_ino = st.st_ino;
|
||||
tpnt->ppnt = (ElfW(Phdr) *) DL_RELOC_ADDR (epnt->e_phoff,
|
||||
tpnt->loadaddr);
|
||||
tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
|
||||
tpnt->n_phent = epnt->e_phnum;
|
||||
|
||||
/*
|
||||
@@ -633,11 +625,9 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
|
||||
}
|
||||
|
||||
_dl_if_debug_dprint("\n\tfile='%s'; generating link map\n", libname);
|
||||
_dl_if_debug_dprint("\t\tdynamic: %x base: %x\n", dynamic_addr,
|
||||
DL_LOADADDR_BASE (libaddr));
|
||||
_dl_if_debug_dprint("\t\tdynamic: %x base: %x\n", dynamic_addr, libaddr);
|
||||
_dl_if_debug_dprint("\t\t entry: %x phdr: %x phnum: %x\n\n",
|
||||
DL_RELOC_ADDR (epnt->e_entry, lib_loadaddr),
|
||||
tpnt->ppnt, tpnt->n_phent);
|
||||
epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent);
|
||||
|
||||
_dl_munmap(header, _dl_pagesize);
|
||||
|
||||
@@ -811,7 +801,7 @@ char *_dl_strdup(const char *string)
|
||||
return retval;
|
||||
}
|
||||
|
||||
void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, DL_LOADADDR_TYPE load_off)
|
||||
void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off)
|
||||
{
|
||||
__dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off);
|
||||
}
|
||||
@@ -828,7 +818,7 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void
|
||||
int ret = 0;
|
||||
|
||||
for (l = _dl_loaded_modules; l != NULL; l = l->next) {
|
||||
info.dlpi_addr = (ElfW(Addr))DL_LOADADDR_BASE (l->loadaddr);
|
||||
info.dlpi_addr = l->loadaddr;
|
||||
info.dlpi_name = l->libname;
|
||||
info.dlpi_phdr = l->ppnt;
|
||||
info.dlpi_phnum = l->n_phent;
|
||||
|
@@ -83,7 +83,7 @@ static inline Elf_Symndx _dl_elf_hash(const char *name)
|
||||
* externals properly.
|
||||
*/
|
||||
struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
|
||||
DL_LOADADDR_TYPE loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr,
|
||||
char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr,
|
||||
attribute_unused unsigned long dynamic_size)
|
||||
{
|
||||
Elf_Symndx *hash_addr;
|
||||
@@ -117,7 +117,7 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
|
||||
hash_addr += tpnt->nbucket;
|
||||
tpnt->chains = hash_addr;
|
||||
}
|
||||
tpnt->loadaddr = loadaddr;
|
||||
tpnt->loadaddr = (ElfW(Addr))loadaddr;
|
||||
for (i = 0; i < DYNAMIC_SIZE; i++)
|
||||
tpnt->dynamic_info[i] = dynamic_info[i];
|
||||
return tpnt;
|
||||
@@ -163,10 +163,8 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *
|
||||
|
||||
/* Avoid calling .urem here. */
|
||||
do_rem(hn, elf_hash_number, tpnt->nbucket);
|
||||
symtab = (ElfW(Sym) *) DL_RELOC_ADDR (tpnt->dynamic_info[DT_SYMTAB],
|
||||
tpnt->loadaddr);
|
||||
strtab = (char *) DL_RELOC_ADDR (tpnt->dynamic_info[DT_STRTAB],
|
||||
tpnt->loadaddr);
|
||||
symtab = (ElfW(Sym) *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB]);
|
||||
strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]);
|
||||
|
||||
for (si = tpnt->elf_buckets[hn]; si != STN_UNDEF; si = tpnt->chains[si]) {
|
||||
sym = &symtab[si];
|
||||
@@ -186,13 +184,11 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *
|
||||
/* Perhaps we should support old style weak symbol handling
|
||||
* per what glibc does when you export LD_DYNAMIC_WEAK */
|
||||
if (!weak_result)
|
||||
weak_result = (char *) DL_RELOC_ADDR (sym->st_value,
|
||||
tpnt->loadaddr);
|
||||
weak_result = (char *)tpnt->loadaddr + sym->st_value;
|
||||
break;
|
||||
#endif
|
||||
case STB_GLOBAL:
|
||||
return (char*) DL_RELOC_ADDR (sym->st_value,
|
||||
tpnt->loadaddr);
|
||||
return (char*)tpnt->loadaddr + sym->st_value;
|
||||
default: /* Local symbols not handled here */
|
||||
break;
|
||||
}
|
||||
|
@@ -114,7 +114,7 @@ static void * __attribute_used__ _dl_start(unsigned long args)
|
||||
{
|
||||
unsigned int argc;
|
||||
char **argv, **envp;
|
||||
DL_LOADADDR_TYPE load_addr;
|
||||
ElfW(Addr) load_addr;
|
||||
ElfW(Addr) got;
|
||||
unsigned long *aux_dat;
|
||||
ElfW(Ehdr) *header;
|
||||
@@ -168,7 +168,7 @@ static void * __attribute_used__ _dl_start(unsigned long args)
|
||||
* (esp since SEND_STDERR() needs this on some platforms... */
|
||||
if (!auxvt[AT_BASE].a_un.a_val)
|
||||
auxvt[AT_BASE].a_un.a_val = elf_machine_load_address();
|
||||
DL_INIT_LOADADDR_BOOT(load_addr, auxvt[AT_BASE].a_un.a_val);
|
||||
load_addr = auxvt[AT_BASE].a_un.a_val;
|
||||
header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
|
||||
|
||||
/* Check the ELF header to make sure everything looks ok. */
|
||||
@@ -186,14 +186,14 @@ static void * __attribute_used__ _dl_start(unsigned long args)
|
||||
_dl_exit(0);
|
||||
}
|
||||
SEND_STDERR_DEBUG("ELF header=");
|
||||
SEND_ADDRESS_STDERR_DEBUG(DL_LOADADDR_BASE (load_addr), 1);
|
||||
SEND_ADDRESS_STDERR_DEBUG(load_addr, 1);
|
||||
|
||||
/* 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... */
|
||||
got = elf_machine_dynamic();
|
||||
dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR (got, load_addr);
|
||||
dpnt = (ElfW(Dyn) *) (got + load_addr);
|
||||
SEND_STDERR_DEBUG("First Dynamic section entry=");
|
||||
SEND_ADDRESS_STDERR_DEBUG(dpnt, 1);
|
||||
_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
|
||||
@@ -259,10 +259,9 @@ static void * __attribute_used__ _dl_start(unsigned long args)
|
||||
rel_addr += relative_count * sizeof(ELF_RELOC);
|
||||
}
|
||||
|
||||
rpnt = (ELF_RELOC *) DL_RELOC_ADDR (rel_addr, load_addr);
|
||||
rpnt = (ELF_RELOC *) (rel_addr + load_addr);
|
||||
for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
|
||||
reloc_addr = (unsigned long *) DL_RELOC_ADDR ((unsigned long) rpnt->r_offset,
|
||||
load_addr);
|
||||
reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
|
||||
symtab_index = ELF_R_SYM(rpnt->r_info);
|
||||
symbol_addr = 0;
|
||||
sym = NULL;
|
||||
@@ -273,7 +272,7 @@ static void * __attribute_used__ _dl_start(unsigned long args)
|
||||
symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB];
|
||||
strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
|
||||
sym = &symtab[symtab_index];
|
||||
symbol_addr = (unsigned long) DL_RELOC_ADDR (sym->st_value, load_addr);
|
||||
symbol_addr = load_addr + sym->st_value;
|
||||
|
||||
SEND_STDERR_DEBUG("relocating symbol: ");
|
||||
SEND_STDERR_DEBUG(strtab + sym->st_name);
|
||||
|
@@ -102,18 +102,17 @@ uintptr_t __guard attribute_relro;
|
||||
#endif
|
||||
|
||||
static void _dl_run_array_forward(unsigned long array, unsigned long size,
|
||||
DL_LOADADDR_TYPE loadaddr)
|
||||
ElfW(Addr) loadaddr)
|
||||
{
|
||||
if (array != 0) {
|
||||
unsigned int j;
|
||||
unsigned int jm;
|
||||
ElfW(Addr) *addrs;
|
||||
jm = size / sizeof (ElfW(Addr));
|
||||
addrs = (ElfW(Addr) *) DL_RELOC_ADDR (array, loadaddr);
|
||||
addrs = (ElfW(Addr) *) (array + loadaddr);
|
||||
for (j = 0; j < jm; ++j) {
|
||||
void (*dl_elf_func) (void);
|
||||
dl_elf_func = (void (*)(void)) DL_RELOC_ADDR (addrs[j],
|
||||
loadaddr);
|
||||
dl_elf_func = (void (*)(void)) (intptr_t) addrs[j];
|
||||
(*dl_elf_func) ();
|
||||
}
|
||||
}
|
||||
@@ -137,13 +136,11 @@ void _dl_run_fini_array(struct elf_resolve *tpnt);
|
||||
void _dl_run_fini_array(struct elf_resolve *tpnt)
|
||||
{
|
||||
if (tpnt->dynamic_info[DT_FINI_ARRAY]) {
|
||||
ElfW(Addr) *array = (ElfW(Addr) *) DL_RELOC_ADDR (tpnt->dynamic_info[DT_FINI_ARRAY],
|
||||
tpnt->loadaddr);
|
||||
ElfW(Addr) *array = (ElfW(Addr) *) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI_ARRAY]);
|
||||
unsigned int i = (tpnt->dynamic_info[DT_FINI_ARRAYSZ] / sizeof(ElfW(Addr)));
|
||||
while (i-- > 0) {
|
||||
void (*dl_elf_func) (void);
|
||||
dl_elf_func = (void (*)(void)) DL_RELOC_ADDR (array[i],
|
||||
tpnt->loadaddr);
|
||||
dl_elf_func = (void (*)(void)) (intptr_t) array[i];
|
||||
(*dl_elf_func) ();
|
||||
}
|
||||
}
|
||||
@@ -169,15 +166,14 @@ static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
|
||||
if (tpnt->dynamic_info[DT_FINI]) {
|
||||
void (*dl_elf_func) (void);
|
||||
|
||||
dl_elf_func = (void (*)(void)) DL_RELOC_ADDR (tpnt->dynamic_info[DT_FINI],
|
||||
tpnt->loadaddr);
|
||||
dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
|
||||
_dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
|
||||
(*dl_elf_func) ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
|
||||
ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp,
|
||||
char **argv)
|
||||
{
|
||||
@@ -299,13 +295,13 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
|
||||
for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
|
||||
if (phdr->p_type == PT_PHDR) {
|
||||
DL_INIT_LOADADDR_PROG (app_tpnt->loadaddr, (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr));
|
||||
app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (DL_LOADADDR_BASE (app_tpnt->loadaddr))
|
||||
if (app_tpnt->loadaddr)
|
||||
_dl_debug_early("Position Independent Executable: "
|
||||
"app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE (app_tpnt->loadaddr));
|
||||
"app_tpnt->loadaddr=%x\n", app_tpnt->loadaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -322,7 +318,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
relro_size = ppnt->p_memsz;
|
||||
}
|
||||
if (ppnt->p_type == PT_DYNAMIC) {
|
||||
dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR (ppnt->p_vaddr, app_tpnt->loadaddr);
|
||||
dpnt = (ElfW(Dyn) *) (ppnt->p_vaddr + app_tpnt->loadaddr);
|
||||
_dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
|
||||
#ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
|
||||
/* Ugly, ugly. We need to call mprotect to change the
|
||||
@@ -335,11 +331,11 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
if (app_tpnt->dynamic_info[DT_TEXTREL]) {
|
||||
ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
|
||||
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
|
||||
if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) {
|
||||
void *base = DL_RELOC_ADDR (ppnt->p_vaddr & PAGE_ALIGN, app_tpnt->loadaddr);
|
||||
_dl_mprotect(base, (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz,
|
||||
if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
|
||||
_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
|
||||
@@ -350,10 +346,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
continue;
|
||||
#endif
|
||||
/* OK, we have what we need - slip this one into the list. */
|
||||
app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
|
||||
app_tpnt->dynamic_info,
|
||||
(unsigned long) DL_RELOC_ADDR (ppnt->p_vaddr, app_tpnt->loadaddr),
|
||||
ppnt->p_filesz);
|
||||
app_tpnt = _dl_add_elf_hash_table(_dl_progname, (char *)app_tpnt->loadaddr,
|
||||
app_tpnt->dynamic_info, ppnt->p_vaddr + app_tpnt->loadaddr, ppnt->p_filesz);
|
||||
_dl_loaded_modules->libtype = elf_executable;
|
||||
_dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
|
||||
_dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
|
||||
@@ -374,7 +368,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
if (ppnt->p_type == PT_INTERP) {
|
||||
char *ptmp;
|
||||
|
||||
tpnt->libname = (char *) DL_RELOC_ADDR (ppnt->p_vaddr, app_tpnt->loadaddr);
|
||||
tpnt->libname = (char *) ppnt->p_vaddr + app_tpnt->loadaddr;
|
||||
|
||||
/* Store the path where the shared lib loader was found
|
||||
* for later use
|
||||
@@ -384,8 +378,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
if (ptmp != _dl_ldsopath)
|
||||
*ptmp = '\0';
|
||||
|
||||
_dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE (tpnt->loadaddr),
|
||||
tpnt->libname);
|
||||
_dl_debug_early("Lib Loader: (%x) %s\n", tpnt->loadaddr, tpnt->libname);
|
||||
}
|
||||
}
|
||||
app_tpnt->relro_addr = relro_addr;
|
||||
@@ -457,7 +450,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
*/
|
||||
debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
|
||||
debug_addr->r_version = 1;
|
||||
debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE (load_addr);
|
||||
debug_addr->r_ldbase = load_addr;
|
||||
debug_addr->r_brk = (unsigned long) &_dl_debug_state;
|
||||
_dl_debug_addr = debug_addr;
|
||||
|
||||
@@ -504,7 +497,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
} else {
|
||||
tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
|
||||
|
||||
_dl_debug_early("Loading: (%x) %s\n", (unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr), tpnt1->libname);
|
||||
_dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
|
||||
|
||||
#ifdef __LDSO_LDD_SUPPORT__
|
||||
if (trace_loaded_objects &&
|
||||
@@ -516,7 +509,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
*/
|
||||
if (_dl_strcmp(_dl_progname, str) != 0)
|
||||
_dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
|
||||
(unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr));
|
||||
tpnt1->loadaddr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -595,14 +588,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
} else {
|
||||
tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
|
||||
|
||||
_dl_debug_early("Loading: (%x) %s\n", (unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr), tpnt1->libname);
|
||||
_dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
|
||||
|
||||
#ifdef __LDSO_LDD_SUPPORT__
|
||||
if (trace_loaded_objects &&
|
||||
tpnt1->usage_count == 1) {
|
||||
_dl_dprintf(1, "\t%s => %s (%x)\n",
|
||||
cp2, tpnt1->libname,
|
||||
(unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr));
|
||||
(unsigned)tpnt1->loadaddr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -654,14 +647,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
|
||||
tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
|
||||
|
||||
_dl_debug_early("Loading: (%x) %s\n", (unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr), tpnt1->libname);
|
||||
_dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
|
||||
|
||||
#ifdef __LDSO_LDD_SUPPORT__
|
||||
if (trace_loaded_objects &&
|
||||
tpnt1->usage_count == 1) {
|
||||
_dl_dprintf(1, "\t%s => %s (%x)\n",
|
||||
lpntstr, tpnt1->libname,
|
||||
(unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr));
|
||||
(unsigned)tpnt1->loadaddr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -722,10 +715,10 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
*/
|
||||
if (tpnt) {
|
||||
ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
|
||||
ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR (epnt->e_phoff, load_addr);
|
||||
ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
|
||||
int j;
|
||||
|
||||
tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
|
||||
tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr,
|
||||
tpnt->dynamic_info,
|
||||
(unsigned long)tpnt->dynamic_addr,
|
||||
0);
|
||||
@@ -772,7 +765,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
if (trace_loaded_objects) {
|
||||
_dl_dprintf(1, "\t%s => %s (%x)\n",
|
||||
rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
|
||||
rpnt->dyn->libname, (unsigned) DL_LOADADDR_BASE (rpnt->dyn->loadaddr));
|
||||
rpnt->dyn->libname, rpnt->dyn->loadaddr);
|
||||
_dl_exit(0);
|
||||
}
|
||||
#endif
|
||||
@@ -824,10 +817,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
|
||||
for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
|
||||
if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
|
||||
void *base = DL_RELOC_ADDR (myppnt->p_vaddr & PAGE_ALIGN, tpnt->loadaddr);
|
||||
_dl_mprotect(base,
|
||||
(myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz,
|
||||
LXFLAGS(myppnt->p_flags));
|
||||
_dl_mprotect((void *) (tpnt->loadaddr + (myppnt->p_vaddr & PAGE_ALIGN)),
|
||||
(myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -855,7 +846,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
|
||||
if (tpnt->dynamic_info[DT_INIT]) {
|
||||
void (*dl_elf_func) (void);
|
||||
|
||||
dl_elf_func = (void (*)(void)) DL_RELOC_ADDR (tpnt->dynamic_info[DT_INIT], tpnt->loadaddr);
|
||||
dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
|
||||
|
||||
_dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
|
||||
|
||||
|
@@ -175,7 +175,8 @@ void *dlopen(const char *libname, int flag)
|
||||
tfrom = NULL;
|
||||
for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
|
||||
tpnt = dpnt->dyn;
|
||||
if (DL_ADDR_IN_LOADADDR (from, tpnt, tfrom))
|
||||
if (tpnt->loadaddr < from
|
||||
&& (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
|
||||
tfrom = tpnt;
|
||||
}
|
||||
}
|
||||
@@ -377,7 +378,7 @@ void *dlopen(const char *libname, int flag)
|
||||
|
||||
if (tpnt->dynamic_info[DT_INIT]) {
|
||||
void (*dl_elf_func) (void);
|
||||
dl_elf_func = (void (*)(void)) DL_RELOC_ADDR (tpnt->dynamic_info[DT_INIT], tpnt->loadaddr);
|
||||
dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
|
||||
if (dl_elf_func && *dl_elf_func != NULL) {
|
||||
_dl_if_debug_print("running ctors for library %s at '%p'\n",
|
||||
tpnt->libname, dl_elf_func);
|
||||
@@ -435,7 +436,8 @@ void *dlsym(void *vhandle, const char *name)
|
||||
tfrom = NULL;
|
||||
for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next) {
|
||||
tpnt = rpnt->dyn;
|
||||
if (DL_ADDR_IN_LOADADDR (from, tpnt, tfrom)) {
|
||||
if (tpnt->loadaddr < from
|
||||
&& (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) {
|
||||
tfrom = tpnt;
|
||||
handle = rpnt->next;
|
||||
}
|
||||
@@ -510,7 +512,7 @@ static int do_dlclose(void *vhandle, int need_fini)
|
||||
#endif
|
||||
|
||||
if (tpnt->dynamic_info[DT_FINI]) {
|
||||
dl_elf_fini = (int (*)(void)) DL_RELOC_ADDR (tpnt->dynamic_info[DT_FINI], tpnt->loadaddr);
|
||||
dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
|
||||
_dl_if_debug_print("running dtors for library %s at '%p'\n",
|
||||
tpnt->libname, dl_elf_fini);
|
||||
(*dl_elf_fini) ();
|
||||
@@ -620,7 +622,7 @@ int dlinfo(void)
|
||||
/* First start with a complete list of all of the loaded files. */
|
||||
for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
|
||||
fprintf(stderr, "\t%p %p %p %s %d %s\n",
|
||||
DL_LOADADDR_BASE (tpnt->loadaddr), tpnt, tpnt->symbol_scope,
|
||||
tpnt->loadaddr, tpnt, tpnt->symbol_scope,
|
||||
type[tpnt->libtype],
|
||||
tpnt->usage_count, tpnt->libname);
|
||||
}
|
||||
@@ -660,10 +662,12 @@ int dladdr(const void *__address, Dl_info * __info)
|
||||
tpnt = rpnt;
|
||||
#if 0
|
||||
fprintf(stderr, "Module \"%s\" at %p\n",
|
||||
tpnt->libname, DL_LOADADDR_BASE (tpnt->loadaddr));
|
||||
tpnt->libname, tpnt->loadaddr);
|
||||
#endif
|
||||
if (DL_ADDR_IN_LOADADDR ((ElfW(Addr)) __address, tpnt, pelf))
|
||||
if (tpnt->loadaddr < (ElfW(Addr)) __address
|
||||
&& (pelf == NULL || pelf->loadaddr < tpnt->loadaddr)) {
|
||||
pelf = tpnt;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pelf) {
|
||||
@@ -689,7 +693,7 @@ int dladdr(const void *__address, Dl_info * __info)
|
||||
for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) {
|
||||
ElfW(Addr) symbol_addr;
|
||||
|
||||
symbol_addr = (ElfW(Addr)) DL_RELOC_ADDR (symtab[si].st_value, pelf->loadaddr);
|
||||
symbol_addr = pelf->loadaddr + symtab[si].st_value;
|
||||
if (symbol_addr <= (ElfW(Addr))__address && (!sf || sa < symbol_addr)) {
|
||||
sa = symbol_addr;
|
||||
sn = si;
|
||||
@@ -704,7 +708,7 @@ int dladdr(const void *__address, Dl_info * __info)
|
||||
|
||||
if (sf) {
|
||||
__info->dli_fname = pelf->libname;
|
||||
__info->dli_fbase = DL_LOADADDR_BASE (pelf->loadaddr);
|
||||
__info->dli_fbase = (void *)pelf->loadaddr;
|
||||
__info->dli_sname = strtab + symtab[sn].st_name;
|
||||
__info->dli_saddr = (void *)sa;
|
||||
}
|
||||
|
Reference in New Issue
Block a user