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