| Index: third_party/binutils/long-plt.patch
|
| diff --git a/third_party/binutils/long-plt.patch b/third_party/binutils/long-plt.patch
|
| deleted file mode 100644
|
| index 9132377efcff82efa9e8a6d4304ae3c23da176e3..0000000000000000000000000000000000000000
|
| --- a/third_party/binutils/long-plt.patch
|
| +++ /dev/null
|
| @@ -1,232 +0,0 @@
|
| -commit ee8713f5cfc38be0e92d78f2afbc77d701ef189d
|
| -Author: Peter Collingbourne <pcc@google.com>
|
| -Date: Thu Dec 17 16:50:35 2015 -0800
|
| -
|
| - Implement --long-plt flag (ARM only).
|
| -
|
| - gold/
|
| - PR gold/18780
|
| - * arm.cc (Target_arm::do_make_data_plt): Choose PLT generator based
|
| - on value of --long-plt flag.
|
| - (Output_data_plt_arm_standard::do_get_plt_entry_size): Moved to
|
| - Output_data_plt_arm_short.
|
| - (Output_data_plt_arm_standard::do_fill_plt_entry): Likewise.
|
| - (Output_data_plt_arm_standard::plt_entry): Likewise.
|
| - (Output_data_plt_arm_standard::do_fill_first_plt_entry): Fix
|
| - variable reference.
|
| - (Output_data_plt_arm_short): New class.
|
| - (Output_data_plt_arm_short::do_fill_plt_entry): Error out on too large
|
| - PLT offsets instead of asserting.
|
| - (Output_data_plt_arm_long): New class.
|
| - * options.h (General_options): Define --long-plt flag.
|
| -
|
| -diff --git a/gold/arm.cc b/gold/arm.cc
|
| -index 6c472bb..a10d785 100644
|
| ---- a/gold/arm.cc
|
| -+++ b/gold/arm.cc
|
| -@@ -62,7 +62,10 @@ template<bool big_endian>
|
| - class Output_data_plt_arm;
|
| -
|
| - template<bool big_endian>
|
| --class Output_data_plt_arm_standard;
|
| -+class Output_data_plt_arm_short;
|
| -+
|
| -+template<bool big_endian>
|
| -+class Output_data_plt_arm_long;
|
| -
|
| - template<bool big_endian>
|
| - class Stub_table;
|
| -@@ -2532,7 +2535,12 @@ class Target_arm : public Sized_target<32, big_endian>
|
| - virtual Output_data_plt_arm<big_endian>*
|
| - do_make_data_plt(Layout* layout, Output_data_space* got_plt)
|
| - {
|
| -- return new Output_data_plt_arm_standard<big_endian>(layout, got_plt);
|
| -+ if (parameters->options().long_plt())
|
| -+ return new Output_data_plt_arm_long<big_endian>(
|
| -+ layout, got_plt);
|
| -+ else
|
| -+ return new Output_data_plt_arm_short<big_endian>(
|
| -+ layout, got_plt);
|
| - }
|
| -
|
| - private:
|
| -@@ -7382,29 +7390,14 @@ class Output_data_plt_arm_standard : public Output_data_plt_arm<big_endian>
|
| - do_first_plt_entry_offset() const
|
| - { return sizeof(first_plt_entry); }
|
| -
|
| -- // Return the size of a PLT entry.
|
| -- virtual unsigned int
|
| -- do_get_plt_entry_size() const
|
| -- { return sizeof(plt_entry); }
|
| --
|
| - virtual void
|
| - do_fill_first_plt_entry(unsigned char* pov,
|
| - Arm_address got_address,
|
| - Arm_address plt_address);
|
| -
|
| -- virtual void
|
| -- do_fill_plt_entry(unsigned char* pov,
|
| -- Arm_address got_address,
|
| -- Arm_address plt_address,
|
| -- unsigned int got_offset,
|
| -- unsigned int plt_offset);
|
| --
|
| - private:
|
| - // Template for the first PLT entry.
|
| - static const uint32_t first_plt_entry[5];
|
| --
|
| -- // Template for subsequent PLT entries.
|
| -- static const uint32_t plt_entry[3];
|
| - };
|
| -
|
| - // ARM PLTs.
|
| -@@ -7432,7 +7425,7 @@ Output_data_plt_arm_standard<big_endian>::do_fill_first_plt_entry(
|
| - {
|
| - // Write first PLT entry. All but the last word are constants.
|
| - const size_t num_first_plt_words = (sizeof(first_plt_entry)
|
| -- / sizeof(plt_entry[0]));
|
| -+ / sizeof(first_plt_entry[0]));
|
| - for (size_t i = 0; i < num_first_plt_words - 1; i++)
|
| - elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]);
|
| - // Last word in first PLT entry is &GOT[0] - .
|
| -@@ -7441,9 +7434,37 @@ Output_data_plt_arm_standard<big_endian>::do_fill_first_plt_entry(
|
| - }
|
| -
|
| - // Subsequent entries in the PLT.
|
| -+// This class generates short (12-byte) entries, for displacements up to 2^28.
|
| -+
|
| -+template<bool big_endian>
|
| -+class Output_data_plt_arm_short : public Output_data_plt_arm_standard<big_endian>
|
| -+{
|
| -+ public:
|
| -+ Output_data_plt_arm_short(Layout* layout,
|
| -+ Output_data_space* got_plt)
|
| -+ : Output_data_plt_arm_standard<big_endian>(layout, got_plt)
|
| -+ { }
|
| -+
|
| -+ protected:
|
| -+ // Return the size of a PLT entry.
|
| -+ virtual unsigned int
|
| -+ do_get_plt_entry_size() const
|
| -+ { return sizeof(plt_entry); }
|
| -+
|
| -+ virtual void
|
| -+ do_fill_plt_entry(unsigned char* pov,
|
| -+ Arm_address got_address,
|
| -+ Arm_address plt_address,
|
| -+ unsigned int got_offset,
|
| -+ unsigned int plt_offset);
|
| -+
|
| -+ private:
|
| -+ // Template for subsequent PLT entries.
|
| -+ static const uint32_t plt_entry[3];
|
| -+};
|
| -
|
| - template<bool big_endian>
|
| --const uint32_t Output_data_plt_arm_standard<big_endian>::plt_entry[3] =
|
| -+const uint32_t Output_data_plt_arm_short<big_endian>::plt_entry[3] =
|
| - {
|
| - 0xe28fc600, // add ip, pc, #0xNN00000
|
| - 0xe28cca00, // add ip, ip, #0xNN000
|
| -@@ -7452,7 +7473,7 @@ const uint32_t Output_data_plt_arm_standard<big_endian>::plt_entry[3] =
|
| -
|
| - template<bool big_endian>
|
| - void
|
| --Output_data_plt_arm_standard<big_endian>::do_fill_plt_entry(
|
| -+Output_data_plt_arm_short<big_endian>::do_fill_plt_entry(
|
| - unsigned char* pov,
|
| - Arm_address got_address,
|
| - Arm_address plt_address,
|
| -@@ -7461,8 +7482,9 @@ Output_data_plt_arm_standard<big_endian>::do_fill_plt_entry(
|
| - {
|
| - int32_t offset = ((got_address + got_offset)
|
| - - (plt_address + plt_offset + 8));
|
| -+ if (offset < 0 || offset > 0x0fffffff)
|
| -+ gold_error(_("PLT offset too large, try linking with --long-plt"));
|
| -
|
| -- gold_assert(offset >= 0 && offset < 0x0fffffff);
|
| - uint32_t plt_insn0 = plt_entry[0] | ((offset >> 20) & 0xff);
|
| - elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0);
|
| - uint32_t plt_insn1 = plt_entry[1] | ((offset >> 12) & 0xff);
|
| -@@ -7471,6 +7493,66 @@ Output_data_plt_arm_standard<big_endian>::do_fill_plt_entry(
|
| - elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2);
|
| - }
|
| -
|
| -+// This class generates long (16-byte) entries, for arbitrary displacements.
|
| -+
|
| -+template<bool big_endian>
|
| -+class Output_data_plt_arm_long : public Output_data_plt_arm_standard<big_endian>
|
| -+{
|
| -+ public:
|
| -+ Output_data_plt_arm_long(Layout* layout,
|
| -+ Output_data_space* got_plt)
|
| -+ : Output_data_plt_arm_standard<big_endian>(layout, got_plt)
|
| -+ { }
|
| -+
|
| -+ protected:
|
| -+ // Return the size of a PLT entry.
|
| -+ virtual unsigned int
|
| -+ do_get_plt_entry_size() const
|
| -+ { return sizeof(plt_entry); }
|
| -+
|
| -+ virtual void
|
| -+ do_fill_plt_entry(unsigned char* pov,
|
| -+ Arm_address got_address,
|
| -+ Arm_address plt_address,
|
| -+ unsigned int got_offset,
|
| -+ unsigned int plt_offset);
|
| -+
|
| -+ private:
|
| -+ // Template for subsequent PLT entries.
|
| -+ static const uint32_t plt_entry[4];
|
| -+};
|
| -+
|
| -+template<bool big_endian>
|
| -+const uint32_t Output_data_plt_arm_long<big_endian>::plt_entry[4] =
|
| -+{
|
| -+ 0xe28fc200, // add ip, pc, #0xN0000000
|
| -+ 0xe28cc600, // add ip, ip, #0xNN00000
|
| -+ 0xe28cca00, // add ip, ip, #0xNN000
|
| -+ 0xe5bcf000, // ldr pc, [ip, #0xNNN]!
|
| -+};
|
| -+
|
| -+template<bool big_endian>
|
| -+void
|
| -+Output_data_plt_arm_long<big_endian>::do_fill_plt_entry(
|
| -+ unsigned char* pov,
|
| -+ Arm_address got_address,
|
| -+ Arm_address plt_address,
|
| -+ unsigned int got_offset,
|
| -+ unsigned int plt_offset)
|
| -+{
|
| -+ int32_t offset = ((got_address + got_offset)
|
| -+ - (plt_address + plt_offset + 8));
|
| -+
|
| -+ uint32_t plt_insn0 = plt_entry[0] | (offset >> 28);
|
| -+ elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0);
|
| -+ uint32_t plt_insn1 = plt_entry[1] | ((offset >> 20) & 0xff);
|
| -+ elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1);
|
| -+ uint32_t plt_insn2 = plt_entry[2] | ((offset >> 12) & 0xff);
|
| -+ elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2);
|
| -+ uint32_t plt_insn3 = plt_entry[3] | (offset & 0xfff);
|
| -+ elfcpp::Swap<32, big_endian>::writeval(pov + 12, plt_insn3);
|
| -+}
|
| -+
|
| - // Write out the PLT. This uses the hand-coded instructions above,
|
| - // and adjusts them as needed. This is all specified by the arm ELF
|
| - // Processor Supplement.
|
| -diff --git a/gold/options.h b/gold/options.h
|
| -index cf3b705..5bd93b1e 100644
|
| ---- a/gold/options.h
|
| -+++ b/gold/options.h
|
| -@@ -826,6 +826,10 @@ class General_options
|
| - "veneer"),
|
| - NULL);
|
| -
|
| -+ DEFINE_bool(long_plt, options::TWO_DASHES, '\0', false,
|
| -+ N_("(ARM only) Generate long PLT entries"),
|
| -+ N_("(ARM only) Do not generate long PLT entries"));
|
| -+
|
| - DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false,
|
| - N_("Ignored"), NULL);
|
| -
|
|
|