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