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