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