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