summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-08-06 16:12:11 +0000
committerEric Andersen <andersen@codepoet.org>2004-08-06 16:12:11 +0000
commit758d1c9ff67def05e29859d4698eadc29ebb24de (patch)
tree5eec1b153d18010ab83cd7c945182fa3747de196
parent4efa075cf3b7d772bcb1b82d175dd6ddb0cd29c5 (diff)
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.
-rw-r--r--ldso/ldso/dl-elf.c11
-rw-r--r--ldso/ldso/powerpc/dl-sysdep.h4
-rw-r--r--ldso/ldso/sparc/dl-sysdep.h3
3 files changed, 17 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]) {
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