As noted in from the first attempt at fixing this:
The pr11138 testcase links an executable with a version script. On
mips64-linux the presence of a version script was causing the
MIPS_RLD_MAP dynamic tag to be populated with a NULL value. When
such an executable was run ld.so would try to dereference this and
receive SIGSEGV, thus killing the process.
The root cause of this is that the mips linker synthesizes a
special symbol "__RLD_MAP", and then sets MIPS_RLD_MAP to point to
it. When a version script is present, this symbol gets versioned
along with all the rest, and when it is time to take its address,
the symbol can no longer be found as it has had version information
appended to its name.
This problem has also been reported in the wild when linking the
This new patch, at Richard's suggestion, remembers the __RLD_MAP (which
also goes by several other names) symbol before it can get hidden or
renamed by the symbol versioning code.
Then when it comes time to calculate the DT_MIPS_RLD_MAP value, we can
get the required information from the now remembered symbol.
We can get rid of a big blob of code in
_bfd_mips_elf_finish_dynamic_symbol that is now unused. Also the size
of the .rld_map section was not being set properly for ELF64 targets,
so I fixed that as well.
Tested on mips64-linux-gnu where it fixes the pr11138 testcase
failures. Also tested by bootstrapping GCC with the patched binutils.
Not tested on IRIX6 which has slightly different handling of these
things, but I think the code 'looks plausible', so what could possibly
Comments? or OK to commit?
2011-12-09 David Daney <email@example.com>
* /elfxx-mips.c (mips_elf_link_hash_table.rld_value): Remove.
(mips_elf_link_hash_table.rld_symbol): New field;
(MIPS_ELF_RLD_MAP_SIZE): New macro.
(_bfd_mips_elf_add_symbol_hook): Remember __rld_obj_head symbol
(_bfd_mips_elf_create_dynamic_sections): Remember __rld_map symbol
(_bfd_mips_elf_size_dynamic_sections): Set correct size for .rld_map.
(_bfd_mips_elf_finish_dynamic_symbol): Remove .rld_map handling.
(_bfd_mips_elf_finish_dynamic_sections): Use rld_symbol to
calculate DT_MIPS_RLD_MAP value.
(_bfd_mips_elf_link_hash_table_create): Initialize rld_symbol,
quit initializing rld_value.
Description: Text document