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