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