diff options
author | Filippo Arcidiacono <filippo.arcidiacono@st.com> | 2010-10-11 12:56:21 +0200 |
---|---|---|
committer | Carmelo Amoroso <carmelo.amoroso@st.com> | 2010-10-11 12:58:04 +0200 |
commit | 4ec89b87bc0eea8d9ca6b50564d12eeb3b1b0119 (patch) | |
tree | baf8ca74e568ca5f8468a1913376832689a9899a | |
parent | 8d29ef117dba66ab67419a69d272779d50f147f0 (diff) |
ldso: Extend prelink support for all other achitectures
Update Arch specific part of the dynamic linker to the
latest cahnges required by prelink:
- Use _dl_loaded_modules->scope as global symbol scope
- Pass the sym argument (or NULL) to the _dl_find_hash
- Update _dl_parse, _dl_do_reloc, _dl_do_lazy_reloc and
_dl_parse_relocation_information to reflect the change of
the scope argument's type
- Add the call to _dl_debug_lookup used for trace prelinking.
Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
-rw-r--r-- | ldso/ldso/arm/elfinterp.c | 23 | ||||
-rw-r--r-- | ldso/ldso/avr32/elfinterp.c | 20 | ||||
-rw-r--r-- | ldso/ldso/bfin/elfinterp.c | 23 | ||||
-rw-r--r-- | ldso/ldso/cris/elfinterp.c | 21 | ||||
-rw-r--r-- | ldso/ldso/frv/elfinterp.c | 14 | ||||
-rw-r--r-- | ldso/ldso/i386/elfinterp.c | 22 | ||||
-rw-r--r-- | ldso/ldso/m68k/elfinterp.c | 22 | ||||
-rw-r--r-- | ldso/ldso/mips/elfinterp.c | 26 | ||||
-rw-r--r-- | ldso/ldso/powerpc/elfinterp.c | 20 | ||||
-rw-r--r-- | ldso/ldso/sh64/elfinterp.c | 21 | ||||
-rw-r--r-- | ldso/ldso/sparc/elfinterp.c | 23 | ||||
-rw-r--r-- | ldso/ldso/x86_64/elfinterp.c | 21 | ||||
-rw-r--r-- | ldso/ldso/xtensa/elfinterp.c | 20 |
13 files changed, 171 insertions, 105 deletions
diff --git a/ldso/ldso/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c index adc282a57..ee2d1e559 100644 --- a/ldso/ldso/arm/elfinterp.c +++ b/ldso/ldso/arm/elfinterp.c @@ -69,8 +69,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, - tpnt, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, + tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); @@ -99,9 +99,9 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) } static int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc) (struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { int i; @@ -181,7 +181,7 @@ fix_bad_pc24 (unsigned long *const reloc_addr, unsigned long value) #endif static int -_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, +_dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -192,6 +192,8 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, struct elf_resolve *def_mod = 0; int goof = 0; + struct sym_val current_value = { NULL, NULL }; + reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); @@ -202,7 +204,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other) != STV_PROTECTED)) { symbol_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, - scope, tpnt, elf_machine_type_class(reloc_type), &def_mod); + scope, tpnt, ¤t_value, elf_machine_type_class(reloc_type), &def_mod); /* * We want to allow undefined references to weak symbols - this might @@ -215,6 +217,9 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, return 1; } + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } else { /* * Relocs against STN_UNDEF are usually treated as using a @@ -311,7 +316,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, } static int -_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -350,8 +355,8 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, } int _dl_parse_relocation_information(struct dyn_elf *rpnt, - unsigned long rel_addr, unsigned long rel_size) + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } diff --git a/ldso/ldso/avr32/elfinterp.c b/ldso/ldso/avr32/elfinterp.c index 797f8513e..e741fd60e 100644 --- a/ldso/ldso/avr32/elfinterp.c +++ b/ldso/ldso/avr32/elfinterp.c @@ -51,8 +51,8 @@ unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got) symname = strtab + sym->st_name; new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name, - tpnt->symbol_scope, tpnt, - resolver); + &_dl_loaded_modules->symbol_scope, tpnt, + NULL, 0, resolver); entry = (unsigned long *)(got + local_gotno + sym_index - gotsym); *entry = new_addr; @@ -63,9 +63,9 @@ unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got) } static int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_func)(struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_func)(struct elf_resolve *tpnt, struct r_scope_elem *scope, Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)) { Elf32_Sym *symtab; @@ -116,7 +116,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, return 0; } -static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +static int _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -128,6 +128,8 @@ static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, unsigned long old_val; #endif + struct sym_val current_value = { NULL, NULL }; + reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); @@ -137,7 +139,7 @@ static int _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, - tpnt->symbol_scope, tpnt, + scope, tpnt, ¤t_value, elf_machine_type_class(reloc_type), NULL); /* Allow undefined references to weak symbols */ @@ -147,6 +149,9 @@ static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, _dl_progname, symname); return 0; } + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } #if defined(__SUPPORT_LD_DEBUG__) @@ -185,9 +190,10 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, } int _dl_parse_relocation_information(struct dyn_elf *rpnt, + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } diff --git a/ldso/ldso/bfin/elfinterp.c b/ldso/ldso/bfin/elfinterp.c index e8d88bd5a..466a3b4c1 100644 --- a/ldso/ldso/bfin/elfinterp.c +++ b/ldso/ldso/bfin/elfinterp.c @@ -65,9 +65,9 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) got_entry = (struct funcdesc_value *) DL_RELOC_ADDR(tpnt->loadaddr, this_reloc->r_offset); /* Get the address to be used to fill in the GOT entry. */ - new_addr = _dl_lookup_hash(symname, tpnt->symbol_scope, NULL, 0, &new_tpnt); + new_addr = _dl_lookup_hash(symname, &_dl_loaded_modules->symbol_scope, NULL, NULL, 0, &new_tpnt); if (!new_addr) { - new_addr = _dl_lookup_hash(symname, NULL, NULL, 0, &new_tpnt); + new_addr = _dl_lookup_hash(symname, NULL, NULL, NULL, 0, &new_tpnt); if (!new_addr) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); @@ -99,9 +99,9 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) } static int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc) (struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)) { unsigned int i; @@ -150,7 +150,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, +_dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) { int reloc_type; @@ -166,6 +166,8 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, unsigned long old_val; #endif + struct sym_val current_value = { NULL, NULL }; + reloc_addr = (unsigned long *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset); __asm__ ("" : "=r" (reloc_addr_packed) : "0" (reloc_addr)); reloc_type = ELF_R_TYPE(rpnt->r_info); @@ -179,7 +181,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, } else { symbol_addr = (unsigned long) - _dl_lookup_hash(symname, scope, NULL, 0, &symbol_tpnt); + _dl_lookup_hash(symname, scope, NULL, ¤t_value, 0, &symbol_tpnt); /* * We want to allow undefined references to weak symbols - this might @@ -192,6 +194,9 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, _dl_progname, strtab + symtab[symtab_index].st_name); _dl_exit (1); } + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } #if defined (__SUPPORT_LD_DEBUG__) @@ -275,7 +280,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, static int _dl_do_lazy_reloc (struct elf_resolve *tpnt, - struct dyn_elf *scope __attribute__((unused)), + struct r_scope_elem *scope __attribute__((unused)), ELF_RELOC *rpnt, ElfW(Sym) *symtab __attribute__((unused)), char *strtab __attribute__((unused))) { @@ -321,9 +326,9 @@ _dl_parse_lazy_relocation_information int _dl_parse_relocation_information -(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size) +(struct dyn_elf *rpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } /* We don't have copy relocs. */ diff --git a/ldso/ldso/cris/elfinterp.c b/ldso/ldso/cris/elfinterp.c index 32ea2da9e..48802aa7c 100644 --- a/ldso/ldso/cris/elfinterp.c +++ b/ldso/ldso/cris/elfinterp.c @@ -66,7 +66,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, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); @@ -91,9 +91,9 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) } static int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc)(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { int symtab_index; @@ -150,7 +150,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -162,6 +162,8 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, unsigned long old_val; #endif + struct sym_val current_value = { NULL, NULL }; + reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); @@ -174,15 +176,17 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, symbol_addr = (unsigned long)tpnt->loadaddr; } else { symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt, - elf_machine_type_class(reloc_type), NULL); + ¤t_value, elf_machine_type_class(reloc_type), NULL); } if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); } - symbol_addr += rpnt->r_addend; + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } #if defined (__SUPPORT_LD_DEBUG__) @@ -227,7 +231,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -279,8 +283,9 @@ _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, int _dl_parse_relocation_information(struct dyn_elf *rpnt, + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } diff --git a/ldso/ldso/frv/elfinterp.c b/ldso/ldso/frv/elfinterp.c index 4b94033de..726b58b09 100644 --- a/ldso/ldso/frv/elfinterp.c +++ b/ldso/ldso/frv/elfinterp.c @@ -54,7 +54,7 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) DL_RELOC_ADDR (this_reloc->r_offset, tpnt->loadaddr); /* Get the address to be used to fill in the GOT entry. */ - new_addr = _dl_find_hash_mod(symname, tpnt->symbol_scope, NULL, 0, + new_addr = _dl_find_hash_mod(symname, &_dl_loaded_modules->symbol_scope, NULL, 0, &new_tpnt); if (!new_addr) { new_addr = _dl_find_hash_mod(symname, NULL, NULL, 0, @@ -91,9 +91,9 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) } static int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc) (struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { unsigned int i; @@ -146,7 +146,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, +_dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -276,7 +276,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, static int _dl_do_lazy_reloc (struct elf_resolve *tpnt, - struct dyn_elf *scope __attribute_used__, + struct r_scope_elem *scope __attribute_used__, ELF_RELOC *rpnt, Elf32_Sym *symtab __attribute_used__, char *strtab __attribute_used__) { @@ -325,9 +325,9 @@ _dl_parse_lazy_relocation_information int _dl_parse_relocation_information -(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size) +(struct dyn_elf *rpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } /* We don't have copy relocs. */ diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c index 1e3a2b248..0c821ce8b 100644 --- a/ldso/ldso/i386/elfinterp.c +++ b/ldso/ldso/i386/elfinterp.c @@ -71,7 +71,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, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname); _dl_exit(1); @@ -98,9 +98,9 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) } static int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc)(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { unsigned int i; @@ -156,7 +156,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -169,6 +169,8 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, unsigned long old_val; #endif + struct sym_val current_value = { NULL, NULL }; + reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); @@ -179,7 +181,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other) != STV_PROTECTED)) { symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt, - elf_machine_type_class(reloc_type), &tls_tpnt); + ¤t_value, elf_machine_type_class(reloc_type), &tls_tpnt); /* * We want to allow undefined references to weak symbols - this @@ -189,6 +191,10 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, if (unlikely(!symbol_addr && (ELF_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS) && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) return 1; + + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } else { if (symtab_index) symbol_addr = DL_FIND_HASH_VALUE(tpnt, elf_machine_type_class(reloc_type), @@ -198,7 +204,6 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, tls_tpnt = tpnt; } - #if defined (__SUPPORT_LD_DEBUG__) old_val = *reloc_addr; #endif @@ -268,7 +273,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -317,8 +322,9 @@ _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, int _dl_parse_relocation_information(struct dyn_elf *rpnt, + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } diff --git a/ldso/ldso/m68k/elfinterp.c b/ldso/ldso/m68k/elfinterp.c index 04c301ebb..195dba5e5 100644 --- a/ldso/ldso/m68k/elfinterp.c +++ b/ldso/ldso/m68k/elfinterp.c @@ -70,7 +70,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, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); @@ -94,9 +94,9 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) } static int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc)(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)) { unsigned int i; @@ -151,7 +151,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) { int reloc_type; @@ -164,6 +164,8 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ElfW(Addr) old_val; #endif + struct sym_val current_value = { NULL, NULL }; + reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); reloc_type = ELF_R_TYPE(rpnt->r_info); symtab_index = ELF_R_SYM(rpnt->r_info); @@ -173,7 +175,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, if (symtab_index) { symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, - elf_machine_type_class(reloc_type), NULL); + ¤t_value, elf_machine_type_class(reloc_type), NULL); /* * We want to allow undefined references to weak symbols - this * might have been intentional. We should not be linking local @@ -183,6 +185,9 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); } + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } #if defined (__SUPPORT_LD_DEBUG__) @@ -256,7 +261,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, #undef LAZY_RELOC_WORKS #ifdef LAZY_RELOC_WORKS static int -_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) { int reloc_type; @@ -305,14 +310,15 @@ _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, #ifdef LAZY_RELOC_WORKS (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc); #else - _dl_parse_relocation_information(rpnt, rel_addr, rel_size); + _dl_parse_relocation_information(rpnt, &_dl_loaded_modules->symbol_scope, rel_addr, rel_size); #endif } int _dl_parse_relocation_information(struct dyn_elf *rpnt, + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c index a56ee81b4..2a433e282 100644 --- a/ldso/ldso/mips/elfinterp.c +++ b/ldso/ldso/mips/elfinterp.c @@ -56,7 +56,7 @@ unsigned long __dl_runtime_resolve(unsigned long sym_index, symname = strtab + sym->st_name; new_addr = (unsigned long) _dl_find_hash(symname, - tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf (2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); @@ -111,7 +111,7 @@ __dl_runtime_pltresolve(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, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname); _dl_exit(1); @@ -145,7 +145,7 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, } int _dl_parse_relocation_information(struct dyn_elf *xpnt, - unsigned long rel_addr, unsigned long rel_size) + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { ElfW(Sym) *symtab; ELF_RELOC *rpnt; @@ -161,6 +161,8 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, unsigned long old_val=0; #endif + struct sym_val current_value = { NULL, NULL }; + /* Now parse the relocation information */ rel_size = rel_size / sizeof(ElfW(Rel)); rpnt = (ELF_RELOC *) rel_addr; @@ -186,11 +188,14 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, if (reloc_type == R_MIPS_JUMP_SLOT || reloc_type == R_MIPS_COPY) { symbol_addr = (unsigned long)_dl_find_hash(symname, - tpnt->symbol_scope, - tpnt, + scope, + tpnt, ¤t_value, elf_machine_type_class(reloc_type), NULL); if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) return 1; + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } if (!symtab_index) { /* Relocs against STN_UNDEF are usually treated as using a @@ -215,8 +220,8 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, struct elf_resolve *tpnt_tls = NULL; if (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_LOCAL) { - symbol_addr = (unsigned long) _dl_find_hash(symname, tpnt->symbol_scope, - tpnt, elf_machine_type_class(reloc_type), &tpnt_tls); + symbol_addr = (unsigned long) _dl_find_hash(symname, scope, + tpnt, ¤t_value, elf_machine_type_class(reloc_type), &tpnt_tls); } /* In case of a TLS reloc, tpnt_tls NULL means we have an 'anonymous' symbol. This is the case for a static tls variable, so the lookup @@ -314,7 +319,6 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, _dl_exit(1); } } - } #if defined (__SUPPORT_LD_DEBUG__) if (_dl_debug_reloc && _dl_debug_detail && reloc_addr) @@ -358,12 +362,12 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy) } else { *got_entry = (unsigned long) _dl_find_hash(strtab + - sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + sym->st_name, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); } } else if (sym->st_shndx == SHN_COMMON) { *got_entry = (unsigned long) _dl_find_hash(strtab + - sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + sym->st_name, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); } else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC && *got_entry != sym->st_value && tmp_lazy) { @@ -375,7 +379,7 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy) } else { *got_entry = (unsigned long) _dl_find_hash(strtab + - sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + sym->st_name, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); } got_entry++; diff --git a/ldso/ldso/powerpc/elfinterp.c b/ldso/ldso/powerpc/elfinterp.c index 855c040d3..043534ed1 100644 --- a/ldso/ldso/powerpc/elfinterp.c +++ b/ldso/ldso/powerpc/elfinterp.c @@ -139,7 +139,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, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!finaladdr)) { _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname); _dl_exit(1); @@ -182,7 +182,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) } static __inline__ int -_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, +_dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -197,6 +197,8 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, unsigned long old_val; #endif + struct sym_val current_value = { NULL, NULL }; + symbol_addr = tpnt->loadaddr; /* For R_PPC_RELATIVE */ reloc_addr = (Elf32_Addr *)(intptr_t) (symbol_addr + (unsigned long) rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); @@ -205,7 +207,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, symname = strtab + sym->st_name; if (symtab_index) { symbol_addr = (unsigned long) _dl_find_hash(symname, scope, tpnt, - elf_machine_type_class(reloc_type), &tls_tpnt); + ¤t_value, elf_machine_type_class(reloc_type), &tls_tpnt); /* We want to allow undefined references to weak symbols - this might * have been intentional. We should not be linking local symbols * here, so all bases should be covered. @@ -214,10 +216,14 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, && (ELF32_ST_TYPE(sym->st_info) != STT_TLS && ELF32_ST_BIND(sym->st_info) != STB_WEAK))) return 1; + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } else { symbol_addr = sym->st_value; tls_tpnt = tpnt; } + #if defined (__SUPPORT_LD_DEBUG__) old_val = *reloc_addr; #endif @@ -385,9 +391,9 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, } static __inline__ int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc) (struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { unsigned int i; @@ -440,7 +446,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, } int _dl_parse_relocation_information(struct dyn_elf *rpnt, - unsigned long rel_addr, unsigned long rel_size) + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } diff --git a/ldso/ldso/sh64/elfinterp.c b/ldso/ldso/sh64/elfinterp.c index 74fda04dc..8f6b32067 100644 --- a/ldso/ldso/sh64/elfinterp.c +++ b/ldso/ldso/sh64/elfinterp.c @@ -73,7 +73,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, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); @@ -102,10 +102,10 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) return (unsigned long)new_addr; } -static int _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +static int _dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, int (*reloc_fnc)(struct elf_resolve *tpnt, - struct dyn_elf *scope, + struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { @@ -162,7 +162,7 @@ static int _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, return 0; } -static int _dl_do_reloc(struct elf_resolve *tpnt,struct dyn_elf *scope, +static int _dl_do_reloc(struct elf_resolve *tpnt,struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -174,6 +174,8 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct dyn_elf *scope, unsigned long old_val; #endif + struct sym_val current_value = { NULL, NULL }; + reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); symbol_addr = 0; @@ -186,7 +188,7 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct dyn_elf *scope, int stb; symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt, - elf_machine_type_class(reloc_type), NULL); + ¤t_value, elf_machine_type_class(reloc_type), NULL); /* * We want to allow undefined references to weak symbols - this @@ -200,6 +202,9 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct dyn_elf *scope, _dl_progname, strtab + symtab[symtab_index].st_name); _dl_exit (1); } + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } #ifdef __SUPPORT_LD_DEBUG__ @@ -287,7 +292,7 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct dyn_elf *scope, return 0; } -static int _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +static int _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type, symtab_index, lsb; @@ -332,7 +337,7 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, } int _dl_parse_relocation_information(struct dyn_elf *rpnt, - unsigned long rel_addr, unsigned long rel_size) + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } diff --git a/ldso/ldso/sparc/elfinterp.c b/ldso/ldso/sparc/elfinterp.c index 56335cb5c..b33ad91b1 100644 --- a/ldso/ldso/sparc/elfinterp.c +++ b/ldso/ldso/sparc/elfinterp.c @@ -80,7 +80,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, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); @@ -107,9 +107,9 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) } static int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc)(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)) { unsigned int i; @@ -164,7 +164,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) { int reloc_type; @@ -178,6 +178,8 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ElfW(Addr) old_val; #endif + struct sym_val current_value = { NULL, NULL }; + reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); reloc_type = ELF_R_TYPE(rpnt->r_info); symtab_index = ELF_R_SYM(rpnt->r_info); @@ -186,7 +188,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, symname = strtab + sym->st_name; if (symtab_index) { - symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, + symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, ¤t_value, elf_machine_type_class(reloc_type), &tls_tpnt); /* * We want to allow undefined references to weak symbols - this @@ -199,6 +201,9 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, return 1; } + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } else { /* Relocs against STN_UNDEF are usually treated as using a * symbol value of zero, and using the module containing the @@ -308,7 +313,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, #undef __SPARC_LAZY_RELOC_WORKS #ifdef __SPARC_LAZY_RELOC_WORKS static int -_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) { int reloc_type; @@ -356,14 +361,16 @@ _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, #ifdef __SPARC_LAZY_RELOC_WORKS (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc); #else - _dl_parse_relocation_information(rpnt, rel_addr, rel_size); + _dl_parse_relocation_information(rpnt, &_dl_loaded_modules->symbol_scope, + rel_addr, rel_size); #endif } int _dl_parse_relocation_information(struct dyn_elf *rpnt, + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } diff --git a/ldso/ldso/x86_64/elfinterp.c b/ldso/ldso/x86_64/elfinterp.c index fce2ec7be..de5a8c01e 100644 --- a/ldso/ldso/x86_64/elfinterp.c +++ b/ldso/ldso/x86_64/elfinterp.c @@ -70,7 +70,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, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); @@ -94,9 +94,9 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) } static int -_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc)(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)) { unsigned int i; @@ -151,7 +151,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) { int reloc_type; @@ -165,6 +165,8 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ElfW(Addr) old_val; #endif + struct sym_val current_value = { NULL, NULL }; + reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); reloc_type = ELF_R_TYPE(rpnt->r_info); symtab_index = ELF_R_SYM(rpnt->r_info); @@ -173,7 +175,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, symname = strtab + sym->st_name; if (symtab_index) { - symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, + symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, ¤t_value, elf_machine_type_class(reloc_type), &tls_tpnt); /* * We want to allow undefined references to weak symbols - this @@ -185,6 +187,9 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, /* This may be non-fatal if called from dlopen. */ return 1; } + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } else { /* Relocs against STN_UNDEF are usually treated as using a * symbol value of zero, and using the module containing the @@ -193,7 +198,6 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, tls_tpnt = tpnt; } - #if defined (__SUPPORT_LD_DEBUG__) old_val = *reloc_addr; #endif @@ -274,7 +278,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, } static int -_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) { int reloc_type; @@ -324,8 +328,9 @@ _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, int _dl_parse_relocation_information(struct dyn_elf *rpnt, + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } diff --git a/ldso/ldso/xtensa/elfinterp.c b/ldso/ldso/xtensa/elfinterp.c index 48281913d..59f641571 100644 --- a/ldso/ldso/xtensa/elfinterp.c +++ b/ldso/ldso/xtensa/elfinterp.c @@ -56,7 +56,7 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) got_addr = (char **) (this_reloc->r_offset + tpnt->loadaddr); /* Get the address of the GOT entry. */ - new_addr = _dl_find_hash (symname, tpnt->symbol_scope, tpnt, + new_addr = _dl_find_hash (symname, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely (!new_addr)) { _dl_dprintf (2, "%s: can't resolve symbol '%s'\n", @@ -82,9 +82,9 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) static int -_dl_parse (struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_parse (struct elf_resolve *tpnt, struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope, + int (*reloc_fnc) (struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { unsigned int i; @@ -140,7 +140,7 @@ _dl_parse (struct elf_resolve *tpnt, struct dyn_elf *scope, static int -_dl_do_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -153,6 +153,8 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, Elf32_Addr old_val; #endif + struct sym_val current_value = { NULL, NULL }; + reloc_addr = (Elf32_Addr *) (tpnt->loadaddr + rpnt->r_offset); reloc_type = ELF32_R_TYPE (rpnt->r_info); symtab_index = ELF32_R_SYM (rpnt->r_info); @@ -162,7 +164,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, if (symtab_index) { symbol_addr = (Elf32_Addr) - _dl_find_hash (symname, scope, tpnt, + _dl_find_hash (symname, scope, tpnt, ¤t_value, elf_machine_type_class (reloc_type), NULL); /* @@ -176,6 +178,9 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, _dl_progname, symname); _dl_exit (1); } + if (_dl_trace_prelink) + _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], + ¤t_value, elf_machine_type_class(reloc_type)); } #if defined (__SUPPORT_LD_DEBUG__) @@ -222,7 +227,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, static int -_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { int reloc_type; @@ -269,9 +274,10 @@ _dl_parse_lazy_relocation_information (struct dyn_elf *rpnt, int _dl_parse_relocation_information (struct dyn_elf *rpnt, + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) { - return _dl_parse (rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, + return _dl_parse (rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } |