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