This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] reloc_count problem in the linker
- From: Jakub Jelinek <jakub at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Wed, 19 Mar 2003 10:28:33 +0100
- Subject: [PATCH] reloc_count problem in the linker
- References: <20030318152815.Z1717@sunsite.ms.mff.cuni.cz>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Tue, Mar 18, 2003 at 03:28:15PM +0100, Jakub Jelinek wrote:
> I'm seeing linker segfault on sparc64 (and I suppose
> mips64 can have the same problems) when linking tst-ildouble test.
> The problem seems to be that in bfd, there are 2 different reloc reading
> APIs, _bfd_elfNN_link_read_relocs which stores the relocations in
> elf_section_data (sec)->relocs array and their count into sec->reloc_count
> and bfd_canonicalize_reloc which stores the relocations in sec->relocation
> and their count into sec->reloc_count.
Fixed thusly:
2003-03-19 Jakub Jelinek <jakub at redhat dot com>
* elf64-sparc.c (struct sparc64_elf_section_data): Add reloc_count
field.
(canon_reloc_count): Define.
(sparc64_elf_slurp_one_reloc_table, sparc64_elf_slurp_reloc_table,
sparc64_elf_canonicalize_dynamic_reloc): Use it instead of
reloc_count.
(sparc64_elf_canonicalize_reloc): New routine.
(bfd_elf64_canonicalize_reloc): Define.
--- bfd/elf64-sparc.c.jj 2003-02-22 15:46:41.000000000 -0500
+++ bfd/elf64-sparc.c 2003-03-18 19:20:50.000000000 -0500
@@ -96,6 +96,8 @@ static bfd_boolean sparc64_elf_slurp_one
PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, asymbol **, bfd_boolean));
static bfd_boolean sparc64_elf_slurp_reloc_table
PARAMS ((bfd *, asection *, asymbol **, bfd_boolean));
+static long sparc64_elf_canonicalize_reloc
+ PARAMS ((bfd *, asection *, arelent **, asymbol **));
static long sparc64_elf_canonicalize_dynamic_reloc
PARAMS ((bfd *, arelent **, asymbol **));
static void sparc64_elf_write_relocs PARAMS ((bfd *, asection *, PTR));
@@ -311,6 +313,17 @@ sparc64_elf_info_to_howto (abfd, cache_p
cache_ptr->howto = &sparc64_elf_howto_table[ELF64_R_TYPE_ID (dst->r_info)];
}
+struct sparc64_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+ unsigned int do_relax, reloc_count;
+};
+
+#define sec_do_relax(sec) \
+ ((struct sparc64_elf_section_data *) elf_section_data (sec))->do_relax
+#define canon_reloc_count(sec) \
+ ((struct sparc64_elf_section_data *) elf_section_data (sec))->reloc_count
+
/* Due to the way how we handle R_SPARC_OLO10, each entry in a SHT_RELA
section can represent up to two relocs, we must tell the user to allocate
more space. */
@@ -361,7 +374,7 @@ sparc64_elf_slurp_one_reloc_table (abfd,
native_relocs = (bfd_byte *) allocated;
- relents = asect->relocation + asect->reloc_count;
+ relents = asect->relocation + canon_reloc_count (asect);
entsize = rel_hdr->sh_entsize;
BFD_ASSERT (entsize == sizeof (Elf64_External_Rela));
@@ -416,7 +429,7 @@ sparc64_elf_slurp_one_reloc_table (abfd,
relent->howto = &sparc64_elf_howto_table[ELF64_R_TYPE_ID (rela.r_info)];
}
- asect->reloc_count += relent - relents;
+ canon_reloc_count (asect) += relent - relents;
if (allocated != NULL)
free (allocated);
@@ -478,8 +491,9 @@ sparc64_elf_slurp_reloc_table (abfd, ase
if (asect->relocation == NULL)
return FALSE;
- /* The sparc64_elf_slurp_one_reloc_table routine increments reloc_count. */
- asect->reloc_count = 0;
+ /* The sparc64_elf_slurp_one_reloc_table routine increments
+ canon_reloc_count. */
+ canon_reloc_count (asect) = 0;
if (!sparc64_elf_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
dynamic))
@@ -493,6 +507,32 @@ sparc64_elf_slurp_reloc_table (abfd, ase
return TRUE;
}
+/* Canonicalize the relocs. */
+
+static long
+sparc64_elf_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *tblptr;
+ unsigned int i;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
+ return -1;
+
+ tblptr = section->relocation;
+ for (i = 0; i < canon_reloc_count (section); i++)
+ *relptr++ = tblptr++;
+
+ *relptr = NULL;
+
+ return canon_reloc_count (section);
+}
+
+
/* Canonicalize the dynamic relocation entries. Note that we return
the dynamic relocations as a single block, although they are
actually associated with particular sections; the interface, which
@@ -528,7 +568,7 @@ sparc64_elf_canonicalize_dynamic_reloc (
if (! sparc64_elf_slurp_reloc_table (abfd, s, syms, TRUE))
return -1;
- count = s->reloc_count;
+ count = canon_reloc_count (s);
p = s->relocation;
for (i = 0; i < count; i++)
*storage++ = p++;
@@ -1918,15 +1958,6 @@ sparc64_elf_size_dynamic_sections (outpu
return TRUE;
}
-struct sparc64_elf_section_data
-{
- struct bfd_elf_section_data elf;
- unsigned int do_relax;
-};
-
-#define sec_do_relax(sec) \
- ((struct sparc64_elf_section_data *) elf_section_data (sec))->do_relax
-
static bfd_boolean
sparc64_elf_new_section_hook (abfd, sec)
bfd *abfd;
@@ -3177,6 +3208,8 @@ const struct elf_size_info sparc64_elf_s
sparc64_elf_get_reloc_upper_bound
#define bfd_elf64_get_dynamic_reloc_upper_bound \
sparc64_elf_get_dynamic_reloc_upper_bound
+#define bfd_elf64_canonicalize_reloc \
+ sparc64_elf_canonicalize_reloc
#define bfd_elf64_canonicalize_dynamic_reloc \
sparc64_elf_canonicalize_dynamic_reloc
#define bfd_elf64_bfd_reloc_type_lookup \
Jakub