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