elf32-microblaze.c revision 1.1.1.1.8.1 1 1.1 christos /* Xilinx MicroBlaze-specific support for 32-bit ELF
2 1.1 christos
3 1.1.1.1.8.1 tls Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of BFD, the Binary File Descriptor library.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; if not, write to the
19 1.1 christos Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 1.1 christos Boston, MA 02110-1301, USA. */
21 1.1 christos
22 1.1 christos
23 1.1 christos int dbg = 0;
24 1.1 christos
25 1.1 christos #include "sysdep.h"
26 1.1.1.1.8.1 tls #include "bfd.h"
27 1.1 christos #include "bfdlink.h"
28 1.1 christos #include "libbfd.h"
29 1.1 christos #include "elf-bfd.h"
30 1.1 christos #include "elf/microblaze.h"
31 1.1 christos #include <assert.h>
32 1.1 christos
33 1.1 christos #define USE_RELA /* Only USE_REL is actually significant, but this is
34 1.1 christos here are a reminder... */
35 1.1 christos #define INST_WORD_SIZE 4
36 1.1 christos
37 1.1 christos static int ro_small_data_pointer = 0;
38 1.1 christos static int rw_small_data_pointer = 0;
39 1.1 christos
40 1.1 christos static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
41 1.1 christos
42 1.1 christos static reloc_howto_type microblaze_elf_howto_raw[] =
43 1.1 christos {
44 1.1 christos /* This reloc does nothing. */
45 1.1 christos HOWTO (R_MICROBLAZE_NONE, /* Type. */
46 1.1 christos 0, /* Rightshift. */
47 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
48 1.1 christos 32, /* Bitsize. */
49 1.1 christos FALSE, /* PC_relative. */
50 1.1 christos 0, /* Bitpos. */
51 1.1 christos complain_overflow_bitfield, /* Complain on overflow. */
52 1.1 christos NULL, /* Special Function. */
53 1.1 christos "R_MICROBLAZE_NONE", /* Name. */
54 1.1 christos FALSE, /* Partial Inplace. */
55 1.1 christos 0, /* Source Mask. */
56 1.1 christos 0, /* Dest Mask. */
57 1.1 christos FALSE), /* PC relative offset? */
58 1.1 christos
59 1.1 christos /* A standard 32 bit relocation. */
60 1.1 christos HOWTO (R_MICROBLAZE_32, /* Type. */
61 1.1 christos 0, /* Rightshift. */
62 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
63 1.1 christos 32, /* Bitsize. */
64 1.1 christos FALSE, /* PC_relative. */
65 1.1 christos 0, /* Bitpos. */
66 1.1 christos complain_overflow_bitfield, /* Complain on overflow. */
67 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
68 1.1 christos "R_MICROBLAZE_32", /* Name. */
69 1.1 christos FALSE, /* Partial Inplace. */
70 1.1 christos 0, /* Source Mask. */
71 1.1 christos 0xffffffff, /* Dest Mask. */
72 1.1 christos FALSE), /* PC relative offset? */
73 1.1 christos
74 1.1 christos /* A standard PCREL 32 bit relocation. */
75 1.1 christos HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */
76 1.1 christos 0, /* Rightshift. */
77 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
78 1.1 christos 32, /* Bitsize. */
79 1.1 christos TRUE, /* PC_relative. */
80 1.1 christos 0, /* Bitpos. */
81 1.1 christos complain_overflow_bitfield, /* Complain on overflow. */
82 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
83 1.1 christos "R_MICROBLAZE_32_PCREL", /* Name. */
84 1.1 christos TRUE, /* Partial Inplace. */
85 1.1 christos 0, /* Source Mask. */
86 1.1 christos 0xffffffff, /* Dest Mask. */
87 1.1 christos TRUE), /* PC relative offset? */
88 1.1 christos
89 1.1 christos /* A 64 bit PCREL relocation. Table-entry not really used. */
90 1.1 christos HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */
91 1.1 christos 0, /* Rightshift. */
92 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
93 1.1 christos 16, /* Bitsize. */
94 1.1 christos TRUE, /* PC_relative. */
95 1.1 christos 0, /* Bitpos. */
96 1.1 christos complain_overflow_dont, /* Complain on overflow. */
97 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
98 1.1 christos "R_MICROBLAZE_64_PCREL", /* Name. */
99 1.1 christos FALSE, /* Partial Inplace. */
100 1.1 christos 0, /* Source Mask. */
101 1.1 christos 0x0000ffff, /* Dest Mask. */
102 1.1 christos TRUE), /* PC relative offset? */
103 1.1 christos
104 1.1 christos /* The low half of a PCREL 32 bit relocation. */
105 1.1 christos HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */
106 1.1 christos 0, /* Rightshift. */
107 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
108 1.1 christos 16, /* Bitsize. */
109 1.1 christos TRUE, /* PC_relative. */
110 1.1 christos 0, /* Bitpos. */
111 1.1 christos complain_overflow_signed, /* Complain on overflow. */
112 1.1 christos bfd_elf_generic_reloc, /* Special Function. */
113 1.1 christos "R_MICROBLAZE_32_PCREL_LO", /* Name. */
114 1.1 christos FALSE, /* Partial Inplace. */
115 1.1 christos 0, /* Source Mask. */
116 1.1 christos 0x0000ffff, /* Dest Mask. */
117 1.1 christos TRUE), /* PC relative offset? */
118 1.1 christos
119 1.1 christos /* A 64 bit relocation. Table entry not really used. */
120 1.1 christos HOWTO (R_MICROBLAZE_64, /* Type. */
121 1.1 christos 0, /* Rightshift. */
122 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
123 1.1 christos 16, /* Bitsize. */
124 1.1 christos FALSE, /* PC_relative. */
125 1.1 christos 0, /* Bitpos. */
126 1.1 christos complain_overflow_dont, /* Complain on overflow. */
127 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
128 1.1 christos "R_MICROBLAZE_64", /* Name. */
129 1.1 christos FALSE, /* Partial Inplace. */
130 1.1 christos 0, /* Source Mask. */
131 1.1 christos 0x0000ffff, /* Dest Mask. */
132 1.1 christos FALSE), /* PC relative offset? */
133 1.1 christos
134 1.1 christos /* The low half of a 32 bit relocation. */
135 1.1 christos HOWTO (R_MICROBLAZE_32_LO, /* Type. */
136 1.1 christos 0, /* Rightshift. */
137 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
138 1.1 christos 16, /* Bitsize. */
139 1.1 christos FALSE, /* PC_relative. */
140 1.1 christos 0, /* Bitpos. */
141 1.1 christos complain_overflow_signed, /* Complain on overflow. */
142 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
143 1.1 christos "R_MICROBLAZE_32_LO", /* Name. */
144 1.1 christos FALSE, /* Partial Inplace. */
145 1.1 christos 0, /* Source Mask. */
146 1.1 christos 0x0000ffff, /* Dest Mask. */
147 1.1 christos FALSE), /* PC relative offset? */
148 1.1 christos
149 1.1 christos /* Read-only small data section relocation. */
150 1.1 christos HOWTO (R_MICROBLAZE_SRO32, /* Type. */
151 1.1 christos 0, /* Rightshift. */
152 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
153 1.1 christos 16, /* Bitsize. */
154 1.1 christos FALSE, /* PC_relative. */
155 1.1 christos 0, /* Bitpos. */
156 1.1 christos complain_overflow_bitfield, /* Complain on overflow. */
157 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
158 1.1 christos "R_MICROBLAZE_SRO32", /* Name. */
159 1.1 christos FALSE, /* Partial Inplace. */
160 1.1 christos 0, /* Source Mask. */
161 1.1 christos 0x0000ffff, /* Dest Mask. */
162 1.1 christos FALSE), /* PC relative offset? */
163 1.1 christos
164 1.1 christos /* Read-write small data area relocation. */
165 1.1 christos HOWTO (R_MICROBLAZE_SRW32, /* Type. */
166 1.1 christos 0, /* Rightshift. */
167 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
168 1.1 christos 16, /* Bitsize. */
169 1.1 christos FALSE, /* PC_relative. */
170 1.1 christos 0, /* Bitpos. */
171 1.1 christos complain_overflow_bitfield, /* Complain on overflow. */
172 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
173 1.1 christos "R_MICROBLAZE_SRW32", /* Name. */
174 1.1 christos FALSE, /* Partial Inplace. */
175 1.1 christos 0, /* Source Mask. */
176 1.1 christos 0x0000ffff, /* Dest Mask. */
177 1.1 christos FALSE), /* PC relative offset? */
178 1.1 christos
179 1.1 christos /* This reloc does nothing. Used for relaxation. */
180 1.1 christos HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
181 1.1 christos 0, /* Rightshift. */
182 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
183 1.1 christos 32, /* Bitsize. */
184 1.1 christos TRUE, /* PC_relative. */
185 1.1 christos 0, /* Bitpos. */
186 1.1 christos complain_overflow_bitfield, /* Complain on overflow. */
187 1.1 christos NULL, /* Special Function. */
188 1.1 christos "R_MICROBLAZE_64_NONE",/* Name. */
189 1.1 christos FALSE, /* Partial Inplace. */
190 1.1 christos 0, /* Source Mask. */
191 1.1 christos 0, /* Dest Mask. */
192 1.1 christos FALSE), /* PC relative offset? */
193 1.1 christos
194 1.1 christos /* Symbol Op Symbol relocation. */
195 1.1 christos HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */
196 1.1 christos 0, /* Rightshift. */
197 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
198 1.1 christos 32, /* Bitsize. */
199 1.1 christos FALSE, /* PC_relative. */
200 1.1 christos 0, /* Bitpos. */
201 1.1 christos complain_overflow_bitfield, /* Complain on overflow. */
202 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
203 1.1 christos "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
204 1.1 christos FALSE, /* Partial Inplace. */
205 1.1 christos 0, /* Source Mask. */
206 1.1 christos 0xffffffff, /* Dest Mask. */
207 1.1 christos FALSE), /* PC relative offset? */
208 1.1 christos
209 1.1 christos /* GNU extension to record C++ vtable hierarchy. */
210 1.1 christos HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */
211 1.1 christos 0, /* Rightshift. */
212 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
213 1.1 christos 0, /* Bitsize. */
214 1.1 christos FALSE, /* PC_relative. */
215 1.1 christos 0, /* Bitpos. */
216 1.1 christos complain_overflow_dont,/* Complain on overflow. */
217 1.1 christos NULL, /* Special Function. */
218 1.1 christos "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
219 1.1 christos FALSE, /* Partial Inplace. */
220 1.1 christos 0, /* Source Mask. */
221 1.1 christos 0, /* Dest Mask. */
222 1.1 christos FALSE), /* PC relative offset? */
223 1.1 christos
224 1.1 christos /* GNU extension to record C++ vtable member usage. */
225 1.1 christos HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */
226 1.1 christos 0, /* Rightshift. */
227 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
228 1.1 christos 0, /* Bitsize. */
229 1.1 christos FALSE, /* PC_relative. */
230 1.1 christos 0, /* Bitpos. */
231 1.1 christos complain_overflow_dont,/* Complain on overflow. */
232 1.1 christos _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */
233 1.1 christos "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
234 1.1 christos FALSE, /* Partial Inplace. */
235 1.1 christos 0, /* Source Mask. */
236 1.1 christos 0, /* Dest Mask. */
237 1.1 christos FALSE), /* PC relative offset? */
238 1.1 christos
239 1.1 christos /* A 64 bit GOTPC relocation. Table-entry not really used. */
240 1.1 christos HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */
241 1.1 christos 0, /* Rightshift. */
242 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
243 1.1 christos 16, /* Bitsize. */
244 1.1 christos TRUE, /* PC_relative. */
245 1.1 christos 0, /* Bitpos. */
246 1.1 christos complain_overflow_dont, /* Complain on overflow. */
247 1.1 christos bfd_elf_generic_reloc, /* Special Function. */
248 1.1 christos "R_MICROBLAZE_GOTPC_64", /* Name. */
249 1.1 christos FALSE, /* Partial Inplace. */
250 1.1 christos 0, /* Source Mask. */
251 1.1 christos 0x0000ffff, /* Dest Mask. */
252 1.1 christos TRUE), /* PC relative offset? */
253 1.1 christos
254 1.1 christos /* A 64 bit GOT relocation. Table-entry not really used. */
255 1.1 christos HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
256 1.1 christos 0, /* Rightshift. */
257 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
258 1.1 christos 16, /* Bitsize. */
259 1.1 christos FALSE, /* PC_relative. */
260 1.1 christos 0, /* Bitpos. */
261 1.1 christos complain_overflow_dont, /* Complain on overflow. */
262 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
263 1.1 christos "R_MICROBLAZE_GOT_64",/* Name. */
264 1.1 christos FALSE, /* Partial Inplace. */
265 1.1 christos 0, /* Source Mask. */
266 1.1 christos 0x0000ffff, /* Dest Mask. */
267 1.1 christos FALSE), /* PC relative offset? */
268 1.1 christos
269 1.1 christos /* A 64 bit PLT relocation. Table-entry not really used. */
270 1.1 christos HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
271 1.1 christos 0, /* Rightshift. */
272 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
273 1.1 christos 16, /* Bitsize. */
274 1.1 christos TRUE, /* PC_relative. */
275 1.1 christos 0, /* Bitpos. */
276 1.1 christos complain_overflow_dont, /* Complain on overflow. */
277 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
278 1.1 christos "R_MICROBLAZE_PLT_64",/* Name. */
279 1.1 christos FALSE, /* Partial Inplace. */
280 1.1 christos 0, /* Source Mask. */
281 1.1 christos 0x0000ffff, /* Dest Mask. */
282 1.1 christos TRUE), /* PC relative offset? */
283 1.1 christos
284 1.1 christos /* Table-entry not really used. */
285 1.1 christos HOWTO (R_MICROBLAZE_REL, /* Type. */
286 1.1 christos 0, /* Rightshift. */
287 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
288 1.1 christos 16, /* Bitsize. */
289 1.1 christos TRUE, /* PC_relative. */
290 1.1 christos 0, /* Bitpos. */
291 1.1 christos complain_overflow_dont, /* Complain on overflow. */
292 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
293 1.1 christos "R_MICROBLAZE_REL", /* Name. */
294 1.1 christos FALSE, /* Partial Inplace. */
295 1.1 christos 0, /* Source Mask. */
296 1.1 christos 0x0000ffff, /* Dest Mask. */
297 1.1 christos TRUE), /* PC relative offset? */
298 1.1 christos
299 1.1 christos /* Table-entry not really used. */
300 1.1 christos HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
301 1.1 christos 0, /* Rightshift. */
302 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
303 1.1 christos 16, /* Bitsize. */
304 1.1 christos TRUE, /* PC_relative. */
305 1.1 christos 0, /* Bitpos. */
306 1.1 christos complain_overflow_dont, /* Complain on overflow. */
307 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
308 1.1 christos "R_MICROBLAZE_JUMP_SLOT", /* Name. */
309 1.1 christos FALSE, /* Partial Inplace. */
310 1.1 christos 0, /* Source Mask. */
311 1.1 christos 0x0000ffff, /* Dest Mask. */
312 1.1 christos TRUE), /* PC relative offset? */
313 1.1 christos
314 1.1 christos /* Table-entry not really used. */
315 1.1 christos HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
316 1.1 christos 0, /* Rightshift. */
317 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
318 1.1 christos 16, /* Bitsize. */
319 1.1 christos TRUE, /* PC_relative. */
320 1.1 christos 0, /* Bitpos. */
321 1.1 christos complain_overflow_dont, /* Complain on overflow. */
322 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
323 1.1 christos "R_MICROBLAZE_GLOB_DAT", /* Name. */
324 1.1 christos FALSE, /* Partial Inplace. */
325 1.1 christos 0, /* Source Mask. */
326 1.1 christos 0x0000ffff, /* Dest Mask. */
327 1.1 christos TRUE), /* PC relative offset? */
328 1.1 christos
329 1.1 christos /* A 64 bit GOT relative relocation. Table-entry not really used. */
330 1.1 christos HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */
331 1.1 christos 0, /* Rightshift. */
332 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
333 1.1 christos 16, /* Bitsize. */
334 1.1 christos FALSE, /* PC_relative. */
335 1.1 christos 0, /* Bitpos. */
336 1.1 christos complain_overflow_dont, /* Complain on overflow. */
337 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
338 1.1 christos "R_MICROBLAZE_GOTOFF_64", /* Name. */
339 1.1 christos FALSE, /* Partial Inplace. */
340 1.1 christos 0, /* Source Mask. */
341 1.1 christos 0x0000ffff, /* Dest Mask. */
342 1.1 christos FALSE), /* PC relative offset? */
343 1.1 christos
344 1.1 christos /* A 32 bit GOT relative relocation. Table-entry not really used. */
345 1.1 christos HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */
346 1.1 christos 0, /* Rightshift. */
347 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
348 1.1 christos 16, /* Bitsize. */
349 1.1 christos FALSE, /* PC_relative. */
350 1.1 christos 0, /* Bitpos. */
351 1.1 christos complain_overflow_dont, /* Complain on overflow. */
352 1.1 christos bfd_elf_generic_reloc, /* Special Function. */
353 1.1 christos "R_MICROBLAZE_GOTOFF_32", /* Name. */
354 1.1 christos FALSE, /* Partial Inplace. */
355 1.1 christos 0, /* Source Mask. */
356 1.1 christos 0x0000ffff, /* Dest Mask. */
357 1.1 christos FALSE), /* PC relative offset? */
358 1.1 christos
359 1.1 christos /* COPY relocation. Table-entry not really used. */
360 1.1 christos HOWTO (R_MICROBLAZE_COPY, /* Type. */
361 1.1 christos 0, /* Rightshift. */
362 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
363 1.1 christos 16, /* Bitsize. */
364 1.1 christos FALSE, /* PC_relative. */
365 1.1 christos 0, /* Bitpos. */
366 1.1 christos complain_overflow_dont, /* Complain on overflow. */
367 1.1 christos bfd_elf_generic_reloc,/* Special Function. */
368 1.1 christos "R_MICROBLAZE_COPY", /* Name. */
369 1.1 christos FALSE, /* Partial Inplace. */
370 1.1 christos 0, /* Source Mask. */
371 1.1 christos 0x0000ffff, /* Dest Mask. */
372 1.1 christos FALSE), /* PC relative offset? */
373 1.1.1.1.8.1 tls
374 1.1.1.1.8.1 tls /* Marker relocs for TLS. */
375 1.1.1.1.8.1 tls HOWTO (R_MICROBLAZE_TLS,
376 1.1.1.1.8.1 tls 0, /* rightshift */
377 1.1.1.1.8.1 tls 2, /* size (0 = byte, 1 = short, 2 = long) */
378 1.1.1.1.8.1 tls 32, /* bitsize */
379 1.1.1.1.8.1 tls FALSE, /* pc_relative */
380 1.1.1.1.8.1 tls 0, /* bitpos */
381 1.1.1.1.8.1 tls complain_overflow_dont, /* complain_on_overflow */
382 1.1.1.1.8.1 tls bfd_elf_generic_reloc, /* special_function */
383 1.1.1.1.8.1 tls "R_MICROBLAZE_TLS", /* name */
384 1.1.1.1.8.1 tls FALSE, /* partial_inplace */
385 1.1.1.1.8.1 tls 0, /* src_mask */
386 1.1.1.1.8.1 tls 0x0000ffff, /* dst_mask */
387 1.1.1.1.8.1 tls FALSE), /* pcrel_offset */
388 1.1.1.1.8.1 tls
389 1.1.1.1.8.1 tls HOWTO (R_MICROBLAZE_TLSGD,
390 1.1.1.1.8.1 tls 0, /* rightshift */
391 1.1.1.1.8.1 tls 2, /* size (0 = byte, 1 = short, 2 = long) */
392 1.1.1.1.8.1 tls 32, /* bitsize */
393 1.1.1.1.8.1 tls FALSE, /* pc_relative */
394 1.1.1.1.8.1 tls 0, /* bitpos */
395 1.1.1.1.8.1 tls complain_overflow_dont, /* complain_on_overflow */
396 1.1.1.1.8.1 tls bfd_elf_generic_reloc, /* special_function */
397 1.1.1.1.8.1 tls "R_MICROBLAZE_TLSGD", /* name */
398 1.1.1.1.8.1 tls FALSE, /* partial_inplace */
399 1.1.1.1.8.1 tls 0, /* src_mask */
400 1.1.1.1.8.1 tls 0x0000ffff, /* dst_mask */
401 1.1.1.1.8.1 tls FALSE), /* pcrel_offset */
402 1.1.1.1.8.1 tls
403 1.1.1.1.8.1 tls HOWTO (R_MICROBLAZE_TLSLD,
404 1.1.1.1.8.1 tls 0, /* rightshift */
405 1.1.1.1.8.1 tls 2, /* size (0 = byte, 1 = short, 2 = long) */
406 1.1.1.1.8.1 tls 32, /* bitsize */
407 1.1.1.1.8.1 tls FALSE, /* pc_relative */
408 1.1.1.1.8.1 tls 0, /* bitpos */
409 1.1.1.1.8.1 tls complain_overflow_dont, /* complain_on_overflow */
410 1.1.1.1.8.1 tls bfd_elf_generic_reloc, /* special_function */
411 1.1.1.1.8.1 tls "R_MICROBLAZE_TLSLD", /* name */
412 1.1.1.1.8.1 tls FALSE, /* partial_inplace */
413 1.1.1.1.8.1 tls 0, /* src_mask */
414 1.1.1.1.8.1 tls 0x0000ffff, /* dst_mask */
415 1.1.1.1.8.1 tls FALSE), /* pcrel_offset */
416 1.1.1.1.8.1 tls
417 1.1.1.1.8.1 tls /* Computes the load module index of the load module that contains the
418 1.1.1.1.8.1 tls definition of its TLS sym. */
419 1.1.1.1.8.1 tls HOWTO (R_MICROBLAZE_TLSDTPMOD32,
420 1.1.1.1.8.1 tls 0, /* rightshift */
421 1.1.1.1.8.1 tls 2, /* size (0 = byte, 1 = short, 2 = long) */
422 1.1.1.1.8.1 tls 32, /* bitsize */
423 1.1.1.1.8.1 tls FALSE, /* pc_relative */
424 1.1.1.1.8.1 tls 0, /* bitpos */
425 1.1.1.1.8.1 tls complain_overflow_dont, /* complain_on_overflow */
426 1.1.1.1.8.1 tls bfd_elf_generic_reloc, /* special_function */
427 1.1.1.1.8.1 tls "R_MICROBLAZE_TLSDTPMOD32", /* name */
428 1.1.1.1.8.1 tls FALSE, /* partial_inplace */
429 1.1.1.1.8.1 tls 0, /* src_mask */
430 1.1.1.1.8.1 tls 0x0000ffff, /* dst_mask */
431 1.1.1.1.8.1 tls FALSE), /* pcrel_offset */
432 1.1.1.1.8.1 tls
433 1.1.1.1.8.1 tls /* Computes a dtv-relative displacement, the difference between the value
434 1.1.1.1.8.1 tls of sym+add and the base address of the thread-local storage block that
435 1.1.1.1.8.1 tls contains the definition of sym, minus 0x8000. Used for initializing GOT */
436 1.1.1.1.8.1 tls HOWTO (R_MICROBLAZE_TLSDTPREL32,
437 1.1.1.1.8.1 tls 0, /* rightshift */
438 1.1.1.1.8.1 tls 2, /* size (0 = byte, 1 = short, 2 = long) */
439 1.1.1.1.8.1 tls 32, /* bitsize */
440 1.1.1.1.8.1 tls FALSE, /* pc_relative */
441 1.1.1.1.8.1 tls 0, /* bitpos */
442 1.1.1.1.8.1 tls complain_overflow_dont, /* complain_on_overflow */
443 1.1.1.1.8.1 tls bfd_elf_generic_reloc, /* special_function */
444 1.1.1.1.8.1 tls "R_MICROBLAZE_TLSDTPREL32", /* name */
445 1.1.1.1.8.1 tls FALSE, /* partial_inplace */
446 1.1.1.1.8.1 tls 0, /* src_mask */
447 1.1.1.1.8.1 tls 0x0000ffff, /* dst_mask */
448 1.1.1.1.8.1 tls FALSE), /* pcrel_offset */
449 1.1.1.1.8.1 tls
450 1.1.1.1.8.1 tls /* Computes a dtv-relative displacement, the difference between the value
451 1.1.1.1.8.1 tls of sym+add and the base address of the thread-local storage block that
452 1.1.1.1.8.1 tls contains the definition of sym, minus 0x8000. */
453 1.1.1.1.8.1 tls HOWTO (R_MICROBLAZE_TLSDTPREL64,
454 1.1.1.1.8.1 tls 0, /* rightshift */
455 1.1.1.1.8.1 tls 2, /* size (0 = byte, 1 = short, 2 = long) */
456 1.1.1.1.8.1 tls 32, /* bitsize */
457 1.1.1.1.8.1 tls FALSE, /* pc_relative */
458 1.1.1.1.8.1 tls 0, /* bitpos */
459 1.1.1.1.8.1 tls complain_overflow_dont, /* complain_on_overflow */
460 1.1.1.1.8.1 tls bfd_elf_generic_reloc, /* special_function */
461 1.1.1.1.8.1 tls "R_MICROBLAZE_TLSDTPREL64", /* name */
462 1.1.1.1.8.1 tls FALSE, /* partial_inplace */
463 1.1.1.1.8.1 tls 0, /* src_mask */
464 1.1.1.1.8.1 tls 0x0000ffff, /* dst_mask */
465 1.1.1.1.8.1 tls FALSE), /* pcrel_offset */
466 1.1.1.1.8.1 tls
467 1.1.1.1.8.1 tls /* Computes a tp-relative displacement, the difference between the value of
468 1.1.1.1.8.1 tls sym+add and the value of the thread pointer (r13). */
469 1.1.1.1.8.1 tls HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
470 1.1.1.1.8.1 tls 0, /* rightshift */
471 1.1.1.1.8.1 tls 2, /* size (0 = byte, 1 = short, 2 = long) */
472 1.1.1.1.8.1 tls 32, /* bitsize */
473 1.1.1.1.8.1 tls FALSE, /* pc_relative */
474 1.1.1.1.8.1 tls 0, /* bitpos */
475 1.1.1.1.8.1 tls complain_overflow_dont, /* complain_on_overflow */
476 1.1.1.1.8.1 tls bfd_elf_generic_reloc, /* special_function */
477 1.1.1.1.8.1 tls "R_MICROBLAZE_TLSGOTTPREL32", /* name */
478 1.1.1.1.8.1 tls FALSE, /* partial_inplace */
479 1.1.1.1.8.1 tls 0, /* src_mask */
480 1.1.1.1.8.1 tls 0x0000ffff, /* dst_mask */
481 1.1.1.1.8.1 tls FALSE), /* pcrel_offset */
482 1.1.1.1.8.1 tls
483 1.1.1.1.8.1 tls /* Computes a tp-relative displacement, the difference between the value of
484 1.1.1.1.8.1 tls sym+add and the value of the thread pointer (r13). */
485 1.1.1.1.8.1 tls HOWTO (R_MICROBLAZE_TLSTPREL32,
486 1.1.1.1.8.1 tls 0, /* rightshift */
487 1.1.1.1.8.1 tls 2, /* size (0 = byte, 1 = short, 2 = long) */
488 1.1.1.1.8.1 tls 32, /* bitsize */
489 1.1.1.1.8.1 tls FALSE, /* pc_relative */
490 1.1.1.1.8.1 tls 0, /* bitpos */
491 1.1.1.1.8.1 tls complain_overflow_dont, /* complain_on_overflow */
492 1.1.1.1.8.1 tls bfd_elf_generic_reloc, /* special_function */
493 1.1.1.1.8.1 tls "R_MICROBLAZE_TLSTPREL32", /* name */
494 1.1.1.1.8.1 tls FALSE, /* partial_inplace */
495 1.1.1.1.8.1 tls 0, /* src_mask */
496 1.1.1.1.8.1 tls 0x0000ffff, /* dst_mask */
497 1.1.1.1.8.1 tls FALSE), /* pcrel_offset */
498 1.1.1.1.8.1 tls
499 1.1 christos };
500 1.1 christos
501 1.1 christos #ifndef NUM_ELEM
502 1.1 christos #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
503 1.1 christos #endif
504 1.1 christos
505 1.1 christos /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
507 1.1 christos
508 1.1 christos static void
509 1.1 christos microblaze_elf_howto_init (void)
510 1.1 christos {
511 1.1 christos unsigned int i;
512 1.1 christos
513 1.1 christos for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
514 1.1 christos {
515 1.1 christos unsigned int type;
516 1.1 christos
517 1.1 christos type = microblaze_elf_howto_raw[i].type;
518 1.1 christos
519 1.1 christos BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
520 1.1 christos
521 1.1 christos microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
522 1.1 christos }
523 1.1 christos }
524 1.1 christos
525 1.1 christos static reloc_howto_type *
527 1.1 christos microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
528 1.1 christos bfd_reloc_code_real_type code)
529 1.1 christos {
530 1.1 christos enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
531 1.1 christos
532 1.1 christos switch (code)
533 1.1 christos {
534 1.1 christos case BFD_RELOC_NONE:
535 1.1 christos microblaze_reloc = R_MICROBLAZE_NONE;
536 1.1 christos break;
537 1.1 christos case BFD_RELOC_MICROBLAZE_64_NONE:
538 1.1 christos microblaze_reloc = R_MICROBLAZE_64_NONE;
539 1.1 christos break;
540 1.1 christos case BFD_RELOC_32:
541 1.1 christos microblaze_reloc = R_MICROBLAZE_32;
542 1.1 christos break;
543 1.1 christos /* RVA is treated the same as 32 */
544 1.1 christos case BFD_RELOC_RVA:
545 1.1 christos microblaze_reloc = R_MICROBLAZE_32;
546 1.1 christos break;
547 1.1 christos case BFD_RELOC_32_PCREL:
548 1.1 christos microblaze_reloc = R_MICROBLAZE_32_PCREL;
549 1.1 christos break;
550 1.1 christos case BFD_RELOC_64_PCREL:
551 1.1 christos microblaze_reloc = R_MICROBLAZE_64_PCREL;
552 1.1 christos break;
553 1.1 christos case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
554 1.1 christos microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
555 1.1 christos break;
556 1.1 christos case BFD_RELOC_64:
557 1.1 christos microblaze_reloc = R_MICROBLAZE_64;
558 1.1 christos break;
559 1.1 christos case BFD_RELOC_MICROBLAZE_32_LO:
560 1.1 christos microblaze_reloc = R_MICROBLAZE_32_LO;
561 1.1 christos break;
562 1.1 christos case BFD_RELOC_MICROBLAZE_32_ROSDA:
563 1.1 christos microblaze_reloc = R_MICROBLAZE_SRO32;
564 1.1 christos break;
565 1.1 christos case BFD_RELOC_MICROBLAZE_32_RWSDA:
566 1.1 christos microblaze_reloc = R_MICROBLAZE_SRW32;
567 1.1 christos break;
568 1.1 christos case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
569 1.1 christos microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
570 1.1 christos break;
571 1.1 christos case BFD_RELOC_VTABLE_INHERIT:
572 1.1 christos microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
573 1.1 christos break;
574 1.1 christos case BFD_RELOC_VTABLE_ENTRY:
575 1.1 christos microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
576 1.1 christos break;
577 1.1 christos case BFD_RELOC_MICROBLAZE_64_GOTPC:
578 1.1 christos microblaze_reloc = R_MICROBLAZE_GOTPC_64;
579 1.1 christos break;
580 1.1 christos case BFD_RELOC_MICROBLAZE_64_GOT:
581 1.1 christos microblaze_reloc = R_MICROBLAZE_GOT_64;
582 1.1 christos break;
583 1.1 christos case BFD_RELOC_MICROBLAZE_64_PLT:
584 1.1 christos microblaze_reloc = R_MICROBLAZE_PLT_64;
585 1.1 christos break;
586 1.1 christos case BFD_RELOC_MICROBLAZE_64_GOTOFF:
587 1.1 christos microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
588 1.1 christos break;
589 1.1 christos case BFD_RELOC_MICROBLAZE_32_GOTOFF:
590 1.1.1.1.8.1 tls microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
591 1.1.1.1.8.1 tls break;
592 1.1.1.1.8.1 tls case BFD_RELOC_MICROBLAZE_64_TLSGD:
593 1.1.1.1.8.1 tls microblaze_reloc = R_MICROBLAZE_TLSGD;
594 1.1.1.1.8.1 tls break;
595 1.1.1.1.8.1 tls case BFD_RELOC_MICROBLAZE_64_TLSLD:
596 1.1.1.1.8.1 tls microblaze_reloc = R_MICROBLAZE_TLSLD;
597 1.1.1.1.8.1 tls break;
598 1.1.1.1.8.1 tls case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
599 1.1.1.1.8.1 tls microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
600 1.1.1.1.8.1 tls break;
601 1.1.1.1.8.1 tls case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
602 1.1.1.1.8.1 tls microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
603 1.1.1.1.8.1 tls break;
604 1.1.1.1.8.1 tls case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
605 1.1.1.1.8.1 tls microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
606 1.1.1.1.8.1 tls break;
607 1.1.1.1.8.1 tls case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
608 1.1.1.1.8.1 tls microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
609 1.1.1.1.8.1 tls break;
610 1.1.1.1.8.1 tls case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
611 1.1 christos microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
612 1.1 christos break;
613 1.1 christos case BFD_RELOC_MICROBLAZE_COPY:
614 1.1 christos microblaze_reloc = R_MICROBLAZE_COPY;
615 1.1 christos break;
616 1.1 christos default:
617 1.1 christos return (reloc_howto_type *) NULL;
618 1.1 christos }
619 1.1 christos
620 1.1 christos if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
621 1.1 christos /* Initialize howto table if needed. */
622 1.1 christos microblaze_elf_howto_init ();
623 1.1 christos
624 1.1 christos return microblaze_elf_howto_table [(int) microblaze_reloc];
625 1.1 christos };
626 1.1 christos
627 1.1 christos static reloc_howto_type *
628 1.1 christos microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
629 1.1 christos const char *r_name)
630 1.1 christos {
631 1.1 christos unsigned int i;
632 1.1 christos
633 1.1 christos for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
634 1.1 christos if (microblaze_elf_howto_raw[i].name != NULL
635 1.1 christos && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
636 1.1 christos return µblaze_elf_howto_raw[i];
637 1.1 christos
638 1.1 christos return NULL;
639 1.1 christos }
640 1.1 christos
641 1.1 christos /* Set the howto pointer for a RCE ELF reloc. */
642 1.1 christos
643 1.1 christos static void
644 1.1 christos microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
645 1.1 christos arelent * cache_ptr,
646 1.1 christos Elf_Internal_Rela * dst)
647 1.1 christos {
648 1.1 christos if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
649 1.1 christos /* Initialize howto table if needed. */
650 1.1 christos microblaze_elf_howto_init ();
651 1.1 christos
652 1.1 christos BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MICROBLAZE_max);
653 1.1 christos
654 1.1 christos cache_ptr->howto = microblaze_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
655 1.1 christos }
656 1.1 christos
657 1.1 christos /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
658 1.1 christos
659 1.1 christos static bfd_boolean
660 1.1 christos microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
661 1.1 christos {
662 1.1 christos if (name[0] == 'L' && name[1] == '.')
663 1.1 christos return TRUE;
664 1.1 christos
665 1.1 christos if (name[0] == '$' && name[1] == 'L')
666 1.1 christos return TRUE;
667 1.1 christos
668 1.1 christos /* With gcc, the labels go back to starting with '.', so we accept
669 1.1 christos the generic ELF local label syntax as well. */
670 1.1 christos return _bfd_elf_is_local_label_name (abfd, name);
671 1.1 christos }
672 1.1 christos
673 1.1 christos /* The microblaze linker (like many others) needs to keep track of
674 1.1 christos the number of relocs that it decides to copy as dynamic relocs in
675 1.1 christos check_relocs for each symbol. This is so that it can later discard
676 1.1 christos them if they are found to be unnecessary. We store the information
677 1.1 christos in a field extending the regular ELF linker hash table. */
678 1.1 christos
679 1.1 christos struct elf32_mb_dyn_relocs
680 1.1 christos {
681 1.1 christos struct elf32_mb_dyn_relocs *next;
682 1.1 christos
683 1.1 christos /* The input section of the reloc. */
684 1.1 christos asection *sec;
685 1.1 christos
686 1.1 christos /* Total number of relocs copied for the input section. */
687 1.1 christos bfd_size_type count;
688 1.1 christos
689 1.1 christos /* Number of pc-relative relocs copied for the input section. */
690 1.1 christos bfd_size_type pc_count;
691 1.1 christos };
692 1.1 christos
693 1.1 christos /* ELF linker hash entry. */
694 1.1 christos
695 1.1 christos struct elf32_mb_link_hash_entry
696 1.1 christos {
697 1.1 christos struct elf_link_hash_entry elf;
698 1.1 christos
699 1.1 christos /* Track dynamic relocs copied for this symbol. */
700 1.1.1.1.8.1 tls struct elf32_mb_dyn_relocs *dyn_relocs;
701 1.1.1.1.8.1 tls
702 1.1.1.1.8.1 tls /* TLS Reference Types for the symbol; Updated by check_relocs */
703 1.1.1.1.8.1 tls #define TLS_GD 1 /* GD reloc. */
704 1.1.1.1.8.1 tls #define TLS_LD 2 /* LD reloc. */
705 1.1.1.1.8.1 tls #define TLS_TPREL 4 /* TPREL reloc, => IE. */
706 1.1.1.1.8.1 tls #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
707 1.1.1.1.8.1 tls #define TLS_TLS 16 /* Any TLS reloc. */
708 1.1 christos unsigned char tls_mask;
709 1.1 christos
710 1.1.1.1.8.1 tls };
711 1.1.1.1.8.1 tls
712 1.1.1.1.8.1 tls #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
713 1.1.1.1.8.1 tls #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
714 1.1.1.1.8.1 tls #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
715 1.1 christos #define IS_TLS_NONE(x) (x == 0)
716 1.1 christos
717 1.1 christos #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
718 1.1 christos
719 1.1 christos /* ELF linker hash table. */
720 1.1 christos
721 1.1 christos struct elf32_mb_link_hash_table
722 1.1 christos {
723 1.1 christos struct elf_link_hash_table elf;
724 1.1 christos
725 1.1 christos /* Short-cuts to get to dynamic linker sections. */
726 1.1 christos asection *sgot;
727 1.1 christos asection *sgotplt;
728 1.1 christos asection *srelgot;
729 1.1 christos asection *splt;
730 1.1 christos asection *srelplt;
731 1.1 christos asection *sdynbss;
732 1.1 christos asection *srelbss;
733 1.1 christos
734 1.1.1.1.8.1 tls /* Small local sym to section mapping cache. */
735 1.1.1.1.8.1 tls struct sym_cache sym_sec;
736 1.1.1.1.8.1 tls
737 1.1.1.1.8.1 tls /* TLS Local Dynamic GOT Entry */
738 1.1.1.1.8.1 tls union {
739 1.1.1.1.8.1 tls bfd_signed_vma refcount;
740 1.1 christos bfd_vma offset;
741 1.1 christos } tlsld_got;
742 1.1.1.1.8.1 tls };
743 1.1.1.1.8.1 tls
744 1.1.1.1.8.1 tls /* Nonzero if this section has TLS related relocations. */
745 1.1 christos #define has_tls_reloc sec_flg0
746 1.1 christos
747 1.1 christos /* Get the ELF linker hash table from a link_info structure. */
748 1.1 christos
749 1.1 christos #define elf32_mb_hash_table(p) \
750 1.1 christos (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
751 1.1 christos == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL)
752 1.1 christos
753 1.1 christos /* Create an entry in a microblaze ELF linker hash table. */
754 1.1 christos
755 1.1 christos static struct bfd_hash_entry *
756 1.1 christos link_hash_newfunc (struct bfd_hash_entry *entry,
757 1.1 christos struct bfd_hash_table *table,
758 1.1 christos const char *string)
759 1.1 christos {
760 1.1 christos /* Allocate the structure if it has not already been allocated by a
761 1.1 christos subclass. */
762 1.1 christos if (entry == NULL)
763 1.1 christos {
764 1.1 christos entry = bfd_hash_allocate (table,
765 1.1 christos sizeof (struct elf32_mb_link_hash_entry));
766 1.1 christos if (entry == NULL)
767 1.1 christos return entry;
768 1.1 christos }
769 1.1 christos
770 1.1 christos /* Call the allocation method of the superclass. */
771 1.1 christos entry = _bfd_elf_link_hash_newfunc (entry, table, string);
772 1.1 christos if (entry != NULL)
773 1.1 christos {
774 1.1 christos struct elf32_mb_link_hash_entry *eh;
775 1.1 christos
776 1.1.1.1.8.1 tls eh = (struct elf32_mb_link_hash_entry *) entry;
777 1.1 christos eh->dyn_relocs = NULL;
778 1.1 christos eh->tls_mask = 0;
779 1.1 christos }
780 1.1 christos
781 1.1 christos return entry;
782 1.1 christos }
783 1.1 christos
784 1.1 christos /* Create a mb ELF linker hash table. */
785 1.1 christos
786 1.1 christos static struct bfd_link_hash_table *
787 1.1 christos microblaze_elf_link_hash_table_create (bfd *abfd)
788 1.1 christos {
789 1.1 christos struct elf32_mb_link_hash_table *ret;
790 1.1 christos bfd_size_type amt = sizeof (struct elf32_mb_link_hash_table);
791 1.1 christos
792 1.1 christos ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt);
793 1.1 christos if (ret == NULL)
794 1.1 christos return NULL;
795 1.1 christos
796 1.1 christos if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
797 1.1 christos sizeof (struct elf32_mb_link_hash_entry),
798 1.1 christos MICROBLAZE_ELF_DATA))
799 1.1 christos {
800 1.1 christos free (ret);
801 1.1 christos return NULL;
802 1.1 christos }
803 1.1 christos
804 1.1 christos return &ret->elf.root;
805 1.1 christos }
806 1.1 christos
807 1.1 christos /* Set the values of the small data pointers. */
809 1.1 christos
810 1.1 christos static void
811 1.1 christos microblaze_elf_final_sdp (struct bfd_link_info *info)
812 1.1 christos {
813 1.1 christos struct bfd_link_hash_entry *h;
814 1.1 christos
815 1.1 christos h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
816 1.1 christos if (h != (struct bfd_link_hash_entry *) NULL
817 1.1 christos && h->type == bfd_link_hash_defined)
818 1.1 christos ro_small_data_pointer = (h->u.def.value
819 1.1 christos + h->u.def.section->output_section->vma
820 1.1 christos + h->u.def.section->output_offset);
821 1.1 christos
822 1.1 christos h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
823 1.1 christos if (h != (struct bfd_link_hash_entry *) NULL
824 1.1 christos && h->type == bfd_link_hash_defined)
825 1.1 christos rw_small_data_pointer = (h->u.def.value
826 1.1 christos + h->u.def.section->output_section->vma
827 1.1.1.1.8.1 tls + h->u.def.section->output_offset);
828 1.1.1.1.8.1 tls }
829 1.1.1.1.8.1 tls
830 1.1.1.1.8.1 tls static bfd_vma
831 1.1.1.1.8.1 tls dtprel_base (struct bfd_link_info *info)
832 1.1.1.1.8.1 tls {
833 1.1.1.1.8.1 tls /* If tls_sec is NULL, we should have signalled an error already. */
834 1.1.1.1.8.1 tls if (elf_hash_table (info)->tls_sec == NULL)
835 1.1.1.1.8.1 tls return 0;
836 1.1.1.1.8.1 tls return elf_hash_table (info)->tls_sec->vma;
837 1.1.1.1.8.1 tls }
838 1.1.1.1.8.1 tls
839 1.1.1.1.8.1 tls /* The size of the thread control block. */
840 1.1.1.1.8.1 tls #define TCB_SIZE 8
841 1.1.1.1.8.1 tls
842 1.1.1.1.8.1 tls /* Output a simple dynamic relocation into SRELOC. */
843 1.1.1.1.8.1 tls
844 1.1.1.1.8.1 tls static void
845 1.1.1.1.8.1 tls microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
846 1.1.1.1.8.1 tls asection *sreloc,
847 1.1.1.1.8.1 tls unsigned long reloc_index,
848 1.1.1.1.8.1 tls unsigned long indx,
849 1.1.1.1.8.1 tls int r_type,
850 1.1.1.1.8.1 tls bfd_vma offset,
851 1.1.1.1.8.1 tls bfd_vma addend)
852 1.1.1.1.8.1 tls {
853 1.1.1.1.8.1 tls
854 1.1.1.1.8.1 tls Elf_Internal_Rela rel;
855 1.1.1.1.8.1 tls
856 1.1.1.1.8.1 tls rel.r_info = ELF32_R_INFO (indx, r_type);
857 1.1.1.1.8.1 tls rel.r_offset = offset;
858 1.1.1.1.8.1 tls rel.r_addend = addend;
859 1.1.1.1.8.1 tls
860 1.1.1.1.8.1 tls bfd_elf32_swap_reloca_out (output_bfd, &rel,
861 1.1 christos (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela)));
862 1.1 christos }
863 1.1 christos
864 1.1 christos /* This code is taken from elf32-m32r.c
865 1.1 christos There is some attempt to make this function usable for many architectures,
866 1.1 christos both USE_REL and USE_RELA ['twould be nice if such a critter existed],
867 1.1 christos if only to serve as a learning tool.
868 1.1 christos
869 1.1 christos The RELOCATE_SECTION function is called by the new ELF backend linker
870 1.1 christos to handle the relocations for a section.
871 1.1 christos
872 1.1 christos The relocs are always passed as Rela structures; if the section
873 1.1 christos actually uses Rel structures, the r_addend field will always be
874 1.1 christos zero.
875 1.1 christos
876 1.1 christos This function is responsible for adjust the section contents as
877 1.1 christos necessary, and (if using Rela relocs and generating a
878 1.1 christos relocatable output file) adjusting the reloc addend as
879 1.1 christos necessary.
880 1.1 christos
881 1.1 christos This function does not have to worry about setting the reloc
882 1.1 christos address or the reloc symbol index.
883 1.1 christos
884 1.1 christos LOCAL_SYMS is a pointer to the swapped in local symbols.
885 1.1 christos
886 1.1 christos LOCAL_SECTIONS is an array giving the section in the input file
887 1.1 christos corresponding to the st_shndx field of each local symbol.
888 1.1 christos
889 1.1 christos The global hash table entry for the global symbols can be found
890 1.1 christos via elf_sym_hashes (input_bfd).
891 1.1 christos
892 1.1 christos When generating relocatable output, this function must handle
893 1.1 christos STB_LOCAL/STT_SECTION symbols specially. The output symbol is
894 1.1 christos going to be the section symbol corresponding to the output
895 1.1 christos section, which means that the addend must be adjusted
896 1.1 christos accordingly. */
897 1.1 christos
898 1.1 christos static bfd_boolean
899 1.1 christos microblaze_elf_relocate_section (bfd *output_bfd,
900 1.1 christos struct bfd_link_info *info,
901 1.1 christos bfd *input_bfd,
902 1.1 christos asection *input_section,
903 1.1 christos bfd_byte *contents,
904 1.1 christos Elf_Internal_Rela *relocs,
905 1.1 christos Elf_Internal_Sym *local_syms,
906 1.1 christos asection **local_sections)
907 1.1 christos {
908 1.1 christos struct elf32_mb_link_hash_table *htab;
909 1.1.1.1.8.1 tls Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
910 1.1 christos struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
911 1.1 christos Elf_Internal_Rela *rel, *relend;
912 1.1 christos int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
913 1.1 christos /* Assume success. */
914 1.1.1.1.8.1 tls bfd_boolean ret = TRUE;
915 1.1 christos asection *sreloc;
916 1.1 christos bfd_vma *local_got_offsets;
917 1.1 christos unsigned int tls_type;
918 1.1 christos
919 1.1 christos if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
920 1.1 christos microblaze_elf_howto_init ();
921 1.1 christos
922 1.1 christos htab = elf32_mb_hash_table (info);
923 1.1 christos if (htab == NULL)
924 1.1 christos return FALSE;
925 1.1 christos
926 1.1 christos local_got_offsets = elf_local_got_offsets (input_bfd);
927 1.1 christos
928 1.1 christos sreloc = elf_section_data (input_section)->sreloc;
929 1.1 christos
930 1.1 christos rel = relocs;
931 1.1 christos relend = relocs + input_section->reloc_count;
932 1.1 christos for (; rel < relend; rel++)
933 1.1 christos {
934 1.1 christos int r_type;
935 1.1 christos reloc_howto_type *howto;
936 1.1 christos unsigned long r_symndx;
937 1.1 christos bfd_vma addend = rel->r_addend;
938 1.1 christos bfd_vma offset = rel->r_offset;
939 1.1 christos struct elf_link_hash_entry *h;
940 1.1 christos Elf_Internal_Sym *sym;
941 1.1 christos asection *sec;
942 1.1 christos const char *sym_name;
943 1.1 christos bfd_reloc_status_type r = bfd_reloc_ok;
944 1.1 christos const char *errmsg = NULL;
945 1.1 christos bfd_boolean unresolved_reloc = FALSE;
946 1.1.1.1.8.1 tls
947 1.1.1.1.8.1 tls h = NULL;
948 1.1 christos r_type = ELF32_R_TYPE (rel->r_info);
949 1.1 christos tls_type = 0;
950 1.1 christos
951 1.1 christos if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
952 1.1 christos {
953 1.1 christos (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
954 1.1 christos bfd_get_filename (input_bfd), (int) r_type);
955 1.1 christos bfd_set_error (bfd_error_bad_value);
956 1.1 christos ret = FALSE;
957 1.1 christos continue;
958 1.1 christos }
959 1.1 christos
960 1.1 christos howto = microblaze_elf_howto_table[r_type];
961 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
962 1.1 christos
963 1.1 christos if (info->relocatable)
964 1.1 christos {
965 1.1 christos /* This is a relocatable link. We don't have to change
966 1.1 christos anything, unless the reloc is against a section symbol,
967 1.1 christos in which case we have to adjust according to where the
968 1.1 christos section symbol winds up in the output section. */
969 1.1 christos sec = NULL;
970 1.1 christos if (r_symndx >= symtab_hdr->sh_info)
971 1.1 christos /* External symbol. */
972 1.1 christos continue;
973 1.1 christos
974 1.1 christos /* Local symbol. */
975 1.1 christos sym = local_syms + r_symndx;
976 1.1 christos sym_name = "<local symbol>";
977 1.1 christos /* STT_SECTION: symbol is associated with a section. */
978 1.1 christos if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
979 1.1 christos /* Symbol isn't associated with a section. Nothing to do. */
980 1.1 christos continue;
981 1.1 christos
982 1.1 christos sec = local_sections[r_symndx];
983 1.1 christos addend += sec->output_offset + sym->st_value;
984 1.1 christos #ifndef USE_REL
985 1.1 christos /* This can't be done for USE_REL because it doesn't mean anything
986 1.1 christos and elf_link_input_bfd asserts this stays zero. */
987 1.1 christos /* rel->r_addend = addend; */
988 1.1 christos #endif
989 1.1 christos
990 1.1 christos #ifndef USE_REL
991 1.1 christos /* Addends are stored with relocs. We're done. */
992 1.1 christos continue;
993 1.1 christos #else /* USE_REL */
994 1.1 christos /* If partial_inplace, we need to store any additional addend
995 1.1 christos back in the section. */
996 1.1 christos if (!howto->partial_inplace)
997 1.1 christos continue;
998 1.1 christos /* ??? Here is a nice place to call a special_function like handler. */
999 1.1 christos r = _bfd_relocate_contents (howto, input_bfd, addend,
1000 1.1 christos contents + offset);
1001 1.1 christos #endif /* USE_REL */
1002 1.1 christos }
1003 1.1 christos else
1004 1.1 christos {
1005 1.1 christos bfd_vma relocation;
1006 1.1 christos
1007 1.1 christos /* This is a final link. */
1008 1.1 christos sym = NULL;
1009 1.1 christos sec = NULL;
1010 1.1 christos unresolved_reloc = FALSE;
1011 1.1 christos
1012 1.1 christos if (r_symndx < symtab_hdr->sh_info)
1013 1.1 christos {
1014 1.1 christos /* Local symbol. */
1015 1.1 christos sym = local_syms + r_symndx;
1016 1.1 christos sec = local_sections[r_symndx];
1017 1.1 christos if (sec == 0)
1018 1.1 christos continue;
1019 1.1 christos sym_name = "<local symbol>";
1020 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1021 1.1 christos /* r_addend may have changed if the reference section was
1022 1.1 christos a merge section. */
1023 1.1 christos addend = rel->r_addend;
1024 1.1 christos }
1025 1.1 christos else
1026 1.1.1.1.8.1 tls {
1027 1.1 christos /* External symbol. */
1028 1.1 christos bfd_boolean warned ATTRIBUTE_UNUSED;
1029 1.1 christos bfd_boolean ignored ATTRIBUTE_UNUSED;
1030 1.1 christos
1031 1.1.1.1.8.1 tls RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1032 1.1 christos r_symndx, symtab_hdr, sym_hashes,
1033 1.1 christos h, sec, relocation,
1034 1.1 christos unresolved_reloc, warned, ignored);
1035 1.1 christos sym_name = h->root.root.string;
1036 1.1.1.1.8.1 tls }
1037 1.1 christos
1038 1.1 christos /* Sanity check the address. */
1039 1.1 christos if (offset > bfd_get_section_limit (input_bfd, input_section))
1040 1.1 christos {
1041 1.1 christos r = bfd_reloc_outofrange;
1042 1.1 christos goto check_reloc;
1043 1.1 christos }
1044 1.1 christos
1045 1.1 christos switch ((int) r_type)
1046 1.1 christos {
1047 1.1 christos case (int) R_MICROBLAZE_SRO32 :
1048 1.1 christos {
1049 1.1 christos const char *name;
1050 1.1 christos
1051 1.1.1.1.8.1 tls /* Only relocate if the symbol is defined. */
1052 1.1 christos if (sec)
1053 1.1 christos {
1054 1.1 christos name = bfd_get_section_name (sec->owner, sec);
1055 1.1 christos
1056 1.1 christos if (strcmp (name, ".sdata2") == 0
1057 1.1 christos || strcmp (name, ".sbss2") == 0)
1058 1.1 christos {
1059 1.1 christos if (ro_small_data_pointer == 0)
1060 1.1 christos microblaze_elf_final_sdp (info);
1061 1.1 christos if (ro_small_data_pointer == 0)
1062 1.1 christos {
1063 1.1 christos ret = FALSE;
1064 1.1 christos r = bfd_reloc_undefined;
1065 1.1 christos goto check_reloc;
1066 1.1 christos }
1067 1.1 christos
1068 1.1 christos /* At this point `relocation' contains the object's
1069 1.1 christos address. */
1070 1.1 christos relocation -= ro_small_data_pointer;
1071 1.1 christos /* Now it contains the offset from _SDA2_BASE_. */
1072 1.1 christos r = _bfd_final_link_relocate (howto, input_bfd,
1073 1.1 christos input_section,
1074 1.1 christos contents, offset,
1075 1.1 christos relocation, addend);
1076 1.1 christos }
1077 1.1 christos else
1078 1.1 christos {
1079 1.1 christos (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
1080 1.1.1.1.8.1 tls bfd_get_filename (input_bfd),
1081 1.1 christos sym_name,
1082 1.1 christos microblaze_elf_howto_table[(int) r_type]->name,
1083 1.1 christos bfd_get_section_name (sec->owner, sec));
1084 1.1 christos /*bfd_set_error (bfd_error_bad_value); ??? why? */
1085 1.1 christos ret = FALSE;
1086 1.1 christos continue;
1087 1.1 christos }
1088 1.1 christos }
1089 1.1 christos }
1090 1.1 christos break;
1091 1.1 christos
1092 1.1 christos case (int) R_MICROBLAZE_SRW32 :
1093 1.1 christos {
1094 1.1 christos const char *name;
1095 1.1 christos
1096 1.1.1.1.8.1 tls /* Only relocate if the symbol is defined. */
1097 1.1 christos if (sec)
1098 1.1 christos {
1099 1.1 christos name = bfd_get_section_name (sec->owner, sec);
1100 1.1 christos
1101 1.1 christos if (strcmp (name, ".sdata") == 0
1102 1.1 christos || strcmp (name, ".sbss") == 0)
1103 1.1 christos {
1104 1.1 christos if (rw_small_data_pointer == 0)
1105 1.1 christos microblaze_elf_final_sdp (info);
1106 1.1 christos if (rw_small_data_pointer == 0)
1107 1.1 christos {
1108 1.1 christos ret = FALSE;
1109 1.1 christos r = bfd_reloc_undefined;
1110 1.1 christos goto check_reloc;
1111 1.1 christos }
1112 1.1 christos
1113 1.1 christos /* At this point `relocation' contains the object's
1114 1.1 christos address. */
1115 1.1 christos relocation -= rw_small_data_pointer;
1116 1.1 christos /* Now it contains the offset from _SDA_BASE_. */
1117 1.1 christos r = _bfd_final_link_relocate (howto, input_bfd,
1118 1.1 christos input_section,
1119 1.1 christos contents, offset,
1120 1.1 christos relocation, addend);
1121 1.1 christos }
1122 1.1 christos else
1123 1.1 christos {
1124 1.1 christos (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
1125 1.1.1.1.8.1 tls bfd_get_filename (input_bfd),
1126 1.1 christos sym_name,
1127 1.1 christos microblaze_elf_howto_table[(int) r_type]->name,
1128 1.1 christos bfd_get_section_name (sec->owner, sec));
1129 1.1 christos /*bfd_set_error (bfd_error_bad_value); ??? why? */
1130 1.1 christos ret = FALSE;
1131 1.1 christos continue;
1132 1.1 christos }
1133 1.1 christos }
1134 1.1 christos }
1135 1.1 christos break;
1136 1.1 christos
1137 1.1 christos case (int) R_MICROBLAZE_32_SYM_OP_SYM:
1138 1.1 christos break; /* Do nothing. */
1139 1.1 christos
1140 1.1 christos case (int) R_MICROBLAZE_GOTPC_64:
1141 1.1 christos relocation = htab->sgotplt->output_section->vma
1142 1.1 christos + htab->sgotplt->output_offset;
1143 1.1 christos relocation -= (input_section->output_section->vma
1144 1.1 christos + input_section->output_offset
1145 1.1.1.1.8.1 tls + offset + INST_WORD_SIZE);
1146 1.1 christos relocation += addend;
1147 1.1.1.1.8.1 tls bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1148 1.1 christos contents + offset + endian);
1149 1.1 christos bfd_put_16 (input_bfd, relocation & 0xffff,
1150 1.1 christos contents + offset + endian + INST_WORD_SIZE);
1151 1.1 christos break;
1152 1.1 christos
1153 1.1 christos case (int) R_MICROBLAZE_PLT_64:
1154 1.1 christos {
1155 1.1 christos bfd_vma immediate;
1156 1.1 christos if (htab->splt != NULL && h != NULL
1157 1.1 christos && h->plt.offset != (bfd_vma) -1)
1158 1.1 christos {
1159 1.1 christos relocation = (htab->splt->output_section->vma
1160 1.1 christos + htab->splt->output_offset
1161 1.1 christos + h->plt.offset);
1162 1.1 christos unresolved_reloc = FALSE;
1163 1.1 christos immediate = relocation - (input_section->output_section->vma
1164 1.1.1.1.8.1 tls + input_section->output_offset
1165 1.1 christos + offset + INST_WORD_SIZE);
1166 1.1.1.1.8.1 tls bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1167 1.1 christos contents + offset + endian);
1168 1.1 christos bfd_put_16 (input_bfd, immediate & 0xffff,
1169 1.1 christos contents + offset + endian + INST_WORD_SIZE);
1170 1.1 christos }
1171 1.1 christos else
1172 1.1 christos {
1173 1.1 christos relocation -= (input_section->output_section->vma
1174 1.1 christos + input_section->output_offset
1175 1.1.1.1.8.1 tls + offset + INST_WORD_SIZE);
1176 1.1 christos immediate = relocation;
1177 1.1.1.1.8.1 tls bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1178 1.1 christos contents + offset + endian);
1179 1.1 christos bfd_put_16 (input_bfd, immediate & 0xffff,
1180 1.1 christos contents + offset + endian + INST_WORD_SIZE);
1181 1.1 christos }
1182 1.1.1.1.8.1 tls break;
1183 1.1.1.1.8.1 tls }
1184 1.1.1.1.8.1 tls
1185 1.1.1.1.8.1 tls case (int) R_MICROBLAZE_TLSGD:
1186 1.1.1.1.8.1 tls tls_type = (TLS_TLS | TLS_GD);
1187 1.1.1.1.8.1 tls goto dogot;
1188 1.1 christos case (int) R_MICROBLAZE_TLSLD:
1189 1.1 christos tls_type = (TLS_TLS | TLS_LD);
1190 1.1.1.1.8.1 tls dogot:
1191 1.1.1.1.8.1 tls case (int) R_MICROBLAZE_GOT_64:
1192 1.1.1.1.8.1 tls {
1193 1.1.1.1.8.1 tls bfd_vma *offp;
1194 1.1.1.1.8.1 tls bfd_vma off, off2;
1195 1.1.1.1.8.1 tls unsigned long indx;
1196 1.1 christos bfd_vma static_value;
1197 1.1 christos
1198 1.1.1.1.8.1 tls bfd_boolean need_relocs = FALSE;
1199 1.1.1.1.8.1 tls if (htab->sgot == NULL)
1200 1.1.1.1.8.1 tls abort ();
1201 1.1.1.1.8.1 tls
1202 1.1.1.1.8.1 tls indx = 0;
1203 1.1.1.1.8.1 tls offp = NULL;
1204 1.1.1.1.8.1 tls
1205 1.1.1.1.8.1 tls /* 1. Identify GOT Offset;
1206 1.1.1.1.8.1 tls 2. Compute Static Values
1207 1.1.1.1.8.1 tls 3. Process Module Id, Process Offset
1208 1.1.1.1.8.1 tls 4. Fixup Relocation with GOT offset value. */
1209 1.1.1.1.8.1 tls
1210 1.1.1.1.8.1 tls /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1211 1.1.1.1.8.1 tls if (IS_TLS_LD (tls_type))
1212 1.1.1.1.8.1 tls offp = &htab->tlsld_got.offset;
1213 1.1.1.1.8.1 tls else if (h != NULL)
1214 1.1.1.1.8.1 tls {
1215 1.1.1.1.8.1 tls if (htab->sgotplt != NULL && h->got.offset != (bfd_vma) -1)
1216 1.1.1.1.8.1 tls offp = &h->got.offset;
1217 1.1.1.1.8.1 tls else
1218 1.1 christos abort ();
1219 1.1 christos }
1220 1.1 christos else
1221 1.1.1.1.8.1 tls {
1222 1.1.1.1.8.1 tls if (local_got_offsets == NULL)
1223 1.1.1.1.8.1 tls abort ();
1224 1.1.1.1.8.1 tls offp = &local_got_offsets[r_symndx];
1225 1.1.1.1.8.1 tls }
1226 1.1.1.1.8.1 tls
1227 1.1.1.1.8.1 tls if (!offp)
1228 1.1.1.1.8.1 tls abort ();
1229 1.1.1.1.8.1 tls
1230 1.1.1.1.8.1 tls off = (*offp) & ~1;
1231 1.1.1.1.8.1 tls off2 = off;
1232 1.1.1.1.8.1 tls
1233 1.1.1.1.8.1 tls if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
1234 1.1.1.1.8.1 tls off2 = off + 4;
1235 1.1.1.1.8.1 tls
1236 1.1.1.1.8.1 tls /* Symbol index to use for relocs */
1237 1.1.1.1.8.1 tls if (h != NULL)
1238 1.1.1.1.8.1 tls {
1239 1.1.1.1.8.1 tls bfd_boolean dyn =
1240 1.1.1.1.8.1 tls elf_hash_table (info)->dynamic_sections_created;
1241 1.1.1.1.8.1 tls
1242 1.1.1.1.8.1 tls if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
1243 1.1 christos && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, h)))
1244 1.1.1.1.8.1 tls indx = h->dynindx;
1245 1.1.1.1.8.1 tls }
1246 1.1.1.1.8.1 tls
1247 1.1.1.1.8.1 tls /* Need to generate relocs ? */
1248 1.1.1.1.8.1 tls if ((info->shared || indx != 0)
1249 1.1.1.1.8.1 tls && (h == NULL
1250 1.1.1.1.8.1 tls || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1251 1.1.1.1.8.1 tls || h->root.type != bfd_link_hash_undefweak))
1252 1.1.1.1.8.1 tls need_relocs = TRUE;
1253 1.1.1.1.8.1 tls
1254 1.1.1.1.8.1 tls /* 2. Compute/Emit Static value of r-expression */
1255 1.1.1.1.8.1 tls static_value = relocation + addend;
1256 1.1.1.1.8.1 tls
1257 1.1.1.1.8.1 tls /* 3. Process module-id and offset */
1258 1.1.1.1.8.1 tls if (! ((*offp) & 1) )
1259 1.1.1.1.8.1 tls {
1260 1.1.1.1.8.1 tls bfd_vma got_offset;
1261 1.1.1.1.8.1 tls
1262 1.1.1.1.8.1 tls got_offset = (htab->sgot->output_section->vma
1263 1.1.1.1.8.1 tls + htab->sgot->output_offset
1264 1.1.1.1.8.1 tls + off);
1265 1.1.1.1.8.1 tls
1266 1.1.1.1.8.1 tls /* Process module-id */
1267 1.1 christos if (IS_TLS_LD(tls_type))
1268 1.1.1.1.8.1 tls {
1269 1.1.1.1.8.1 tls if (! info->shared)
1270 1.1.1.1.8.1 tls {
1271 1.1.1.1.8.1 tls bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
1272 1.1.1.1.8.1 tls }
1273 1.1.1.1.8.1 tls else
1274 1.1.1.1.8.1 tls {
1275 1.1.1.1.8.1 tls microblaze_elf_output_dynamic_relocation (output_bfd,
1276 1.1 christos htab->srelgot, htab->srelgot->reloc_count++,
1277 1.1 christos /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
1278 1.1.1.1.8.1 tls got_offset, 0);
1279 1.1.1.1.8.1 tls }
1280 1.1.1.1.8.1 tls }
1281 1.1.1.1.8.1 tls else if (IS_TLS_GD(tls_type))
1282 1.1.1.1.8.1 tls {
1283 1.1.1.1.8.1 tls if (! need_relocs)
1284 1.1.1.1.8.1 tls {
1285 1.1.1.1.8.1 tls bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
1286 1.1.1.1.8.1 tls }
1287 1.1.1.1.8.1 tls else
1288 1.1.1.1.8.1 tls {
1289 1.1.1.1.8.1 tls microblaze_elf_output_dynamic_relocation (output_bfd,
1290 1.1.1.1.8.1 tls htab->srelgot,
1291 1.1.1.1.8.1 tls htab->srelgot->reloc_count++,
1292 1.1.1.1.8.1 tls /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
1293 1.1.1.1.8.1 tls got_offset, indx ? 0 : static_value);
1294 1.1.1.1.8.1 tls }
1295 1.1.1.1.8.1 tls }
1296 1.1.1.1.8.1 tls
1297 1.1.1.1.8.1 tls /* Process Offset */
1298 1.1.1.1.8.1 tls if (htab->srelgot == NULL)
1299 1.1.1.1.8.1 tls abort ();
1300 1.1.1.1.8.1 tls
1301 1.1.1.1.8.1 tls got_offset = (htab->sgot->output_section->vma
1302 1.1 christos + htab->sgot->output_offset
1303 1.1.1.1.8.1 tls + off2);
1304 1.1.1.1.8.1 tls if (IS_TLS_LD(tls_type))
1305 1.1.1.1.8.1 tls {
1306 1.1.1.1.8.1 tls /* For LD, offset should be 0 */
1307 1.1.1.1.8.1 tls *offp |= 1;
1308 1.1.1.1.8.1 tls bfd_put_32 (output_bfd, 0, htab->sgot->contents + off2);
1309 1.1.1.1.8.1 tls }
1310 1.1.1.1.8.1 tls else if (IS_TLS_GD(tls_type))
1311 1.1.1.1.8.1 tls {
1312 1.1.1.1.8.1 tls *offp |= 1;
1313 1.1.1.1.8.1 tls static_value -= dtprel_base(info);
1314 1.1.1.1.8.1 tls if (need_relocs)
1315 1.1.1.1.8.1 tls {
1316 1.1.1.1.8.1 tls microblaze_elf_output_dynamic_relocation (output_bfd,
1317 1.1.1.1.8.1 tls htab->srelgot, htab->srelgot->reloc_count++,
1318 1.1.1.1.8.1 tls /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
1319 1.1.1.1.8.1 tls got_offset, indx ? 0 : static_value);
1320 1.1.1.1.8.1 tls }
1321 1.1.1.1.8.1 tls else
1322 1.1.1.1.8.1 tls {
1323 1.1 christos bfd_put_32 (output_bfd, static_value,
1324 1.1 christos htab->sgot->contents + off2);
1325 1.1.1.1.8.1 tls }
1326 1.1.1.1.8.1 tls }
1327 1.1.1.1.8.1 tls else
1328 1.1.1.1.8.1 tls {
1329 1.1.1.1.8.1 tls bfd_put_32 (output_bfd, static_value,
1330 1.1.1.1.8.1 tls htab->sgot->contents + off2);
1331 1.1.1.1.8.1 tls
1332 1.1.1.1.8.1 tls /* Relocs for dyn symbols generated by
1333 1.1.1.1.8.1 tls finish_dynamic_symbols */
1334 1.1.1.1.8.1 tls if (info->shared && h == NULL)
1335 1.1.1.1.8.1 tls {
1336 1.1.1.1.8.1 tls *offp |= 1;
1337 1.1.1.1.8.1 tls microblaze_elf_output_dynamic_relocation (output_bfd,
1338 1.1.1.1.8.1 tls htab->srelgot, htab->srelgot->reloc_count++,
1339 1.1.1.1.8.1 tls /* symindex= */ indx, R_MICROBLAZE_REL,
1340 1.1 christos got_offset, static_value);
1341 1.1.1.1.8.1 tls }
1342 1.1.1.1.8.1 tls }
1343 1.1.1.1.8.1 tls }
1344 1.1.1.1.8.1 tls
1345 1.1.1.1.8.1 tls /* 4. Fixup Relocation with GOT offset value
1346 1.1.1.1.8.1 tls Compute relative address of GOT entry for applying
1347 1.1.1.1.8.1 tls the current relocation */
1348 1.1.1.1.8.1 tls relocation = htab->sgot->output_section->vma
1349 1.1.1.1.8.1 tls + htab->sgot->output_offset
1350 1.1.1.1.8.1 tls + off
1351 1.1.1.1.8.1 tls - htab->sgotplt->output_section->vma
1352 1.1 christos - htab->sgotplt->output_offset;
1353 1.1.1.1.8.1 tls
1354 1.1 christos /* Apply Current Relocation */
1355 1.1.1.1.8.1 tls bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1356 1.1.1.1.8.1 tls contents + offset + endian);
1357 1.1.1.1.8.1 tls bfd_put_16 (input_bfd, relocation & 0xffff,
1358 1.1 christos contents + offset + endian + INST_WORD_SIZE);
1359 1.1 christos
1360 1.1 christos unresolved_reloc = FALSE;
1361 1.1 christos break;
1362 1.1 christos }
1363 1.1 christos
1364 1.1 christos case (int) R_MICROBLAZE_GOTOFF_64:
1365 1.1 christos {
1366 1.1 christos bfd_vma immediate;
1367 1.1 christos unsigned short lo, high;
1368 1.1 christos relocation += addend;
1369 1.1 christos relocation -= htab->sgotplt->output_section->vma
1370 1.1 christos + htab->sgotplt->output_offset;
1371 1.1 christos /* Write this value into correct location. */
1372 1.1.1.1.8.1 tls immediate = relocation;
1373 1.1.1.1.8.1 tls lo = immediate & 0x0000ffff;
1374 1.1 christos high = (immediate >> 16) & 0x0000ffff;
1375 1.1 christos bfd_put_16 (input_bfd, high, contents + offset + endian);
1376 1.1 christos bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian);
1377 1.1 christos break;
1378 1.1 christos }
1379 1.1 christos
1380 1.1 christos case (int) R_MICROBLAZE_GOTOFF_32:
1381 1.1 christos {
1382 1.1 christos relocation += addend;
1383 1.1 christos relocation -= htab->sgotplt->output_section->vma
1384 1.1 christos + htab->sgotplt->output_offset;
1385 1.1 christos /* Write this value into correct location. */
1386 1.1 christos bfd_put_32 (input_bfd, relocation, contents + offset);
1387 1.1.1.1.8.1 tls break;
1388 1.1.1.1.8.1 tls }
1389 1.1.1.1.8.1 tls
1390 1.1.1.1.8.1 tls case (int) R_MICROBLAZE_TLSDTPREL64:
1391 1.1.1.1.8.1 tls relocation += addend;
1392 1.1.1.1.8.1 tls relocation -= dtprel_base(info);
1393 1.1.1.1.8.1 tls bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1394 1.1.1.1.8.1 tls contents + offset + 2);
1395 1.1 christos bfd_put_16 (input_bfd, relocation & 0xffff,
1396 1.1 christos contents + offset + 2 + INST_WORD_SIZE);
1397 1.1 christos break;
1398 1.1 christos case (int) R_MICROBLAZE_64_PCREL :
1399 1.1 christos case (int) R_MICROBLAZE_64:
1400 1.1 christos case (int) R_MICROBLAZE_32:
1401 1.1 christos {
1402 1.1 christos /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1403 1.1 christos from removed linkonce sections, or sections discarded by
1404 1.1 christos a linker script. */
1405 1.1 christos if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
1406 1.1 christos {
1407 1.1 christos relocation += addend;
1408 1.1 christos if (r_type == R_MICROBLAZE_32)
1409 1.1 christos bfd_put_32 (input_bfd, relocation, contents + offset);
1410 1.1 christos else
1411 1.1 christos {
1412 1.1 christos if (r_type == R_MICROBLAZE_64_PCREL)
1413 1.1 christos relocation -= (input_section->output_section->vma
1414 1.1.1.1.8.1 tls + input_section->output_offset
1415 1.1 christos + offset + INST_WORD_SIZE);
1416 1.1.1.1.8.1 tls bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1417 1.1 christos contents + offset + endian);
1418 1.1 christos bfd_put_16 (input_bfd, relocation & 0xffff,
1419 1.1 christos contents + offset + endian + INST_WORD_SIZE);
1420 1.1 christos }
1421 1.1 christos break;
1422 1.1 christos }
1423 1.1 christos
1424 1.1 christos if ((info->shared
1425 1.1 christos && (h == NULL
1426 1.1 christos || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1427 1.1 christos || h->root.type != bfd_link_hash_undefweak)
1428 1.1 christos && (!howto->pc_relative
1429 1.1 christos || (h != NULL
1430 1.1 christos && h->dynindx != -1
1431 1.1 christos && (!info->symbolic
1432 1.1 christos || !h->def_regular))))
1433 1.1 christos || (!info->shared
1434 1.1 christos && h != NULL
1435 1.1 christos && h->dynindx != -1
1436 1.1 christos && !h->non_got_ref
1437 1.1 christos && ((h->def_dynamic
1438 1.1 christos && !h->def_regular)
1439 1.1 christos || h->root.type == bfd_link_hash_undefweak
1440 1.1 christos || h->root.type == bfd_link_hash_undefined)))
1441 1.1 christos {
1442 1.1 christos Elf_Internal_Rela outrel;
1443 1.1 christos bfd_byte *loc;
1444 1.1 christos bfd_boolean skip;
1445 1.1 christos
1446 1.1 christos /* When generating a shared object, these relocations
1447 1.1 christos are copied into the output file to be resolved at run
1448 1.1 christos time. */
1449 1.1 christos
1450 1.1 christos BFD_ASSERT (sreloc != NULL);
1451 1.1 christos
1452 1.1 christos skip = FALSE;
1453 1.1 christos
1454 1.1 christos outrel.r_offset =
1455 1.1 christos _bfd_elf_section_offset (output_bfd, info, input_section,
1456 1.1 christos rel->r_offset);
1457 1.1 christos if (outrel.r_offset == (bfd_vma) -1)
1458 1.1 christos skip = TRUE;
1459 1.1 christos else if (outrel.r_offset == (bfd_vma) -2)
1460 1.1 christos skip = TRUE;
1461 1.1 christos outrel.r_offset += (input_section->output_section->vma
1462 1.1 christos + input_section->output_offset);
1463 1.1 christos
1464 1.1 christos if (skip)
1465 1.1 christos memset (&outrel, 0, sizeof outrel);
1466 1.1 christos /* h->dynindx may be -1 if the symbol was marked to
1467 1.1 christos become local. */
1468 1.1 christos else if (h != NULL
1469 1.1 christos && ((! info->symbolic && h->dynindx != -1)
1470 1.1 christos || !h->def_regular))
1471 1.1 christos {
1472 1.1 christos BFD_ASSERT (h->dynindx != -1);
1473 1.1 christos outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1474 1.1 christos outrel.r_addend = addend;
1475 1.1 christos }
1476 1.1 christos else
1477 1.1 christos {
1478 1.1 christos if (r_type == R_MICROBLAZE_32)
1479 1.1 christos {
1480 1.1 christos outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1481 1.1 christos outrel.r_addend = relocation + addend;
1482 1.1 christos }
1483 1.1 christos else
1484 1.1 christos {
1485 1.1 christos BFD_FAIL ();
1486 1.1 christos (*_bfd_error_handler)
1487 1.1 christos (_("%B: probably compiled without -fPIC?"),
1488 1.1 christos input_bfd);
1489 1.1 christos bfd_set_error (bfd_error_bad_value);
1490 1.1 christos return FALSE;
1491 1.1 christos }
1492 1.1 christos }
1493 1.1 christos
1494 1.1 christos loc = sreloc->contents;
1495 1.1 christos loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1496 1.1 christos bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1497 1.1 christos break;
1498 1.1 christos }
1499 1.1 christos else
1500 1.1 christos {
1501 1.1 christos relocation += addend;
1502 1.1 christos if (r_type == R_MICROBLAZE_32)
1503 1.1 christos bfd_put_32 (input_bfd, relocation, contents + offset);
1504 1.1 christos else
1505 1.1 christos {
1506 1.1 christos if (r_type == R_MICROBLAZE_64_PCREL)
1507 1.1 christos relocation -= (input_section->output_section->vma
1508 1.1.1.1.8.1 tls + input_section->output_offset
1509 1.1 christos + offset + INST_WORD_SIZE);
1510 1.1.1.1.8.1 tls bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1511 1.1 christos contents + offset + endian);
1512 1.1 christos bfd_put_16 (input_bfd, relocation & 0xffff,
1513 1.1 christos contents + offset + endian + INST_WORD_SIZE);
1514 1.1 christos }
1515 1.1 christos break;
1516 1.1 christos }
1517 1.1 christos }
1518 1.1 christos
1519 1.1 christos default :
1520 1.1 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1521 1.1 christos contents, offset,
1522 1.1 christos relocation, addend);
1523 1.1 christos break;
1524 1.1 christos }
1525 1.1 christos }
1526 1.1 christos
1527 1.1 christos check_reloc:
1528 1.1 christos
1529 1.1 christos if (r != bfd_reloc_ok)
1530 1.1 christos {
1531 1.1 christos /* FIXME: This should be generic enough to go in a utility. */
1532 1.1 christos const char *name;
1533 1.1 christos
1534 1.1 christos if (h != NULL)
1535 1.1 christos name = h->root.root.string;
1536 1.1 christos else
1537 1.1 christos {
1538 1.1 christos name = (bfd_elf_string_from_elf_section
1539 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name));
1540 1.1 christos if (name == NULL || *name == '\0')
1541 1.1 christos name = bfd_section_name (input_bfd, sec);
1542 1.1 christos }
1543 1.1 christos
1544 1.1 christos if (errmsg != NULL)
1545 1.1 christos goto common_error;
1546 1.1 christos
1547 1.1 christos switch (r)
1548 1.1 christos {
1549 1.1 christos case bfd_reloc_overflow:
1550 1.1 christos if (!((*info->callbacks->reloc_overflow)
1551 1.1 christos (info, (h ? &h->root : NULL), name, howto->name,
1552 1.1 christos (bfd_vma) 0, input_bfd, input_section, offset)))
1553 1.1 christos return FALSE;
1554 1.1 christos break;
1555 1.1 christos
1556 1.1 christos case bfd_reloc_undefined:
1557 1.1 christos if (!((*info->callbacks->undefined_symbol)
1558 1.1 christos (info, name, input_bfd, input_section, offset, TRUE)))
1559 1.1 christos return FALSE;
1560 1.1 christos break;
1561 1.1 christos
1562 1.1 christos case bfd_reloc_outofrange:
1563 1.1 christos errmsg = _("internal error: out of range error");
1564 1.1 christos goto common_error;
1565 1.1 christos
1566 1.1 christos case bfd_reloc_notsupported:
1567 1.1 christos errmsg = _("internal error: unsupported relocation error");
1568 1.1 christos goto common_error;
1569 1.1 christos
1570 1.1 christos case bfd_reloc_dangerous:
1571 1.1 christos errmsg = _("internal error: dangerous error");
1572 1.1 christos goto common_error;
1573 1.1 christos
1574 1.1 christos default:
1575 1.1 christos errmsg = _("internal error: unknown error");
1576 1.1 christos /* Fall through. */
1577 1.1 christos common_error:
1578 1.1 christos if (!((*info->callbacks->warning)
1579 1.1 christos (info, errmsg, name, input_bfd, input_section, offset)))
1580 1.1 christos return FALSE;
1581 1.1 christos break;
1582 1.1 christos }
1583 1.1 christos }
1584 1.1 christos }
1585 1.1.1.1.8.1 tls
1586 1.1.1.1.8.1 tls return ret;
1587 1.1.1.1.8.1 tls }
1588 1.1.1.1.8.1 tls
1589 1.1.1.1.8.1 tls /* Merge backend specific data from an object file to the output
1590 1.1.1.1.8.1 tls object file when linking.
1591 1.1.1.1.8.1 tls
1592 1.1.1.1.8.1 tls Note: We only use this hook to catch endian mismatches. */
1593 1.1.1.1.8.1 tls static bfd_boolean
1594 1.1.1.1.8.1 tls microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
1595 1.1.1.1.8.1 tls {
1596 1.1.1.1.8.1 tls /* Check if we have the same endianess. */
1597 1.1.1.1.8.1 tls if (! _bfd_generic_verify_endian_match (ibfd, obfd))
1598 1.1.1.1.8.1 tls return FALSE;
1599 1.1.1.1.8.1 tls
1600 1.1 christos return TRUE;
1601 1.1 christos }
1602 1.1 christos
1603 1.1 christos
1604 1.1.1.1.8.1 tls /* Calculate fixup value for reference. */
1606 1.1.1.1.8.1 tls
1607 1.1 christos static int
1608 1.1 christos calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
1609 1.1 christos {
1610 1.1 christos bfd_vma end = start + size;
1611 1.1 christos int i, fixup = 0;
1612 1.1 christos
1613 1.1 christos if (sec == NULL || sec->relax == NULL)
1614 1.1 christos return 0;
1615 1.1.1.1.8.1 tls
1616 1.1 christos /* Look for addr in relax table, total fixup value. */
1617 1.1.1.1.8.1 tls for (i = 0; i < sec->relax_count; i++)
1618 1.1.1.1.8.1 tls {
1619 1.1 christos if (end <= sec->relax[i].addr)
1620 1.1 christos break;
1621 1.1 christos if ((end != start) && (start > sec->relax[i].addr))
1622 1.1 christos continue;
1623 1.1 christos fixup += sec->relax[i].size;
1624 1.1.1.1.8.1 tls }
1625 1.1.1.1.8.1 tls return fixup;
1626 1.1.1.1.8.1 tls }
1627 1.1.1.1.8.1 tls
1628 1.1.1.1.8.1 tls /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1629 1.1.1.1.8.1 tls a 32-bit instruction. */
1630 1.1.1.1.8.1 tls static void
1631 1.1.1.1.8.1 tls microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1632 1.1.1.1.8.1 tls {
1633 1.1.1.1.8.1 tls unsigned long instr = bfd_get_32 (abfd, bfd_addr);
1634 1.1.1.1.8.1 tls instr &= ~0x0000ffff;
1635 1.1.1.1.8.1 tls instr |= (val & 0x0000ffff);
1636 1.1.1.1.8.1 tls bfd_put_32 (abfd, instr, bfd_addr);
1637 1.1.1.1.8.1 tls }
1638 1.1.1.1.8.1 tls
1639 1.1.1.1.8.1 tls /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1640 1.1.1.1.8.1 tls two consecutive 32-bit instructions. */
1641 1.1.1.1.8.1 tls static void
1642 1.1.1.1.8.1 tls microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1643 1.1.1.1.8.1 tls {
1644 1.1.1.1.8.1 tls unsigned long instr_hi;
1645 1.1.1.1.8.1 tls unsigned long instr_lo;
1646 1.1.1.1.8.1 tls
1647 1.1.1.1.8.1 tls instr_hi = bfd_get_32 (abfd, bfd_addr);
1648 1.1.1.1.8.1 tls instr_hi &= ~0x0000ffff;
1649 1.1.1.1.8.1 tls instr_hi |= ((val >> 16) & 0x0000ffff);
1650 1.1.1.1.8.1 tls bfd_put_32 (abfd, instr_hi, bfd_addr);
1651 1.1.1.1.8.1 tls
1652 1.1.1.1.8.1 tls instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
1653 1.1.1.1.8.1 tls instr_lo &= ~0x0000ffff;
1654 1.1 christos instr_lo |= (val & 0x0000ffff);
1655 1.1 christos bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
1656 1.1 christos }
1657 1.1 christos
1658 1.1 christos static bfd_boolean
1659 1.1 christos microblaze_elf_relax_section (bfd *abfd,
1660 1.1 christos asection *sec,
1661 1.1 christos struct bfd_link_info *link_info,
1662 1.1 christos bfd_boolean *again)
1663 1.1 christos {
1664 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1665 1.1 christos Elf_Internal_Rela *internal_relocs;
1666 1.1 christos Elf_Internal_Rela *free_relocs = NULL;
1667 1.1 christos Elf_Internal_Rela *irel, *irelend;
1668 1.1 christos bfd_byte *contents = NULL;
1669 1.1 christos bfd_byte *free_contents = NULL;
1670 1.1 christos int rel_count;
1671 1.1 christos unsigned int shndx;
1672 1.1 christos int i, sym_index;
1673 1.1 christos asection *o;
1674 1.1 christos struct elf_link_hash_entry *sym_hash;
1675 1.1 christos Elf_Internal_Sym *isymbuf, *isymend;
1676 1.1 christos Elf_Internal_Sym *isym;
1677 1.1 christos int symcount;
1678 1.1 christos int offset;
1679 1.1 christos bfd_vma src, dest;
1680 1.1 christos
1681 1.1 christos /* We only do this once per section. We may be able to delete some code
1682 1.1 christos by running multiple passes, but it is not worth it. */
1683 1.1 christos *again = FALSE;
1684 1.1.1.1.8.1 tls
1685 1.1.1.1.8.1 tls /* Only do this for a text section. */
1686 1.1 christos if (link_info->relocatable
1687 1.1 christos || (sec->flags & SEC_RELOC) == 0
1688 1.1 christos || (sec->reloc_count == 0)
1689 1.1 christos || (sec->flags & SEC_CODE) == 0)
1690 1.1 christos return TRUE;
1691 1.1 christos
1692 1.1 christos BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1693 1.1 christos
1694 1.1 christos /* If this is the first time we have been called for this section,
1695 1.1 christos initialize the cooked size. */
1696 1.1 christos if (sec->size == 0)
1697 1.1 christos sec->size = sec->rawsize;
1698 1.1 christos
1699 1.1 christos /* Get symbols for this section. */
1700 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1701 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1702 1.1 christos symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1703 1.1 christos if (isymbuf == NULL)
1704 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1705 1.1 christos 0, NULL, NULL, NULL);
1706 1.1 christos BFD_ASSERT (isymbuf != NULL);
1707 1.1 christos
1708 1.1 christos internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1709 1.1 christos if (internal_relocs == NULL)
1710 1.1 christos goto error_return;
1711 1.1 christos if (! link_info->keep_memory)
1712 1.1 christos free_relocs = internal_relocs;
1713 1.1 christos
1714 1.1 christos sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1715 1.1 christos * sizeof (struct relax_table));
1716 1.1 christos if (sec->relax == NULL)
1717 1.1 christos goto error_return;
1718 1.1 christos sec->relax_count = 0;
1719 1.1 christos
1720 1.1 christos irelend = internal_relocs + sec->reloc_count;
1721 1.1 christos rel_count = 0;
1722 1.1 christos for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1723 1.1 christos {
1724 1.1 christos bfd_vma symval;
1725 1.1 christos if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1726 1.1 christos && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 ))
1727 1.1 christos continue; /* Can't delete this reloc. */
1728 1.1 christos
1729 1.1 christos /* Get the section contents. */
1730 1.1 christos if (contents == NULL)
1731 1.1 christos {
1732 1.1 christos if (elf_section_data (sec)->this_hdr.contents != NULL)
1733 1.1 christos contents = elf_section_data (sec)->this_hdr.contents;
1734 1.1 christos else
1735 1.1 christos {
1736 1.1 christos contents = (bfd_byte *) bfd_malloc (sec->size);
1737 1.1 christos if (contents == NULL)
1738 1.1 christos goto error_return;
1739 1.1 christos free_contents = contents;
1740 1.1 christos
1741 1.1 christos if (!bfd_get_section_contents (abfd, sec, contents,
1742 1.1 christos (file_ptr) 0, sec->size))
1743 1.1 christos goto error_return;
1744 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1745 1.1 christos }
1746 1.1 christos }
1747 1.1 christos
1748 1.1 christos /* Get the value of the symbol referred to by the reloc. */
1749 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1750 1.1 christos {
1751 1.1 christos /* A local symbol. */
1752 1.1 christos asection *sym_sec;
1753 1.1 christos
1754 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
1755 1.1 christos if (isym->st_shndx == SHN_UNDEF)
1756 1.1 christos sym_sec = bfd_und_section_ptr;
1757 1.1 christos else if (isym->st_shndx == SHN_ABS)
1758 1.1 christos sym_sec = bfd_abs_section_ptr;
1759 1.1 christos else if (isym->st_shndx == SHN_COMMON)
1760 1.1 christos sym_sec = bfd_com_section_ptr;
1761 1.1 christos else
1762 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1763 1.1 christos
1764 1.1 christos symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1765 1.1 christos }
1766 1.1 christos else
1767 1.1 christos {
1768 1.1 christos unsigned long indx;
1769 1.1 christos struct elf_link_hash_entry *h;
1770 1.1 christos
1771 1.1 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1772 1.1 christos h = elf_sym_hashes (abfd)[indx];
1773 1.1 christos BFD_ASSERT (h != NULL);
1774 1.1 christos
1775 1.1 christos if (h->root.type != bfd_link_hash_defined
1776 1.1 christos && h->root.type != bfd_link_hash_defweak)
1777 1.1 christos /* This appears to be a reference to an undefined
1778 1.1 christos symbol. Just ignore it--it will be caught by the
1779 1.1 christos regular reloc processing. */
1780 1.1 christos continue;
1781 1.1 christos
1782 1.1 christos symval = (h->root.u.def.value
1783 1.1 christos + h->root.u.def.section->output_section->vma
1784 1.1 christos + h->root.u.def.section->output_offset);
1785 1.1 christos }
1786 1.1 christos
1787 1.1 christos /* If this is a PC-relative reloc, subtract the instr offset from
1788 1.1 christos the symbol value. */
1789 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
1790 1.1 christos {
1791 1.1 christos symval = symval + irel->r_addend
1792 1.1 christos - (irel->r_offset
1793 1.1 christos + sec->output_section->vma
1794 1.1 christos + sec->output_offset);
1795 1.1 christos }
1796 1.1 christos else
1797 1.1 christos symval += irel->r_addend;
1798 1.1 christos
1799 1.1 christos if ((symval & 0xffff8000) == 0
1800 1.1 christos || (symval & 0xffff8000) == 0xffff8000)
1801 1.1 christos {
1802 1.1 christos /* We can delete this instruction. */
1803 1.1 christos sec->relax[sec->relax_count].addr = irel->r_offset;
1804 1.1 christos sec->relax[sec->relax_count].size = INST_WORD_SIZE;
1805 1.1 christos sec->relax_count++;
1806 1.1 christos
1807 1.1 christos /* Rewrite relocation type. */
1808 1.1 christos switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1809 1.1 christos {
1810 1.1 christos case R_MICROBLAZE_64_PCREL:
1811 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1812 1.1 christos (int) R_MICROBLAZE_32_PCREL_LO);
1813 1.1 christos break;
1814 1.1 christos case R_MICROBLAZE_64:
1815 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1816 1.1 christos (int) R_MICROBLAZE_32_LO);
1817 1.1 christos break;
1818 1.1 christos default:
1819 1.1 christos /* Cannot happen. */
1820 1.1 christos BFD_ASSERT (FALSE);
1821 1.1 christos }
1822 1.1 christos }
1823 1.1 christos } /* Loop through all relocations. */
1824 1.1 christos
1825 1.1 christos /* Loop through the relocs again, and see if anything needs to change. */
1826 1.1 christos if (sec->relax_count > 0)
1827 1.1 christos {
1828 1.1 christos shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1829 1.1 christos rel_count = 0;
1830 1.1 christos sec->relax[sec->relax_count].addr = sec->size;
1831 1.1 christos
1832 1.1 christos for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1833 1.1.1.1.8.1 tls {
1834 1.1 christos bfd_vma nraddr;
1835 1.1 christos
1836 1.1 christos /* Get the new reloc address. */
1837 1.1 christos nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
1838 1.1 christos switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1839 1.1 christos {
1840 1.1 christos default:
1841 1.1 christos break;
1842 1.1 christos case R_MICROBLAZE_64_PCREL:
1843 1.1 christos break;
1844 1.1 christos case R_MICROBLAZE_64:
1845 1.1 christos case R_MICROBLAZE_32_LO:
1846 1.1 christos /* If this reloc is against a symbol defined in this
1847 1.1 christos section, we must check the addend to see it will put the value in
1848 1.1 christos range to be adjusted, and hence must be changed. */
1849 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1850 1.1 christos {
1851 1.1.1.1.8.1 tls isym = isymbuf + ELF32_R_SYM (irel->r_info);
1852 1.1 christos /* Only handle relocs against .text. */
1853 1.1 christos if (isym->st_shndx == shndx
1854 1.1 christos && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
1855 1.1 christos irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
1856 1.1 christos }
1857 1.1 christos break;
1858 1.1 christos case R_MICROBLAZE_NONE:
1859 1.1 christos {
1860 1.1 christos /* This was a PC-relative instruction that was
1861 1.1.1.1.8.1 tls completely resolved. */
1862 1.1.1.1.8.1 tls int sfix, efix;
1863 1.1 christos bfd_vma target_address;
1864 1.1 christos target_address = irel->r_addend + irel->r_offset;
1865 1.1.1.1.8.1 tls sfix = calc_fixup (irel->r_offset, 0, sec);
1866 1.1.1.1.8.1 tls efix = calc_fixup (target_address, 0, sec);
1867 1.1 christos irel->r_addend -= (efix - sfix);
1868 1.1 christos /* Should use HOWTO. */
1869 1.1 christos microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
1870 1.1 christos irel->r_addend);
1871 1.1 christos }
1872 1.1 christos break;
1873 1.1 christos case R_MICROBLAZE_64_NONE:
1874 1.1 christos {
1875 1.1 christos /* This was a PC-relative 64-bit instruction that was
1876 1.1.1.1.8.1 tls completely resolved. */
1877 1.1.1.1.8.1 tls int sfix, efix;
1878 1.1 christos bfd_vma target_address;
1879 1.1.1.1.8.1 tls target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
1880 1.1.1.1.8.1 tls sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
1881 1.1 christos efix = calc_fixup (target_address, 0, sec);
1882 1.1 christos irel->r_addend -= (efix - sfix);
1883 1.1 christos microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
1884 1.1 christos + INST_WORD_SIZE, irel->r_addend);
1885 1.1 christos }
1886 1.1 christos break;
1887 1.1 christos }
1888 1.1 christos irel->r_offset = nraddr;
1889 1.1 christos } /* Change all relocs in this section. */
1890 1.1 christos
1891 1.1 christos /* Look through all other sections. */
1892 1.1 christos for (o = abfd->sections; o != NULL; o = o->next)
1893 1.1 christos {
1894 1.1 christos Elf_Internal_Rela *irelocs;
1895 1.1 christos Elf_Internal_Rela *irelscan, *irelscanend;
1896 1.1 christos bfd_byte *ocontents;
1897 1.1 christos
1898 1.1 christos if (o == sec
1899 1.1 christos || (o->flags & SEC_RELOC) == 0
1900 1.1 christos || o->reloc_count == 0)
1901 1.1 christos continue;
1902 1.1 christos
1903 1.1 christos /* We always cache the relocs. Perhaps, if info->keep_memory is
1904 1.1 christos FALSE, we should free them, if we are permitted to. */
1905 1.1 christos
1906 1.1 christos irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE);
1907 1.1 christos if (irelocs == NULL)
1908 1.1 christos goto error_return;
1909 1.1 christos
1910 1.1 christos ocontents = NULL;
1911 1.1 christos irelscanend = irelocs + o->reloc_count;
1912 1.1 christos for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
1913 1.1 christos {
1914 1.1 christos if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
1915 1.1 christos {
1916 1.1 christos isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1917 1.1 christos
1918 1.1 christos /* Look at the reloc only if the value has been resolved. */
1919 1.1 christos if (isym->st_shndx == shndx
1920 1.1 christos && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1921 1.1 christos {
1922 1.1 christos if (ocontents == NULL)
1923 1.1 christos {
1924 1.1 christos if (elf_section_data (o)->this_hdr.contents != NULL)
1925 1.1 christos ocontents = elf_section_data (o)->this_hdr.contents;
1926 1.1 christos else
1927 1.1 christos {
1928 1.1 christos /* We always cache the section contents.
1929 1.1 christos Perhaps, if info->keep_memory is FALSE, we
1930 1.1 christos should free them, if we are permitted to. */
1931 1.1 christos if (o->rawsize == 0)
1932 1.1 christos o->rawsize = o->size;
1933 1.1 christos ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1934 1.1 christos if (ocontents == NULL)
1935 1.1 christos goto error_return;
1936 1.1 christos if (!bfd_get_section_contents (abfd, o, ocontents,
1937 1.1 christos (file_ptr) 0,
1938 1.1 christos o->rawsize))
1939 1.1 christos goto error_return;
1940 1.1.1.1.8.1 tls elf_section_data (o)->this_hdr.contents = ocontents;
1941 1.1 christos }
1942 1.1 christos
1943 1.1 christos }
1944 1.1 christos irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
1945 1.1 christos }
1946 1.1 christos else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
1947 1.1 christos {
1948 1.1 christos isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1949 1.1 christos
1950 1.1 christos /* Look at the reloc only if the value has been resolved. */
1951 1.1 christos if (ocontents == NULL)
1952 1.1 christos {
1953 1.1 christos if (elf_section_data (o)->this_hdr.contents != NULL)
1954 1.1 christos ocontents = elf_section_data (o)->this_hdr.contents;
1955 1.1 christos else
1956 1.1 christos {
1957 1.1 christos /* We always cache the section contents.
1958 1.1 christos Perhaps, if info->keep_memory is FALSE, we
1959 1.1 christos should free them, if we are permitted to. */
1960 1.1 christos
1961 1.1 christos if (o->rawsize == 0)
1962 1.1 christos o->rawsize = o->size;
1963 1.1 christos ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1964 1.1 christos if (ocontents == NULL)
1965 1.1 christos goto error_return;
1966 1.1 christos if (!bfd_get_section_contents (abfd, o, ocontents,
1967 1.1 christos (file_ptr) 0,
1968 1.1 christos o->rawsize))
1969 1.1 christos goto error_return;
1970 1.1 christos elf_section_data (o)->this_hdr.contents = ocontents;
1971 1.1.1.1.8.1 tls }
1972 1.1 christos }
1973 1.1 christos irelscan->r_addend -= calc_fixup (irel->r_addend
1974 1.1 christos + isym->st_value,
1975 1.1 christos 0,
1976 1.1 christos sec);
1977 1.1 christos }
1978 1.1 christos }
1979 1.1 christos else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
1980 1.1 christos || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO))
1981 1.1 christos {
1982 1.1 christos isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1983 1.1 christos
1984 1.1 christos /* Look at the reloc only if the value has been resolved. */
1985 1.1 christos if (isym->st_shndx == shndx
1986 1.1 christos && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1987 1.1 christos {
1988 1.1 christos bfd_vma immediate;
1989 1.1 christos bfd_vma target_address;
1990 1.1 christos
1991 1.1 christos if (ocontents == NULL)
1992 1.1 christos {
1993 1.1 christos if (elf_section_data (o)->this_hdr.contents != NULL)
1994 1.1 christos ocontents = elf_section_data (o)->this_hdr.contents;
1995 1.1 christos else
1996 1.1 christos {
1997 1.1 christos /* We always cache the section contents.
1998 1.1 christos Perhaps, if info->keep_memory is FALSE, we
1999 1.1 christos should free them, if we are permitted to. */
2000 1.1 christos if (o->rawsize == 0)
2001 1.1 christos o->rawsize = o->size;
2002 1.1 christos ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2003 1.1 christos if (ocontents == NULL)
2004 1.1 christos goto error_return;
2005 1.1 christos if (!bfd_get_section_contents (abfd, o, ocontents,
2006 1.1 christos (file_ptr) 0,
2007 1.1 christos o->rawsize))
2008 1.1 christos goto error_return;
2009 1.1.1.1.8.1 tls elf_section_data (o)->this_hdr.contents = ocontents;
2010 1.1.1.1.8.1 tls }
2011 1.1 christos }
2012 1.1.1.1.8.1 tls
2013 1.1 christos unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2014 1.1 christos immediate = instr & 0x0000ffff;
2015 1.1.1.1.8.1 tls target_address = immediate;
2016 1.1.1.1.8.1 tls offset = calc_fixup (target_address, 0, sec);
2017 1.1 christos immediate -= offset;
2018 1.1 christos irelscan->r_addend -= offset;
2019 1.1 christos microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2020 1.1 christos irelscan->r_addend);
2021 1.1 christos }
2022 1.1 christos }
2023 1.1 christos
2024 1.1 christos if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64)
2025 1.1 christos {
2026 1.1 christos isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2027 1.1 christos
2028 1.1 christos /* Look at the reloc only if the value has been resolved. */
2029 1.1 christos if (isym->st_shndx == shndx
2030 1.1 christos && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2031 1.1 christos {
2032 1.1 christos bfd_vma immediate;
2033 1.1 christos
2034 1.1 christos if (ocontents == NULL)
2035 1.1 christos {
2036 1.1 christos if (elf_section_data (o)->this_hdr.contents != NULL)
2037 1.1 christos ocontents = elf_section_data (o)->this_hdr.contents;
2038 1.1 christos else
2039 1.1 christos {
2040 1.1 christos /* We always cache the section contents.
2041 1.1 christos Perhaps, if info->keep_memory is FALSE, we
2042 1.1 christos should free them, if we are permitted to. */
2043 1.1 christos
2044 1.1 christos if (o->rawsize == 0)
2045 1.1 christos o->rawsize = o->size;
2046 1.1 christos ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2047 1.1 christos if (ocontents == NULL)
2048 1.1 christos goto error_return;
2049 1.1 christos if (!bfd_get_section_contents (abfd, o, ocontents,
2050 1.1 christos (file_ptr) 0,
2051 1.1 christos o->rawsize))
2052 1.1.1.1.8.1 tls goto error_return;
2053 1.1.1.1.8.1 tls elf_section_data (o)->this_hdr.contents = ocontents;
2054 1.1.1.1.8.1 tls }
2055 1.1.1.1.8.1 tls }
2056 1.1.1.1.8.1 tls unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2057 1.1.1.1.8.1 tls + irelscan->r_offset);
2058 1.1.1.1.8.1 tls unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2059 1.1.1.1.8.1 tls + irelscan->r_offset
2060 1.1 christos + INST_WORD_SIZE);
2061 1.1 christos immediate = (instr_hi & 0x0000ffff) << 16;
2062 1.1 christos immediate |= (instr_lo & 0x0000ffff);
2063 1.1 christos offset = calc_fixup (irelscan->r_addend, 0, sec);
2064 1.1 christos immediate -= offset;
2065 1.1 christos irelscan->r_addend -= offset;
2066 1.1 christos }
2067 1.1 christos }
2068 1.1 christos else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
2069 1.1 christos {
2070 1.1 christos isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2071 1.1 christos
2072 1.1 christos /* Look at the reloc only if the value has been resolved. */
2073 1.1 christos if (isym->st_shndx == shndx
2074 1.1 christos && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2075 1.1 christos {
2076 1.1 christos bfd_vma immediate;
2077 1.1 christos bfd_vma target_address;
2078 1.1 christos
2079 1.1 christos if (ocontents == NULL)
2080 1.1 christos {
2081 1.1 christos if (elf_section_data (o)->this_hdr.contents != NULL)
2082 1.1 christos ocontents = elf_section_data (o)->this_hdr.contents;
2083 1.1 christos else
2084 1.1 christos {
2085 1.1 christos /* We always cache the section contents.
2086 1.1 christos Perhaps, if info->keep_memory is FALSE, we
2087 1.1 christos should free them, if we are permitted to. */
2088 1.1 christos if (o->rawsize == 0)
2089 1.1 christos o->rawsize = o->size;
2090 1.1 christos ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2091 1.1 christos if (ocontents == NULL)
2092 1.1 christos goto error_return;
2093 1.1 christos if (!bfd_get_section_contents (abfd, o, ocontents,
2094 1.1 christos (file_ptr) 0,
2095 1.1 christos o->rawsize))
2096 1.1.1.1.8.1 tls goto error_return;
2097 1.1.1.1.8.1 tls elf_section_data (o)->this_hdr.contents = ocontents;
2098 1.1.1.1.8.1 tls }
2099 1.1.1.1.8.1 tls }
2100 1.1.1.1.8.1 tls unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2101 1.1.1.1.8.1 tls + irelscan->r_offset);
2102 1.1.1.1.8.1 tls unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2103 1.1 christos + irelscan->r_offset
2104 1.1.1.1.8.1 tls + INST_WORD_SIZE);
2105 1.1 christos immediate = (instr_hi & 0x0000ffff) << 16;
2106 1.1 christos immediate |= (instr_lo & 0x0000ffff);
2107 1.1.1.1.8.1 tls target_address = immediate;
2108 1.1.1.1.8.1 tls offset = calc_fixup (target_address, 0, sec);
2109 1.1 christos immediate -= offset;
2110 1.1 christos irelscan->r_addend -= offset;
2111 1.1 christos microblaze_bfd_write_imm_value_64 (abfd, ocontents
2112 1.1 christos + irelscan->r_offset, immediate);
2113 1.1 christos }
2114 1.1 christos }
2115 1.1 christos }
2116 1.1 christos }
2117 1.1 christos
2118 1.1 christos /* Adjust the local symbols defined in this section. */
2119 1.1.1.1.8.1 tls isymend = isymbuf + symtab_hdr->sh_info;
2120 1.1.1.1.8.1 tls for (isym = isymbuf; isym < isymend; isym++)
2121 1.1.1.1.8.1 tls {
2122 1.1.1.1.8.1 tls if (isym->st_shndx == shndx)
2123 1.1.1.1.8.1 tls {
2124 1.1 christos isym->st_value -= calc_fixup (isym->st_value, 0, sec);
2125 1.1 christos if (isym->st_size)
2126 1.1 christos isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
2127 1.1 christos }
2128 1.1.1.1.8.1 tls }
2129 1.1.1.1.8.1 tls
2130 1.1 christos /* Now adjust the global symbols defined in this section. */
2131 1.1 christos isym = isymbuf + symtab_hdr->sh_info;
2132 1.1.1.1.8.1 tls symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
2133 1.1 christos for (sym_index = 0; sym_index < symcount; sym_index++)
2134 1.1 christos {
2135 1.1.1.1.8.1 tls sym_hash = elf_sym_hashes (abfd)[sym_index];
2136 1.1.1.1.8.1 tls if ((sym_hash->root.type == bfd_link_hash_defined
2137 1.1.1.1.8.1 tls || sym_hash->root.type == bfd_link_hash_defweak)
2138 1.1.1.1.8.1 tls && sym_hash->root.u.def.section == sec)
2139 1.1.1.1.8.1 tls {
2140 1.1.1.1.8.1 tls sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
2141 1.1.1.1.8.1 tls 0, sec);
2142 1.1.1.1.8.1 tls if (sym_hash->size)
2143 1.1 christos sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
2144 1.1 christos sym_hash->size, sec);
2145 1.1 christos }
2146 1.1 christos }
2147 1.1 christos
2148 1.1 christos /* Physically move the code and change the cooked size. */
2149 1.1 christos dest = sec->relax[0].addr;
2150 1.1 christos for (i = 0; i < sec->relax_count; i++)
2151 1.1 christos {
2152 1.1 christos int len;
2153 1.1 christos src = sec->relax[i].addr + sec->relax[i].size;
2154 1.1 christos len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size;
2155 1.1 christos
2156 1.1 christos memmove (contents + dest, contents + src, len);
2157 1.1 christos sec->size -= sec->relax[i].size;
2158 1.1 christos dest += len;
2159 1.1 christos }
2160 1.1 christos
2161 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
2162 1.1 christos free_relocs = NULL;
2163 1.1 christos
2164 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
2165 1.1 christos free_contents = NULL;
2166 1.1 christos
2167 1.1 christos symtab_hdr->contents = (bfd_byte *) isymbuf;
2168 1.1 christos }
2169 1.1 christos
2170 1.1 christos if (free_relocs != NULL)
2171 1.1 christos {
2172 1.1 christos free (free_relocs);
2173 1.1 christos free_relocs = NULL;
2174 1.1 christos }
2175 1.1 christos
2176 1.1 christos if (free_contents != NULL)
2177 1.1 christos {
2178 1.1 christos if (!link_info->keep_memory)
2179 1.1 christos free (free_contents);
2180 1.1 christos else
2181 1.1 christos /* Cache the section contents for elf_link_input_bfd. */
2182 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
2183 1.1 christos free_contents = NULL;
2184 1.1.1.1.8.1 tls }
2185 1.1 christos
2186 1.1 christos if (sec->relax_count == 0)
2187 1.1 christos {
2188 1.1.1.1.8.1 tls *again = FALSE;
2189 1.1.1.1.8.1 tls free (sec->relax);
2190 1.1 christos sec->relax = NULL;
2191 1.1 christos }
2192 1.1 christos else
2193 1.1 christos *again = TRUE;
2194 1.1 christos return TRUE;
2195 1.1 christos
2196 1.1 christos error_return:
2197 1.1 christos if (free_relocs != NULL)
2198 1.1 christos free (free_relocs);
2199 1.1 christos if (free_contents != NULL)
2200 1.1 christos free (free_contents);
2201 1.1 christos if (sec->relax != NULL)
2202 1.1 christos {
2203 1.1 christos free (sec->relax);
2204 1.1 christos sec->relax = NULL;
2205 1.1 christos sec->relax_count = 0;
2206 1.1 christos }
2207 1.1 christos return FALSE;
2208 1.1 christos }
2209 1.1 christos
2210 1.1 christos /* Return the section that should be marked against GC for a given
2211 1.1 christos relocation. */
2212 1.1 christos
2213 1.1 christos static asection *
2214 1.1 christos microblaze_elf_gc_mark_hook (asection *sec,
2215 1.1 christos struct bfd_link_info * info,
2216 1.1 christos Elf_Internal_Rela * rel,
2217 1.1 christos struct elf_link_hash_entry * h,
2218 1.1 christos Elf_Internal_Sym * sym)
2219 1.1 christos {
2220 1.1 christos if (h != NULL)
2221 1.1 christos switch (ELF32_R_TYPE (rel->r_info))
2222 1.1 christos {
2223 1.1 christos case R_MICROBLAZE_GNU_VTINHERIT:
2224 1.1 christos case R_MICROBLAZE_GNU_VTENTRY:
2225 1.1 christos return NULL;
2226 1.1 christos }
2227 1.1 christos
2228 1.1 christos return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2229 1.1 christos }
2230 1.1 christos
2231 1.1 christos /* Update the got entry reference counts for the section being removed. */
2232 1.1 christos
2233 1.1 christos static bfd_boolean
2234 1.1 christos microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
2235 1.1 christos struct bfd_link_info * info ATTRIBUTE_UNUSED,
2236 1.1 christos asection * sec ATTRIBUTE_UNUSED,
2237 1.1 christos const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
2238 1.1 christos {
2239 1.1 christos return TRUE;
2240 1.1 christos }
2241 1.1 christos
2242 1.1 christos /* PIC support. */
2243 1.1 christos
2244 1.1 christos #define PLT_ENTRY_SIZE 16
2245 1.1 christos
2246 1.1 christos #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2247 1.1 christos #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2248 1.1 christos #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2249 1.1 christos #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2250 1.1 christos #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2251 1.1 christos
2252 1.1 christos /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
2253 1.1 christos shortcuts to them in our hash table. */
2254 1.1 christos
2255 1.1 christos static bfd_boolean
2256 1.1 christos create_got_section (bfd *dynobj, struct bfd_link_info *info)
2257 1.1 christos {
2258 1.1 christos struct elf32_mb_link_hash_table *htab;
2259 1.1 christos
2260 1.1 christos if (! _bfd_elf_create_got_section (dynobj, info))
2261 1.1 christos return FALSE;
2262 1.1.1.1.8.1 tls htab = elf32_mb_hash_table (info);
2263 1.1.1.1.8.1 tls if (htab == NULL)
2264 1.1 christos return FALSE;
2265 1.1 christos
2266 1.1 christos htab->sgot = bfd_get_linker_section (dynobj, ".got");
2267 1.1.1.1.8.1 tls htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
2268 1.1.1.1.8.1 tls if (!htab->sgot || !htab->sgotplt)
2269 1.1 christos return FALSE;
2270 1.1 christos
2271 1.1 christos if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL)
2272 1.1 christos htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got");
2273 1.1 christos if (htab->srelgot == NULL
2274 1.1 christos || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
2275 1.1 christos | SEC_LOAD
2276 1.1 christos | SEC_HAS_CONTENTS
2277 1.1 christos | SEC_IN_MEMORY
2278 1.1 christos | SEC_LINKER_CREATED
2279 1.1 christos | SEC_READONLY)
2280 1.1 christos || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
2281 1.1.1.1.8.1 tls return FALSE;
2282 1.1.1.1.8.1 tls return TRUE;
2283 1.1.1.1.8.1 tls }
2284 1.1.1.1.8.1 tls
2285 1.1.1.1.8.1 tls static bfd_boolean
2286 1.1.1.1.8.1 tls update_local_sym_info (bfd *abfd,
2287 1.1.1.1.8.1 tls Elf_Internal_Shdr *symtab_hdr,
2288 1.1.1.1.8.1 tls unsigned long r_symndx,
2289 1.1.1.1.8.1 tls unsigned int tls_type)
2290 1.1.1.1.8.1 tls {
2291 1.1.1.1.8.1 tls bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
2292 1.1.1.1.8.1 tls unsigned char *local_got_tls_masks;
2293 1.1.1.1.8.1 tls
2294 1.1.1.1.8.1 tls if (local_got_refcounts == NULL)
2295 1.1.1.1.8.1 tls {
2296 1.1.1.1.8.1 tls bfd_size_type size = symtab_hdr->sh_info;
2297 1.1.1.1.8.1 tls
2298 1.1.1.1.8.1 tls size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
2299 1.1.1.1.8.1 tls local_got_refcounts = bfd_zalloc (abfd, size);
2300 1.1.1.1.8.1 tls if (local_got_refcounts == NULL)
2301 1.1.1.1.8.1 tls return FALSE;
2302 1.1.1.1.8.1 tls elf_local_got_refcounts (abfd) = local_got_refcounts;
2303 1.1.1.1.8.1 tls }
2304 1.1.1.1.8.1 tls
2305 1.1.1.1.8.1 tls local_got_tls_masks =
2306 1.1.1.1.8.1 tls (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
2307 1.1.1.1.8.1 tls local_got_tls_masks[r_symndx] |= tls_type;
2308 1.1 christos local_got_refcounts[r_symndx] += 1;
2309 1.1 christos
2310 1.1 christos return TRUE;
2311 1.1 christos }
2312 1.1 christos /* Look through the relocs for a section during the first phase. */
2313 1.1 christos
2314 1.1 christos static bfd_boolean
2315 1.1 christos microblaze_elf_check_relocs (bfd * abfd,
2316 1.1 christos struct bfd_link_info * info,
2317 1.1 christos asection * sec,
2318 1.1 christos const Elf_Internal_Rela * relocs)
2319 1.1 christos {
2320 1.1 christos Elf_Internal_Shdr * symtab_hdr;
2321 1.1 christos struct elf_link_hash_entry ** sym_hashes;
2322 1.1 christos struct elf_link_hash_entry ** sym_hashes_end;
2323 1.1 christos const Elf_Internal_Rela * rel;
2324 1.1 christos const Elf_Internal_Rela * rel_end;
2325 1.1 christos struct elf32_mb_link_hash_table *htab;
2326 1.1 christos asection *sreloc = NULL;
2327 1.1 christos
2328 1.1 christos if (info->relocatable)
2329 1.1 christos return TRUE;
2330 1.1 christos
2331 1.1 christos htab = elf32_mb_hash_table (info);
2332 1.1 christos if (htab == NULL)
2333 1.1 christos return FALSE;
2334 1.1 christos
2335 1.1 christos symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2336 1.1 christos sym_hashes = elf_sym_hashes (abfd);
2337 1.1 christos sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
2338 1.1 christos if (!elf_bad_symtab (abfd))
2339 1.1 christos sym_hashes_end -= symtab_hdr->sh_info;
2340 1.1 christos
2341 1.1 christos rel_end = relocs + sec->reloc_count;
2342 1.1 christos
2343 1.1 christos for (rel = relocs; rel < rel_end; rel++)
2344 1.1.1.1.8.1 tls {
2345 1.1 christos unsigned int r_type;
2346 1.1 christos struct elf_link_hash_entry * h;
2347 1.1 christos unsigned long r_symndx;
2348 1.1 christos unsigned char tls_type = 0;
2349 1.1 christos
2350 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
2351 1.1 christos r_type = ELF32_R_TYPE (rel->r_info);
2352 1.1.1.1.8.1 tls
2353 1.1.1.1.8.1 tls if (r_symndx < symtab_hdr->sh_info)
2354 1.1.1.1.8.1 tls h = NULL;
2355 1.1.1.1.8.1 tls else
2356 1.1.1.1.8.1 tls {
2357 1.1.1.1.8.1 tls h = sym_hashes [r_symndx - symtab_hdr->sh_info];
2358 1.1.1.1.8.1 tls
2359 1.1 christos /* PR15323, ref flags aren't set for references in the same
2360 1.1 christos object. */
2361 1.1 christos h->root.non_ir_ref = 1;
2362 1.1 christos }
2363 1.1 christos
2364 1.1 christos switch (r_type)
2365 1.1 christos {
2366 1.1 christos /* This relocation describes the C++ object vtable hierarchy.
2367 1.1 christos Reconstruct it for later use during GC. */
2368 1.1 christos case R_MICROBLAZE_GNU_VTINHERIT:
2369 1.1 christos if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2370 1.1 christos return FALSE;
2371 1.1 christos break;
2372 1.1 christos
2373 1.1 christos /* This relocation describes which C++ vtable entries are actually
2374 1.1 christos used. Record for later use during GC. */
2375 1.1 christos case R_MICROBLAZE_GNU_VTENTRY:
2376 1.1 christos if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2377 1.1 christos return FALSE;
2378 1.1 christos break;
2379 1.1 christos
2380 1.1 christos /* This relocation requires .plt entry. */
2381 1.1 christos case R_MICROBLAZE_PLT_64:
2382 1.1 christos if (h != NULL)
2383 1.1 christos {
2384 1.1 christos h->needs_plt = 1;
2385 1.1 christos h->plt.refcount += 1;
2386 1.1.1.1.8.1 tls }
2387 1.1.1.1.8.1 tls break;
2388 1.1.1.1.8.1 tls
2389 1.1.1.1.8.1 tls /* This relocation requires .got entry. */
2390 1.1.1.1.8.1 tls case R_MICROBLAZE_TLSGD:
2391 1.1.1.1.8.1 tls tls_type |= (TLS_TLS | TLS_GD);
2392 1.1.1.1.8.1 tls goto dogottls;
2393 1.1 christos case R_MICROBLAZE_TLSLD:
2394 1.1 christos tls_type |= (TLS_TLS | TLS_LD);
2395 1.1 christos dogottls:
2396 1.1 christos sec->has_tls_reloc = 1;
2397 1.1 christos case R_MICROBLAZE_GOT_64:
2398 1.1 christos if (htab->sgot == NULL)
2399 1.1 christos {
2400 1.1 christos if (htab->elf.dynobj == NULL)
2401 1.1 christos htab->elf.dynobj = abfd;
2402 1.1 christos if (!create_got_section (htab->elf.dynobj, info))
2403 1.1 christos return FALSE;
2404 1.1.1.1.8.1 tls }
2405 1.1 christos if (h != NULL)
2406 1.1 christos {
2407 1.1 christos h->got.refcount += 1;
2408 1.1.1.1.8.1 tls elf32_mb_hash_entry (h)->tls_mask |= tls_type;
2409 1.1.1.1.8.1 tls }
2410 1.1 christos else
2411 1.1 christos {
2412 1.1 christos if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
2413 1.1 christos return FALSE;
2414 1.1 christos }
2415 1.1 christos break;
2416 1.1 christos
2417 1.1 christos case R_MICROBLAZE_64:
2418 1.1 christos case R_MICROBLAZE_64_PCREL:
2419 1.1 christos case R_MICROBLAZE_32:
2420 1.1 christos {
2421 1.1 christos if (h != NULL && !info->shared)
2422 1.1 christos {
2423 1.1 christos /* we may need a copy reloc. */
2424 1.1 christos h->non_got_ref = 1;
2425 1.1 christos
2426 1.1 christos /* we may also need a .plt entry. */
2427 1.1 christos h->plt.refcount += 1;
2428 1.1 christos if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2429 1.1 christos h->pointer_equality_needed = 1;
2430 1.1 christos }
2431 1.1 christos
2432 1.1 christos
2433 1.1 christos /* If we are creating a shared library, and this is a reloc
2434 1.1 christos against a global symbol, or a non PC relative reloc
2435 1.1 christos against a local symbol, then we need to copy the reloc
2436 1.1 christos into the shared library. However, if we are linking with
2437 1.1 christos -Bsymbolic, we do not need to copy a reloc against a
2438 1.1 christos global symbol which is defined in an object we are
2439 1.1 christos including in the link (i.e., DEF_REGULAR is set). At
2440 1.1 christos this point we have not seen all the input files, so it is
2441 1.1 christos possible that DEF_REGULAR is not set now but will be set
2442 1.1 christos later (it is never cleared). In case of a weak definition,
2443 1.1 christos DEF_REGULAR may be cleared later by a strong definition in
2444 1.1 christos a shared library. We account for that possibility below by
2445 1.1 christos storing information in the relocs_copied field of the hash
2446 1.1 christos table entry. A similar situation occurs when creating
2447 1.1 christos shared libraries and symbol visibility changes render the
2448 1.1 christos symbol local.
2449 1.1 christos
2450 1.1 christos If on the other hand, we are creating an executable, we
2451 1.1 christos may need to keep relocations for symbols satisfied by a
2452 1.1 christos dynamic library if we manage to avoid copy relocs for the
2453 1.1 christos symbol. */
2454 1.1 christos
2455 1.1 christos if ((info->shared
2456 1.1 christos && (sec->flags & SEC_ALLOC) != 0
2457 1.1 christos && (r_type != R_MICROBLAZE_64_PCREL
2458 1.1 christos || (h != NULL
2459 1.1 christos && (! info->symbolic
2460 1.1 christos || h->root.type == bfd_link_hash_defweak
2461 1.1 christos || !h->def_regular))))
2462 1.1 christos || (!info->shared
2463 1.1 christos && (sec->flags & SEC_ALLOC) != 0
2464 1.1 christos && h != NULL
2465 1.1 christos && (h->root.type == bfd_link_hash_defweak
2466 1.1 christos || !h->def_regular)))
2467 1.1 christos {
2468 1.1 christos struct elf32_mb_dyn_relocs *p;
2469 1.1 christos struct elf32_mb_dyn_relocs **head;
2470 1.1 christos
2471 1.1 christos /* When creating a shared object, we must copy these
2472 1.1 christos relocs into the output file. We create a reloc
2473 1.1 christos section in dynobj and make room for the reloc. */
2474 1.1 christos
2475 1.1 christos if (sreloc == NULL)
2476 1.1 christos {
2477 1.1 christos bfd *dynobj;
2478 1.1 christos
2479 1.1.1.1.8.1 tls if (htab->elf.dynobj == NULL)
2480 1.1.1.1.8.1 tls htab->elf.dynobj = abfd;
2481 1.1 christos dynobj = htab->elf.dynobj;
2482 1.1.1.1.8.1 tls
2483 1.1 christos sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2484 1.1 christos 2, abfd, 1);
2485 1.1 christos if (sreloc == NULL)
2486 1.1 christos return FALSE;
2487 1.1 christos }
2488 1.1 christos
2489 1.1 christos /* If this is a global symbol, we count the number of
2490 1.1 christos relocations we need for this symbol. */
2491 1.1 christos if (h != NULL)
2492 1.1 christos head = &((struct elf32_mb_link_hash_entry *) h)->dyn_relocs;
2493 1.1 christos else
2494 1.1 christos {
2495 1.1 christos /* Track dynamic relocs needed for local syms too.
2496 1.1 christos We really need local syms available to do this
2497 1.1 christos easily. Oh well. */
2498 1.1 christos
2499 1.1 christos asection *s;
2500 1.1 christos Elf_Internal_Sym *isym;
2501 1.1 christos void *vpp;
2502 1.1 christos
2503 1.1 christos isym = bfd_sym_from_r_symndx (&htab->sym_sec,
2504 1.1 christos abfd, r_symndx);
2505 1.1 christos if (isym == NULL)
2506 1.1 christos return FALSE;
2507 1.1 christos
2508 1.1 christos s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2509 1.1 christos if (s == NULL)
2510 1.1 christos return FALSE;
2511 1.1 christos
2512 1.1 christos vpp = &elf_section_data (s)->local_dynrel;
2513 1.1 christos head = (struct elf32_mb_dyn_relocs **) vpp;
2514 1.1 christos }
2515 1.1 christos
2516 1.1 christos p = *head;
2517 1.1 christos if (p == NULL || p->sec != sec)
2518 1.1 christos {
2519 1.1 christos bfd_size_type amt = sizeof *p;
2520 1.1 christos p = ((struct elf32_mb_dyn_relocs *)
2521 1.1 christos bfd_alloc (htab->elf.dynobj, amt));
2522 1.1 christos if (p == NULL)
2523 1.1 christos return FALSE;
2524 1.1 christos p->next = *head;
2525 1.1 christos *head = p;
2526 1.1 christos p->sec = sec;
2527 1.1 christos p->count = 0;
2528 1.1 christos p->pc_count = 0;
2529 1.1 christos }
2530 1.1 christos
2531 1.1 christos p->count += 1;
2532 1.1 christos if (r_type == R_MICROBLAZE_64_PCREL)
2533 1.1 christos p->pc_count += 1;
2534 1.1 christos }
2535 1.1 christos }
2536 1.1 christos break;
2537 1.1 christos }
2538 1.1 christos }
2539 1.1 christos
2540 1.1 christos return TRUE;
2541 1.1 christos }
2542 1.1 christos
2543 1.1 christos static bfd_boolean
2544 1.1 christos microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
2545 1.1 christos {
2546 1.1 christos struct elf32_mb_link_hash_table *htab;
2547 1.1 christos
2548 1.1 christos htab = elf32_mb_hash_table (info);
2549 1.1 christos if (htab == NULL)
2550 1.1 christos return FALSE;
2551 1.1 christos
2552 1.1 christos if (!htab->sgot && !create_got_section (dynobj, info))
2553 1.1 christos return FALSE;
2554 1.1.1.1.8.1 tls
2555 1.1.1.1.8.1 tls if (!_bfd_elf_create_dynamic_sections (dynobj, info))
2556 1.1.1.1.8.1 tls return FALSE;
2557 1.1 christos
2558 1.1.1.1.8.1 tls htab->splt = bfd_get_linker_section (dynobj, ".plt");
2559 1.1 christos htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
2560 1.1 christos htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
2561 1.1 christos if (!info->shared)
2562 1.1 christos htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
2563 1.1 christos
2564 1.1 christos if (!htab->splt || !htab->srelplt || !htab->sdynbss
2565 1.1 christos || (!info->shared && !htab->srelbss))
2566 1.1 christos abort ();
2567 1.1 christos
2568 1.1 christos return TRUE;
2569 1.1 christos }
2570 1.1 christos
2571 1.1 christos /* Copy the extra info we tack onto an elf_link_hash_entry. */
2572 1.1 christos
2573 1.1 christos static void
2574 1.1 christos microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2575 1.1 christos struct elf_link_hash_entry *dir,
2576 1.1 christos struct elf_link_hash_entry *ind)
2577 1.1 christos {
2578 1.1 christos struct elf32_mb_link_hash_entry *edir, *eind;
2579 1.1 christos
2580 1.1 christos edir = (struct elf32_mb_link_hash_entry *) dir;
2581 1.1 christos eind = (struct elf32_mb_link_hash_entry *) ind;
2582 1.1 christos
2583 1.1 christos if (eind->dyn_relocs != NULL)
2584 1.1 christos {
2585 1.1 christos if (edir->dyn_relocs != NULL)
2586 1.1 christos {
2587 1.1 christos struct elf32_mb_dyn_relocs **pp;
2588 1.1 christos struct elf32_mb_dyn_relocs *p;
2589 1.1 christos
2590 1.1 christos if (ind->root.type == bfd_link_hash_indirect)
2591 1.1 christos abort ();
2592 1.1 christos
2593 1.1 christos /* Add reloc counts against the weak sym to the strong sym
2594 1.1 christos list. Merge any entries against the same section. */
2595 1.1 christos for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
2596 1.1 christos {
2597 1.1 christos struct elf32_mb_dyn_relocs *q;
2598 1.1 christos
2599 1.1 christos for (q = edir->dyn_relocs; q != NULL; q = q->next)
2600 1.1 christos if (q->sec == p->sec)
2601 1.1 christos {
2602 1.1 christos q->pc_count += p->pc_count;
2603 1.1 christos q->count += p->count;
2604 1.1 christos *pp = p->next;
2605 1.1 christos break;
2606 1.1 christos }
2607 1.1 christos if (q == NULL)
2608 1.1 christos pp = &p->next;
2609 1.1 christos }
2610 1.1 christos *pp = edir->dyn_relocs;
2611 1.1 christos }
2612 1.1 christos
2613 1.1.1.1.8.1 tls edir->dyn_relocs = eind->dyn_relocs;
2614 1.1.1.1.8.1 tls eind->dyn_relocs = NULL;
2615 1.1 christos }
2616 1.1 christos
2617 1.1 christos edir->tls_mask |= eind->tls_mask;
2618 1.1 christos
2619 1.1 christos _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2620 1.1 christos }
2621 1.1 christos
2622 1.1 christos static bfd_boolean
2623 1.1 christos microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2624 1.1 christos struct elf_link_hash_entry *h)
2625 1.1 christos {
2626 1.1 christos struct elf32_mb_link_hash_table *htab;
2627 1.1 christos struct elf32_mb_link_hash_entry * eh;
2628 1.1 christos struct elf32_mb_dyn_relocs *p;
2629 1.1 christos asection *sdynbss, *s;
2630 1.1 christos unsigned int power_of_two;
2631 1.1 christos bfd *dynobj;
2632 1.1 christos
2633 1.1 christos htab = elf32_mb_hash_table (info);
2634 1.1 christos if (htab == NULL)
2635 1.1 christos return FALSE;
2636 1.1 christos
2637 1.1 christos /* If this is a function, put it in the procedure linkage table. We
2638 1.1 christos will fill in the contents of the procedure linkage table later,
2639 1.1 christos when we know the address of the .got section. */
2640 1.1 christos if (h->type == STT_FUNC
2641 1.1 christos || h->needs_plt)
2642 1.1 christos {
2643 1.1 christos if (h->plt.refcount <= 0
2644 1.1 christos || SYMBOL_CALLS_LOCAL (info, h)
2645 1.1 christos || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2646 1.1 christos && h->root.type == bfd_link_hash_undefweak))
2647 1.1 christos {
2648 1.1 christos /* This case can occur if we saw a PLT reloc in an input
2649 1.1 christos file, but the symbol was never referred to by a dynamic
2650 1.1 christos object, or if all references were garbage collected. In
2651 1.1 christos such a case, we don't actually need to build a procedure
2652 1.1 christos linkage table, and we can just do a PC32 reloc instead. */
2653 1.1 christos h->plt.offset = (bfd_vma) -1;
2654 1.1 christos h->needs_plt = 0;
2655 1.1 christos }
2656 1.1 christos
2657 1.1 christos return TRUE;
2658 1.1 christos }
2659 1.1 christos else
2660 1.1 christos /* It's possible that we incorrectly decided a .plt reloc was
2661 1.1 christos needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2662 1.1 christos check_relocs. We can't decide accurately between function and
2663 1.1 christos non-function syms in check-relocs; Objects loaded later in
2664 1.1 christos the link may change h->type. So fix it now. */
2665 1.1 christos h->plt.offset = (bfd_vma) -1;
2666 1.1 christos
2667 1.1 christos /* If this is a weak symbol, and there is a real definition, the
2668 1.1 christos processor independent code will have arranged for us to see the
2669 1.1 christos real definition first, and we can just use the same value. */
2670 1.1 christos if (h->u.weakdef != NULL)
2671 1.1 christos {
2672 1.1 christos BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2673 1.1 christos || h->u.weakdef->root.type == bfd_link_hash_defweak);
2674 1.1 christos h->root.u.def.section = h->u.weakdef->root.u.def.section;
2675 1.1 christos h->root.u.def.value = h->u.weakdef->root.u.def.value;
2676 1.1 christos return TRUE;
2677 1.1 christos }
2678 1.1 christos
2679 1.1 christos /* This is a reference to a symbol defined by a dynamic object which
2680 1.1 christos is not a function. */
2681 1.1 christos
2682 1.1 christos /* If we are creating a shared library, we must presume that the
2683 1.1 christos only references to the symbol are via the global offset table.
2684 1.1 christos For such cases we need not do anything here; the relocations will
2685 1.1 christos be handled correctly by relocate_section. */
2686 1.1 christos if (info->shared)
2687 1.1 christos return TRUE;
2688 1.1 christos
2689 1.1 christos /* If there are no references to this symbol that do not use the
2690 1.1 christos GOT, we don't need to generate a copy reloc. */
2691 1.1 christos if (!h->non_got_ref)
2692 1.1 christos return TRUE;
2693 1.1 christos
2694 1.1 christos /* If -z nocopyreloc was given, we won't generate them either. */
2695 1.1 christos if (info->nocopyreloc)
2696 1.1 christos {
2697 1.1 christos h->non_got_ref = 0;
2698 1.1 christos return TRUE;
2699 1.1 christos }
2700 1.1 christos
2701 1.1 christos eh = (struct elf32_mb_link_hash_entry *) h;
2702 1.1 christos for (p = eh->dyn_relocs; p != NULL; p = p->next)
2703 1.1 christos {
2704 1.1 christos s = p->sec->output_section;
2705 1.1 christos if (s != NULL && (s->flags & SEC_READONLY) != 0)
2706 1.1 christos break;
2707 1.1 christos }
2708 1.1 christos
2709 1.1 christos /* If we didn't find any dynamic relocs in read-only sections, then
2710 1.1 christos we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2711 1.1 christos if (p == NULL)
2712 1.1 christos {
2713 1.1 christos h->non_got_ref = 0;
2714 1.1 christos return TRUE;
2715 1.1 christos }
2716 1.1 christos
2717 1.1 christos /* We must allocate the symbol in our .dynbss section, which will
2718 1.1 christos become part of the .bss section of the executable. There will be
2719 1.1 christos an entry for this symbol in the .dynsym section. The dynamic
2720 1.1 christos object will contain position independent code, so all references
2721 1.1 christos from the dynamic object to this symbol will go through the global
2722 1.1 christos offset table. The dynamic linker will use the .dynsym entry to
2723 1.1 christos determine the address it must put in the global offset table, so
2724 1.1 christos both the dynamic object and the regular object will refer to the
2725 1.1 christos same memory location for the variable. */
2726 1.1 christos
2727 1.1 christos /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2728 1.1 christos to copy the initial value out of the dynamic object and into the
2729 1.1 christos runtime process image. */
2730 1.1 christos dynobj = elf_hash_table (info)->dynobj;
2731 1.1 christos BFD_ASSERT (dynobj != NULL);
2732 1.1 christos if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2733 1.1 christos {
2734 1.1 christos htab->srelbss->size += sizeof (Elf32_External_Rela);
2735 1.1 christos h->needs_copy = 1;
2736 1.1 christos }
2737 1.1 christos
2738 1.1 christos /* We need to figure out the alignment required for this symbol. I
2739 1.1 christos have no idea how ELF linkers handle this. */
2740 1.1 christos power_of_two = bfd_log2 (h->size);
2741 1.1 christos if (power_of_two > 3)
2742 1.1 christos power_of_two = 3;
2743 1.1 christos
2744 1.1 christos sdynbss = htab->sdynbss;
2745 1.1 christos /* Apply the required alignment. */
2746 1.1 christos sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
2747 1.1 christos if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss))
2748 1.1 christos {
2749 1.1 christos if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two))
2750 1.1 christos return FALSE;
2751 1.1 christos }
2752 1.1 christos
2753 1.1 christos /* Define the symbol as being at this point in the section. */
2754 1.1 christos h->root.u.def.section = sdynbss;
2755 1.1 christos h->root.u.def.value = sdynbss->size;
2756 1.1 christos
2757 1.1 christos /* Increment the section size to make room for the symbol. */
2758 1.1 christos sdynbss->size += h->size;
2759 1.1 christos return TRUE;
2760 1.1 christos }
2761 1.1 christos
2762 1.1 christos /* Allocate space in .plt, .got and associated reloc sections for
2763 1.1 christos dynamic relocs. */
2764 1.1 christos
2765 1.1 christos static bfd_boolean
2766 1.1 christos allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
2767 1.1 christos {
2768 1.1 christos struct bfd_link_info *info;
2769 1.1 christos struct elf32_mb_link_hash_table *htab;
2770 1.1 christos struct elf32_mb_link_hash_entry *eh;
2771 1.1 christos struct elf32_mb_dyn_relocs *p;
2772 1.1 christos
2773 1.1 christos if (h->root.type == bfd_link_hash_indirect)
2774 1.1 christos return TRUE;
2775 1.1 christos
2776 1.1 christos info = (struct bfd_link_info *) dat;
2777 1.1 christos htab = elf32_mb_hash_table (info);
2778 1.1 christos if (htab == NULL)
2779 1.1 christos return FALSE;
2780 1.1 christos
2781 1.1 christos if (htab->elf.dynamic_sections_created
2782 1.1 christos && h->plt.refcount > 0)
2783 1.1 christos {
2784 1.1 christos /* Make sure this symbol is output as a dynamic symbol.
2785 1.1 christos Undefined weak syms won't yet be marked as dynamic. */
2786 1.1 christos if (h->dynindx == -1
2787 1.1 christos && !h->forced_local)
2788 1.1 christos {
2789 1.1 christos if (! bfd_elf_link_record_dynamic_symbol (info, h))
2790 1.1 christos return FALSE;
2791 1.1 christos }
2792 1.1 christos
2793 1.1 christos if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
2794 1.1 christos {
2795 1.1 christos asection *s = htab->splt;
2796 1.1 christos
2797 1.1 christos /* The first entry in .plt is reserved. */
2798 1.1 christos if (s->size == 0)
2799 1.1 christos s->size = PLT_ENTRY_SIZE;
2800 1.1 christos
2801 1.1 christos h->plt.offset = s->size;
2802 1.1 christos
2803 1.1 christos /* If this symbol is not defined in a regular file, and we are
2804 1.1 christos not generating a shared library, then set the symbol to this
2805 1.1 christos location in the .plt. This is required to make function
2806 1.1 christos pointers compare as equal between the normal executable and
2807 1.1 christos the shared library. */
2808 1.1 christos if (! info->shared
2809 1.1 christos && !h->def_regular)
2810 1.1 christos {
2811 1.1 christos h->root.u.def.section = s;
2812 1.1 christos h->root.u.def.value = h->plt.offset;
2813 1.1 christos }
2814 1.1 christos
2815 1.1 christos /* Make room for this entry. */
2816 1.1 christos s->size += PLT_ENTRY_SIZE;
2817 1.1 christos
2818 1.1 christos /* We also need to make an entry in the .got.plt section, which
2819 1.1 christos will be placed in the .got section by the linker script. */
2820 1.1 christos htab->sgotplt->size += 4;
2821 1.1 christos
2822 1.1 christos /* We also need to make an entry in the .rel.plt section. */
2823 1.1 christos htab->srelplt->size += sizeof (Elf32_External_Rela);
2824 1.1 christos }
2825 1.1 christos else
2826 1.1 christos {
2827 1.1 christos h->plt.offset = (bfd_vma) -1;
2828 1.1 christos h->needs_plt = 0;
2829 1.1 christos }
2830 1.1 christos }
2831 1.1 christos else
2832 1.1 christos {
2833 1.1.1.1.8.1 tls h->plt.offset = (bfd_vma) -1;
2834 1.1 christos h->needs_plt = 0;
2835 1.1 christos }
2836 1.1.1.1.8.1 tls
2837 1.1 christos eh = (struct elf32_mb_link_hash_entry *) h;
2838 1.1 christos if (h->got.refcount > 0)
2839 1.1 christos {
2840 1.1 christos unsigned int need;
2841 1.1 christos asection *s;
2842 1.1 christos
2843 1.1 christos /* Make sure this symbol is output as a dynamic symbol.
2844 1.1 christos Undefined weak syms won't yet be marked as dynamic. */
2845 1.1 christos if (h->dynindx == -1
2846 1.1 christos && !h->forced_local)
2847 1.1 christos {
2848 1.1.1.1.8.1 tls if (! bfd_elf_link_record_dynamic_symbol (info, h))
2849 1.1.1.1.8.1 tls return FALSE;
2850 1.1.1.1.8.1 tls }
2851 1.1.1.1.8.1 tls
2852 1.1.1.1.8.1 tls need = 0;
2853 1.1.1.1.8.1 tls if ((eh->tls_mask & TLS_TLS) != 0)
2854 1.1.1.1.8.1 tls {
2855 1.1.1.1.8.1 tls /* Handle TLS Symbol */
2856 1.1.1.1.8.1 tls if ((eh->tls_mask & TLS_LD) != 0)
2857 1.1.1.1.8.1 tls {
2858 1.1.1.1.8.1 tls if (!eh->elf.def_dynamic)
2859 1.1.1.1.8.1 tls /* We'll just use htab->tlsld_got.offset. This should
2860 1.1.1.1.8.1 tls always be the case. It's a little odd if we have
2861 1.1.1.1.8.1 tls a local dynamic reloc against a non-local symbol. */
2862 1.1.1.1.8.1 tls htab->tlsld_got.refcount += 1;
2863 1.1.1.1.8.1 tls else
2864 1.1.1.1.8.1 tls need += 8;
2865 1.1.1.1.8.1 tls }
2866 1.1.1.1.8.1 tls if ((eh->tls_mask & TLS_GD) != 0)
2867 1.1.1.1.8.1 tls need += 8;
2868 1.1.1.1.8.1 tls }
2869 1.1.1.1.8.1 tls else
2870 1.1.1.1.8.1 tls {
2871 1.1.1.1.8.1 tls /* Regular (non-TLS) symbol */
2872 1.1.1.1.8.1 tls need += 4;
2873 1.1.1.1.8.1 tls }
2874 1.1.1.1.8.1 tls if (need == 0)
2875 1.1.1.1.8.1 tls {
2876 1.1.1.1.8.1 tls h->got.offset = (bfd_vma) -1;
2877 1.1.1.1.8.1 tls }
2878 1.1.1.1.8.1 tls else
2879 1.1.1.1.8.1 tls {
2880 1.1.1.1.8.1 tls s = htab->sgot;
2881 1.1 christos h->got.offset = s->size;
2882 1.1 christos s->size += need;
2883 1.1 christos htab->srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
2884 1.1 christos }
2885 1.1 christos }
2886 1.1 christos else
2887 1.1 christos h->got.offset = (bfd_vma) -1;
2888 1.1 christos
2889 1.1 christos if (eh->dyn_relocs == NULL)
2890 1.1 christos return TRUE;
2891 1.1 christos
2892 1.1 christos /* In the shared -Bsymbolic case, discard space allocated for
2893 1.1 christos dynamic pc-relative relocs against symbols which turn out to be
2894 1.1 christos defined in regular objects. For the normal shared case, discard
2895 1.1 christos space for pc-relative relocs that have become local due to symbol
2896 1.1 christos visibility changes. */
2897 1.1 christos
2898 1.1 christos if (info->shared)
2899 1.1 christos {
2900 1.1 christos if (h->def_regular
2901 1.1 christos && (h->forced_local
2902 1.1 christos || info->symbolic))
2903 1.1 christos {
2904 1.1 christos struct elf32_mb_dyn_relocs **pp;
2905 1.1 christos
2906 1.1 christos for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2907 1.1 christos {
2908 1.1 christos p->count -= p->pc_count;
2909 1.1 christos p->pc_count = 0;
2910 1.1 christos if (p->count == 0)
2911 1.1 christos *pp = p->next;
2912 1.1 christos else
2913 1.1 christos pp = &p->next;
2914 1.1 christos }
2915 1.1 christos }
2916 1.1 christos }
2917 1.1 christos else
2918 1.1 christos {
2919 1.1 christos /* For the non-shared case, discard space for relocs against
2920 1.1 christos symbols which turn out to need copy relocs or are not
2921 1.1 christos dynamic. */
2922 1.1 christos
2923 1.1 christos if (!h->non_got_ref
2924 1.1 christos && ((h->def_dynamic
2925 1.1 christos && !h->def_regular)
2926 1.1 christos || (htab->elf.dynamic_sections_created
2927 1.1 christos && (h->root.type == bfd_link_hash_undefweak
2928 1.1 christos || h->root.type == bfd_link_hash_undefined))))
2929 1.1 christos {
2930 1.1 christos /* Make sure this symbol is output as a dynamic symbol.
2931 1.1 christos Undefined weak syms won't yet be marked as dynamic. */
2932 1.1 christos if (h->dynindx == -1
2933 1.1 christos && !h->forced_local)
2934 1.1 christos {
2935 1.1 christos if (! bfd_elf_link_record_dynamic_symbol (info, h))
2936 1.1 christos return FALSE;
2937 1.1 christos }
2938 1.1 christos
2939 1.1 christos /* If that succeeded, we know we'll be keeping all the
2940 1.1 christos relocs. */
2941 1.1 christos if (h->dynindx != -1)
2942 1.1 christos goto keep;
2943 1.1 christos }
2944 1.1 christos
2945 1.1 christos eh->dyn_relocs = NULL;
2946 1.1 christos
2947 1.1 christos keep: ;
2948 1.1 christos }
2949 1.1 christos
2950 1.1 christos /* Finally, allocate space. */
2951 1.1 christos for (p = eh->dyn_relocs; p != NULL; p = p->next)
2952 1.1 christos {
2953 1.1 christos asection *sreloc = elf_section_data (p->sec)->sreloc;
2954 1.1 christos sreloc->size += p->count * sizeof (Elf32_External_Rela);
2955 1.1 christos }
2956 1.1 christos
2957 1.1 christos return TRUE;
2958 1.1 christos }
2959 1.1 christos
2960 1.1 christos /* Set the sizes of the dynamic sections. */
2961 1.1 christos
2962 1.1 christos static bfd_boolean
2963 1.1 christos microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2964 1.1 christos struct bfd_link_info *info)
2965 1.1 christos {
2966 1.1 christos struct elf32_mb_link_hash_table *htab;
2967 1.1 christos bfd *dynobj;
2968 1.1 christos asection *s;
2969 1.1 christos bfd *ibfd;
2970 1.1 christos
2971 1.1 christos htab = elf32_mb_hash_table (info);
2972 1.1 christos if (htab == NULL)
2973 1.1 christos return FALSE;
2974 1.1 christos
2975 1.1 christos dynobj = htab->elf.dynobj;
2976 1.1 christos BFD_ASSERT (dynobj != NULL);
2977 1.1 christos
2978 1.1 christos /* Set up .got offsets for local syms, and space for local dynamic
2979 1.1 christos relocs. */
2980 1.1 christos for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2981 1.1 christos {
2982 1.1.1.1.8.1 tls bfd_signed_vma *local_got;
2983 1.1 christos bfd_signed_vma *end_local_got;
2984 1.1 christos bfd_size_type locsymcount;
2985 1.1 christos Elf_Internal_Shdr *symtab_hdr;
2986 1.1 christos unsigned char *lgot_masks;
2987 1.1 christos asection *srel;
2988 1.1 christos
2989 1.1 christos if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2990 1.1 christos continue;
2991 1.1 christos
2992 1.1 christos for (s = ibfd->sections; s != NULL; s = s->next)
2993 1.1 christos {
2994 1.1 christos struct elf32_mb_dyn_relocs *p;
2995 1.1 christos
2996 1.1 christos for (p = ((struct elf32_mb_dyn_relocs *)
2997 1.1 christos elf_section_data (s)->local_dynrel);
2998 1.1 christos p != NULL;
2999 1.1 christos p = p->next)
3000 1.1 christos {
3001 1.1 christos if (!bfd_is_abs_section (p->sec)
3002 1.1 christos && bfd_is_abs_section (p->sec->output_section))
3003 1.1 christos {
3004 1.1 christos /* Input section has been discarded, either because
3005 1.1 christos it is a copy of a linkonce section or due to
3006 1.1 christos linker script /DISCARD/, so we'll be discarding
3007 1.1 christos the relocs too. */
3008 1.1 christos }
3009 1.1 christos else if (p->count != 0)
3010 1.1 christos {
3011 1.1 christos srel = elf_section_data (p->sec)->sreloc;
3012 1.1 christos srel->size += p->count * sizeof (Elf32_External_Rela);
3013 1.1 christos if ((p->sec->output_section->flags & SEC_READONLY) != 0)
3014 1.1 christos info->flags |= DF_TEXTREL;
3015 1.1 christos }
3016 1.1 christos }
3017 1.1 christos }
3018 1.1 christos
3019 1.1 christos local_got = elf_local_got_refcounts (ibfd);
3020 1.1 christos if (!local_got)
3021 1.1 christos continue;
3022 1.1.1.1.8.1 tls
3023 1.1 christos symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3024 1.1 christos locsymcount = symtab_hdr->sh_info;
3025 1.1 christos end_local_got = local_got + locsymcount;
3026 1.1.1.1.8.1 tls lgot_masks = (unsigned char *) end_local_got;
3027 1.1.1.1.8.1 tls s = htab->sgot;
3028 1.1.1.1.8.1 tls srel = htab->srelgot;
3029 1.1.1.1.8.1 tls
3030 1.1.1.1.8.1 tls for (; local_got < end_local_got; ++local_got, ++lgot_masks)
3031 1.1.1.1.8.1 tls {
3032 1.1.1.1.8.1 tls if (*local_got > 0)
3033 1.1.1.1.8.1 tls {
3034 1.1.1.1.8.1 tls unsigned int need = 0;
3035 1.1.1.1.8.1 tls if ((*lgot_masks & TLS_TLS) != 0)
3036 1.1.1.1.8.1 tls {
3037 1.1.1.1.8.1 tls if ((*lgot_masks & TLS_GD) != 0)
3038 1.1.1.1.8.1 tls need += 8;
3039 1.1.1.1.8.1 tls if ((*lgot_masks & TLS_LD) != 0)
3040 1.1.1.1.8.1 tls htab->tlsld_got.refcount += 1;
3041 1.1.1.1.8.1 tls }
3042 1.1.1.1.8.1 tls else
3043 1.1.1.1.8.1 tls need += 4;
3044 1.1.1.1.8.1 tls
3045 1.1.1.1.8.1 tls if (need == 0)
3046 1.1.1.1.8.1 tls {
3047 1.1.1.1.8.1 tls *local_got = (bfd_vma) -1;
3048 1.1.1.1.8.1 tls }
3049 1.1.1.1.8.1 tls else
3050 1.1.1.1.8.1 tls {
3051 1.1.1.1.8.1 tls *local_got = s->size;
3052 1.1 christos s->size += need;
3053 1.1 christos if (info->shared)
3054 1.1 christos srel->size += need * (sizeof (Elf32_External_Rela) / 4);
3055 1.1 christos }
3056 1.1 christos }
3057 1.1 christos else
3058 1.1 christos *local_got = (bfd_vma) -1;
3059 1.1 christos }
3060 1.1 christos }
3061 1.1 christos
3062 1.1.1.1.8.1 tls /* Allocate global sym .plt and .got entries, and space for global
3063 1.1.1.1.8.1 tls sym dynamic relocs. */
3064 1.1.1.1.8.1 tls elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
3065 1.1.1.1.8.1 tls
3066 1.1.1.1.8.1 tls if (htab->tlsld_got.refcount > 0)
3067 1.1.1.1.8.1 tls {
3068 1.1.1.1.8.1 tls htab->tlsld_got.offset = htab->sgot->size;
3069 1.1.1.1.8.1 tls htab->sgot->size += 8;
3070 1.1.1.1.8.1 tls if (info->shared)
3071 1.1.1.1.8.1 tls htab->srelgot->size += sizeof (Elf32_External_Rela);
3072 1.1 christos }
3073 1.1 christos else
3074 1.1 christos htab->tlsld_got.offset = (bfd_vma) -1;
3075 1.1 christos
3076 1.1 christos if (elf_hash_table (info)->dynamic_sections_created)
3077 1.1 christos {
3078 1.1 christos /* Make space for the trailing nop in .plt. */
3079 1.1 christos if (htab->splt->size > 0)
3080 1.1 christos htab->splt->size += 4;
3081 1.1 christos }
3082 1.1 christos
3083 1.1 christos /* The check_relocs and adjust_dynamic_symbol entry points have
3084 1.1 christos determined the sizes of the various dynamic sections. Allocate
3085 1.1 christos memory for them. */
3086 1.1 christos for (s = dynobj->sections; s != NULL; s = s->next)
3087 1.1 christos {
3088 1.1 christos const char *name;
3089 1.1 christos bfd_boolean strip = FALSE;
3090 1.1 christos
3091 1.1 christos if ((s->flags & SEC_LINKER_CREATED) == 0)
3092 1.1 christos continue;
3093 1.1 christos
3094 1.1 christos /* It's OK to base decisions on the section name, because none
3095 1.1 christos of the dynobj section names depend upon the input files. */
3096 1.1 christos name = bfd_get_section_name (dynobj, s);
3097 1.1 christos
3098 1.1 christos if (strncmp (name, ".rela", 5) == 0)
3099 1.1 christos {
3100 1.1 christos if (s->size == 0)
3101 1.1 christos {
3102 1.1 christos /* If we don't need this section, strip it from the
3103 1.1 christos output file. This is to handle .rela.bss and
3104 1.1 christos .rela.plt. We must create it in
3105 1.1 christos create_dynamic_sections, because it must be created
3106 1.1 christos before the linker maps input sections to output
3107 1.1 christos sections. The linker does that before
3108 1.1 christos adjust_dynamic_symbol is called, and it is that
3109 1.1 christos function which decides whether anything needs to go
3110 1.1 christos into these sections. */
3111 1.1 christos strip = TRUE;
3112 1.1 christos }
3113 1.1 christos else
3114 1.1 christos {
3115 1.1 christos /* We use the reloc_count field as a counter if we need
3116 1.1 christos to copy relocs into the output file. */
3117 1.1 christos s->reloc_count = 0;
3118 1.1 christos }
3119 1.1 christos }
3120 1.1 christos else if (s != htab->splt && s != htab->sgot && s != htab->sgotplt)
3121 1.1 christos {
3122 1.1 christos /* It's not one of our sections, so don't allocate space. */
3123 1.1 christos continue;
3124 1.1 christos }
3125 1.1 christos
3126 1.1 christos if (strip)
3127 1.1 christos {
3128 1.1 christos s->flags |= SEC_EXCLUDE;
3129 1.1 christos continue;
3130 1.1 christos }
3131 1.1 christos
3132 1.1 christos /* Allocate memory for the section contents. */
3133 1.1 christos /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3134 1.1 christos Unused entries should be reclaimed before the section's contents
3135 1.1 christos are written out, but at the moment this does not happen. Thus in
3136 1.1 christos order to prevent writing out garbage, we initialise the section's
3137 1.1 christos contents to zero. */
3138 1.1 christos s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3139 1.1 christos if (s->contents == NULL && s->size != 0)
3140 1.1 christos return FALSE;
3141 1.1 christos }
3142 1.1 christos
3143 1.1 christos if (elf_hash_table (info)->dynamic_sections_created)
3144 1.1 christos {
3145 1.1 christos /* Add some entries to the .dynamic section. We fill in the
3146 1.1 christos values later, in microblaze_elf_finish_dynamic_sections, but we
3147 1.1 christos must add the entries now so that we get the correct size for
3148 1.1 christos the .dynamic section. The DT_DEBUG entry is filled in by the
3149 1.1 christos dynamic linker and used by the debugger. */
3150 1.1 christos #define add_dynamic_entry(TAG, VAL) \
3151 1.1 christos _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3152 1.1 christos
3153 1.1 christos if (info->executable)
3154 1.1 christos {
3155 1.1 christos if (!add_dynamic_entry (DT_DEBUG, 0))
3156 1.1 christos return FALSE;
3157 1.1 christos }
3158 1.1 christos
3159 1.1 christos if (!add_dynamic_entry (DT_RELA, 0)
3160 1.1 christos || !add_dynamic_entry (DT_RELASZ, 0)
3161 1.1 christos || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
3162 1.1 christos return FALSE;
3163 1.1 christos
3164 1.1 christos if (htab->splt->size != 0)
3165 1.1 christos {
3166 1.1 christos if (!add_dynamic_entry (DT_PLTGOT, 0)
3167 1.1 christos || !add_dynamic_entry (DT_PLTRELSZ, 0)
3168 1.1 christos || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3169 1.1 christos || !add_dynamic_entry (DT_JMPREL, 0)
3170 1.1 christos || !add_dynamic_entry (DT_BIND_NOW, 1))
3171 1.1 christos return FALSE;
3172 1.1 christos }
3173 1.1 christos
3174 1.1 christos if (info->flags & DF_TEXTREL)
3175 1.1 christos {
3176 1.1 christos if (!add_dynamic_entry (DT_TEXTREL, 0))
3177 1.1 christos return FALSE;
3178 1.1 christos }
3179 1.1 christos }
3180 1.1 christos #undef add_dynamic_entry
3181 1.1 christos return TRUE;
3182 1.1 christos }
3183 1.1 christos
3184 1.1 christos /* Finish up dynamic symbol handling. We set the contents of various
3185 1.1 christos dynamic sections here. */
3186 1.1 christos
3187 1.1 christos static bfd_boolean
3188 1.1 christos microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
3189 1.1 christos struct bfd_link_info *info,
3190 1.1.1.1.8.1 tls struct elf_link_hash_entry *h,
3191 1.1 christos Elf_Internal_Sym *sym)
3192 1.1 christos {
3193 1.1 christos struct elf32_mb_link_hash_table *htab;
3194 1.1 christos struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h);
3195 1.1 christos
3196 1.1 christos htab = elf32_mb_hash_table (info);
3197 1.1 christos if (htab == NULL)
3198 1.1 christos return FALSE;
3199 1.1 christos
3200 1.1 christos if (h->plt.offset != (bfd_vma) -1)
3201 1.1 christos {
3202 1.1 christos asection *splt;
3203 1.1 christos asection *srela;
3204 1.1 christos asection *sgotplt;
3205 1.1 christos Elf_Internal_Rela rela;
3206 1.1 christos bfd_byte *loc;
3207 1.1 christos bfd_vma plt_index;
3208 1.1 christos bfd_vma got_offset;
3209 1.1 christos bfd_vma got_addr;
3210 1.1 christos
3211 1.1 christos /* This symbol has an entry in the procedure linkage table. Set
3212 1.1 christos it up. */
3213 1.1 christos BFD_ASSERT (h->dynindx != -1);
3214 1.1 christos
3215 1.1 christos splt = htab->splt;
3216 1.1 christos srela = htab->srelplt;
3217 1.1 christos sgotplt = htab->sgotplt;
3218 1.1 christos BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
3219 1.1 christos
3220 1.1 christos plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
3221 1.1 christos got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
3222 1.1 christos got_addr = got_offset;
3223 1.1 christos
3224 1.1 christos /* For non-PIC objects we need absolute address of the GOT entry. */
3225 1.1 christos if (!info->shared)
3226 1.1 christos got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset;
3227 1.1 christos
3228 1.1 christos /* Fill in the entry in the procedure linkage table. */
3229 1.1 christos bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
3230 1.1 christos splt->contents + h->plt.offset);
3231 1.1 christos if (info->shared)
3232 1.1 christos bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
3233 1.1 christos splt->contents + h->plt.offset + 4);
3234 1.1 christos else
3235 1.1 christos bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
3236 1.1 christos splt->contents + h->plt.offset + 4);
3237 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
3238 1.1 christos splt->contents + h->plt.offset + 8);
3239 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
3240 1.1 christos splt->contents + h->plt.offset + 12);
3241 1.1 christos
3242 1.1 christos /* Any additions to the .got section??? */
3243 1.1 christos /* bfd_put_32 (output_bfd,
3244 1.1 christos splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3245 1.1 christos sgotplt->contents + got_offset); */
3246 1.1 christos
3247 1.1 christos /* Fill in the entry in the .rela.plt section. */
3248 1.1 christos rela.r_offset = (sgotplt->output_section->vma
3249 1.1 christos + sgotplt->output_offset
3250 1.1 christos + got_offset);
3251 1.1 christos rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
3252 1.1 christos rela.r_addend = 0;
3253 1.1 christos loc = srela->contents;
3254 1.1 christos loc += plt_index * sizeof (Elf32_External_Rela);
3255 1.1 christos bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3256 1.1 christos
3257 1.1 christos if (!h->def_regular)
3258 1.1 christos {
3259 1.1 christos /* Mark the symbol as undefined, rather than as defined in
3260 1.1 christos the .plt section. Zero the value. */
3261 1.1 christos sym->st_shndx = SHN_UNDEF;
3262 1.1.1.1.8.1 tls sym->st_value = 0;
3263 1.1.1.1.8.1 tls }
3264 1.1.1.1.8.1 tls }
3265 1.1.1.1.8.1 tls
3266 1.1 christos /* h->got.refcount to be checked ? */
3267 1.1 christos if (h->got.offset != (bfd_vma) -1 &&
3268 1.1 christos ! ((h->got.offset & 1) ||
3269 1.1.1.1.8.1 tls IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
3270 1.1 christos {
3271 1.1 christos asection *sgot;
3272 1.1 christos asection *srela;
3273 1.1 christos bfd_vma offset;
3274 1.1 christos
3275 1.1 christos /* This symbol has an entry in the global offset table. Set it
3276 1.1 christos up. */
3277 1.1 christos
3278 1.1.1.1.8.1 tls sgot = htab->sgot;
3279 1.1 christos srela = htab->srelgot;
3280 1.1 christos BFD_ASSERT (sgot != NULL && srela != NULL);
3281 1.1 christos
3282 1.1 christos offset = (sgot->output_section->vma + sgot->output_offset
3283 1.1 christos + (h->got.offset &~ (bfd_vma) 1));
3284 1.1 christos
3285 1.1 christos /* If this is a -Bsymbolic link, and the symbol is defined
3286 1.1 christos locally, we just want to emit a RELATIVE reloc. Likewise if
3287 1.1 christos the symbol was forced to be local because of a version file.
3288 1.1 christos The entry in the global offset table will already have been
3289 1.1 christos initialized in the relocate_section function. */
3290 1.1 christos if (info->shared
3291 1.1.1.1.8.1 tls && (info->symbolic || h->dynindx == -1)
3292 1.1.1.1.8.1 tls && h->def_regular)
3293 1.1.1.1.8.1 tls {
3294 1.1.1.1.8.1 tls asection *sec = h->root.u.def.section;
3295 1.1.1.1.8.1 tls microblaze_elf_output_dynamic_relocation (output_bfd,
3296 1.1.1.1.8.1 tls srela, srela->reloc_count++,
3297 1.1.1.1.8.1 tls /* symindex= */ 0,
3298 1.1 christos R_MICROBLAZE_REL, offset,
3299 1.1 christos h->root.u.def.value
3300 1.1 christos + sec->output_section->vma
3301 1.1.1.1.8.1 tls + sec->output_offset);
3302 1.1.1.1.8.1 tls }
3303 1.1.1.1.8.1 tls else
3304 1.1.1.1.8.1 tls {
3305 1.1.1.1.8.1 tls microblaze_elf_output_dynamic_relocation (output_bfd,
3306 1.1 christos srela, srela->reloc_count++,
3307 1.1 christos h->dynindx,
3308 1.1 christos R_MICROBLAZE_GLOB_DAT,
3309 1.1 christos offset, 0);
3310 1.1 christos }
3311 1.1 christos
3312 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) 0,
3313 1.1 christos sgot->contents + (h->got.offset &~ (bfd_vma) 1));
3314 1.1 christos }
3315 1.1 christos
3316 1.1 christos if (h->needs_copy)
3317 1.1 christos {
3318 1.1 christos asection *s;
3319 1.1 christos Elf_Internal_Rela rela;
3320 1.1 christos bfd_byte *loc;
3321 1.1 christos
3322 1.1.1.1.8.1 tls /* This symbols needs a copy reloc. Set it up. */
3323 1.1 christos
3324 1.1 christos BFD_ASSERT (h->dynindx != -1);
3325 1.1 christos
3326 1.1 christos s = bfd_get_linker_section (htab->elf.dynobj, ".rela.bss");
3327 1.1 christos BFD_ASSERT (s != NULL);
3328 1.1 christos
3329 1.1 christos rela.r_offset = (h->root.u.def.value
3330 1.1 christos + h->root.u.def.section->output_section->vma
3331 1.1 christos + h->root.u.def.section->output_offset);
3332 1.1 christos rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
3333 1.1 christos rela.r_addend = 0;
3334 1.1 christos loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
3335 1.1.1.1.8.1 tls bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3336 1.1.1.1.8.1 tls }
3337 1.1.1.1.8.1 tls
3338 1.1 christos /* Mark some specially defined symbols as absolute. */
3339 1.1 christos if (h == htab->elf.hdynamic
3340 1.1 christos || h == htab->elf.hgot
3341 1.1 christos || h == htab->elf.hplt)
3342 1.1 christos sym->st_shndx = SHN_ABS;
3343 1.1 christos
3344 1.1 christos return TRUE;
3345 1.1 christos }
3346 1.1 christos
3347 1.1 christos
3348 1.1 christos /* Finish up the dynamic sections. */
3349 1.1 christos
3350 1.1 christos static bfd_boolean
3351 1.1 christos microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
3352 1.1 christos struct bfd_link_info *info)
3353 1.1 christos {
3354 1.1 christos bfd *dynobj;
3355 1.1 christos asection *sdyn, *sgot;
3356 1.1 christos struct elf32_mb_link_hash_table *htab;
3357 1.1 christos
3358 1.1 christos htab = elf32_mb_hash_table (info);
3359 1.1 christos if (htab == NULL)
3360 1.1.1.1.8.1 tls return FALSE;
3361 1.1 christos
3362 1.1 christos dynobj = htab->elf.dynobj;
3363 1.1 christos
3364 1.1 christos sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3365 1.1 christos
3366 1.1 christos if (htab->elf.dynamic_sections_created)
3367 1.1.1.1.8.1 tls {
3368 1.1 christos asection *splt;
3369 1.1 christos Elf32_External_Dyn *dyncon, *dynconend;
3370 1.1 christos
3371 1.1 christos splt = bfd_get_linker_section (dynobj, ".plt");
3372 1.1 christos BFD_ASSERT (splt != NULL && sdyn != NULL);
3373 1.1 christos
3374 1.1 christos dyncon = (Elf32_External_Dyn *) sdyn->contents;
3375 1.1 christos dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
3376 1.1 christos for (; dyncon < dynconend; dyncon++)
3377 1.1 christos {
3378 1.1 christos Elf_Internal_Dyn dyn;
3379 1.1 christos const char *name;
3380 1.1 christos bfd_boolean size;
3381 1.1 christos
3382 1.1 christos bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
3383 1.1 christos
3384 1.1 christos switch (dyn.d_tag)
3385 1.1 christos {
3386 1.1 christos case DT_PLTGOT: name = ".got.plt"; size = FALSE; break;
3387 1.1 christos case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
3388 1.1 christos case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
3389 1.1 christos case DT_RELA: name = ".rela.dyn"; size = FALSE; break;
3390 1.1 christos case DT_RELASZ: name = ".rela.dyn"; size = TRUE; break;
3391 1.1 christos default: name = NULL; size = FALSE; break;
3392 1.1 christos }
3393 1.1 christos
3394 1.1 christos if (name != NULL)
3395 1.1 christos {
3396 1.1 christos asection *s;
3397 1.1 christos
3398 1.1 christos s = bfd_get_section_by_name (output_bfd, name);
3399 1.1 christos if (s == NULL)
3400 1.1 christos dyn.d_un.d_val = 0;
3401 1.1 christos else
3402 1.1 christos {
3403 1.1 christos if (! size)
3404 1.1 christos dyn.d_un.d_ptr = s->vma;
3405 1.1 christos else
3406 1.1 christos dyn.d_un.d_val = s->size;
3407 1.1 christos }
3408 1.1 christos bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3409 1.1 christos }
3410 1.1 christos }
3411 1.1 christos
3412 1.1 christos /* Clear the first entry in the procedure linkage table,
3413 1.1 christos and put a nop in the last four bytes. */
3414 1.1 christos if (splt->size > 0)
3415 1.1 christos {
3416 1.1 christos memset (splt->contents, 0, PLT_ENTRY_SIZE);
3417 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
3418 1.1 christos splt->contents + splt->size - 4);
3419 1.1 christos }
3420 1.1 christos
3421 1.1 christos elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
3422 1.1.1.1.8.1 tls }
3423 1.1 christos
3424 1.1 christos /* Set the first entry in the global offset table to the address of
3425 1.1 christos the dynamic section. */
3426 1.1 christos sgot = bfd_get_linker_section (dynobj, ".got.plt");
3427 1.1 christos if (sgot && sgot->size > 0)
3428 1.1 christos {
3429 1.1 christos if (sdyn == NULL)
3430 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3431 1.1 christos else
3432 1.1 christos bfd_put_32 (output_bfd,
3433 1.1 christos sdyn->output_section->vma + sdyn->output_offset,
3434 1.1 christos sgot->contents);
3435 1.1 christos elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3436 1.1 christos }
3437 1.1 christos
3438 1.1 christos if (htab->sgot && htab->sgot->size > 0)
3439 1.1 christos elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
3440 1.1 christos
3441 1.1 christos return TRUE;
3442 1.1 christos }
3443 1.1 christos
3444 1.1 christos /* Hook called by the linker routine which adds symbols from an object
3445 1.1 christos file. We use it to put .comm items in .sbss, and not .bss. */
3446 1.1 christos
3447 1.1 christos static bfd_boolean
3448 1.1 christos microblaze_elf_add_symbol_hook (bfd *abfd,
3449 1.1 christos struct bfd_link_info *info,
3450 1.1 christos Elf_Internal_Sym *sym,
3451 1.1 christos const char **namep ATTRIBUTE_UNUSED,
3452 1.1 christos flagword *flagsp ATTRIBUTE_UNUSED,
3453 1.1 christos asection **secp,
3454 1.1 christos bfd_vma *valp)
3455 1.1 christos {
3456 1.1 christos if (sym->st_shndx == SHN_COMMON
3457 1.1 christos && !info->relocatable
3458 1.1.1.1.8.1 tls && sym->st_size <= elf_gp_size (abfd))
3459 1.1 christos {
3460 1.1 christos /* Common symbols less than or equal to -G nn bytes are automatically
3461 1.1 christos put into .sbss. */
3462 1.1 christos *secp = bfd_make_section_old_way (abfd, ".sbss");
3463 1.1 christos if (*secp == NULL
3464 1.1 christos || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON))
3465 1.1 christos return FALSE;
3466 1.1 christos
3467 1.1 christos *valp = sym->st_size;
3468 1.1 christos }
3469 1.1.1.1.8.1 tls
3470 1.1.1.1.8.1 tls return TRUE;
3471 1.1 christos }
3472 1.1 christos
3473 1.1 christos #define TARGET_LITTLE_SYM bfd_elf32_microblazeel_vec
3474 1.1 christos #define TARGET_LITTLE_NAME "elf32-microblazeel"
3475 1.1 christos
3476 1.1 christos #define TARGET_BIG_SYM bfd_elf32_microblaze_vec
3477 1.1 christos #define TARGET_BIG_NAME "elf32-microblaze"
3478 1.1 christos
3479 1.1.1.1.8.1 tls #define ELF_ARCH bfd_arch_microblaze
3480 1.1 christos #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3481 1.1 christos #define ELF_MACHINE_CODE EM_MICROBLAZE
3482 1.1 christos #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3483 1.1 christos #define ELF_MAXPAGESIZE 0x1000
3484 1.1 christos #define elf_info_to_howto microblaze_elf_info_to_howto
3485 1.1 christos #define elf_info_to_howto_rel NULL
3486 1.1 christos
3487 1.1.1.1.8.1 tls #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3488 1.1 christos #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3489 1.1 christos #define elf_backend_relocate_section microblaze_elf_relocate_section
3490 1.1 christos #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3491 1.1 christos #define bfd_elf32_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data
3492 1.1 christos #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3493 1.1 christos
3494 1.1 christos #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3495 1.1 christos #define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
3496 1.1 christos #define elf_backend_check_relocs microblaze_elf_check_relocs
3497 1.1 christos #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3498 1.1 christos #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3499 1.1 christos #define elf_backend_can_gc_sections 1
3500 1.1 christos #define elf_backend_can_refcount 1
3501 1.1 christos #define elf_backend_want_got_plt 1
3502 1.1 christos #define elf_backend_plt_readonly 1
3503 1.1 christos #define elf_backend_got_header_size 12
3504 1.1 christos #define elf_backend_rela_normal 1
3505 1.1 christos
3506 1.1 christos #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3507 1.1 christos #define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
3508 1.1 christos #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3509 1.1 christos #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3510 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3511 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3512
3513 #include "elf32-target.h"
3514