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