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