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