summaryrefslogtreecommitdiff
path: root/ldso/ldso/dl-elf.c
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2005-03-14 13:25:07 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2005-03-14 13:25:07 +0000
commit7d137fcf818e9a157a9f7ed9df61896f6cf97490 (patch)
tree4cd0201de5e99f8f7fc3e40ac97fe9e44411d29f /ldso/ldso/dl-elf.c
parent3b67c539e3f14a7acf59608d6f7a37b710033a5c (diff)
Generalize optimized relative reloc procesing.
Add elf_machine_dynamic() and elf_machine_load_address() for all archs. elf_machine_dynamic() replaces the #ifdef mess to get at the GOT. elf_machine_load_address() is needed to execute ldso directly, this is not complete yet. I probably broke one or two archs(only tested PPC) so please try and report problems. For a report to be useful you need to enable __SUPPORT_LD_DEBUG_EARLY__ and __SUPPORT_LD_DEBUG__
Diffstat (limited to 'ldso/ldso/dl-elf.c')
-rw-r--r--ldso/ldso/dl-elf.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index e1cc005a0..bcf83346e 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -726,7 +726,7 @@ int _dl_fixup(struct dyn_elf *rpnt, int now_flag)
{
int goof = 0;
struct elf_resolve *tpnt;
- unsigned long reloc_size;
+ Elf32_Word reloc_size, reloc_addr, relative_count;
if (rpnt->next)
goof += _dl_fixup(rpnt->next, now_flag);
@@ -757,8 +757,15 @@ int _dl_fixup(struct dyn_elf *rpnt, int now_flag)
if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR] &&
!(tpnt->init_flag & RELOCS_DONE)) {
tpnt->init_flag |= RELOCS_DONE;
+ reloc_addr = tpnt->dynamic_info[DT_RELOC_TABLE_ADDR];
+ relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
+ if (relative_count) { /* Optimize the XX_RELATIVE relocations if possible */
+ reloc_size -= relative_count * sizeof(ELF_RELOC);
+ elf_machine_relative (tpnt->loadaddr, reloc_addr, relative_count);
+ reloc_addr += relative_count * sizeof(ELF_RELOC);
+ }
goof += _dl_parse_relocation_information(rpnt,
- tpnt->dynamic_info[DT_RELOC_TABLE_ADDR],
+ reloc_addr,
reloc_size);
}
if (tpnt->dynamic_info[DT_BIND_NOW])