Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(981)

Side by Side Diff: third_party/binutils/long-plt.patch

Issue 1550453002: Revert of Gold: Patch linker to implement --long-plt flag. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/binutils/build-all.sh ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 commit ee8713f5cfc38be0e92d78f2afbc77d701ef189d
2 Author: Peter Collingbourne <pcc@google.com>
3 Date: Thu Dec 17 16:50:35 2015 -0800
4
5 Implement --long-plt flag (ARM only).
6
7 gold/
8 PR gold/18780
9 * arm.cc (Target_arm::do_make_data_plt): Choose PLT generator based
10 on value of --long-plt flag.
11 (Output_data_plt_arm_standard::do_get_plt_entry_size): Moved to
12 Output_data_plt_arm_short.
13 (Output_data_plt_arm_standard::do_fill_plt_entry): Likewise.
14 (Output_data_plt_arm_standard::plt_entry): Likewise.
15 (Output_data_plt_arm_standard::do_fill_first_plt_entry): Fix
16 variable reference.
17 (Output_data_plt_arm_short): New class.
18 (Output_data_plt_arm_short::do_fill_plt_entry): Error out on too large
19 PLT offsets instead of asserting.
20 (Output_data_plt_arm_long): New class.
21 * options.h (General_options): Define --long-plt flag.
22
23 diff --git a/gold/arm.cc b/gold/arm.cc
24 index 6c472bb..a10d785 100644
25 --- a/gold/arm.cc
26 +++ b/gold/arm.cc
27 @@ -62,7 +62,10 @@ template<bool big_endian>
28 class Output_data_plt_arm;
29
30 template<bool big_endian>
31 -class Output_data_plt_arm_standard;
32 +class Output_data_plt_arm_short;
33 +
34 +template<bool big_endian>
35 +class Output_data_plt_arm_long;
36
37 template<bool big_endian>
38 class Stub_table;
39 @@ -2532,7 +2535,12 @@ class Target_arm : public Sized_target<32, big_endian>
40 virtual Output_data_plt_arm<big_endian>*
41 do_make_data_plt(Layout* layout, Output_data_space* got_plt)
42 {
43 - return new Output_data_plt_arm_standard<big_endian>(layout, got_plt);
44 + if (parameters->options().long_plt())
45 + return new Output_data_plt_arm_long<big_endian>(
46 + layout, got_plt);
47 + else
48 + return new Output_data_plt_arm_short<big_endian>(
49 + layout, got_plt);
50 }
51
52 private:
53 @@ -7382,29 +7390,14 @@ class Output_data_plt_arm_standard : public Output_data_ plt_arm<big_endian>
54 do_first_plt_entry_offset() const
55 { return sizeof(first_plt_entry); }
56
57 - // Return the size of a PLT entry.
58 - virtual unsigned int
59 - do_get_plt_entry_size() const
60 - { return sizeof(plt_entry); }
61 -
62 virtual void
63 do_fill_first_plt_entry(unsigned char* pov,
64 Arm_address got_address,
65 Arm_address plt_address);
66
67 - virtual void
68 - do_fill_plt_entry(unsigned char* pov,
69 - Arm_address got_address,
70 - Arm_address plt_address,
71 - unsigned int got_offset,
72 - unsigned int plt_offset);
73 -
74 private:
75 // Template for the first PLT entry.
76 static const uint32_t first_plt_entry[5];
77 -
78 - // Template for subsequent PLT entries.
79 - static const uint32_t plt_entry[3];
80 };
81
82 // ARM PLTs.
83 @@ -7432,7 +7425,7 @@ Output_data_plt_arm_standard<big_endian>::do_fill_first_pl t_entry(
84 {
85 // Write first PLT entry. All but the last word are constants.
86 const size_t num_first_plt_words = (sizeof(first_plt_entry)
87 - / sizeof(plt_entry[0]));
88 + / sizeof(first_plt_entry[0]));
89 for (size_t i = 0; i < num_first_plt_words - 1; i++)
90 elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]);
91 // Last word in first PLT entry is &GOT[0] - .
92 @@ -7441,9 +7434,37 @@ Output_data_plt_arm_standard<big_endian>::do_fill_first_p lt_entry(
93 }
94
95 // Subsequent entries in the PLT.
96 +// This class generates short (12-byte) entries, for displacements up to 2^28.
97 +
98 +template<bool big_endian>
99 +class Output_data_plt_arm_short : public Output_data_plt_arm_standard<big_endia n>
100 +{
101 + public:
102 + Output_data_plt_arm_short(Layout* layout,
103 + Output_data_space* got_plt)
104 + : Output_data_plt_arm_standard<big_endian>(layout, got_plt)
105 + { }
106 +
107 + protected:
108 + // Return the size of a PLT entry.
109 + virtual unsigned int
110 + do_get_plt_entry_size() const
111 + { return sizeof(plt_entry); }
112 +
113 + virtual void
114 + do_fill_plt_entry(unsigned char* pov,
115 + Arm_address got_address,
116 + Arm_address plt_address,
117 + unsigned int got_offset,
118 + unsigned int plt_offset);
119 +
120 + private:
121 + // Template for subsequent PLT entries.
122 + static const uint32_t plt_entry[3];
123 +};
124
125 template<bool big_endian>
126 -const uint32_t Output_data_plt_arm_standard<big_endian>::plt_entry[3] =
127 +const uint32_t Output_data_plt_arm_short<big_endian>::plt_entry[3] =
128 {
129 0xe28fc600, // add ip, pc, #0xNN00000
130 0xe28cca00, // add ip, ip, #0xNN000
131 @@ -7452,7 +7473,7 @@ const uint32_t Output_data_plt_arm_standard<big_endian>::p lt_entry[3] =
132
133 template<bool big_endian>
134 void
135 -Output_data_plt_arm_standard<big_endian>::do_fill_plt_entry(
136 +Output_data_plt_arm_short<big_endian>::do_fill_plt_entry(
137 unsigned char* pov,
138 Arm_address got_address,
139 Arm_address plt_address,
140 @@ -7461,8 +7482,9 @@ Output_data_plt_arm_standard<big_endian>::do_fill_plt_entr y(
141 {
142 int32_t offset = ((got_address + got_offset)
143 - (plt_address + plt_offset + 8));
144 + if (offset < 0 || offset > 0x0fffffff)
145 + gold_error(_("PLT offset too large, try linking with --long-plt"));
146
147 - gold_assert(offset >= 0 && offset < 0x0fffffff);
148 uint32_t plt_insn0 = plt_entry[0] | ((offset >> 20) & 0xff);
149 elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0);
150 uint32_t plt_insn1 = plt_entry[1] | ((offset >> 12) & 0xff);
151 @@ -7471,6 +7493,66 @@ Output_data_plt_arm_standard<big_endian>::do_fill_plt_ent ry(
152 elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2);
153 }
154
155 +// This class generates long (16-byte) entries, for arbitrary displacements.
156 +
157 +template<bool big_endian>
158 +class Output_data_plt_arm_long : public Output_data_plt_arm_standard<big_endian >
159 +{
160 + public:
161 + Output_data_plt_arm_long(Layout* layout,
162 + Output_data_space* got_plt)
163 + : Output_data_plt_arm_standard<big_endian>(layout, got_plt)
164 + { }
165 +
166 + protected:
167 + // Return the size of a PLT entry.
168 + virtual unsigned int
169 + do_get_plt_entry_size() const
170 + { return sizeof(plt_entry); }
171 +
172 + virtual void
173 + do_fill_plt_entry(unsigned char* pov,
174 + Arm_address got_address,
175 + Arm_address plt_address,
176 + unsigned int got_offset,
177 + unsigned int plt_offset);
178 +
179 + private:
180 + // Template for subsequent PLT entries.
181 + static const uint32_t plt_entry[4];
182 +};
183 +
184 +template<bool big_endian>
185 +const uint32_t Output_data_plt_arm_long<big_endian>::plt_entry[4] =
186 +{
187 + 0xe28fc200, // add ip, pc, #0xN0000000
188 + 0xe28cc600, // add ip, ip, #0xNN00000
189 + 0xe28cca00, // add ip, ip, #0xNN000
190 + 0xe5bcf000, // ldr pc, [ip, #0xNNN]!
191 +};
192 +
193 +template<bool big_endian>
194 +void
195 +Output_data_plt_arm_long<big_endian>::do_fill_plt_entry(
196 + unsigned char* pov,
197 + Arm_address got_address,
198 + Arm_address plt_address,
199 + unsigned int got_offset,
200 + unsigned int plt_offset)
201 +{
202 + int32_t offset = ((got_address + got_offset)
203 + - (plt_address + plt_offset + 8));
204 +
205 + uint32_t plt_insn0 = plt_entry[0] | (offset >> 28);
206 + elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0);
207 + uint32_t plt_insn1 = plt_entry[1] | ((offset >> 20) & 0xff);
208 + elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1);
209 + uint32_t plt_insn2 = plt_entry[2] | ((offset >> 12) & 0xff);
210 + elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2);
211 + uint32_t plt_insn3 = plt_entry[3] | (offset & 0xfff);
212 + elfcpp::Swap<32, big_endian>::writeval(pov + 12, plt_insn3);
213 +}
214 +
215 // Write out the PLT. This uses the hand-coded instructions above,
216 // and adjusts them as needed. This is all specified by the arm ELF
217 // Processor Supplement.
218 diff --git a/gold/options.h b/gold/options.h
219 index cf3b705..5bd93b1e 100644
220 --- a/gold/options.h
221 +++ b/gold/options.h
222 @@ -826,6 +826,10 @@ class General_options
223 "veneer"),
224 NULL);
225
226 + DEFINE_bool(long_plt, options::TWO_DASHES, '\0', false,
227 + N_("(ARM only) Generate long PLT entries"),
228 + N_("(ARM only) Do not generate long PLT entries"));
229 +
230 DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false,
231 N_("Ignored"), NULL);
232
OLDNEW
« no previous file with comments | « third_party/binutils/build-all.sh ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698