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