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); |
- |