From 758d1c9ff67def05e29859d4698eadc29ebb24de Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Fri, 6 Aug 2004 16:12:11 +0000 Subject: Joakim Tjernlund writes: PPC32, SPARC32/64 and S390 includes the PLT in its RELA size. This caused ldso to always do unlazy relocation of the JMPRELs. This patch fixes it. --- ldso/ldso/dl-elf.c | 11 ++++++++++- ldso/ldso/powerpc/dl-sysdep.h | 4 ++++ ldso/ldso/sparc/dl-sysdep.h | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) (limited to 'ldso') 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]) { diff --git a/ldso/ldso/powerpc/dl-sysdep.h b/ldso/ldso/powerpc/dl-sysdep.h index 41d37e35c..b614318bb 100644 --- a/ldso/ldso/powerpc/dl-sysdep.h +++ b/ldso/ldso/powerpc/dl-sysdep.h @@ -87,3 +87,7 @@ void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt); || (type) == R_PPC_REL24 \ || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_PPC_COPY) * ELF_RTYPE_CLASS_COPY)) + +/* The SVR4 ABI specifies that the JMPREL relocs must be inside the + DT_RELA table. */ +#define ELF_MACHINE_PLTREL_OVERLAP 1 diff --git a/ldso/ldso/sparc/dl-sysdep.h b/ldso/ldso/sparc/dl-sysdep.h index ddf74e21e..448bef055 100644 --- a/ldso/ldso/sparc/dl-sysdep.h +++ b/ldso/ldso/sparc/dl-sysdep.h @@ -107,3 +107,6 @@ sparc_mod(unsigned long m, unsigned long p) #define elf_machine_type_class(type) \ ((((type) == R_SPARC_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY)) + +/* The SPARC overlaps DT_RELA and DT_PLTREL. */ +#define ELF_MACHINE_PLTREL_OVERLAP 1 -- cgit v1.2.3