summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-08-17 13:37:54 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-08-17 13:37:54 +0000
commit6d6f3a5c26adcf6b105edfb4b53e97ceee81944c (patch)
treefdf250e80080d49b1e421f7157661033821c5fb7 /ldso
parentd965f80088fafaacfd33d0b0770724f4fbcbe6e5 (diff)
Let ldso decide if it should relocate itselft a second time. This
is needed if ldso should use libcs malloc whenever possible. Fix RTLD_LAZY propagation to RTLD_NOW relocation when requested by libdl.
Diffstat (limited to 'ldso')
-rw-r--r--ldso/include/dl-hash.h2
-rw-r--r--ldso/ldso/arm/elfinterp.c5
-rw-r--r--ldso/ldso/cris/elfinterp.c12
-rw-r--r--ldso/ldso/dl-elf.c27
-rw-r--r--ldso/ldso/frv/elfinterp.c14
-rw-r--r--ldso/ldso/i386/elfinterp.c5
-rw-r--r--ldso/ldso/ldso.c65
-rw-r--r--ldso/ldso/m68k/elfinterp.c17
-rw-r--r--ldso/ldso/mips/elfinterp.c9
-rw-r--r--ldso/ldso/powerpc/elfinterp.c9
-rw-r--r--ldso/ldso/sh/elfinterp.c9
-rw-r--r--ldso/ldso/sh64/elfinterp.c9
-rw-r--r--ldso/ldso/sparc/elfinterp.c19
-rw-r--r--ldso/libdl/Makefile2
-rw-r--r--ldso/libdl/libdl.c9
15 files changed, 46 insertions, 167 deletions
diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h
index 767c2ac46..a224012c4 100644
--- a/ldso/include/dl-hash.h
+++ b/ldso/include/dl-hash.h
@@ -6,7 +6,6 @@
#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;
@@ -26,6 +25,7 @@ struct elf_resolve{
struct dyn_elf * symbol_scope;
unsigned short usage_count;
unsigned short int init_flag;
+ unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */
unsigned int nbucket;
unsigned long * elf_buckets;
/*
diff --git a/ldso/ldso/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c
index 93ae35e8b..ab66eed1a 100644
--- a/ldso/ldso/arm/elfinterp.c
+++ b/ldso/ldso/arm/elfinterp.c
@@ -189,11 +189,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
ELF_RELOC *rpnt;
int symtab_index;
- /* When the dynamic linker bootstrapped itself, it resolved some symbols.
- Make sure we do not do them again */
- if (tpnt->libtype == program_interpreter)
- return 0;
-
/* Now parse the relocation information */
rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr);
rel_size = rel_size / sizeof(ELF_RELOC);
diff --git a/ldso/ldso/cris/elfinterp.c b/ldso/ldso/cris/elfinterp.c
index 2fed69e74..6030a6575 100644
--- a/ldso/ldso/cris/elfinterp.c
+++ b/ldso/ldso/cris/elfinterp.c
@@ -182,18 +182,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, unsigned long rel_add
for (i = 0; i < rel_size; i++, rpnt++) {
symtab_index = ELF32_R_SYM(rpnt->r_info);
-
- /*
- * Make sure the same symbols that the linker resolved when it
- * bootstapped itself isn't resolved again.
- */
- if (!symtab_index && tpnt->libtype == program_interpreter)
- continue;
-
- if (symtab_index && tpnt->libtype == program_interpreter &&
- _dl_symbol(strtab + symtab[symtab_index].st_name))
- continue;
-
#if defined (__SUPPORT_LD_DEBUG__)
debug_sym(symtab, strtab, symtab_index);
debug_reloc(symtab, strtab, rpnt);
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 25c82401f..8af9e78f6 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -730,15 +730,15 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
return tpnt;
}
-
-int _dl_fixup(struct dyn_elf *rpnt, int flag)
+/* now_flag must be RTLD_NOW or zero */
+int _dl_fixup(struct dyn_elf *rpnt, int now_flag)
{
int goof = 0;
struct elf_resolve *tpnt;
unsigned long reloc_size;
if (rpnt->next)
- goof += _dl_fixup(rpnt->next, flag);
+ goof += _dl_fixup(rpnt->next, now_flag);
tpnt = rpnt->dyn;
#if defined (__SUPPORT_LD_DEBUG__)
@@ -756,28 +756,25 @@ int _dl_fixup(struct dyn_elf *rpnt, int flag)
return goof;
}
+ reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE];
/* On some machines, notably SPARC & PPC, DT_REL* includes DT_JMPREL in its
range. Note that according to the ELF spec, this is completely legal! */
#ifdef ELF_MACHINE_PLTREL_OVERLAP
- reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE] -
- tpnt->dynamic_info [DT_PLTRELSZ];
-#else
- reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE];
+ reloc_size -= tpnt->dynamic_info [DT_PLTRELSZ];
#endif
- if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]) {
- if (tpnt->init_flag & RELOCS_DONE)
- return goof;
+ if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR] &&
+ !(tpnt->init_flag & RELOCS_DONE)) {
tpnt->init_flag |= RELOCS_DONE;
goof += _dl_parse_relocation_information(rpnt,
tpnt->dynamic_info[DT_RELOC_TABLE_ADDR],
reloc_size, 0);
}
-
- if (tpnt->dynamic_info[DT_JMPREL]) {
- if (tpnt->init_flag & JMP_RELOCS_DONE)
- return goof;
+ if (tpnt->dynamic_info[DT_JMPREL] &&
+ (!(tpnt->init_flag & JMP_RELOCS_DONE) ||
+ (now_flag && !(tpnt->rtld_flags & now_flag)))) {
+ tpnt->rtld_flags |= now_flag;
tpnt->init_flag |= JMP_RELOCS_DONE;
- if (flag & RTLD_LAZY) {
+ if (!(tpnt->rtld_flags & RTLD_NOW)) {
_dl_parse_lazy_relocation_information(rpnt,
tpnt->dynamic_info[DT_JMPREL],
tpnt->dynamic_info [DT_PLTRELSZ], 0);
diff --git a/ldso/ldso/frv/elfinterp.c b/ldso/ldso/frv/elfinterp.c
index 227ef8cad..7e61763ae 100644
--- a/ldso/ldso/frv/elfinterp.c
+++ b/ldso/ldso/frv/elfinterp.c
@@ -213,15 +213,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
int res;
symtab_index = ELF32_R_SYM(rpnt->r_info);
-
- /* When the dynamic linker bootstrapped itself, it resolved some symbols.
- Make sure we do not do them again */
- if (!symtab_index && tpnt->libtype == program_interpreter)
- continue;
- if (symtab_index && tpnt->libtype == program_interpreter &&
- _dl_symbol(strtab + symtab[symtab_index].st_name))
- continue;
-
#if defined (__SUPPORT_LD_DEBUG__)
debug_sym(symtab,strtab,symtab_index);
debug_reloc(symtab,strtab,rpnt);
@@ -444,11 +435,6 @@ _dl_parse_relocation_information
(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size,
int type __attribute_used__)
{
- /* The interpreter initial self-relocation is complete, and we
- can't re-apply relocations. */
- if (rpnt->dyn->libtype == program_interpreter)
- return 0;
-
return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
}
diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c
index dca5fe54d..4cb9047be 100644
--- a/ldso/ldso/i386/elfinterp.c
+++ b/ldso/ldso/i386/elfinterp.c
@@ -183,11 +183,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
ELF_RELOC *rpnt;
int symtab_index;
- /* When the dynamic linker bootstrapped itself, it resolved some symbols.
- Make sure we do not do them again */
- if (tpnt->libtype == program_interpreter)
- return 0;
-
/* Now parse the relocation information */
rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
rel_size = rel_size / sizeof(ELF_RELOC);
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 4256189e7..62b6c7437 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -91,7 +91,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
{
ElfW(Phdr) *ppnt;
char *lpntstr;
- int i, goof = 0, be_lazy = RTLD_LAZY, trace_loaded_objects = 0;
+ int i, goof = 0, unlazy = 0, trace_loaded_objects = 0;
struct dyn_elf *rpnt;
struct elf_resolve *tcurr;
struct elf_resolve *tpnt1;
@@ -127,26 +127,6 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
* this beast to run. We start with the basic executable, and then
* go from there. Eventually we will run across ourself, and we
* will need to properly deal with that as well. */
- lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
-
- tpnt->chains = hash_addr;
- tpnt->next = 0;
- tpnt->libname = 0;
- tpnt->libtype = program_interpreter;
- tpnt->loadaddr = (ElfW(Addr)) load_addr;
-
-#ifdef ALLOW_ZERO_PLTGOT
- if (tpnt->dynamic_info[DT_PLTGOT])
-#endif
- {
- INIT_GOT(lpnt, tpnt);
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- _dl_dprintf(_dl_debug_file, "GOT found at %x\n", lpnt);
-#endif
- }
-
- /* OK, this was a big step, now we need to scan all of the user images
- and load them properly. */
{
ElfW(Ehdr) *epnt;
ElfW(Phdr) *myppnt;
@@ -165,6 +145,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
brk_addr = 0;
rpnt = NULL;
+ if (_dl_getenv("LD_BIND_NOW", envp))
+ unlazy = RTLD_NOW;
/* At this point we are now free to examine the user application,
and figure out which libraries are supposed to be called. Until
@@ -191,6 +173,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
_dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
rpnt->dyn = _dl_loaded_modules;
+ app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
app_tpnt->usage_count++;
app_tpnt->symbol_scope = _dl_symbol_tables;
lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT] + app_tpnt->loadaddr);
@@ -236,13 +219,9 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
}
}
-
/* Now we need to figure out what kind of options are selected.
Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
{
- if (_dl_getenv("LD_BIND_NOW", envp))
- be_lazy = 0;
-
if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
(auxvt[AT_UID].a_un.a_val != -1 &&
auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val
@@ -383,6 +362,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
_dl_exit(15);
}
} else {
+ tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
#ifdef __SUPPORT_LD_DEBUG_EARLY__
_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
#endif
@@ -468,6 +448,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
_dl_exit(15);
}
} else {
+ tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
#ifdef __SUPPORT_LD_DEBUG_EARLY__
_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
#endif
@@ -525,6 +506,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
_dl_exit(16);
}
} else {
+ tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
#ifdef __SUPPORT_LD_DEBUG_EARLY__
_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
#endif
@@ -545,23 +527,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
/*
* If the program interpreter is not in the module chain, add it. This will
* be required for dlopen to be able to access the internal functions in the
- * dynamic linker.
+ * dynamic linker and to relocate the interpreter again once all libs are loaded.
*/
if (tpnt) {
- tcurr = _dl_loaded_modules;
- if (tcurr)
- while (tcurr->next)
- tcurr = tcurr->next;
- tpnt->next = NULL;
+ tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr, tpnt->dynamic_info,
+ (unsigned long)tpnt->dynamic_addr, tpnt->dynamic_size);
+ tpnt->libtype = program_interpreter;
tpnt->usage_count++;
-
- if (tcurr) {
- tcurr->next = tpnt;
- tpnt->prev = tcurr;
- } else {
- _dl_loaded_modules = tpnt;
- tpnt->prev = NULL;
- }
+ tpnt->symbol_scope = _dl_symbol_tables;
if (rpnt) {
rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
_dl_memset(rpnt->next, 0, sizeof(struct dyn_elf));
@@ -572,6 +545,18 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
}
rpnt->dyn = tpnt;
+ tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
+#ifdef RERELOCATE_LDSO
+ /* Only rerelocate functions for now. */
+ tpnt->init_flag = RELOCS_DONE | COPY_RELOCS_DONE;
+ lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+# ifdef ALLOW_ZERO_PLTGOT
+ if (tpnt->dynamic_info[DT_PLTGOT])
+# endif
+ INIT_GOT(lpnt, tpnt);
+#else
+ tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE | COPY_RELOCS_DONE;
+#endif
tpnt = NULL;
}
@@ -602,7 +587,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
* to the GOT tables. We need to do this in reverse order so that COPY
* directives work correctly */
if (_dl_symbol_tables)
- goof += _dl_fixup(_dl_symbol_tables, be_lazy);
+ goof += _dl_fixup(_dl_symbol_tables, unlazy);
/* OK, at this point things are pretty much ready to run. Now we
diff --git a/ldso/ldso/m68k/elfinterp.c b/ldso/ldso/m68k/elfinterp.c
index a3f529402..5e8249504 100644
--- a/ldso/ldso/m68k/elfinterp.c
+++ b/ldso/ldso/m68k/elfinterp.c
@@ -152,13 +152,6 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
reloc_type = ELF32_R_TYPE (rpnt->r_info);
symtab_index = ELF32_R_SYM (rpnt->r_info);
- /* When the dynamic linker bootstrapped itself, it resolved some symbols.
- Make sure we do not do them again. */
- if (tpnt->libtype == program_interpreter
- && (!symtab_index
- || _dl_symbol (strtab + symtab[symtab_index].st_name)))
- continue;
-
switch (reloc_type)
{
case R_68K_NONE:
@@ -207,12 +200,6 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
reloc_type = ELF32_R_TYPE (rpnt->r_info);
symtab_index = ELF32_R_SYM (rpnt->r_info);
symbol_addr = 0;
-
- if (tpnt->libtype == program_interpreter
- && (!symtab_index
- || _dl_symbol (strtab + symtab[symtab_index].st_name)))
- continue;
-
if (symtab_index)
{
symbol_addr = (unsigned int)
@@ -334,10 +321,6 @@ int _dl_parse_copy_information(struct dyn_elf *xpnt,
continue;
symtab_index = ELF32_R_SYM (rpnt->r_info);
symbol_addr = 0;
- if (tpnt->libtype == program_interpreter
- && (!symtab_index
- || _dl_symbol (strtab + symtab[symtab_index].st_name)))
- continue;
if (symtab_index)
{
symbol_addr = (unsigned int)
diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c
index dfbc88fdc..5457e6d7a 100644
--- a/ldso/ldso/mips/elfinterp.c
+++ b/ldso/ldso/mips/elfinterp.c
@@ -186,10 +186,6 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
#if defined (__SUPPORT_LD_DEBUG__)
unsigned long old_val=0;
#endif
-
- if (tpnt->libtype == program_interpreter)
- return 0;
-
/* Now parse the relocation information */
rel_size = rel_size / sizeof(Elf32_Rel);
rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
@@ -264,11 +260,6 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
unsigned long *got_entry;
for (; tpnt ; tpnt = tpnt->next) {
-
- /* We don't touch the dynamic linker */
- if (tpnt->libtype == program_interpreter)
- continue;
-
/* Setup the loop variables */
got_entry = (unsigned long *) (tpnt->loadaddr +
tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;
diff --git a/ldso/ldso/powerpc/elfinterp.c b/ldso/ldso/powerpc/elfinterp.c
index 0cecf7dc8..103a0fb56 100644
--- a/ldso/ldso/powerpc/elfinterp.c
+++ b/ldso/ldso/powerpc/elfinterp.c
@@ -396,10 +396,6 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
(void) type;
num_plt_entries = rel_size / sizeof(ELF_RELOC);
- /* When the dynamic linker bootstrapped itself, it resolved some symbols.
- Make sure we do not do them again */
- if (tpnt->libtype == program_interpreter)
- return;
rel_offset_words = PLT_DATA_START_WORDS(num_plt_entries);
plt = (Elf32_Word *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
@@ -443,11 +439,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
ELF_RELOC *rpnt;
int symtab_index;
- /* When the dynamic linker bootstrapped itself, it resolved some symbols.
- Make sure we do not do them again */
- if (tpnt->libtype == program_interpreter)
- return 0;
-
/* Now parse the relocation information */
rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
rel_size = rel_size / sizeof(ELF_RELOC);
diff --git a/ldso/ldso/sh/elfinterp.c b/ldso/ldso/sh/elfinterp.c
index fe920bb9a..3899b70b4 100644
--- a/ldso/ldso/sh/elfinterp.c
+++ b/ldso/ldso/sh/elfinterp.c
@@ -199,15 +199,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
int res;
symtab_index = ELF32_R_SYM(rpnt->r_info);
-
- /* When the dynamic linker bootstrapped itself, it resolved some symbols.
- Make sure we do not do them again */
- if (!symtab_index && tpnt->libtype == program_interpreter)
- continue;
- if (symtab_index && tpnt->libtype == program_interpreter &&
- _dl_symbol(strtab + symtab[symtab_index].st_name))
- continue;
-
#if defined (__SUPPORT_LD_DEBUG__)
debug_sym(symtab,strtab,symtab_index);
debug_reloc(symtab,strtab,rpnt);
diff --git a/ldso/ldso/sh64/elfinterp.c b/ldso/ldso/sh64/elfinterp.c
index 3a2b4172c..886349dd2 100644
--- a/ldso/ldso/sh64/elfinterp.c
+++ b/ldso/ldso/sh64/elfinterp.c
@@ -244,15 +244,6 @@ static int _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
int res;
symtab_index = ELF32_R_SYM(rpnt->r_info);
-
- /* When the dynamic linker bootstrapped itself, it resolved
- some symbols. Make sure we do not do them again */
- if (!symtab_index && tpnt->libtype == program_interpreter)
- continue;
- if (symtab_index && tpnt->libtype == program_interpreter &&
- _dl_symbol(strtab + symtab[symtab_index].st_name))
- continue;
-
#ifdef __SUPPORT_LD_DEBUG__
debug_sym(symtab,strtab,symtab_index);
debug_reloc(symtab,strtab,rpnt);
diff --git a/ldso/ldso/sparc/elfinterp.c b/ldso/ldso/sparc/elfinterp.c
index 98435cbd4..44d889ff2 100644
--- a/ldso/ldso/sparc/elfinterp.c
+++ b/ldso/ldso/sparc/elfinterp.c
@@ -169,13 +169,6 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
reloc_type = ELF32_R_TYPE(rpnt->r_info);
symtab_index = ELF32_R_SYM(rpnt->r_info);
- /* When the dynamic linker bootstrapped itself, it resolved some symbols.
- Make sure we do not do them again */
- if(!symtab_index && tpnt->libtype == program_interpreter) continue;
- if(symtab_index && tpnt->libtype == program_interpreter &&
- _dl_symbol(strtab + symtab[symtab_index].st_name))
- continue;
-
switch(reloc_type){
case R_SPARC_NONE:
break;
@@ -219,14 +212,8 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
symtab_index = ELF32_R_SYM(rpnt->r_info);
symbol_addr = 0;
- if(!symtab_index && tpnt->libtype == program_interpreter) continue;
-
if(symtab_index) {
- if(tpnt->libtype == program_interpreter &&
- _dl_symbol(strtab + symtab[symtab_index].st_name))
- continue;
-
symbol_addr = (unsigned int)
_dl_find_hash(strtab + symtab[symtab_index].st_name,
tpnt->symbol_scope, elf_machine_type_class(reloc_type));
@@ -337,13 +324,7 @@ int _dl_parse_copy_information(struct dyn_elf *xpnt,
if(reloc_type != R_SPARC_COPY) continue;
symtab_index = ELF32_R_SYM(rpnt->r_info);
symbol_addr = 0;
- if(!symtab_index && tpnt->libtype == program_interpreter) continue;
if(symtab_index) {
-
- if(tpnt->libtype == program_interpreter &&
- _dl_symbol(strtab + symtab[symtab_index].st_name))
- continue;
-
symbol_addr = (unsigned int)
_dl_find_hash(strtab + symtab[symtab_index].st_name,
xpnt->next, ELF_RTYPE_CLASS_COPY);
diff --git a/ldso/libdl/Makefile b/ldso/libdl/Makefile
index f10510f51..471b8b554 100644
--- a/ldso/libdl/Makefile
+++ b/ldso/libdl/Makefile
@@ -71,7 +71,7 @@ libdl_pic.o: libdl.c
$(OBJ): Makefile
-shared:
+shared: $(TOPDIR)lib/$(LIBDL_SHARED_FULLNAME)
$(LD) $(LDFLAGS) -soname=$(LIBDL_SHARED).$(MAJOR_VERSION) \
-o $(LIBDL_SHARED_FULLNAME) -fini dl_cleanup --whole-archive $(LIBDL_PIC) \
--no-whole-archive $(TOPDIR)/libc/misc/internals/interp.o \
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index fd72509d0..d1274e3ff 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -134,6 +134,7 @@ void *dlopen(const char *libname, int flag)
ElfW(Addr) from;
struct elf_resolve *tpnt1;
void (*dl_brk) (void);
+ int now_flag;
/* A bit of sanity checking... */
if (!(flag & (RTLD_LAZY|RTLD_NOW))) {
@@ -188,7 +189,7 @@ void *dlopen(const char *libname, int flag)
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;
+ tpnt->rtld_flags |= RTLD_GLOBAL;
dyn_chain->next_handle = _dl_handles;
_dl_handles = dyn_ptr = dyn_chain;
@@ -219,6 +220,7 @@ void *dlopen(const char *libname, int flag)
_dl_memset (dyn_ptr->next, 0, sizeof (struct dyn_elf));
dyn_ptr = dyn_ptr->next;
dyn_ptr->dyn = tpnt1;
+ tpnt->rtld_flags |= RTLD_GLOBAL;
if (!tpnt1) {
tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, 0);
if (!tpnt1)
@@ -254,7 +256,10 @@ void *dlopen(const char *libname, int flag)
* 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))
+ now_flag = (flag & RTLD_NOW) ? RTLD_NOW : 0;
+ if (getenv("LD_BIND_NOW"))
+ now_flag = RTLD_NOW;
+ if (_dl_fixup(dyn_chain, now_flag))
goto oops;
/* TODO: Should we set the protections of all pages back to R/O now ? */