* reloc_count problem in the linker
@ 2003-03-18 14:28 Jakub Jelinek
2003-03-19 9:28 ` [PATCH] " Jakub Jelinek
2003-03-19 9:36 ` Alan Modra
0 siblings, 2 replies; 3+ messages in thread
From: Jakub Jelinek @ 2003-03-18 14:28 UTC (permalink / raw)
To: binutils
Hi!
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.
The problem is on arches where the two counts might not be equal (this
happens when one external relocation consists of more than one internal
relocations). elf_section_data (sec)->relocs correspond 1:1 with
the external relocs but the canonicalized relocs don't, e.g. sparc64
R_SPARC_OLO10 relocation is canonicalized to R_SPARC_LO10 + R_SPARC_13.
Linker mostly uses the first variant while other tools (objdump,
strip, etc.) mostly use the canonicalized relocs, but when linker emits
a warning, warning_find_reloc calls bfd_canonicalize_reloc
and if elf_section_data (sec)->relocs is already non-NULL,
bfd_canonicalize_reloc changes reloc_count so it no longer matches size
of ->relocs array (and thus linker reads past the end of the array).
What do you think would be best fix for this?
From brief looking at where bfd_canonizalize_reloc is used in the linker
it seems to me like it really doesn't require canonicalized reloc, so maybe
there could be another bfd routine which would get relocs in the same
form as bfd_canonizalize_reloc, but wouldn't actually guarantee their
canonizalization. Alternatively, there could be a routine which would return
just one arelent for abfd, sec, symbol_name tripplet (that's what both
ldmain.c and ldcref.c need apparently).
Jakub
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] reloc_count problem in the linker
2003-03-18 14:28 reloc_count problem in the linker Jakub Jelinek
@ 2003-03-19 9:28 ` Jakub Jelinek
2003-03-19 9:36 ` Alan Modra
1 sibling, 0 replies; 3+ messages in thread
From: Jakub Jelinek @ 2003-03-19 9:28 UTC (permalink / raw)
To: binutils
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@redhat.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)];
}
\f
+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;
}
\f
-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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: reloc_count problem in the linker
2003-03-18 14:28 reloc_count problem in the linker Jakub Jelinek
2003-03-19 9:28 ` [PATCH] " Jakub Jelinek
@ 2003-03-19 9:36 ` Alan Modra
1 sibling, 0 replies; 3+ messages in thread
From: Alan Modra @ 2003-03-19 9:36 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: binutils
On Tue, Mar 18, 2003 at 03:28:15PM +0100, Jakub Jelinek wrote:
> 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.
Stop using sec->reloc_count for ELF relocs, perhaps. We already
have elf_section_data(sec)->rel_count and
elf_section_data(sec)->rel_count2
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-03-19 9:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-03-18 14:28 reloc_count problem in the linker Jakub Jelinek
2003-03-19 9:28 ` [PATCH] " Jakub Jelinek
2003-03-19 9:36 ` Alan Modra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).