diff options
Diffstat (limited to 'ldso/ldso/dl-elf.c')
-rw-r--r-- | ldso/ldso/dl-elf.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 2dd6fc4d0..cf1dae3b2 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -734,6 +734,7 @@ int _dl_fixup(struct dyn_elf *rpnt, int flag) { int goof = 0; struct elf_resolve *tpnt; + unsigned long reloc_size; if (rpnt->next) goof += _dl_fixup(rpnt->next, flag); @@ -754,13 +755,21 @@ int _dl_fixup(struct dyn_elf *rpnt, int flag) return goof; } +/* 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]; +#endif if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]) { if (tpnt->init_flag & RELOCS_DONE) return goof; tpnt->init_flag |= RELOCS_DONE; goof += _dl_parse_relocation_information(rpnt, tpnt->dynamic_info[DT_RELOC_TABLE_ADDR], - tpnt->dynamic_info[DT_RELOC_TABLE_SIZE], 0); + reloc_size, 0); } if (tpnt->dynamic_info[DT_JMPREL]) { |