reloc_count problem in the linker

Jakub Jelinek jakub@redhat.com
Tue Mar 18 14:28:00 GMT 2003
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



More information about the Binutils mailing list