summaryrefslogtreecommitdiff
path: root/ldso/ldso
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-11-10 15:27:26 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-11-10 15:27:26 +0000
commit0038f6a2297be2b66a0177bc74b468dddb0a89fa (patch)
tree2413de564ae1751210c6fd82924636d2b09cebda /ldso/ldso
parent0657ab0d0b7d9a879091653b2e23f0b46c3ecefa (diff)
Add RTLD_LOCAL support for dlopened libs. Reported by
Andrew de Quincey, who has been most helpful getting this sorted out, thanks. Thanks also to Peter Mazinger who did alot of testing. Removed all traces of dl_parse_copy_information() since it is no longer used.
Diffstat (limited to 'ldso/ldso')
-rw-r--r--ldso/ldso/arm/elfinterp.c59
-rw-r--r--ldso/ldso/cris/elfinterp.c4
-rw-r--r--ldso/ldso/dl-hash.c23
-rw-r--r--ldso/ldso/i386/elfinterp.c64
-rw-r--r--ldso/ldso/ldso.c8
-rw-r--r--ldso/ldso/m68k/elfinterp.c64
-rw-r--r--ldso/ldso/mips/elfinterp.c16
-rw-r--r--ldso/ldso/powerpc/elfinterp.c4
-rw-r--r--ldso/ldso/sh/elfinterp.c12
-rw-r--r--ldso/ldso/sh64/elfinterp.c64
-rw-r--r--ldso/ldso/sparc/elfinterp.c62
11 files changed, 40 insertions, 340 deletions
diff --git a/ldso/ldso/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c
index 9e0a6d702..eef82679c 100644
--- a/ldso/ldso/arm/elfinterp.c
+++ b/ldso/ldso/arm/elfinterp.c
@@ -149,8 +149,8 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
got_addr = (char **) instr_addr;
/* Get the address of the GOT entry */
- new_addr = _dl_find_hash(symname,
- tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope,
+ tpnt, ELF_RTYPE_CLASS_PLT);
if (unlikely(!new_addr)) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
_dl_progname, symname);
@@ -278,7 +278,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
if (symtab_index) {
symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name,
- scope, elf_machine_type_class(reloc_type));
+ scope, tpnt, elf_machine_type_class(reloc_type));
/*
* We want to allow undefined references to weak symbols - this might
@@ -391,53 +391,6 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
}
-/* This is done as a separate step, because there are cases where
- information is first copied and later initialized. This results in
- the wrong information being copied. Someone at Sun was complaining about
- a bug in the handling of _COPY by SVr4, and this may in fact be what he
- was talking about. Sigh. */
-
-/* No, there are cases where the SVr4 linker fails to emit COPY relocs
- at all */
-static int
-_dl_do_copy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
- ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
-{
- int reloc_type;
- int symtab_index;
- unsigned long *reloc_addr;
- unsigned long symbol_addr;
- int goof = 0;
- return 0; /* disable now, remove later */
- reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- if (reloc_type != R_ARM_COPY)
- return 0;
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
-
- if (symtab_index) {
-
- symbol_addr = (unsigned long) _dl_find_hash(strtab +
- symtab[symtab_index].st_name, scope,
- ELF_RTYPE_CLASS_COPY);
- if (!symbol_addr) goof++;
- }
- if (!goof) {
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug_move)
- _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
- strtab + symtab[symtab_index].st_name,
- symtab[symtab_index].st_size,
- symbol_addr, symtab[symtab_index].st_value);
-#endif
- _dl_memcpy((char *) symtab[symtab_index].st_value,
- (char *) symbol_addr, symtab[symtab_index].st_size);
- }
-
- return goof;
-}
-
void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
unsigned long rel_addr, unsigned long rel_size)
{
@@ -450,9 +403,3 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
}
-int _dl_parse_copy_information(struct dyn_elf *rpnt,
- unsigned long rel_addr, unsigned long rel_size)
-{
- return _dl_parse(rpnt->dyn, rpnt->next, rel_addr, rel_size, _dl_do_copy_reloc);
-}
-
diff --git a/ldso/ldso/cris/elfinterp.c b/ldso/ldso/cris/elfinterp.c
index 37955cc6f..675fb0117 100644
--- a/ldso/ldso/cris/elfinterp.c
+++ b/ldso/ldso/cris/elfinterp.c
@@ -144,7 +144,7 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
got_addr = (char **)instr_addr;
/* Get the address of the GOT entry. */
- new_addr = _dl_find_hash(symname, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
if (unlikely(!new_addr)) {
_dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname);
_dl_exit(1);
@@ -253,7 +253,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_LOCAL) {
symbol_addr = (unsigned long)tpnt->loadaddr;
} else {
- symbol_addr = (unsigned long)_dl_find_hash(symname, scope,
+ symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
elf_machine_type_class(reloc_type));
}
diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c
index a119e77f9..4719315ee 100644
--- a/ldso/ldso/dl-hash.c
+++ b/ldso/ldso/dl-hash.c
@@ -137,7 +137,7 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
* 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 *rpnt, int type_class)
+char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *mytpnt, int type_class)
{
struct elf_resolve *tpnt;
int si;
@@ -148,17 +148,24 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, int type_class)
char *weak_result = NULL;
elf_hash_number = _dl_elf_hash(name);
-
- /*
- NOTE! RTLD_LOCAL handling for dlopen not implemented yet.
- Everything is treated as RTLD_GLOBAL.
- */
for (; rpnt; rpnt = rpnt->next) {
tpnt = rpnt->dyn;
- if (!(tpnt->rtld_flags & RTLD_GLOBAL))
- continue;
+ if (!(tpnt->rtld_flags & RTLD_GLOBAL) && mytpnt) {
+ if (mytpnt == tpnt)
+ ;
+ else {
+ struct init_fini_list *tmp;
+
+ for (tmp = mytpnt->rtld_local; tmp; tmp = tmp->next) {
+ if (tmp->tpnt == tpnt)
+ break;
+ }
+ if (!tmp)
+ continue;
+ }
+ }
/* Don't search the executable when resolving a copy reloc. */
if ((type_class & ELF_RTYPE_CLASS_COPY) && tpnt->libtype == elf_executable)
continue;
diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c
index 12e67f5d2..cb5a24a9e 100644
--- a/ldso/ldso/i386/elfinterp.c
+++ b/ldso/ldso/i386/elfinterp.c
@@ -147,7 +147,7 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
got_addr = (char **)instr_addr;
/* Get the address of the GOT entry. */
- new_addr = _dl_find_hash(symname, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
if (unlikely(!new_addr)) {
_dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname);
_dl_exit(1);
@@ -253,7 +253,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
symname = strtab + symtab[symtab_index].st_name;
if (symtab_index) {
- symbol_addr = (unsigned long)_dl_find_hash(symname, scope,
+ symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
elf_machine_type_class(reloc_type));
/*
@@ -355,56 +355,6 @@ _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
return 0;
}
-/* This is done as a separate step, because there are cases where
- information is first copied and later initialized. This results in
- the wrong information being copied. Someone at Sun was complaining about
- a bug in the handling of _COPY by SVr4, and this may in fact be what he
- was talking about. Sigh. */
-
-/* No, there are cases where the SVr4 linker fails to emit COPY relocs
- at all */
-static int
-_dl_do_copy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
-{
- int reloc_type;
- int symtab_index;
- unsigned long *reloc_addr;
- unsigned long symbol_addr;
- int goof = 0;
- char *symname;
-
- reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- if (reloc_type != R_386_COPY)
- return 0;
-
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
- symname = strtab + symtab[symtab_index].st_name;
-
- if (symtab_index) {
- symbol_addr = (unsigned long)_dl_find_hash(symname, scope, ELF_RTYPE_CLASS_COPY);
- if (!symbol_addr)
- goof++;
- }
-
- if (!goof) {
-#if defined (__SUPPORT_LD_DEBUG__)
- if (_dl_debug_move)
- _dl_dprintf(_dl_debug_file,
- "\n%s move %x bytes from %x to %x",
- symname, symtab[symtab_index].st_size,
- symbol_addr, symtab[symtab_index].st_value);
-#endif
-
- _dl_memcpy((char *)symtab[symtab_index].st_value,
- (char *)symbol_addr, symtab[symtab_index].st_size);
- }
-
- return goof;
-}
-
void
_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
unsigned long rel_addr,
@@ -420,13 +370,3 @@ _dl_parse_relocation_information(struct dyn_elf *rpnt,
{
return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
}
-
-int
-_dl_parse_copy_information(struct dyn_elf *rpnt,
- unsigned long rel_addr,
- unsigned long rel_size)
-{
- return 0;
- /* just disable for now, remove when we know that it works */
- /* return _dl_parse(rpnt->dyn, rpnt->next, rel_addr, rel_size, _dl_do_copy_reloc); */
-}
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index d231969f8..476dae629 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -774,7 +774,7 @@ next_lib2:
* ld.so.1, so we have to look up each symbol individually.
*/
- _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", _dl_symbol_tables, 0);
+ _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", _dl_symbol_tables, NULL, 0);
if (_dl_envp)
*_dl_envp = (unsigned long) envp;
@@ -798,10 +798,10 @@ next_lib2:
}
#endif
- _dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", _dl_symbol_tables, ELF_RTYPE_CLASS_PLT);
+ _dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
#if defined (__SUPPORT_LD_DEBUG__)
_dl_on_exit = (int (*)(void (*)(int, void *),void*))
- (intptr_t) _dl_find_hash("on_exit", _dl_symbol_tables, ELF_RTYPE_CLASS_PLT);
+ (intptr_t) _dl_find_hash("on_exit", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
#endif
/* Notify the debugger we have added some objects. */
@@ -853,7 +853,7 @@ next_lib2:
_dl_debug_state();
/* Find the real malloc function and make ldso functions use that from now on */
- _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash("malloc", _dl_symbol_tables, ELF_RTYPE_CLASS_PLT);
+ _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash("malloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
}
char *_dl_getenv(const char *symbol, char **envp)
diff --git a/ldso/ldso/m68k/elfinterp.c b/ldso/ldso/m68k/elfinterp.c
index dc5713422..3b2f13b48 100644
--- a/ldso/ldso/m68k/elfinterp.c
+++ b/ldso/ldso/m68k/elfinterp.c
@@ -98,7 +98,7 @@ unsigned int _dl_linux_resolver (int dummy1, int dummy2,
/* Get the address of the GOT entry. */
new_addr = _dl_find_hash (strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
if (unlikely(!new_addr))
{
_dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
@@ -204,7 +204,7 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
{
symbol_addr = (unsigned int)
_dl_find_hash (strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope,
+ tpnt->symbol_scope, tpnt,
elf_machine_type_class(reloc_type));
/* We want to allow undefined references to weak symbols -
@@ -272,63 +272,3 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
}
return goof;
}
-
-/* This is done as a separate step, because there are cases where
- information is first copied and later initialized. This results in
- the wrong information being copied. Someone at Sun was complaining about
- a bug in the handling of _COPY by SVr4, and this may in fact be what he
- was talking about. Sigh. */
-
-/* No, there are cases where the SVr4 linker fails to emit COPY relocs
- at all. */
-
-int _dl_parse_copy_information(struct dyn_elf *xpnt,
- unsigned long rel_addr, unsigned long rel_size)
-{
- int i;
- char *strtab;
- int reloc_type;
- int goof = 0;
- Elf32_Sym *symtab;
- Elf32_Rela *rpnt;
- unsigned int *reloc_addr;
- unsigned int symbol_addr;
- struct elf_resolve *tpnt;
- int symtab_index;
- /* Now parse the relocation information */
- return 0; /* disable now, remove later */
- tpnt = xpnt->dyn;
-
- rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
- rel_size = rel_size / sizeof (Elf32_Rela);
-
- symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
- + tpnt->loadaddr);
- strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
-
- for (i = 0; i < rel_size; i++, rpnt++)
- {
- reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
- reloc_type = ELF32_R_TYPE (rpnt->r_info);
- if (reloc_type != R_68K_COPY)
- continue;
- symtab_index = ELF32_R_SYM (rpnt->r_info);
- symbol_addr = 0;
- if (symtab_index)
- {
- symbol_addr = (unsigned int)
- _dl_find_hash (strtab + symtab[symtab_index].st_name,
- xpnt->next, ELF_RTYPE_CLASS_COPY);
- if (!symbol_addr)
- {
- _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
- _dl_progname, strtab + symtab[symtab_index].st_name);
- goof++;
- }
- }
- if (!goof)
- _dl_memcpy ((void *) symtab[symtab_index].st_value, (void *) symbol_addr,
- symtab[symtab_index].st_size);
- }
- return goof;
-}
diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c
index 74521823e..79a681d35 100644
--- a/ldso/ldso/mips/elfinterp.c
+++ b/ldso/ldso/mips/elfinterp.c
@@ -129,7 +129,7 @@ unsigned long _dl_linux_resolver(unsigned long sym_index,
symname = strtab + sym->st_name;
new_addr = (unsigned long) _dl_find_hash(symname,
- tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
if (unlikely(!new_addr)) {
_dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
_dl_progname, symname);
@@ -164,14 +164,6 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
return;
}
-int _dl_parse_copy_information(struct dyn_elf *rpnt,
- unsigned long rel_addr, unsigned long rel_size)
-{
- /* Nothing to do */
- return 0;
-}
-
-
int _dl_parse_relocation_information(struct dyn_elf *xpnt,
unsigned long rel_addr, unsigned long rel_size)
{
@@ -290,12 +282,12 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
}
else {
*got_entry = (unsigned long) _dl_find_hash(strtab +
- sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
}
}
else if (sym->st_shndx == SHN_COMMON) {
*got_entry = (unsigned long) _dl_find_hash(strtab +
- sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
}
else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
*got_entry != sym->st_value) {
@@ -307,7 +299,7 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
}
else {
*got_entry = (unsigned long) _dl_find_hash(strtab +
- sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
}
got_entry++;
diff --git a/ldso/ldso/powerpc/elfinterp.c b/ldso/ldso/powerpc/elfinterp.c
index d154a18a4..8175a0178 100644
--- a/ldso/ldso/powerpc/elfinterp.c
+++ b/ldso/ldso/powerpc/elfinterp.c
@@ -210,7 +210,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
/* Get the address of the GOT entry */
finaladdr = (Elf32_Addr) _dl_find_hash(symname,
- tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
if (unlikely(!finaladdr)) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
_dl_exit(1);
@@ -269,7 +269,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
symtab_index = ELF32_R_SYM(rpnt->r_info);
symname = strtab + symtab[symtab_index].st_name;
if (symtab_index) {
- symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
+ symbol_addr = (unsigned long) _dl_find_hash(symname, scope, tpnt,
elf_machine_type_class(reloc_type));
/* We want to allow undefined references to weak symbols - this might
* have been intentional. We should not be linking local symbols
diff --git a/ldso/ldso/sh/elfinterp.c b/ldso/ldso/sh/elfinterp.c
index 821b44cbc..18551841c 100644
--- a/ldso/ldso/sh/elfinterp.c
+++ b/ldso/ldso/sh/elfinterp.c
@@ -149,7 +149,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
/* Get the address of the GOT entry */
- new_addr = _dl_find_hash(symname, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
if (unlikely(!new_addr)) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
_dl_exit(1);
@@ -253,9 +253,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
symname = strtab + symtab[symtab_index].st_name;
if (symtab_index) {
-
-
- symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
+ symbol_addr = (unsigned long) _dl_find_hash(symname, scope, tpnt,
elf_machine_type_class(reloc_type));
/*
@@ -360,9 +358,3 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
}
-int _dl_parse_copy_information(struct dyn_elf __attribute__((unused))*rpnt,
- unsigned long __attribute__((unused))rel_addr, unsigned long __attribute__((unused))rel_size)
-{
- return 0;
-}
-
diff --git a/ldso/ldso/sh64/elfinterp.c b/ldso/ldso/sh64/elfinterp.c
index 3152881b3..82d66552a 100644
--- a/ldso/ldso/sh64/elfinterp.c
+++ b/ldso/ldso/sh64/elfinterp.c
@@ -190,7 +190,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
/* Get the address of the GOT entry */
- new_addr = _dl_find_hash(symname, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
if (unlikely(!new_addr)) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
_dl_progname, symname);
@@ -305,7 +305,7 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct dyn_elf *scope,
if (symtab_index) {
int stb;
- symbol_addr = (unsigned long)_dl_find_hash(symname, scope,
+ symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
elf_machine_type_class(reloc_type));
/*
@@ -445,59 +445,6 @@ static int _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
return 0;
}
-/* This is done as a separate step, because there are cases where
- information is first copied and later initialized. This results in
- the wrong information being copied. Someone at Sun was complaining about
- a bug in the handling of _COPY by SVr4, and this may in fact be what he
- was talking about. Sigh. */
-
-/* No, there are cases where the SVr4 linker fails to emit COPY relocs
- at all */
-static int _dl_do_copy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
-{
- int reloc_type;
- int symtab_index;
- unsigned long *reloc_addr;
- unsigned long symbol_addr;
- char *symname;
- int goof = 0;
- return 0; /* disable now, remove later */
- reloc_addr = (unsigned long *)(intptr_t)
- (tpnt->loadaddr + (unsigned long)rpnt->r_offset);
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
-
- if (reloc_type != R_SH_COPY)
- return 0;
-
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
- symname = strtab + symtab[symtab_index].st_name;
-
- if (symtab_index) {
- symbol_addr = (unsigned long)
- _dl_find_hash(symname, scope, ELF_RTYPE_CLASS_COPY);
-
- if (!symbol_addr)
- goof++;
- }
-
- if (!goof) {
-#ifdef __SUPPORT_LD_DEBUG__
- if (_dl_debug_move)
- _dl_dprintf(_dl_debug_file,
- "\n%s move %x bytes from %x to %x",
- symname, symtab[symtab_index].st_size,
- symbol_addr, symtab[symtab_index].st_value);
-#endif
-
- _dl_memcpy((char *)symtab[symtab_index].st_value,
- (char *)symbol_addr, symtab[symtab_index].st_size);
- }
-
- return goof;
-}
-
void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
unsigned long rel_addr, unsigned long rel_size)
{
@@ -509,10 +456,3 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
{
return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
}
-
-int _dl_parse_copy_information(struct dyn_elf *rpnt,
- unsigned long rel_addr, unsigned long rel_size)
-{
- return _dl_parse(rpnt->dyn, rpnt->next, rel_addr, rel_size, _dl_do_copy_reloc);
-}
-
diff --git a/ldso/ldso/sparc/elfinterp.c b/ldso/ldso/sparc/elfinterp.c
index 89993cd84..704837092 100644
--- a/ldso/ldso/sparc/elfinterp.c
+++ b/ldso/ldso/sparc/elfinterp.c
@@ -113,7 +113,7 @@ unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
/* Get the address of the GOT entry */
new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
if(unlikely(!new_addr)) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
_dl_progname, strtab + symtab[symtab_index].st_name);
@@ -216,7 +216,7 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
symbol_addr = (unsigned int)
_dl_find_hash(strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope, elf_machine_type_class(reloc_type));
+ tpnt->symbol_scope, tpnt, elf_machine_type_class(reloc_type));
if(!symbol_addr &&
ELF32_ST_BIND(symtab [symtab_index].st_info) != STB_WEAK) {
@@ -278,61 +278,3 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
};
return goof;
}
-
-
-/* This is done as a separate step, because there are cases where
- information is first copied and later initialized. This results in
- the wrong information being copied. Someone at Sun was complaining about
- a bug in the handling of _COPY by SVr4, and this may in fact be what he
- was talking about. Sigh. */
-
-/* No, there are cases where the SVr4 linker fails to emit COPY relocs
- at all */
-
-int _dl_parse_copy_information(struct dyn_elf *xpnt,
- unsigned long rel_addr, unsigned long rel_size)
-{
- int i;
- char * strtab;
- int reloc_type;
- int goof = 0;
- Elf32_Sym * symtab;
- Elf32_Rela * rpnt;
- unsigned int * reloc_addr;
- unsigned int symbol_addr;
- struct elf_resolve *tpnt;
- int symtab_index;
- /* Now parse the relocation information */
- return 0; /* disable for now, remove later */
- tpnt = xpnt->dyn;
-
- rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
-
- symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
- strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
-
- for(i=0; i< rel_size; i+= sizeof(Elf32_Rela), rpnt++){
- reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- if(reloc_type != R_SPARC_COPY) continue;
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
- if(symtab_index) {
- symbol_addr = (unsigned int)
- _dl_find_hash(strtab + symtab[symtab_index].st_name,
- xpnt->next, ELF_RTYPE_CLASS_COPY);
- if(!symbol_addr) {
- _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
- _dl_progname, strtab + symtab[symtab_index].st_name);
- goof++;
- };
- };
- if (!goof)
- _dl_memcpy((char *) symtab[symtab_index].st_value,
- (char *) symbol_addr,
- symtab[symtab_index].st_size);
- };
- return goof;
-}
-
-