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