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