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