OSDN Git Service

Joakim Tjernlund writes:
authorEric Andersen <andersen@codepoet.org>
Fri, 6 Aug 2004 16:12:11 +0000 (16:12 -0000)
committerEric Andersen <andersen@codepoet.org>
Fri, 6 Aug 2004 16:12:11 +0000 (16:12 -0000)
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
ldso/ldso/powerpc/dl-sysdep.h
ldso/ldso/sparc/dl-sysdep.h

index 2dd6fc4..cf1dae3 100644 (file)
@@ -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]) {
index 41d37e3..b614318 100644 (file)
@@ -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
index ddf74e2..448bef0 100644 (file)
@@ -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