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