diff options
author | Alan Modra <amodra@gmail.com> | 2020-10-09 10:59:33 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2020-10-09 23:23:27 +1030 |
commit | 4290b0ab2b65db23afc9bd8177885bfd91911c0c (patch) | |
tree | 1a61e6787591d50752f0b9e9dec57be28f3ac421 | |
parent | 32930e4edbc06bc6f10c435dbcc63131715df678 (diff) | |
download | gdb-4290b0ab2b65db23afc9bd8177885bfd91911c0c.zip gdb-4290b0ab2b65db23afc9bd8177885bfd91911c0c.tar.gz gdb-4290b0ab2b65db23afc9bd8177885bfd91911c0c.tar.bz2 |
[GOLD] internal error in relocate, at powerpc.cc:10473
GOT relocations can refer directly to a function in a fixed position
executable, unlike ADDR64 which needs a global entry stub, or branch
relocs, which need PLT stubs.
* powerpc.cc (is_got_reloc): New function.
(Target_powerpc::Relocate::relocate): Use it here, exclude GOT
relocs when looking for stubs.
-rw-r--r-- | gold/ChangeLog | 6 | ||||
-rw-r--r-- | gold/powerpc.cc | 22 |
2 files changed, 21 insertions, 7 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 7146535..0c00d96 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,9 @@ +2020-10-09 Alan Modra <amodra@gmail.com> + + * powerpc.cc (is_got_reloc): New function. + (Target_powerpc::Relocate::relocate): Use it here, exclude GOT + relocs when looking for stubs. + 2020-10-08 H.J. Lu <hongjiu.lu@intel.com> * testsuite/split_i386.sh: Updated for --split-stack-adjust-size diff --git a/gold/powerpc.cc b/gold/powerpc.cc index adbc120..f9eb4f9 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -1884,6 +1884,19 @@ is_plt16_reloc(unsigned int r_type) || (size == 64 && r_type == elfcpp::R_PPC64_PLT16_LO_DS)); } +// GOT_TYPE_STANDARD (ie. not TLS) GOT relocs +inline bool +is_got_reloc(unsigned int r_type) +{ + return (r_type == elfcpp::R_POWERPC_GOT16 + || r_type == elfcpp::R_POWERPC_GOT16_LO + || r_type == elfcpp::R_POWERPC_GOT16_HI + || r_type == elfcpp::R_POWERPC_GOT16_HA + || r_type == elfcpp::R_PPC64_GOT16_DS + || r_type == elfcpp::R_PPC64_GOT16_LO_DS + || r_type == elfcpp::R_PPC64_GOT_PCREL34); +} + // If INSN is an opcode that may be used with an @tls operand, return // the transformed insn for TLS optimisation, otherwise return 0. If // REG is non-zero only match an insn with RB or RA equal to REG. @@ -10381,6 +10394,7 @@ Target_powerpc<size, big_endian>::Relocate::relocate( ? gsym->use_plt_offset(Scan::get_reference_flags(r_type, target)) : object->local_has_plt_offset(r_sym)); if (has_plt_offset + && !is_got_reloc(r_type) && !is_plt16_reloc<size>(r_type) && r_type != elfcpp::R_PPC64_PLT_PCREL34 && r_type != elfcpp::R_PPC64_PLT_PCREL34_NOTOC @@ -10523,13 +10537,7 @@ Target_powerpc<size, big_endian>::Relocate::relocate( elfcpp::Swap<32, big_endian>::writeval(iview + 1, pnop & 0xffffffff); r_type = elfcpp::R_POWERPC_NONE; } - else if (r_type == elfcpp::R_POWERPC_GOT16 - || r_type == elfcpp::R_POWERPC_GOT16_LO - || r_type == elfcpp::R_POWERPC_GOT16_HI - || r_type == elfcpp::R_POWERPC_GOT16_HA - || r_type == elfcpp::R_PPC64_GOT16_DS - || r_type == elfcpp::R_PPC64_GOT16_LO_DS - || r_type == elfcpp::R_PPC64_GOT_PCREL34) + else if (is_got_reloc(r_type)) { if (gsym != NULL) { |