coff-arm.c revision 1.10 1 1.1 christos /* BFD back-end for ARM COFF files.
2 1.10 christos Copyright (C) 1990-2022 Free Software Foundation, Inc.
3 1.1 christos Written by Cygnus Support.
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 Free Software
19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 christos MA 02110-1301, USA. */
21 1.1 christos
22 1.1 christos #include "sysdep.h"
23 1.1 christos #include "bfd.h"
24 1.1 christos #include "libbfd.h"
25 1.1 christos #include "coff/arm.h"
26 1.1 christos #include "coff/internal.h"
27 1.9 christos #include "cpu-arm.h"
28 1.9 christos #include "coff-arm.h"
29 1.1 christos
30 1.1 christos #ifdef COFF_WITH_PE
31 1.1 christos #include "coff/pe.h"
32 1.1 christos #endif
33 1.1 christos
34 1.1 christos #include "libcoff.h"
35 1.1 christos
36 1.9 christos /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
37 1.9 christos #define OCTETS_PER_BYTE(ABFD, SEC) 1
38 1.9 christos
39 1.1 christos /* Macros for manipulation the bits in the flags field of the coff data
40 1.1 christos structure. */
41 1.1 christos #define APCS_26_FLAG(abfd) \
42 1.1 christos (coff_data (abfd)->flags & F_APCS_26)
43 1.1 christos
44 1.1 christos #define APCS_FLOAT_FLAG(abfd) \
45 1.1 christos (coff_data (abfd)->flags & F_APCS_FLOAT)
46 1.1 christos
47 1.1 christos #define PIC_FLAG(abfd) \
48 1.1 christos (coff_data (abfd)->flags & F_PIC)
49 1.1 christos
50 1.1 christos #define APCS_SET(abfd) \
51 1.1 christos (coff_data (abfd)->flags & F_APCS_SET)
52 1.1 christos
53 1.1 christos #define SET_APCS_FLAGS(abfd, flgs) \
54 1.1 christos do \
55 1.1 christos { \
56 1.1 christos coff_data (abfd)->flags &= ~(F_APCS_26 | F_APCS_FLOAT | F_PIC); \
57 1.1 christos coff_data (abfd)->flags |= (flgs) | F_APCS_SET; \
58 1.1 christos } \
59 1.1 christos while (0)
60 1.1 christos
61 1.1 christos #define INTERWORK_FLAG(abfd) \
62 1.1 christos (coff_data (abfd)->flags & F_INTERWORK)
63 1.1 christos
64 1.1 christos #define INTERWORK_SET(abfd) \
65 1.1 christos (coff_data (abfd)->flags & F_INTERWORK_SET)
66 1.1 christos
67 1.1 christos #define SET_INTERWORK_FLAG(abfd, flg) \
68 1.1 christos do \
69 1.1 christos { \
70 1.1 christos coff_data (abfd)->flags &= ~F_INTERWORK; \
71 1.1 christos coff_data (abfd)->flags |= (flg) | F_INTERWORK_SET; \
72 1.1 christos } \
73 1.1 christos while (0)
74 1.1 christos
75 1.1 christos #ifndef NUM_ELEM
76 1.1 christos #define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0]))
77 1.1 christos #endif
78 1.1 christos
79 1.1 christos typedef enum {bunknown, b9, b12, b23} thumb_pcrel_branchtype;
80 1.1 christos /* Some typedefs for holding instructions. */
81 1.1 christos typedef unsigned long int insn32;
82 1.1 christos typedef unsigned short int insn16;
83 1.1 christos
84 1.1 christos /* The linker script knows the section names for placement.
85 1.1 christos The entry_names are used to do simple name mangling on the stubs.
86 1.1 christos Given a function name, and its type, the stub can be found. The
87 1.1 christos name can be changed. The only requirement is the %s be present. */
88 1.1 christos
89 1.1 christos #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
90 1.1 christos #define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb"
91 1.1 christos
92 1.1 christos #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
93 1.1 christos #define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm"
94 1.1 christos
95 1.1 christos /* Used by the assembler. */
96 1.1 christos
97 1.1 christos static bfd_reloc_status_type
98 1.1 christos coff_arm_reloc (bfd *abfd,
99 1.1 christos arelent *reloc_entry,
100 1.1 christos asymbol *symbol ATTRIBUTE_UNUSED,
101 1.1 christos void * data,
102 1.9 christos asection *input_section,
103 1.1 christos bfd *output_bfd,
104 1.1 christos char **error_message ATTRIBUTE_UNUSED)
105 1.1 christos {
106 1.1 christos symvalue diff;
107 1.1 christos
108 1.1 christos if (output_bfd == NULL)
109 1.1 christos return bfd_reloc_continue;
110 1.1 christos
111 1.1 christos diff = reloc_entry->addend;
112 1.1 christos
113 1.1 christos #define DOIT(x) \
114 1.1 christos x = ((x & ~howto->dst_mask) \
115 1.1 christos | (((x & howto->src_mask) + diff) & howto->dst_mask))
116 1.1 christos
117 1.8 christos if (diff != 0)
118 1.8 christos {
119 1.8 christos reloc_howto_type *howto = reloc_entry->howto;
120 1.9 christos bfd_size_type octets = (reloc_entry->address
121 1.9 christos * OCTETS_PER_BYTE (abfd, input_section));
122 1.9 christos unsigned char *addr = (unsigned char *) data + octets;
123 1.8 christos
124 1.9 christos if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
125 1.8 christos return bfd_reloc_outofrange;
126 1.1 christos
127 1.10 christos switch (bfd_get_reloc_size (howto))
128 1.8 christos {
129 1.10 christos case 1:
130 1.1 christos {
131 1.8 christos char x = bfd_get_8 (abfd, addr);
132 1.8 christos DOIT (x);
133 1.8 christos bfd_put_8 (abfd, x, addr);
134 1.8 christos }
135 1.8 christos break;
136 1.1 christos
137 1.10 christos case 2:
138 1.8 christos {
139 1.8 christos short x = bfd_get_16 (abfd, addr);
140 1.8 christos DOIT (x);
141 1.8 christos bfd_put_16 (abfd, (bfd_vma) x, addr);
142 1.8 christos }
143 1.8 christos break;
144 1.1 christos
145 1.10 christos case 4:
146 1.8 christos {
147 1.8 christos long x = bfd_get_32 (abfd, addr);
148 1.8 christos DOIT (x);
149 1.8 christos bfd_put_32 (abfd, (bfd_vma) x, addr);
150 1.8 christos }
151 1.8 christos break;
152 1.1 christos
153 1.8 christos default:
154 1.8 christos abort ();
155 1.8 christos }
156 1.8 christos }
157 1.1 christos
158 1.1 christos /* Now let bfd_perform_relocation finish everything up. */
159 1.1 christos return bfd_reloc_continue;
160 1.1 christos }
161 1.1 christos
162 1.1 christos /* If USER_LABEL_PREFIX is defined as "_" (see coff_arm_is_local_label_name()
163 1.1 christos in this file), then TARGET_UNDERSCORE should be defined, otherwise it
164 1.1 christos should not. */
165 1.1 christos #ifndef TARGET_UNDERSCORE
166 1.1 christos #define TARGET_UNDERSCORE '_'
167 1.1 christos #endif
168 1.1 christos
169 1.1 christos #ifndef PCRELOFFSET
170 1.10 christos #define PCRELOFFSET true
171 1.1 christos #endif
172 1.1 christos
173 1.1 christos /* These most certainly belong somewhere else. Just had to get rid of
174 1.1 christos the manifest constants in the code. */
175 1.1 christos
176 1.1 christos #ifdef ARM_WINCE
177 1.1 christos
178 1.1 christos #define ARM_26D 0
179 1.1 christos #define ARM_32 1
180 1.1 christos #define ARM_RVA32 2
181 1.1 christos #define ARM_26 3
182 1.1 christos #define ARM_THUMB12 4
183 1.1 christos #define ARM_SECTION 14
184 1.1 christos #define ARM_SECREL 15
185 1.1 christos
186 1.1 christos #else
187 1.1 christos
188 1.8 christos #define ARM_8 0
189 1.8 christos #define ARM_16 1
190 1.8 christos #define ARM_32 2
191 1.8 christos #define ARM_26 3
192 1.1 christos #define ARM_DISP8 4
193 1.1 christos #define ARM_DISP16 5
194 1.1 christos #define ARM_DISP32 6
195 1.8 christos #define ARM_26D 7
196 1.1 christos /* 8 is unused. */
197 1.1 christos #define ARM_NEG16 9
198 1.1 christos #define ARM_NEG32 10
199 1.1 christos #define ARM_RVA32 11
200 1.1 christos #define ARM_THUMB9 12
201 1.1 christos #define ARM_THUMB12 13
202 1.1 christos #define ARM_THUMB23 14
203 1.1 christos
204 1.1 christos #endif
205 1.1 christos
206 1.1 christos static bfd_reloc_status_type aoutarm_fix_pcrel_26_done
207 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
208 1.1 christos static bfd_reloc_status_type aoutarm_fix_pcrel_26
209 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
210 1.1 christos static bfd_reloc_status_type coff_thumb_pcrel_12
211 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
212 1.1 christos #ifndef ARM_WINCE
213 1.1 christos static bfd_reloc_status_type coff_thumb_pcrel_9
214 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
215 1.1 christos static bfd_reloc_status_type coff_thumb_pcrel_23
216 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
217 1.1 christos #endif
218 1.1 christos
219 1.1 christos static reloc_howto_type aoutarm_std_reloc_howto[] =
220 1.1 christos {
221 1.1 christos #ifdef ARM_WINCE
222 1.1 christos HOWTO (ARM_26D,
223 1.1 christos 2,
224 1.10 christos 4,
225 1.1 christos 24,
226 1.10 christos true,
227 1.1 christos 0,
228 1.1 christos complain_overflow_dont,
229 1.1 christos aoutarm_fix_pcrel_26_done,
230 1.1 christos "ARM_26D",
231 1.10 christos true, /* partial_inplace. */
232 1.1 christos 0x00ffffff,
233 1.1 christos 0x0,
234 1.1 christos PCRELOFFSET),
235 1.1 christos HOWTO (ARM_32,
236 1.1 christos 0,
237 1.10 christos 4,
238 1.1 christos 32,
239 1.10 christos false,
240 1.1 christos 0,
241 1.1 christos complain_overflow_bitfield,
242 1.1 christos coff_arm_reloc,
243 1.1 christos "ARM_32",
244 1.10 christos true, /* partial_inplace. */
245 1.1 christos 0xffffffff,
246 1.1 christos 0xffffffff,
247 1.1 christos PCRELOFFSET),
248 1.1 christos HOWTO (ARM_RVA32,
249 1.1 christos 0,
250 1.10 christos 4,
251 1.1 christos 32,
252 1.10 christos false,
253 1.1 christos 0,
254 1.1 christos complain_overflow_bitfield,
255 1.1 christos coff_arm_reloc,
256 1.1 christos "ARM_RVA32",
257 1.10 christos true, /* partial_inplace. */
258 1.1 christos 0xffffffff,
259 1.1 christos 0xffffffff,
260 1.1 christos PCRELOFFSET),
261 1.1 christos HOWTO (ARM_26,
262 1.1 christos 2,
263 1.10 christos 4,
264 1.1 christos 24,
265 1.10 christos true,
266 1.1 christos 0,
267 1.1 christos complain_overflow_signed,
268 1.1 christos aoutarm_fix_pcrel_26 ,
269 1.1 christos "ARM_26",
270 1.10 christos false,
271 1.1 christos 0x00ffffff,
272 1.1 christos 0x00ffffff,
273 1.1 christos PCRELOFFSET),
274 1.1 christos HOWTO (ARM_THUMB12,
275 1.1 christos 1,
276 1.10 christos 2,
277 1.1 christos 11,
278 1.10 christos true,
279 1.1 christos 0,
280 1.1 christos complain_overflow_signed,
281 1.1 christos coff_thumb_pcrel_12 ,
282 1.1 christos "ARM_THUMB12",
283 1.10 christos false,
284 1.1 christos 0x000007ff,
285 1.1 christos 0x000007ff,
286 1.1 christos PCRELOFFSET),
287 1.1 christos EMPTY_HOWTO (-1),
288 1.1 christos EMPTY_HOWTO (-1),
289 1.1 christos EMPTY_HOWTO (-1),
290 1.1 christos EMPTY_HOWTO (-1),
291 1.1 christos EMPTY_HOWTO (-1),
292 1.1 christos EMPTY_HOWTO (-1),
293 1.1 christos EMPTY_HOWTO (-1),
294 1.1 christos EMPTY_HOWTO (-1),
295 1.1 christos EMPTY_HOWTO (-1),
296 1.1 christos HOWTO (ARM_SECTION,
297 1.1 christos 0,
298 1.10 christos 2,
299 1.1 christos 16,
300 1.10 christos false,
301 1.1 christos 0,
302 1.1 christos complain_overflow_bitfield,
303 1.1 christos coff_arm_reloc,
304 1.1 christos "ARM_SECTION",
305 1.10 christos true, /* partial_inplace. */
306 1.1 christos 0x0000ffff,
307 1.1 christos 0x0000ffff,
308 1.1 christos PCRELOFFSET),
309 1.1 christos HOWTO (ARM_SECREL,
310 1.1 christos 0,
311 1.10 christos 4,
312 1.1 christos 32,
313 1.10 christos false,
314 1.1 christos 0,
315 1.1 christos complain_overflow_bitfield,
316 1.1 christos coff_arm_reloc,
317 1.1 christos "ARM_SECREL",
318 1.10 christos true, /* partial_inplace. */
319 1.1 christos 0xffffffff,
320 1.1 christos 0xffffffff,
321 1.1 christos PCRELOFFSET),
322 1.1 christos #else /* not ARM_WINCE */
323 1.1 christos HOWTO (ARM_8,
324 1.1 christos 0,
325 1.10 christos 1,
326 1.1 christos 8,
327 1.10 christos false,
328 1.1 christos 0,
329 1.1 christos complain_overflow_bitfield,
330 1.1 christos coff_arm_reloc,
331 1.1 christos "ARM_8",
332 1.10 christos true,
333 1.1 christos 0x000000ff,
334 1.1 christos 0x000000ff,
335 1.1 christos PCRELOFFSET),
336 1.1 christos HOWTO (ARM_16,
337 1.1 christos 0,
338 1.10 christos 2,
339 1.1 christos 16,
340 1.10 christos false,
341 1.1 christos 0,
342 1.1 christos complain_overflow_bitfield,
343 1.1 christos coff_arm_reloc,
344 1.1 christos "ARM_16",
345 1.10 christos true,
346 1.1 christos 0x0000ffff,
347 1.1 christos 0x0000ffff,
348 1.1 christos PCRELOFFSET),
349 1.1 christos HOWTO (ARM_32,
350 1.1 christos 0,
351 1.10 christos 4,
352 1.1 christos 32,
353 1.10 christos false,
354 1.1 christos 0,
355 1.1 christos complain_overflow_bitfield,
356 1.1 christos coff_arm_reloc,
357 1.1 christos "ARM_32",
358 1.10 christos true,
359 1.1 christos 0xffffffff,
360 1.1 christos 0xffffffff,
361 1.1 christos PCRELOFFSET),
362 1.1 christos HOWTO (ARM_26,
363 1.1 christos 2,
364 1.10 christos 4,
365 1.1 christos 24,
366 1.10 christos true,
367 1.1 christos 0,
368 1.1 christos complain_overflow_signed,
369 1.1 christos aoutarm_fix_pcrel_26 ,
370 1.1 christos "ARM_26",
371 1.10 christos false,
372 1.1 christos 0x00ffffff,
373 1.1 christos 0x00ffffff,
374 1.1 christos PCRELOFFSET),
375 1.1 christos HOWTO (ARM_DISP8,
376 1.1 christos 0,
377 1.10 christos 1,
378 1.1 christos 8,
379 1.10 christos true,
380 1.1 christos 0,
381 1.1 christos complain_overflow_signed,
382 1.1 christos coff_arm_reloc,
383 1.1 christos "ARM_DISP8",
384 1.10 christos true,
385 1.1 christos 0x000000ff,
386 1.1 christos 0x000000ff,
387 1.10 christos true),
388 1.1 christos HOWTO (ARM_DISP16,
389 1.1 christos 0,
390 1.10 christos 2,
391 1.1 christos 16,
392 1.10 christos true,
393 1.1 christos 0,
394 1.1 christos complain_overflow_signed,
395 1.1 christos coff_arm_reloc,
396 1.1 christos "ARM_DISP16",
397 1.10 christos true,
398 1.1 christos 0x0000ffff,
399 1.1 christos 0x0000ffff,
400 1.10 christos true),
401 1.1 christos HOWTO (ARM_DISP32,
402 1.1 christos 0,
403 1.10 christos 4,
404 1.1 christos 32,
405 1.10 christos true,
406 1.1 christos 0,
407 1.1 christos complain_overflow_signed,
408 1.1 christos coff_arm_reloc,
409 1.1 christos "ARM_DISP32",
410 1.10 christos true,
411 1.1 christos 0xffffffff,
412 1.1 christos 0xffffffff,
413 1.10 christos true),
414 1.1 christos HOWTO (ARM_26D,
415 1.1 christos 2,
416 1.10 christos 4,
417 1.1 christos 24,
418 1.10 christos false,
419 1.1 christos 0,
420 1.1 christos complain_overflow_dont,
421 1.1 christos aoutarm_fix_pcrel_26_done,
422 1.1 christos "ARM_26D",
423 1.10 christos true,
424 1.1 christos 0x00ffffff,
425 1.1 christos 0x0,
426 1.10 christos false),
427 1.1 christos /* 8 is unused */
428 1.1 christos EMPTY_HOWTO (-1),
429 1.1 christos HOWTO (ARM_NEG16,
430 1.1 christos 0,
431 1.10 christos -2,
432 1.1 christos 16,
433 1.10 christos false,
434 1.1 christos 0,
435 1.1 christos complain_overflow_bitfield,
436 1.1 christos coff_arm_reloc,
437 1.1 christos "ARM_NEG16",
438 1.10 christos true,
439 1.1 christos 0x0000ffff,
440 1.1 christos 0x0000ffff,
441 1.10 christos false),
442 1.1 christos HOWTO (ARM_NEG32,
443 1.1 christos 0,
444 1.10 christos -4,
445 1.1 christos 32,
446 1.10 christos false,
447 1.1 christos 0,
448 1.1 christos complain_overflow_bitfield,
449 1.1 christos coff_arm_reloc,
450 1.1 christos "ARM_NEG32",
451 1.10 christos true,
452 1.1 christos 0xffffffff,
453 1.1 christos 0xffffffff,
454 1.10 christos false),
455 1.1 christos HOWTO (ARM_RVA32,
456 1.1 christos 0,
457 1.10 christos 4,
458 1.1 christos 32,
459 1.10 christos false,
460 1.1 christos 0,
461 1.1 christos complain_overflow_bitfield,
462 1.1 christos coff_arm_reloc,
463 1.1 christos "ARM_RVA32",
464 1.10 christos true,
465 1.1 christos 0xffffffff,
466 1.1 christos 0xffffffff,
467 1.1 christos PCRELOFFSET),
468 1.1 christos HOWTO (ARM_THUMB9,
469 1.1 christos 1,
470 1.10 christos 2,
471 1.1 christos 8,
472 1.10 christos true,
473 1.1 christos 0,
474 1.1 christos complain_overflow_signed,
475 1.1 christos coff_thumb_pcrel_9 ,
476 1.1 christos "ARM_THUMB9",
477 1.10 christos false,
478 1.1 christos 0x000000ff,
479 1.1 christos 0x000000ff,
480 1.1 christos PCRELOFFSET),
481 1.1 christos HOWTO (ARM_THUMB12,
482 1.1 christos 1,
483 1.10 christos 2,
484 1.1 christos 11,
485 1.10 christos true,
486 1.1 christos 0,
487 1.1 christos complain_overflow_signed,
488 1.1 christos coff_thumb_pcrel_12 ,
489 1.1 christos "ARM_THUMB12",
490 1.10 christos false,
491 1.1 christos 0x000007ff,
492 1.1 christos 0x000007ff,
493 1.1 christos PCRELOFFSET),
494 1.1 christos HOWTO (ARM_THUMB23,
495 1.1 christos 1,
496 1.10 christos 4,
497 1.1 christos 22,
498 1.10 christos true,
499 1.1 christos 0,
500 1.1 christos complain_overflow_signed,
501 1.1 christos coff_thumb_pcrel_23 ,
502 1.1 christos "ARM_THUMB23",
503 1.10 christos false,
504 1.1 christos 0x07ff07ff,
505 1.1 christos 0x07ff07ff,
506 1.1 christos PCRELOFFSET)
507 1.1 christos #endif /* not ARM_WINCE */
508 1.1 christos };
509 1.1 christos
510 1.1 christos #define NUM_RELOCS NUM_ELEM (aoutarm_std_reloc_howto)
511 1.1 christos
512 1.1 christos #ifdef COFF_WITH_PE
513 1.1 christos /* Return TRUE if this relocation should
514 1.1 christos appear in the output .reloc section. */
515 1.1 christos
516 1.10 christos static bool
517 1.1 christos in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
518 1.1 christos reloc_howto_type * howto)
519 1.1 christos {
520 1.1 christos return !howto->pc_relative && howto->type != ARM_RVA32;
521 1.1 christos }
522 1.1 christos #endif
523 1.1 christos
524 1.1 christos #define RTYPE2HOWTO(cache_ptr, dst) \
525 1.1 christos (cache_ptr)->howto = \
526 1.1 christos (dst)->r_type < NUM_RELOCS \
527 1.1 christos ? aoutarm_std_reloc_howto + (dst)->r_type \
528 1.1 christos : NULL
529 1.1 christos
530 1.1 christos #define coff_rtype_to_howto coff_arm_rtype_to_howto
531 1.1 christos
532 1.1 christos static reloc_howto_type *
533 1.1 christos coff_arm_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
534 1.1 christos asection *sec,
535 1.1 christos struct internal_reloc *rel,
536 1.1 christos struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
537 1.1 christos struct internal_syment *sym ATTRIBUTE_UNUSED,
538 1.1 christos bfd_vma *addendp)
539 1.1 christos {
540 1.1 christos reloc_howto_type * howto;
541 1.1 christos
542 1.1 christos if (rel->r_type >= NUM_RELOCS)
543 1.1 christos return NULL;
544 1.1 christos
545 1.1 christos howto = aoutarm_std_reloc_howto + rel->r_type;
546 1.1 christos
547 1.1 christos if (rel->r_type == ARM_RVA32)
548 1.1 christos *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
549 1.1 christos
550 1.1 christos #if defined COFF_WITH_PE && defined ARM_WINCE
551 1.1 christos if (rel->r_type == ARM_SECREL)
552 1.1 christos {
553 1.1 christos bfd_vma osect_vma;
554 1.1 christos
555 1.1 christos if (h && (h->type == bfd_link_hash_defined
556 1.1 christos || h->type == bfd_link_hash_defweak))
557 1.1 christos osect_vma = h->root.u.def.section->output_section->vma;
558 1.1 christos else
559 1.1 christos {
560 1.1 christos int i;
561 1.1 christos
562 1.1 christos /* Sigh, the only way to get the section to offset against
563 1.1 christos is to find it the hard way. */
564 1.1 christos
565 1.1 christos for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
566 1.1 christos sec = sec->next;
567 1.1 christos
568 1.1 christos osect_vma = sec->output_section->vma;
569 1.1 christos }
570 1.1 christos
571 1.1 christos *addendp -= osect_vma;
572 1.1 christos }
573 1.1 christos #endif
574 1.1 christos
575 1.1 christos return howto;
576 1.1 christos }
577 1.1 christos
578 1.1 christos /* Used by the assembler. */
579 1.1 christos
580 1.1 christos static bfd_reloc_status_type
581 1.1 christos aoutarm_fix_pcrel_26_done (bfd *abfd ATTRIBUTE_UNUSED,
582 1.1 christos arelent *reloc_entry ATTRIBUTE_UNUSED,
583 1.1 christos asymbol *symbol ATTRIBUTE_UNUSED,
584 1.1 christos void * data ATTRIBUTE_UNUSED,
585 1.1 christos asection *input_section ATTRIBUTE_UNUSED,
586 1.1 christos bfd *output_bfd ATTRIBUTE_UNUSED,
587 1.1 christos char **error_message ATTRIBUTE_UNUSED)
588 1.1 christos {
589 1.1 christos /* This is dead simple at present. */
590 1.1 christos return bfd_reloc_ok;
591 1.1 christos }
592 1.1 christos
593 1.1 christos /* Used by the assembler. */
594 1.1 christos
595 1.1 christos static bfd_reloc_status_type
596 1.1 christos aoutarm_fix_pcrel_26 (bfd *abfd,
597 1.1 christos arelent *reloc_entry,
598 1.1 christos asymbol *symbol,
599 1.1 christos void * data,
600 1.1 christos asection *input_section,
601 1.1 christos bfd *output_bfd,
602 1.1 christos char **error_message ATTRIBUTE_UNUSED)
603 1.1 christos {
604 1.1 christos bfd_vma relocation;
605 1.1 christos bfd_size_type addr = reloc_entry->address;
606 1.1 christos long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
607 1.1 christos bfd_reloc_status_type flag = bfd_reloc_ok;
608 1.1 christos
609 1.1 christos /* If this is an undefined symbol, return error. */
610 1.1 christos if (bfd_is_und_section (symbol->section)
611 1.1 christos && (symbol->flags & BSF_WEAK) == 0)
612 1.1 christos return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
613 1.1 christos
614 1.1 christos /* If the sections are different, and we are doing a partial relocation,
615 1.1 christos just ignore it for now. */
616 1.1 christos if (symbol->section->name != input_section->name
617 1.1 christos && output_bfd != (bfd *)NULL)
618 1.1 christos return bfd_reloc_continue;
619 1.1 christos
620 1.1 christos relocation = (target & 0x00ffffff) << 2;
621 1.1 christos relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend. */
622 1.1 christos relocation += symbol->value;
623 1.1 christos relocation += symbol->section->output_section->vma;
624 1.1 christos relocation += symbol->section->output_offset;
625 1.1 christos relocation += reloc_entry->addend;
626 1.1 christos relocation -= input_section->output_section->vma;
627 1.1 christos relocation -= input_section->output_offset;
628 1.1 christos relocation -= addr;
629 1.1 christos
630 1.1 christos if (relocation & 3)
631 1.1 christos return bfd_reloc_overflow;
632 1.1 christos
633 1.1 christos /* Check for overflow. */
634 1.1 christos if (relocation & 0x02000000)
635 1.1 christos {
636 1.1 christos if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
637 1.1 christos flag = bfd_reloc_overflow;
638 1.1 christos }
639 1.1 christos else if (relocation & ~(bfd_vma) 0x03ffffff)
640 1.1 christos flag = bfd_reloc_overflow;
641 1.1 christos
642 1.1 christos target &= ~0x00ffffff;
643 1.1 christos target |= (relocation >> 2) & 0x00ffffff;
644 1.1 christos bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
645 1.1 christos
646 1.1 christos /* Now the ARM magic... Change the reloc type so that it is marked as done.
647 1.1 christos Strictly this is only necessary if we are doing a partial relocation. */
648 1.1 christos reloc_entry->howto = &aoutarm_std_reloc_howto[ARM_26D];
649 1.1 christos
650 1.1 christos return flag;
651 1.1 christos }
652 1.1 christos
653 1.1 christos static bfd_reloc_status_type
654 1.1 christos coff_thumb_pcrel_common (bfd *abfd,
655 1.1 christos arelent *reloc_entry,
656 1.1 christos asymbol *symbol,
657 1.1 christos void * data,
658 1.1 christos asection *input_section,
659 1.1 christos bfd *output_bfd,
660 1.1 christos char **error_message ATTRIBUTE_UNUSED,
661 1.1 christos thumb_pcrel_branchtype btype)
662 1.1 christos {
663 1.1 christos bfd_vma relocation = 0;
664 1.1 christos bfd_size_type addr = reloc_entry->address;
665 1.1 christos long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
666 1.1 christos bfd_reloc_status_type flag = bfd_reloc_ok;
667 1.1 christos bfd_vma dstmsk;
668 1.1 christos bfd_vma offmsk;
669 1.1 christos bfd_vma signbit;
670 1.1 christos
671 1.1 christos /* NOTE: This routine is currently used by GAS, but not by the link
672 1.1 christos phase. */
673 1.1 christos switch (btype)
674 1.1 christos {
675 1.1 christos case b9:
676 1.1 christos dstmsk = 0x000000ff;
677 1.1 christos offmsk = 0x000001fe;
678 1.1 christos signbit = 0x00000100;
679 1.1 christos break;
680 1.1 christos
681 1.1 christos case b12:
682 1.1 christos dstmsk = 0x000007ff;
683 1.1 christos offmsk = 0x00000ffe;
684 1.1 christos signbit = 0x00000800;
685 1.1 christos break;
686 1.1 christos
687 1.1 christos case b23:
688 1.1 christos dstmsk = 0x07ff07ff;
689 1.1 christos offmsk = 0x007fffff;
690 1.1 christos signbit = 0x00400000;
691 1.1 christos break;
692 1.1 christos
693 1.1 christos default:
694 1.1 christos abort ();
695 1.1 christos }
696 1.1 christos
697 1.1 christos /* If this is an undefined symbol, return error. */
698 1.1 christos if (bfd_is_und_section (symbol->section)
699 1.1 christos && (symbol->flags & BSF_WEAK) == 0)
700 1.1 christos return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
701 1.1 christos
702 1.1 christos /* If the sections are different, and we are doing a partial relocation,
703 1.1 christos just ignore it for now. */
704 1.1 christos if (symbol->section->name != input_section->name
705 1.1 christos && output_bfd != (bfd *)NULL)
706 1.1 christos return bfd_reloc_continue;
707 1.1 christos
708 1.1 christos switch (btype)
709 1.1 christos {
710 1.1 christos case b9:
711 1.1 christos case b12:
712 1.1 christos relocation = ((target & dstmsk) << 1);
713 1.1 christos break;
714 1.1 christos
715 1.1 christos case b23:
716 1.1 christos if (bfd_big_endian (abfd))
717 1.1 christos relocation = ((target & 0x7ff) << 1) | ((target & 0x07ff0000) >> 4);
718 1.1 christos else
719 1.1 christos relocation = ((target & 0x7ff) << 12) | ((target & 0x07ff0000) >> 15);
720 1.1 christos break;
721 1.1 christos
722 1.1 christos default:
723 1.1 christos abort ();
724 1.1 christos }
725 1.1 christos
726 1.1 christos relocation = (relocation ^ signbit) - signbit; /* Sign extend. */
727 1.1 christos relocation += symbol->value;
728 1.1 christos relocation += symbol->section->output_section->vma;
729 1.1 christos relocation += symbol->section->output_offset;
730 1.1 christos relocation += reloc_entry->addend;
731 1.1 christos relocation -= input_section->output_section->vma;
732 1.1 christos relocation -= input_section->output_offset;
733 1.1 christos relocation -= addr;
734 1.1 christos
735 1.1 christos if (relocation & 1)
736 1.1 christos return bfd_reloc_overflow;
737 1.1 christos
738 1.1 christos /* Check for overflow. */
739 1.1 christos if (relocation & signbit)
740 1.1 christos {
741 1.1 christos if ((relocation & ~offmsk) != ~offmsk)
742 1.1 christos flag = bfd_reloc_overflow;
743 1.1 christos }
744 1.1 christos else if (relocation & ~offmsk)
745 1.1 christos flag = bfd_reloc_overflow;
746 1.1 christos
747 1.1 christos target &= ~dstmsk;
748 1.1 christos switch (btype)
749 1.1 christos {
750 1.1 christos case b9:
751 1.1 christos case b12:
752 1.1 christos target |= (relocation >> 1);
753 1.1 christos break;
754 1.1 christos
755 1.1 christos case b23:
756 1.1 christos if (bfd_big_endian (abfd))
757 1.1 christos target |= (((relocation & 0xfff) >> 1)
758 1.1 christos | ((relocation << 4) & 0x07ff0000));
759 1.1 christos else
760 1.1 christos target |= (((relocation & 0xffe) << 15)
761 1.1 christos | ((relocation >> 12) & 0x7ff));
762 1.1 christos break;
763 1.1 christos
764 1.1 christos default:
765 1.1 christos abort ();
766 1.1 christos }
767 1.1 christos
768 1.1 christos bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
769 1.1 christos
770 1.1 christos /* Now the ARM magic... Change the reloc type so that it is marked as done.
771 1.1 christos Strictly this is only necessary if we are doing a partial relocation. */
772 1.1 christos reloc_entry->howto = & aoutarm_std_reloc_howto [ARM_26D];
773 1.1 christos
774 1.1 christos /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations. */
775 1.1 christos return flag;
776 1.1 christos }
777 1.1 christos
778 1.1 christos #ifndef ARM_WINCE
779 1.1 christos static bfd_reloc_status_type
780 1.1 christos coff_thumb_pcrel_23 (bfd *abfd,
781 1.1 christos arelent *reloc_entry,
782 1.1 christos asymbol *symbol,
783 1.1 christos void * data,
784 1.1 christos asection *input_section,
785 1.1 christos bfd *output_bfd,
786 1.1 christos char **error_message)
787 1.1 christos {
788 1.1 christos return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
789 1.8 christos input_section, output_bfd, error_message,
790 1.1 christos b23);
791 1.1 christos }
792 1.1 christos
793 1.1 christos static bfd_reloc_status_type
794 1.1 christos coff_thumb_pcrel_9 (bfd *abfd,
795 1.1 christos arelent *reloc_entry,
796 1.1 christos asymbol *symbol,
797 1.1 christos void * data,
798 1.1 christos asection *input_section,
799 1.1 christos bfd *output_bfd,
800 1.1 christos char **error_message)
801 1.1 christos {
802 1.1 christos return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
803 1.8 christos input_section, output_bfd, error_message,
804 1.1 christos b9);
805 1.1 christos }
806 1.1 christos #endif /* not ARM_WINCE */
807 1.1 christos
808 1.1 christos static bfd_reloc_status_type
809 1.1 christos coff_thumb_pcrel_12 (bfd *abfd,
810 1.1 christos arelent *reloc_entry,
811 1.1 christos asymbol *symbol,
812 1.1 christos void * data,
813 1.1 christos asection *input_section,
814 1.1 christos bfd *output_bfd,
815 1.1 christos char **error_message)
816 1.1 christos {
817 1.1 christos return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
818 1.8 christos input_section, output_bfd, error_message,
819 1.1 christos b12);
820 1.1 christos }
821 1.1 christos
822 1.8 christos static reloc_howto_type *
823 1.1 christos coff_arm_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
824 1.1 christos {
825 1.1 christos #define ASTD(i,j) case i: return aoutarm_std_reloc_howto + j
826 1.1 christos
827 1.1 christos if (code == BFD_RELOC_CTOR)
828 1.1 christos switch (bfd_arch_bits_per_address (abfd))
829 1.1 christos {
830 1.1 christos case 32:
831 1.8 christos code = BFD_RELOC_32;
832 1.8 christos break;
833 1.1 christos default:
834 1.1 christos return NULL;
835 1.1 christos }
836 1.1 christos
837 1.1 christos switch (code)
838 1.1 christos {
839 1.1 christos #ifdef ARM_WINCE
840 1.8 christos ASTD (BFD_RELOC_32, ARM_32);
841 1.8 christos ASTD (BFD_RELOC_RVA, ARM_RVA32);
842 1.8 christos ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26);
843 1.1 christos ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
844 1.8 christos ASTD (BFD_RELOC_32_SECREL, ARM_SECREL);
845 1.1 christos #else
846 1.8 christos ASTD (BFD_RELOC_8, ARM_8);
847 1.8 christos ASTD (BFD_RELOC_16, ARM_16);
848 1.8 christos ASTD (BFD_RELOC_32, ARM_32);
849 1.8 christos ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26);
850 1.8 christos ASTD (BFD_RELOC_ARM_PCREL_BLX, ARM_26);
851 1.8 christos ASTD (BFD_RELOC_8_PCREL, ARM_DISP8);
852 1.8 christos ASTD (BFD_RELOC_16_PCREL, ARM_DISP16);
853 1.8 christos ASTD (BFD_RELOC_32_PCREL, ARM_DISP32);
854 1.8 christos ASTD (BFD_RELOC_RVA, ARM_RVA32);
855 1.1 christos ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9, ARM_THUMB9);
856 1.1 christos ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
857 1.1 christos ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23);
858 1.8 christos ASTD (BFD_RELOC_THUMB_PCREL_BLX, ARM_THUMB23);
859 1.1 christos #endif
860 1.1 christos default: return NULL;
861 1.1 christos }
862 1.1 christos }
863 1.1 christos
864 1.1 christos static reloc_howto_type *
865 1.1 christos coff_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
866 1.1 christos const char *r_name)
867 1.1 christos {
868 1.1 christos unsigned int i;
869 1.1 christos
870 1.1 christos for (i = 0;
871 1.1 christos i < (sizeof (aoutarm_std_reloc_howto)
872 1.1 christos / sizeof (aoutarm_std_reloc_howto[0]));
873 1.1 christos i++)
874 1.1 christos if (aoutarm_std_reloc_howto[i].name != NULL
875 1.1 christos && strcasecmp (aoutarm_std_reloc_howto[i].name, r_name) == 0)
876 1.1 christos return &aoutarm_std_reloc_howto[i];
877 1.1 christos
878 1.1 christos return NULL;
879 1.1 christos }
880 1.1 christos
881 1.1 christos #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
882 1.8 christos #define COFF_PAGE_SIZE 0x1000
883 1.1 christos
884 1.1 christos /* Turn a howto into a reloc nunmber. */
885 1.1 christos #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
886 1.8 christos #define BADMAG(x) ARMBADMAG(x)
887 1.8 christos #define ARM 1 /* Customize coffcode.h. */
888 1.1 christos
889 1.1 christos #ifndef ARM_WINCE
890 1.1 christos /* Make sure that the 'r_offset' field is copied properly
891 1.1 christos so that identical binaries will compare the same. */
892 1.1 christos #define SWAP_IN_RELOC_OFFSET H_GET_32
893 1.1 christos #define SWAP_OUT_RELOC_OFFSET H_PUT_32
894 1.1 christos #endif
895 1.1 christos
896 1.1 christos /* Extend the coff_link_hash_table structure with a few ARM specific fields.
897 1.1 christos This allows us to store global data here without actually creating any
898 1.1 christos global variables, which is a no-no in the BFD world. */
899 1.1 christos struct coff_arm_link_hash_table
900 1.1 christos {
901 1.1 christos /* The original coff_link_hash_table structure. MUST be first field. */
902 1.1 christos struct coff_link_hash_table root;
903 1.1 christos
904 1.1 christos /* The size in bytes of the section containing the Thumb-to-ARM glue. */
905 1.1 christos bfd_size_type thumb_glue_size;
906 1.1 christos
907 1.1 christos /* The size in bytes of the section containing the ARM-to-Thumb glue. */
908 1.1 christos bfd_size_type arm_glue_size;
909 1.1 christos
910 1.1 christos /* An arbitrary input BFD chosen to hold the glue sections. */
911 1.1 christos bfd * bfd_of_glue_owner;
912 1.1 christos
913 1.1 christos /* Support interworking with old, non-interworking aware ARM code. */
914 1.8 christos int support_old_code;
915 1.1 christos };
916 1.1 christos
917 1.1 christos /* Get the ARM coff linker hash table from a link_info structure. */
918 1.1 christos #define coff_arm_hash_table(info) \
919 1.1 christos ((struct coff_arm_link_hash_table *) ((info)->hash))
920 1.1 christos
921 1.1 christos /* Create an ARM coff linker hash table. */
922 1.1 christos
923 1.1 christos static struct bfd_link_hash_table *
924 1.1 christos coff_arm_link_hash_table_create (bfd * abfd)
925 1.1 christos {
926 1.1 christos struct coff_arm_link_hash_table * ret;
927 1.9 christos size_t amt = sizeof (struct coff_arm_link_hash_table);
928 1.1 christos
929 1.1 christos ret = bfd_zmalloc (amt);
930 1.1 christos if (ret == NULL)
931 1.1 christos return NULL;
932 1.1 christos
933 1.1 christos if (!_bfd_coff_link_hash_table_init (&ret->root,
934 1.1 christos abfd,
935 1.1 christos _bfd_coff_link_hash_newfunc,
936 1.1 christos sizeof (struct coff_link_hash_entry)))
937 1.1 christos {
938 1.1 christos free (ret);
939 1.1 christos return NULL;
940 1.1 christos }
941 1.1 christos
942 1.1 christos return & ret->root.root;
943 1.1 christos }
944 1.1 christos
945 1.10 christos static bool
946 1.1 christos arm_emit_base_file_entry (struct bfd_link_info *info,
947 1.1 christos bfd *output_bfd,
948 1.1 christos asection *input_section,
949 1.1 christos bfd_vma reloc_offset)
950 1.1 christos {
951 1.1 christos bfd_vma addr = (reloc_offset
952 1.1 christos - input_section->vma
953 1.1 christos + input_section->output_offset
954 1.1 christos + input_section->output_section->vma);
955 1.1 christos
956 1.1 christos if (coff_data (output_bfd)->pe)
957 1.1 christos addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
958 1.1 christos if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
959 1.10 christos return true;
960 1.1 christos
961 1.1 christos bfd_set_error (bfd_error_system_call);
962 1.10 christos return false;
963 1.1 christos }
964 1.1 christos
965 1.1 christos #ifndef ARM_WINCE
967 1.1 christos /* The thumb form of a long branch is a bit finicky, because the offset
968 1.1 christos encoding is split over two fields, each in it's own instruction. They
969 1.1 christos can occur in any order. So given a thumb form of long branch, and an
970 1.1 christos offset, insert the offset into the thumb branch and return finished
971 1.1 christos instruction.
972 1.1 christos
973 1.1 christos It takes two thumb instructions to encode the target address. Each has
974 1.1 christos 11 bits to invest. The upper 11 bits are stored in one (identified by
975 1.1 christos H-0.. see below), the lower 11 bits are stored in the other (identified
976 1.1 christos by H-1).
977 1.1 christos
978 1.1 christos Combine together and shifted left by 1 (it's a half word address) and
979 1.1 christos there you have it.
980 1.1 christos
981 1.1 christos Op: 1111 = F,
982 1.1 christos H-0, upper address-0 = 000
983 1.1 christos Op: 1111 = F,
984 1.1 christos H-1, lower address-0 = 800
985 1.1 christos
986 1.1 christos They can be ordered either way, but the arm tools I've seen always put
987 1.1 christos the lower one first. It probably doesn't matter. krk (at) cygnus.com
988 1.1 christos
989 1.1 christos XXX: Actually the order does matter. The second instruction (H-1)
990 1.1 christos moves the computed address into the PC, so it must be the second one
991 1.1 christos in the sequence. The problem, however is that whilst little endian code
992 1.1 christos stores the instructions in HI then LOW order, big endian code does the
993 1.1 christos reverse. nickc (at) cygnus.com. */
994 1.1 christos
995 1.1 christos #define LOW_HI_ORDER 0xF800F000
996 1.1 christos #define HI_LOW_ORDER 0xF000F800
997 1.1 christos
998 1.1 christos static insn32
999 1.1 christos insert_thumb_branch (insn32 br_insn, int rel_off)
1000 1.1 christos {
1001 1.1 christos unsigned int low_bits;
1002 1.1 christos unsigned int high_bits;
1003 1.1 christos
1004 1.1 christos BFD_ASSERT ((rel_off & 1) != 1);
1005 1.8 christos
1006 1.8 christos rel_off >>= 1; /* Half word aligned address. */
1007 1.1 christos low_bits = rel_off & 0x000007FF; /* The bottom 11 bits. */
1008 1.1 christos high_bits = (rel_off >> 11) & 0x000007FF; /* The top 11 bits. */
1009 1.1 christos
1010 1.1 christos if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
1011 1.1 christos br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
1012 1.1 christos else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
1013 1.1 christos br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
1014 1.1 christos else
1015 1.1 christos /* FIXME: the BFD library should never abort except for internal errors
1016 1.1 christos - it should return an error status. */
1017 1.1 christos abort (); /* Error - not a valid branch instruction form. */
1018 1.1 christos
1019 1.1 christos return br_insn;
1020 1.1 christos }
1021 1.1 christos
1022 1.1 christos
1023 1.1 christos static struct coff_link_hash_entry *
1025 1.1 christos find_thumb_glue (struct bfd_link_info *info,
1026 1.1 christos const char *name,
1027 1.1 christos bfd *input_bfd)
1028 1.1 christos {
1029 1.9 christos char *tmp_name;
1030 1.1 christos struct coff_link_hash_entry *myh;
1031 1.1 christos size_t amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1032 1.1 christos
1033 1.1 christos tmp_name = bfd_malloc (amt);
1034 1.1 christos
1035 1.1 christos BFD_ASSERT (tmp_name);
1036 1.1 christos
1037 1.1 christos sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1038 1.10 christos
1039 1.1 christos myh = coff_link_hash_lookup
1040 1.1 christos (coff_hash_table (info), tmp_name, false, false, true);
1041 1.1 christos
1042 1.8 christos if (myh == NULL)
1043 1.1 christos /* xgettext:c-format */
1044 1.1 christos _bfd_error_handler (_("%pB: unable to find THUMB glue '%s' for `%s'"),
1045 1.1 christos input_bfd, tmp_name, name);
1046 1.1 christos
1047 1.1 christos free (tmp_name);
1048 1.1 christos
1049 1.1 christos return myh;
1050 1.1 christos }
1051 1.1 christos #endif /* not ARM_WINCE */
1052 1.1 christos
1053 1.1 christos static struct coff_link_hash_entry *
1054 1.1 christos find_arm_glue (struct bfd_link_info *info,
1055 1.1 christos const char *name,
1056 1.1 christos bfd *input_bfd)
1057 1.1 christos {
1058 1.9 christos char *tmp_name;
1059 1.1 christos struct coff_link_hash_entry * myh;
1060 1.1 christos size_t amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1061 1.1 christos
1062 1.1 christos tmp_name = bfd_malloc (amt);
1063 1.1 christos
1064 1.1 christos BFD_ASSERT (tmp_name);
1065 1.1 christos
1066 1.1 christos sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1067 1.10 christos
1068 1.1 christos myh = coff_link_hash_lookup
1069 1.1 christos (coff_hash_table (info), tmp_name, false, false, true);
1070 1.1 christos
1071 1.8 christos if (myh == NULL)
1072 1.1 christos /* xgettext:c-format */
1073 1.1 christos _bfd_error_handler (_("%pB: unable to find ARM glue '%s' for `%s'"),
1074 1.1 christos input_bfd, tmp_name, name);
1075 1.1 christos
1076 1.1 christos free (tmp_name);
1077 1.1 christos
1078 1.1 christos return myh;
1079 1.1 christos }
1080 1.1 christos
1081 1.1 christos /*
1082 1.1 christos ARM->Thumb glue:
1083 1.1 christos
1084 1.1 christos .arm
1085 1.1 christos __func_from_arm:
1086 1.1 christos ldr r12, __func_addr
1087 1.8 christos bx r12
1088 1.1 christos __func_addr:
1089 1.1 christos .word func @ behave as if you saw a ARM_32 reloc
1090 1.1 christos */
1091 1.1 christos
1092 1.1 christos #define ARM2THUMB_GLUE_SIZE 12
1093 1.1 christos static const insn32 a2t1_ldr_insn = 0xe59fc000;
1094 1.1 christos static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
1095 1.1 christos static const insn32 a2t3_func_addr_insn = 0x00000001;
1096 1.1 christos
1097 1.1 christos /*
1098 1.1 christos Thumb->ARM: Thumb->(non-interworking aware) ARM
1099 1.1 christos
1100 1.1 christos .thumb .thumb
1101 1.1 christos .align 2 .align 2
1102 1.1 christos __func_from_thumb: __func_from_thumb:
1103 1.1 christos bx pc push {r6, lr}
1104 1.1 christos nop ldr r6, __func_addr
1105 1.8 christos .arm mov lr, pc
1106 1.1 christos __func_change_to_arm: bx r6
1107 1.8 christos b func .arm
1108 1.8 christos __func_back_to_thumb:
1109 1.8 christos ldmia r13! {r6, lr}
1110 1.8 christos bx lr
1111 1.1 christos __func_addr:
1112 1.1 christos .word func
1113 1.1 christos */
1114 1.1 christos
1115 1.1 christos #define THUMB2ARM_GLUE_SIZE (globals->support_old_code ? 20 : 8)
1116 1.1 christos #ifndef ARM_WINCE
1117 1.1 christos static const insn16 t2a1_bx_pc_insn = 0x4778;
1118 1.1 christos static const insn16 t2a2_noop_insn = 0x46c0;
1119 1.1 christos static const insn32 t2a3_b_insn = 0xea000000;
1120 1.1 christos
1121 1.1 christos static const insn16 t2a1_push_insn = 0xb540;
1122 1.1 christos static const insn16 t2a2_ldr_insn = 0x4e03;
1123 1.1 christos static const insn16 t2a3_mov_insn = 0x46fe;
1124 1.1 christos static const insn16 t2a4_bx_insn = 0x4730;
1125 1.1 christos static const insn32 t2a5_pop_insn = 0xe8bd4040;
1126 1.1 christos static const insn32 t2a6_bx_insn = 0xe12fff1e;
1127 1.1 christos #endif
1128 1.1 christos
1129 1.1 christos /* TODO:
1130 1.1 christos We should really create new local (static) symbols in destination
1131 1.1 christos object for each stub we create. We should also create local
1132 1.1 christos (static) symbols within the stubs when switching between ARM and
1133 1.1 christos Thumb code. This will ensure that the debugger and disassembler
1134 1.1 christos can present a better view of stubs.
1135 1.1 christos
1136 1.1 christos We can treat stubs like literal sections, and for the THUMB9 ones
1137 1.1 christos (short addressing range) we should be able to insert the stubs
1138 1.1 christos between sections. i.e. the simplest approach (since relocations
1139 1.1 christos are done on a section basis) is to dump the stubs at the end of
1140 1.1 christos processing a section. That way we can always try and minimise the
1141 1.1 christos offset to and from a stub. However, this does not map well onto
1142 1.1 christos the way that the linker/BFD does its work: mapping all input
1143 1.1 christos sections to output sections via the linker script before doing
1144 1.1 christos all the processing.
1145 1.1 christos
1146 1.1 christos Unfortunately it may be easier to just to disallow short range
1147 1.1 christos Thumb->ARM stubs (i.e. no conditional inter-working branches,
1148 1.1 christos only branch-and-link (BL) calls. This will simplify the processing
1149 1.1 christos since we can then put all of the stubs into their own section.
1150 1.1 christos
1151 1.1 christos TODO:
1152 1.1 christos On a different subject, rather than complaining when a
1153 1.1 christos branch cannot fit in the number of bits available for the
1154 1.1 christos instruction we should generate a trampoline stub (needed to
1155 1.1 christos address the complete 32bit address space). */
1156 1.1 christos
1157 1.9 christos /* The standard COFF backend linker does not cope with the special
1158 1.1 christos Thumb BRANCH23 relocation. The alternative would be to split the
1159 1.1 christos BRANCH23 into separate HI23 and LO23 relocations. However, it is a
1160 1.1 christos bit simpler simply providing our own relocation driver. */
1161 1.1 christos
1162 1.1 christos /* The reloc processing routine for the ARM/Thumb COFF linker. NOTE:
1163 1.1 christos This code is a very slightly modified copy of
1164 1.1 christos _bfd_coff_generic_relocate_section. It would be a much more
1165 1.1 christos maintainable solution to have a MACRO that could be expanded within
1166 1.1 christos _bfd_coff_generic_relocate_section that would only be provided for
1167 1.1 christos ARM/Thumb builds. It is only the code marked THUMBEXTENSION that
1168 1.10 christos is different from the original. */
1169 1.1 christos
1170 1.1 christos static bool
1171 1.1 christos coff_arm_relocate_section (bfd *output_bfd,
1172 1.1 christos struct bfd_link_info *info,
1173 1.1 christos bfd *input_bfd,
1174 1.1 christos asection *input_section,
1175 1.1 christos bfd_byte *contents,
1176 1.1 christos struct internal_reloc *relocs,
1177 1.1 christos struct internal_syment *syms,
1178 1.1 christos asection **sections)
1179 1.1 christos {
1180 1.1 christos struct internal_reloc * rel;
1181 1.1 christos struct internal_reloc * relend;
1182 1.1 christos #ifndef ARM_WINCE
1183 1.1 christos bfd_vma high_address = bfd_get_section_limit (input_bfd, input_section);
1184 1.1 christos #endif
1185 1.1 christos
1186 1.1 christos rel = relocs;
1187 1.1 christos relend = rel + input_section->reloc_count;
1188 1.1 christos
1189 1.8 christos for (; rel < relend; rel++)
1190 1.8 christos {
1191 1.1 christos int done = 0;
1192 1.8 christos long symndx;
1193 1.8 christos struct coff_link_hash_entry * h;
1194 1.8 christos struct internal_syment * sym;
1195 1.8 christos bfd_vma addend;
1196 1.8 christos bfd_vma val;
1197 1.8 christos reloc_howto_type * howto;
1198 1.1 christos bfd_reloc_status_type rstat;
1199 1.1 christos bfd_vma h_val;
1200 1.1 christos
1201 1.1 christos symndx = rel->r_symndx;
1202 1.1 christos
1203 1.1 christos if (symndx == -1)
1204 1.1 christos {
1205 1.1 christos h = NULL;
1206 1.1 christos sym = NULL;
1207 1.1 christos }
1208 1.1 christos else
1209 1.1 christos {
1210 1.1 christos h = obj_coff_sym_hashes (input_bfd)[symndx];
1211 1.1 christos sym = syms + symndx;
1212 1.1 christos }
1213 1.8 christos
1214 1.8 christos /* COFF treats common symbols in one of two ways. Either the
1215 1.8 christos size of the symbol is included in the section contents, or it
1216 1.1 christos is not. We assume that the size is not included, and force
1217 1.1 christos the rtype_to_howto function to adjust the addend as needed. */
1218 1.1 christos
1219 1.1 christos if (sym != NULL && sym->n_scnum != 0)
1220 1.1 christos addend = - sym->n_value;
1221 1.1 christos else
1222 1.1 christos addend = 0;
1223 1.1 christos
1224 1.1 christos howto = coff_rtype_to_howto (input_bfd, input_section, rel, h,
1225 1.10 christos sym, &addend);
1226 1.1 christos if (howto == NULL)
1227 1.1 christos return false;
1228 1.8 christos
1229 1.8 christos /* The relocation_section function will skip pcrel_offset relocs
1230 1.8 christos when doing a relocatable link. However, we want to convert
1231 1.8 christos ARM_26 to ARM_26D relocs if possible. We return a fake howto in
1232 1.8 christos this case without pcrel_offset set, and adjust the addend to
1233 1.1 christos compensate. 'partial_inplace' is also set, since we want 'done'
1234 1.8 christos relocations to be reflected in section's data. */
1235 1.8 christos if (rel->r_type == ARM_26
1236 1.8 christos && h != NULL
1237 1.1 christos && bfd_link_relocatable (info)
1238 1.8 christos && (h->root.type == bfd_link_hash_defined
1239 1.1 christos || h->root.type == bfd_link_hash_defweak)
1240 1.8 christos && (h->root.u.def.section->output_section
1241 1.8 christos == input_section->output_section))
1242 1.1 christos {
1243 1.8 christos static reloc_howto_type fake_arm26_reloc =
1244 1.10 christos HOWTO (ARM_26,
1245 1.8 christos 2,
1246 1.10 christos 4,
1247 1.8 christos 24,
1248 1.8 christos true,
1249 1.8 christos 0,
1250 1.8 christos complain_overflow_signed,
1251 1.10 christos aoutarm_fix_pcrel_26 ,
1252 1.8 christos "ARM_26",
1253 1.8 christos true,
1254 1.10 christos 0x00ffffff,
1255 1.1 christos 0x00ffffff,
1256 1.8 christos false);
1257 1.1 christos
1258 1.8 christos addend -= rel->r_vaddr - input_section->vma;
1259 1.8 christos #ifdef ARM_WINCE
1260 1.8 christos /* FIXME: I don't know why, but the hack is necessary for correct
1261 1.1 christos generation of bl's instruction offset. */
1262 1.8 christos addend -= 8;
1263 1.8 christos #endif
1264 1.1 christos howto = & fake_arm26_reloc;
1265 1.1 christos }
1266 1.1 christos
1267 1.1 christos #ifdef ARM_WINCE
1268 1.6 christos /* MS ARM-CE makes the reloc relative to the opcode's pc, not
1269 1.1 christos the next opcode's pc, so is off by one. */
1270 1.1 christos if (howto->pc_relative && !bfd_link_relocatable (info))
1271 1.1 christos addend -= 8;
1272 1.1 christos #endif
1273 1.8 christos
1274 1.8 christos /* If we are doing a relocatable link, then we can just ignore
1275 1.8 christos a PC relative reloc that is pcrel_offset. It will already
1276 1.1 christos have the correct value. If this is not a relocatable link,
1277 1.8 christos then we should ignore the symbol value. */
1278 1.8 christos if (howto->pc_relative && howto->pcrel_offset)
1279 1.8 christos {
1280 1.1 christos if (bfd_link_relocatable (info))
1281 1.1 christos continue;
1282 1.8 christos /* FIXME - it is not clear which targets need this next test
1283 1.8 christos and which do not. It is known that it is needed for the
1284 1.1 christos VxWorks targets but it is also known that it was suppressed
1285 1.1 christos for other ARM targets. This ought to be sorted out one day. */
1286 1.1 christos #ifdef ARM_COFF_BUGFIX
1287 1.1 christos /* We must not ignore the symbol value. If the symbol is
1288 1.1 christos within the same section, the relocation should have already
1289 1.1 christos been fixed, but if it is not, we'll be handed a reloc into
1290 1.1 christos the beginning of the symbol's section, so we must not cancel
1291 1.8 christos out the symbol's value, otherwise we'll be adding it in
1292 1.8 christos twice. */
1293 1.1 christos if (sym != NULL && sym->n_scnum != 0)
1294 1.8 christos addend += sym->n_value;
1295 1.1 christos #endif
1296 1.1 christos }
1297 1.1 christos
1298 1.1 christos val = 0;
1299 1.1 christos
1300 1.1 christos if (h == NULL)
1301 1.1 christos {
1302 1.1 christos asection *sec;
1303 1.1 christos
1304 1.1 christos if (symndx == -1)
1305 1.1 christos {
1306 1.1 christos sec = bfd_abs_section_ptr;
1307 1.1 christos val = 0;
1308 1.1 christos }
1309 1.1 christos else
1310 1.8 christos {
1311 1.1 christos sec = sections[symndx];
1312 1.1 christos val = (sec->output_section->vma
1313 1.1 christos + sec->output_offset
1314 1.1 christos + sym->n_value
1315 1.1 christos - sec->vma);
1316 1.1 christos }
1317 1.1 christos }
1318 1.8 christos else
1319 1.8 christos {
1320 1.8 christos /* We don't output the stubs if we are generating a
1321 1.1 christos relocatable output file, since we may as well leave the
1322 1.1 christos stub generation to the final linker pass. If we fail to
1323 1.8 christos verify that the name is defined, we'll try to build stubs
1324 1.1 christos for an undefined name... */
1325 1.1 christos if (! bfd_link_relocatable (info)
1326 1.8 christos && ( h->root.type == bfd_link_hash_defined
1327 1.1 christos || h->root.type == bfd_link_hash_defweak))
1328 1.1 christos {
1329 1.1 christos asection * h_sec = h->root.u.def.section;
1330 1.1 christos const char * name = h->root.root.string;
1331 1.1 christos
1332 1.1 christos /* h locates the symbol referenced in the reloc. */
1333 1.1 christos h_val = (h->root.u.def.value
1334 1.1 christos + h_sec->output_section->vma
1335 1.8 christos + h_sec->output_offset);
1336 1.8 christos
1337 1.8 christos if (howto->type == ARM_26)
1338 1.1 christos {
1339 1.1 christos if ( h->symbol_class == C_THUMBSTATFUNC
1340 1.1 christos || h->symbol_class == C_THUMBEXTFUNC)
1341 1.8 christos {
1342 1.8 christos /* Arm code calling a Thumb function. */
1343 1.8 christos unsigned long int tmp;
1344 1.8 christos bfd_vma my_offset;
1345 1.8 christos asection * s;
1346 1.1 christos long int ret_offset;
1347 1.1 christos struct coff_link_hash_entry * myh;
1348 1.1 christos struct coff_arm_link_hash_table * globals;
1349 1.1 christos
1350 1.10 christos myh = find_arm_glue (info, name, input_bfd);
1351 1.1 christos if (myh == NULL)
1352 1.1 christos return false;
1353 1.1 christos
1354 1.1 christos globals = coff_arm_hash_table (info);
1355 1.1 christos
1356 1.1 christos BFD_ASSERT (globals != NULL);
1357 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1358 1.1 christos
1359 1.1 christos my_offset = myh->root.u.def.value;
1360 1.1 christos
1361 1.1 christos s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1362 1.1 christos ARM2THUMB_GLUE_SECTION_NAME);
1363 1.1 christos BFD_ASSERT (s != NULL);
1364 1.1 christos BFD_ASSERT (s->contents != NULL);
1365 1.1 christos BFD_ASSERT (s->output_section != NULL);
1366 1.1 christos
1367 1.1 christos if ((my_offset & 0x01) == 0x01)
1368 1.1 christos {
1369 1.1 christos if (h_sec->owner != NULL
1370 1.1 christos && INTERWORK_SET (h_sec->owner)
1371 1.1 christos && ! INTERWORK_FLAG (h_sec->owner))
1372 1.8 christos _bfd_error_handler
1373 1.8 christos /* xgettext:c-format */
1374 1.7 christos (_("%pB(%s): warning: interworking not enabled; "
1375 1.1 christos "first occurrence: %pB: arm call to thumb"),
1376 1.1 christos h_sec->owner, name, input_bfd);
1377 1.1 christos
1378 1.1 christos --my_offset;
1379 1.1 christos myh->root.u.def.value = my_offset;
1380 1.1 christos
1381 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn,
1382 1.1 christos s->contents + my_offset);
1383 1.1 christos
1384 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) a2t2_bx_r12_insn,
1385 1.1 christos s->contents + my_offset + 4);
1386 1.1 christos
1387 1.1 christos /* It's a thumb address. Add the low order bit. */
1388 1.1 christos bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
1389 1.8 christos s->contents + my_offset + 8);
1390 1.1 christos
1391 1.1 christos if (info->base_file
1392 1.10 christos && !arm_emit_base_file_entry (info, output_bfd,
1393 1.1 christos s, my_offset + 8))
1394 1.1 christos return false;
1395 1.1 christos }
1396 1.1 christos
1397 1.1 christos BFD_ASSERT (my_offset <= globals->arm_glue_size);
1398 1.1 christos
1399 1.1 christos tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1400 1.1 christos - input_section->vma);
1401 1.1 christos
1402 1.1 christos tmp = tmp & 0xFF000000;
1403 1.1 christos
1404 1.1 christos /* Somehow these are both 4 too far, so subtract 8. */
1405 1.1 christos ret_offset =
1406 1.1 christos s->output_offset
1407 1.1 christos + my_offset
1408 1.1 christos + s->output_section->vma
1409 1.1 christos - (input_section->output_offset
1410 1.1 christos + input_section->output_section->vma
1411 1.1 christos + rel->r_vaddr)
1412 1.1 christos - 8;
1413 1.1 christos
1414 1.1 christos tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1415 1.1 christos
1416 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) tmp,
1417 1.1 christos contents + rel->r_vaddr - input_section->vma);
1418 1.8 christos done = 1;
1419 1.1 christos }
1420 1.1 christos }
1421 1.1 christos
1422 1.8 christos #ifndef ARM_WINCE
1423 1.8 christos /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */
1424 1.8 christos else if (howto->type == ARM_THUMB23)
1425 1.1 christos {
1426 1.1 christos if ( h->symbol_class == C_EXT
1427 1.1 christos || h->symbol_class == C_STAT
1428 1.1 christos || h->symbol_class == C_LABEL)
1429 1.8 christos {
1430 1.8 christos /* Thumb code calling an ARM function. */
1431 1.8 christos asection * s = 0;
1432 1.8 christos bfd_vma my_offset;
1433 1.8 christos unsigned long int tmp;
1434 1.8 christos long int ret_offset;
1435 1.1 christos struct coff_link_hash_entry * myh;
1436 1.1 christos struct coff_arm_link_hash_table * globals;
1437 1.1 christos
1438 1.10 christos myh = find_thumb_glue (info, name, input_bfd);
1439 1.1 christos if (myh == NULL)
1440 1.1 christos return false;
1441 1.1 christos
1442 1.1 christos globals = coff_arm_hash_table (info);
1443 1.1 christos
1444 1.1 christos BFD_ASSERT (globals != NULL);
1445 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1446 1.1 christos
1447 1.1 christos my_offset = myh->root.u.def.value;
1448 1.1 christos
1449 1.1 christos s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1450 1.1 christos THUMB2ARM_GLUE_SECTION_NAME);
1451 1.1 christos
1452 1.1 christos BFD_ASSERT (s != NULL);
1453 1.1 christos BFD_ASSERT (s->contents != NULL);
1454 1.1 christos BFD_ASSERT (s->output_section != NULL);
1455 1.1 christos
1456 1.1 christos if ((my_offset & 0x01) == 0x01)
1457 1.1 christos {
1458 1.1 christos if (h_sec->owner != NULL
1459 1.1 christos && INTERWORK_SET (h_sec->owner)
1460 1.1 christos && ! INTERWORK_FLAG (h_sec->owner)
1461 1.1 christos && ! globals->support_old_code)
1462 1.8 christos _bfd_error_handler
1463 1.8 christos /* xgettext:c-format */
1464 1.8 christos (_("%pB(%s): warning: interworking not enabled; "
1465 1.8 christos "first occurrence: %pB: thumb call to arm; "
1466 1.7 christos "consider relinking with --support-old-code "
1467 1.1 christos "enabled"),
1468 1.1 christos h_sec->owner, name, input_bfd);
1469 1.1 christos
1470 1.1 christos -- my_offset;
1471 1.1 christos myh->root.u.def.value = my_offset;
1472 1.1 christos
1473 1.1 christos if (globals->support_old_code)
1474 1.1 christos {
1475 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a1_push_insn,
1476 1.1 christos s->contents + my_offset);
1477 1.1 christos
1478 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a2_ldr_insn,
1479 1.1 christos s->contents + my_offset + 2);
1480 1.1 christos
1481 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a3_mov_insn,
1482 1.1 christos s->contents + my_offset + 4);
1483 1.1 christos
1484 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a4_bx_insn,
1485 1.1 christos s->contents + my_offset + 6);
1486 1.1 christos
1487 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) t2a5_pop_insn,
1488 1.1 christos s->contents + my_offset + 8);
1489 1.1 christos
1490 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) t2a6_bx_insn,
1491 1.1 christos s->contents + my_offset + 12);
1492 1.1 christos
1493 1.1 christos /* Store the address of the function in the last word of the stub. */
1494 1.1 christos bfd_put_32 (output_bfd, h_val,
1495 1.8 christos s->contents + my_offset + 16);
1496 1.1 christos
1497 1.1 christos if (info->base_file
1498 1.1 christos && !arm_emit_base_file_entry (info,
1499 1.10 christos output_bfd, s,
1500 1.1 christos my_offset + 16))
1501 1.1 christos return false;
1502 1.1 christos }
1503 1.1 christos else
1504 1.1 christos {
1505 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn,
1506 1.1 christos s->contents + my_offset);
1507 1.1 christos
1508 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn,
1509 1.1 christos s->contents + my_offset + 2);
1510 1.1 christos
1511 1.1 christos ret_offset =
1512 1.1 christos /* Address of destination of the stub. */
1513 1.1 christos ((bfd_signed_vma) h_val)
1514 1.1 christos - ((bfd_signed_vma)
1515 1.1 christos /* Offset from the start of the current section to the start of the stubs. */
1516 1.1 christos (s->output_offset
1517 1.1 christos /* Offset of the start of this stub from the start of the stubs. */
1518 1.1 christos + my_offset
1519 1.1 christos /* Address of the start of the current section. */
1520 1.1 christos + s->output_section->vma)
1521 1.1 christos /* The branch instruction is 4 bytes into the stub. */
1522 1.1 christos + 4
1523 1.1 christos /* ARM branches work from the pc of the instruction + 8. */
1524 1.1 christos + 8);
1525 1.1 christos
1526 1.1 christos bfd_put_32 (output_bfd,
1527 1.1 christos (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1528 1.1 christos s->contents + my_offset + 4);
1529 1.1 christos
1530 1.1 christos }
1531 1.1 christos }
1532 1.1 christos
1533 1.1 christos BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1534 1.1 christos
1535 1.1 christos /* Now go back and fix up the original BL insn to point
1536 1.1 christos to here. */
1537 1.1 christos ret_offset =
1538 1.1 christos s->output_offset
1539 1.1 christos + my_offset
1540 1.1 christos - (input_section->output_offset
1541 1.1 christos + rel->r_vaddr)
1542 1.1 christos -4;
1543 1.1 christos
1544 1.1 christos tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1545 1.1 christos - input_section->vma);
1546 1.1 christos
1547 1.1 christos bfd_put_32 (output_bfd,
1548 1.1 christos (bfd_vma) insert_thumb_branch (tmp,
1549 1.1 christos ret_offset),
1550 1.1 christos contents + rel->r_vaddr - input_section->vma);
1551 1.8 christos
1552 1.8 christos done = 1;
1553 1.1 christos }
1554 1.8 christos }
1555 1.1 christos #endif
1556 1.8 christos }
1557 1.8 christos
1558 1.8 christos /* If the relocation type and destination symbol does not
1559 1.1 christos fall into one of the above categories, then we can just
1560 1.1 christos perform a direct link. */
1561 1.1 christos
1562 1.1 christos if (done)
1563 1.1 christos rstat = bfd_reloc_ok;
1564 1.1 christos else
1565 1.1 christos if ( h->root.type == bfd_link_hash_defined
1566 1.1 christos || h->root.type == bfd_link_hash_defweak)
1567 1.1 christos {
1568 1.1 christos asection *sec;
1569 1.1 christos
1570 1.1 christos sec = h->root.u.def.section;
1571 1.1 christos val = (h->root.u.def.value
1572 1.1 christos + sec->output_section->vma
1573 1.1 christos + sec->output_offset);
1574 1.6 christos }
1575 1.6 christos
1576 1.6 christos else if (! bfd_link_relocatable (info))
1577 1.10 christos (*info->callbacks->undefined_symbol)
1578 1.1 christos (info, h->root.root.string, input_bfd, input_section,
1579 1.1 christos rel->r_vaddr - input_section->vma, true);
1580 1.1 christos }
1581 1.1 christos
1582 1.1 christos /* Emit a reloc if the backend thinks it needs it. */
1583 1.1 christos if (info->base_file
1584 1.1 christos && sym
1585 1.1 christos && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)
1586 1.10 christos && !arm_emit_base_file_entry (info, output_bfd, input_section,
1587 1.1 christos rel->r_vaddr))
1588 1.1 christos return false;
1589 1.1 christos
1590 1.1 christos if (done)
1591 1.1 christos rstat = bfd_reloc_ok;
1592 1.6 christos #ifndef ARM_WINCE
1593 1.1 christos /* Only perform this fix during the final link, not a relocatable link. */
1594 1.8 christos else if (! bfd_link_relocatable (info)
1595 1.8 christos && howto->type == ARM_THUMB23)
1596 1.8 christos {
1597 1.8 christos /* This is pretty much a copy of what the default
1598 1.8 christos _bfd_final_link_relocate and _bfd_relocate_contents
1599 1.8 christos routines do to perform a relocation, with special
1600 1.8 christos processing for the split addressing of the Thumb BL
1601 1.8 christos instruction. Again, it would probably be simpler adding a
1602 1.1 christos ThumbBRANCH23 specific macro expansion into the default
1603 1.8 christos code. */
1604 1.1 christos
1605 1.1 christos bfd_vma address = rel->r_vaddr - input_section->vma;
1606 1.1 christos
1607 1.8 christos if (address > high_address)
1608 1.8 christos rstat = bfd_reloc_outofrange;
1609 1.8 christos else
1610 1.1 christos {
1611 1.10 christos bfd_vma relocation = val + addend;
1612 1.1 christos int size = bfd_get_reloc_size (howto);
1613 1.1 christos bool overflow = false;
1614 1.1 christos bfd_byte *location = contents + address;
1615 1.1 christos bfd_vma x = bfd_get_32 (input_bfd, location);
1616 1.1 christos bfd_vma src_mask = 0x007FFFFE;
1617 1.1 christos bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1618 1.1 christos bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1619 1.1 christos bfd_vma check;
1620 1.1 christos bfd_signed_vma signed_check;
1621 1.1 christos bfd_vma add;
1622 1.1 christos bfd_signed_vma signed_add;
1623 1.1 christos
1624 1.8 christos BFD_ASSERT (size == 4);
1625 1.8 christos
1626 1.8 christos /* howto->pc_relative should be TRUE for type 14 BRANCH23. */
1627 1.1 christos relocation -= (input_section->output_section->vma
1628 1.8 christos + input_section->output_offset);
1629 1.8 christos
1630 1.1 christos /* howto->pcrel_offset should be TRUE for type 14 BRANCH23. */
1631 1.1 christos relocation -= address;
1632 1.1 christos
1633 1.1 christos /* No need to negate the relocation with BRANCH23. */
1634 1.1 christos /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23. */
1635 1.1 christos /* howto->rightshift == 1 */
1636 1.1 christos
1637 1.1 christos /* Drop unwanted bits from the value we are relocating to. */
1638 1.1 christos check = relocation >> howto->rightshift;
1639 1.1 christos
1640 1.1 christos /* If this is a signed value, the rightshift just dropped
1641 1.1 christos leading 1 bits (assuming twos complement). */
1642 1.1 christos if ((bfd_signed_vma) relocation >= 0)
1643 1.1 christos signed_check = check;
1644 1.1 christos else
1645 1.1 christos signed_check = (check
1646 1.1 christos | ((bfd_vma) - 1
1647 1.1 christos & ~((bfd_vma) - 1 >> howto->rightshift)));
1648 1.1 christos
1649 1.1 christos /* Get the value from the object file. */
1650 1.1 christos if (bfd_big_endian (input_bfd))
1651 1.1 christos add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
1652 1.1 christos else
1653 1.1 christos add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
1654 1.1 christos
1655 1.1 christos /* Get the value from the object file with an appropriate sign.
1656 1.1 christos The expression involving howto->src_mask isolates the upper
1657 1.1 christos bit of src_mask. If that bit is set in the value we are
1658 1.1 christos adding, it is negative, and we subtract out that number times
1659 1.1 christos two. If src_mask includes the highest possible bit, then we
1660 1.1 christos can not get the upper bit, but that does not matter since
1661 1.1 christos signed_add needs no adjustment to become negative in that
1662 1.1 christos case. */
1663 1.1 christos signed_add = add;
1664 1.1 christos
1665 1.1 christos if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
1666 1.1 christos signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
1667 1.1 christos
1668 1.1 christos /* howto->bitpos == 0 */
1669 1.1 christos /* Add the value from the object file, shifted so that it is a
1670 1.1 christos straight number. */
1671 1.1 christos signed_check += signed_add;
1672 1.1 christos relocation += signed_add;
1673 1.1 christos
1674 1.1 christos BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
1675 1.1 christos
1676 1.1 christos /* Assumes two's complement. */
1677 1.10 christos if ( signed_check > reloc_signed_max
1678 1.1 christos || signed_check < reloc_signed_min)
1679 1.1 christos overflow = true;
1680 1.1 christos
1681 1.1 christos /* Put the relocation into the correct bits.
1682 1.1 christos For a BLX instruction, make sure that the relocation is rounded up
1683 1.1 christos to a word boundary. This follows the semantics of the instruction
1684 1.1 christos which specifies that bit 1 of the target address will come from bit
1685 1.8 christos 1 of the base address. */
1686 1.1 christos if (bfd_big_endian (input_bfd))
1687 1.1 christos {
1688 1.1 christos if ((x & 0x1800) == 0x0800 && (relocation & 0x02))
1689 1.1 christos relocation += 2;
1690 1.1 christos relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
1691 1.8 christos }
1692 1.1 christos else
1693 1.1 christos {
1694 1.1 christos if ((x & 0x18000000) == 0x08000000 && (relocation & 0x02))
1695 1.1 christos relocation += 2;
1696 1.1 christos relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1697 1.1 christos }
1698 1.1 christos
1699 1.1 christos /* Add the relocation to the correct bits of X. */
1700 1.1 christos x = ((x & ~howto->dst_mask) | relocation);
1701 1.1 christos
1702 1.1 christos /* Put the relocated value back in the object file. */
1703 1.1 christos bfd_put_32 (input_bfd, x, location);
1704 1.8 christos
1705 1.8 christos rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
1706 1.1 christos }
1707 1.1 christos }
1708 1.8 christos #endif
1709 1.8 christos else
1710 1.8 christos if (bfd_link_relocatable (info) && ! howto->partial_inplace)
1711 1.1 christos rstat = bfd_reloc_ok;
1712 1.1 christos else
1713 1.1 christos rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
1714 1.1 christos contents,
1715 1.1 christos rel->r_vaddr - input_section->vma,
1716 1.6 christos val, addend);
1717 1.1 christos /* Only perform this fix during the final link, not a relocatable link. */
1718 1.1 christos if (! bfd_link_relocatable (info)
1719 1.1 christos && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
1720 1.1 christos {
1721 1.10 christos /* Determine if we need to set the bottom bit of a relocated address
1722 1.1 christos because the address is the address of a Thumb code symbol. */
1723 1.1 christos int patchit = false;
1724 1.1 christos
1725 1.1 christos if (h != NULL
1726 1.1 christos && ( h->symbol_class == C_THUMBSTATFUNC
1727 1.10 christos || h->symbol_class == C_THUMBEXTFUNC))
1728 1.1 christos {
1729 1.1 christos patchit = true;
1730 1.1 christos }
1731 1.1 christos else if (sym != NULL
1732 1.1 christos && sym->n_scnum > N_UNDEF)
1733 1.1 christos {
1734 1.1 christos /* No hash entry - use the symbol instead. */
1735 1.10 christos if ( sym->n_sclass == C_THUMBSTATFUNC
1736 1.1 christos || sym->n_sclass == C_THUMBEXTFUNC)
1737 1.1 christos patchit = true;
1738 1.1 christos }
1739 1.1 christos
1740 1.1 christos if (patchit)
1741 1.8 christos {
1742 1.1 christos bfd_byte * location = contents + rel->r_vaddr - input_section->vma;
1743 1.1 christos bfd_vma x = bfd_get_32 (input_bfd, location);
1744 1.1 christos
1745 1.1 christos bfd_put_32 (input_bfd, x | 1, location);
1746 1.1 christos }
1747 1.1 christos }
1748 1.1 christos
1749 1.1 christos switch (rstat)
1750 1.1 christos {
1751 1.1 christos default:
1752 1.1 christos abort ();
1753 1.1 christos case bfd_reloc_ok:
1754 1.7 christos break;
1755 1.7 christos case bfd_reloc_outofrange:
1756 1.8 christos _bfd_error_handler
1757 1.8 christos /* xgettext:c-format */
1758 1.10 christos (_("%pB: bad reloc address %#" PRIx64 " in section `%pA'"),
1759 1.1 christos input_bfd, (uint64_t) rel->r_vaddr, input_section);
1760 1.1 christos return false;
1761 1.1 christos case bfd_reloc_overflow:
1762 1.1 christos {
1763 1.1 christos const char *name;
1764 1.1 christos char buf[SYMNMLEN + 1];
1765 1.1 christos
1766 1.1 christos if (symndx == -1)
1767 1.1 christos name = "*ABS*";
1768 1.1 christos else if (h != NULL)
1769 1.1 christos name = NULL;
1770 1.1 christos else
1771 1.1 christos {
1772 1.10 christos name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1773 1.1 christos if (name == NULL)
1774 1.1 christos return false;
1775 1.6 christos }
1776 1.6 christos
1777 1.6 christos (*info->callbacks->reloc_overflow)
1778 1.6 christos (info, (h ? &h->root : NULL), name, howto->name,
1779 1.1 christos (bfd_vma) 0, input_bfd, input_section,
1780 1.1 christos rel->r_vaddr - input_section->vma);
1781 1.1 christos }
1782 1.1 christos }
1783 1.10 christos }
1784 1.1 christos
1785 1.1 christos return true;
1786 1.1 christos }
1787 1.1 christos
1788 1.10 christos #ifndef COFF_IMAGE_WITH_PE
1789 1.1 christos
1790 1.1 christos bool
1791 1.8 christos bfd_arm_allocate_interworking_sections (struct bfd_link_info * info)
1792 1.8 christos {
1793 1.1 christos asection * s;
1794 1.1 christos bfd_byte * foo;
1795 1.1 christos struct coff_arm_link_hash_table * globals;
1796 1.1 christos
1797 1.1 christos globals = coff_arm_hash_table (info);
1798 1.1 christos
1799 1.1 christos BFD_ASSERT (globals != NULL);
1800 1.1 christos
1801 1.1 christos if (globals->arm_glue_size != 0)
1802 1.1 christos {
1803 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1804 1.1 christos
1805 1.1 christos s = bfd_get_section_by_name
1806 1.1 christos (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1807 1.1 christos
1808 1.1 christos BFD_ASSERT (s != NULL);
1809 1.1 christos
1810 1.1 christos foo = bfd_alloc (globals->bfd_of_glue_owner, globals->arm_glue_size);
1811 1.1 christos
1812 1.1 christos s->size = globals->arm_glue_size;
1813 1.1 christos s->contents = foo;
1814 1.1 christos }
1815 1.1 christos
1816 1.1 christos if (globals->thumb_glue_size != 0)
1817 1.1 christos {
1818 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1819 1.1 christos
1820 1.1 christos s = bfd_get_section_by_name
1821 1.1 christos (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1822 1.1 christos
1823 1.1 christos BFD_ASSERT (s != NULL);
1824 1.1 christos
1825 1.1 christos foo = bfd_alloc (globals->bfd_of_glue_owner, globals->thumb_glue_size);
1826 1.1 christos
1827 1.1 christos s->size = globals->thumb_glue_size;
1828 1.1 christos s->contents = foo;
1829 1.10 christos }
1830 1.1 christos
1831 1.1 christos return true;
1832 1.1 christos }
1833 1.8 christos
1834 1.1 christos static void
1835 1.1 christos record_arm_to_thumb_glue (struct bfd_link_info * info,
1836 1.8 christos struct coff_link_hash_entry * h)
1837 1.8 christos {
1838 1.8 christos const char * name = h->root.root.string;
1839 1.8 christos register asection * s;
1840 1.8 christos char * tmp_name;
1841 1.1 christos struct coff_link_hash_entry * myh;
1842 1.1 christos struct bfd_link_hash_entry * bh;
1843 1.9 christos struct coff_arm_link_hash_table * globals;
1844 1.1 christos bfd_vma val;
1845 1.1 christos size_t amt;
1846 1.1 christos
1847 1.1 christos globals = coff_arm_hash_table (info);
1848 1.1 christos
1849 1.1 christos BFD_ASSERT (globals != NULL);
1850 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1851 1.1 christos
1852 1.1 christos s = bfd_get_section_by_name
1853 1.1 christos (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1854 1.1 christos
1855 1.1 christos BFD_ASSERT (s != NULL);
1856 1.1 christos
1857 1.1 christos amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1858 1.1 christos tmp_name = bfd_malloc (amt);
1859 1.1 christos
1860 1.1 christos BFD_ASSERT (tmp_name);
1861 1.1 christos
1862 1.1 christos sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1863 1.10 christos
1864 1.1 christos myh = coff_link_hash_lookup
1865 1.1 christos (coff_hash_table (info), tmp_name, false, false, true);
1866 1.1 christos
1867 1.1 christos if (myh != NULL)
1868 1.1 christos {
1869 1.1 christos free (tmp_name);
1870 1.1 christos /* We've already seen this guy. */
1871 1.1 christos return;
1872 1.1 christos }
1873 1.1 christos
1874 1.1 christos /* The only trick here is using globals->arm_glue_size as the value. Even
1875 1.1 christos though the section isn't allocated yet, this is where we will be putting
1876 1.1 christos it. */
1877 1.1 christos bh = NULL;
1878 1.10 christos val = globals->arm_glue_size + 1;
1879 1.1 christos bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1880 1.1 christos BSF_GLOBAL, s, val, NULL, true, false, &bh);
1881 1.1 christos
1882 1.1 christos free (tmp_name);
1883 1.1 christos
1884 1.1 christos globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
1885 1.1 christos
1886 1.1 christos return;
1887 1.1 christos }
1888 1.1 christos
1889 1.8 christos #ifndef ARM_WINCE
1890 1.1 christos static void
1891 1.1 christos record_thumb_to_arm_glue (struct bfd_link_info * info,
1892 1.8 christos struct coff_link_hash_entry * h)
1893 1.8 christos {
1894 1.8 christos const char * name = h->root.root.string;
1895 1.8 christos asection * s;
1896 1.8 christos char * tmp_name;
1897 1.1 christos struct coff_link_hash_entry * myh;
1898 1.1 christos struct bfd_link_hash_entry * bh;
1899 1.9 christos struct coff_arm_link_hash_table * globals;
1900 1.1 christos bfd_vma val;
1901 1.1 christos size_t amt;
1902 1.1 christos
1903 1.1 christos globals = coff_arm_hash_table (info);
1904 1.1 christos
1905 1.1 christos BFD_ASSERT (globals != NULL);
1906 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1907 1.1 christos
1908 1.1 christos s = bfd_get_section_by_name
1909 1.1 christos (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1910 1.1 christos
1911 1.1 christos BFD_ASSERT (s != NULL);
1912 1.1 christos
1913 1.1 christos amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1914 1.1 christos tmp_name = bfd_malloc (amt);
1915 1.1 christos
1916 1.1 christos BFD_ASSERT (tmp_name);
1917 1.1 christos
1918 1.1 christos sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1919 1.10 christos
1920 1.1 christos myh = coff_link_hash_lookup
1921 1.1 christos (coff_hash_table (info), tmp_name, false, false, true);
1922 1.1 christos
1923 1.1 christos if (myh != NULL)
1924 1.1 christos {
1925 1.1 christos free (tmp_name);
1926 1.1 christos /* We've already seen this guy. */
1927 1.1 christos return;
1928 1.1 christos }
1929 1.1 christos
1930 1.1 christos bh = NULL;
1931 1.10 christos val = globals->thumb_glue_size + 1;
1932 1.1 christos bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1933 1.1 christos BSF_GLOBAL, s, val, NULL, true, false, &bh);
1934 1.1 christos
1935 1.1 christos /* If we mark it 'thumb', the disassembler will do a better job. */
1936 1.1 christos myh = (struct coff_link_hash_entry *) bh;
1937 1.1 christos myh->symbol_class = C_THUMBEXTFUNC;
1938 1.1 christos
1939 1.1 christos free (tmp_name);
1940 1.1 christos
1941 1.1 christos /* Allocate another symbol to mark where we switch to arm mode. */
1942 1.1 christos
1943 1.1 christos #define CHANGE_TO_ARM "__%s_change_to_arm"
1944 1.1 christos #define BACK_FROM_ARM "__%s_back_from_arm"
1945 1.1 christos
1946 1.1 christos amt = strlen (name) + strlen (CHANGE_TO_ARM) + 1;
1947 1.1 christos tmp_name = bfd_malloc (amt);
1948 1.1 christos
1949 1.1 christos BFD_ASSERT (tmp_name);
1950 1.1 christos
1951 1.1 christos sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
1952 1.1 christos
1953 1.1 christos bh = NULL;
1954 1.10 christos val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
1955 1.1 christos bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1956 1.1 christos BSF_LOCAL, s, val, NULL, true, false, &bh);
1957 1.1 christos
1958 1.1 christos free (tmp_name);
1959 1.1 christos
1960 1.1 christos globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
1961 1.1 christos
1962 1.1 christos return;
1963 1.1 christos }
1964 1.1 christos #endif /* not ARM_WINCE */
1965 1.1 christos
1966 1.1 christos /* Select a BFD to be used to hold the sections used by the glue code.
1967 1.1 christos This function is called from the linker scripts in ld/emultempl/
1968 1.10 christos {armcoff/pe}.em */
1969 1.8 christos
1970 1.1 christos bool
1971 1.1 christos bfd_arm_get_bfd_for_interworking (bfd * abfd,
1972 1.1 christos struct bfd_link_info * info)
1973 1.8 christos {
1974 1.8 christos struct coff_arm_link_hash_table * globals;
1975 1.1 christos flagword flags;
1976 1.1 christos asection * sec;
1977 1.1 christos
1978 1.6 christos /* If we are only performing a partial link do not bother
1979 1.10 christos getting a bfd to hold the glue. */
1980 1.1 christos if (bfd_link_relocatable (info))
1981 1.1 christos return true;
1982 1.1 christos
1983 1.1 christos globals = coff_arm_hash_table (info);
1984 1.1 christos
1985 1.1 christos BFD_ASSERT (globals != NULL);
1986 1.10 christos
1987 1.1 christos if (globals->bfd_of_glue_owner != NULL)
1988 1.1 christos return true;
1989 1.1 christos
1990 1.1 christos sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1991 1.1 christos
1992 1.1 christos if (sec == NULL)
1993 1.1 christos {
1994 1.1 christos flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1995 1.1 christos | SEC_CODE | SEC_READONLY);
1996 1.1 christos sec = bfd_make_section_with_flags (abfd, ARM2THUMB_GLUE_SECTION_NAME,
1997 1.9 christos flags);
1998 1.10 christos if (sec == NULL
1999 1.1 christos || !bfd_set_section_alignment (sec, 2))
2000 1.1 christos return false;
2001 1.1 christos }
2002 1.1 christos
2003 1.1 christos sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
2004 1.1 christos
2005 1.1 christos if (sec == NULL)
2006 1.1 christos {
2007 1.1 christos flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
2008 1.1 christos | SEC_CODE | SEC_READONLY);
2009 1.1 christos sec = bfd_make_section_with_flags (abfd, THUMB2ARM_GLUE_SECTION_NAME,
2010 1.1 christos flags);
2011 1.9 christos
2012 1.10 christos if (sec == NULL
2013 1.1 christos || !bfd_set_section_alignment (sec, 2))
2014 1.1 christos return false;
2015 1.1 christos }
2016 1.1 christos
2017 1.1 christos /* Save the bfd for later use. */
2018 1.10 christos globals->bfd_of_glue_owner = abfd;
2019 1.1 christos
2020 1.1 christos return true;
2021 1.10 christos }
2022 1.8 christos
2023 1.1 christos bool
2024 1.8 christos bfd_arm_process_before_allocation (bfd * abfd,
2025 1.1 christos struct bfd_link_info * info,
2026 1.1 christos int support_old_code)
2027 1.1 christos {
2028 1.1 christos asection * sec;
2029 1.1 christos struct coff_arm_link_hash_table * globals;
2030 1.1 christos
2031 1.6 christos /* If we are only performing a partial link do not bother
2032 1.10 christos to construct any glue. */
2033 1.1 christos if (bfd_link_relocatable (info))
2034 1.1 christos return true;
2035 1.1 christos
2036 1.1 christos /* Here we have a bfd that is to be included on the link. We have a hook
2037 1.1 christos to do reloc rummaging, before section sizes are nailed down. */
2038 1.1 christos _bfd_coff_get_external_symbols (abfd);
2039 1.1 christos
2040 1.1 christos globals = coff_arm_hash_table (info);
2041 1.1 christos
2042 1.1 christos BFD_ASSERT (globals != NULL);
2043 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
2044 1.1 christos
2045 1.1 christos globals->support_old_code = support_old_code;
2046 1.1 christos
2047 1.1 christos /* Rummage around all the relocs and map the glue vectors. */
2048 1.1 christos sec = abfd->sections;
2049 1.10 christos
2050 1.1 christos if (sec == NULL)
2051 1.1 christos return true;
2052 1.1 christos
2053 1.1 christos for (; sec != NULL; sec = sec->next)
2054 1.1 christos {
2055 1.1 christos struct internal_reloc * i;
2056 1.1 christos struct internal_reloc * rel;
2057 1.1 christos
2058 1.1 christos if (sec->reloc_count == 0)
2059 1.1 christos continue;
2060 1.1 christos
2061 1.1 christos /* Load the relocs. */
2062 1.1 christos /* FIXME: there may be a storage leak here. */
2063 1.1 christos i = _bfd_coff_read_internal_relocs (abfd, sec, 1, 0, 0, 0);
2064 1.1 christos
2065 1.1 christos BFD_ASSERT (i != 0);
2066 1.1 christos
2067 1.8 christos for (rel = i; rel < i + sec->reloc_count; ++rel)
2068 1.8 christos {
2069 1.8 christos unsigned short r_type = rel->r_type;
2070 1.1 christos long symndx;
2071 1.1 christos struct coff_link_hash_entry * h;
2072 1.1 christos
2073 1.1 christos symndx = rel->r_symndx;
2074 1.1 christos
2075 1.1 christos /* If the relocation is not against a symbol it cannot concern us. */
2076 1.1 christos if (symndx == -1)
2077 1.1 christos continue;
2078 1.1 christos
2079 1.1 christos /* If the index is outside of the range of our table, something has gone wrong. */
2080 1.7 christos if (symndx >= obj_conv_table_size (abfd))
2081 1.8 christos {
2082 1.1 christos /* xgettext:c-format */
2083 1.1 christos _bfd_error_handler (_("%pB: illegal symbol index in reloc: %ld"),
2084 1.1 christos abfd, symndx);
2085 1.1 christos continue;
2086 1.1 christos }
2087 1.1 christos
2088 1.1 christos h = obj_coff_sym_hashes (abfd)[symndx];
2089 1.1 christos
2090 1.1 christos /* If the relocation is against a static symbol it must be within
2091 1.1 christos the current section and so cannot be a cross ARM/Thumb relocation. */
2092 1.1 christos if (h == NULL)
2093 1.1 christos continue;
2094 1.1 christos
2095 1.1 christos switch (r_type)
2096 1.1 christos {
2097 1.1 christos case ARM_26:
2098 1.1 christos /* This one is a call from arm code. We need to look up
2099 1.1 christos the target of the call. If it is a thumb target, we
2100 1.1 christos insert glue. */
2101 1.1 christos
2102 1.1 christos if (h->symbol_class == C_THUMBEXTFUNC)
2103 1.1 christos record_arm_to_thumb_glue (info, h);
2104 1.1 christos break;
2105 1.1 christos
2106 1.1 christos #ifndef ARM_WINCE
2107 1.1 christos case ARM_THUMB23:
2108 1.1 christos /* This one is a call from thumb code. We used to look
2109 1.1 christos for ARM_THUMB9 and ARM_THUMB12 as well. We need to look
2110 1.1 christos up the target of the call. If it is an arm target, we
2111 1.1 christos insert glue. If the symbol does not exist it will be
2112 1.1 christos given a class of C_EXT and so we will generate a stub
2113 1.1 christos for it. This is not really a problem, since the link
2114 1.1 christos is doomed anyway. */
2115 1.1 christos
2116 1.1 christos switch (h->symbol_class)
2117 1.1 christos {
2118 1.1 christos case C_EXT:
2119 1.1 christos case C_STAT:
2120 1.1 christos case C_LABEL:
2121 1.1 christos record_thumb_to_arm_glue (info, h);
2122 1.1 christos break;
2123 1.1 christos default:
2124 1.1 christos ;
2125 1.1 christos }
2126 1.1 christos break;
2127 1.1 christos #endif
2128 1.1 christos
2129 1.1 christos default:
2130 1.1 christos break;
2131 1.1 christos }
2132 1.1 christos }
2133 1.10 christos }
2134 1.1 christos
2135 1.1 christos return true;
2136 1.1 christos }
2137 1.1 christos
2138 1.8 christos #endif /* ! defined (COFF_IMAGE_WITH_PE) */
2139 1.8 christos
2140 1.8 christos #define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup
2141 1.8 christos #define coff_bfd_reloc_name_lookup coff_arm_reloc_name_lookup
2142 1.1 christos #define coff_relocate_section coff_arm_relocate_section
2143 1.8 christos #define coff_bfd_is_local_label_name coff_arm_is_local_label_name
2144 1.1 christos #define coff_adjust_symndx coff_arm_adjust_symndx
2145 1.1 christos #define coff_link_output_has_begun coff_arm_link_output_has_begun
2146 1.1 christos #define coff_final_link_postscript coff_arm_final_link_postscript
2147 1.8 christos #define coff_bfd_merge_private_bfd_data coff_arm_merge_private_bfd_data
2148 1.8 christos #define coff_bfd_print_private_bfd_data coff_arm_print_private_bfd_data
2149 1.1 christos #define coff_bfd_set_private_flags _bfd_coff_arm_set_private_flags
2150 1.1 christos #define coff_bfd_copy_private_bfd_data coff_arm_copy_private_bfd_data
2151 1.1 christos #define coff_bfd_link_hash_table_create coff_arm_link_hash_table_create
2152 1.1 christos
2153 1.1 christos /* When doing a relocatable link, we want to convert ARM_26 relocs
2154 1.10 christos into ARM_26D relocs. */
2155 1.1 christos
2156 1.1 christos static bool
2157 1.1 christos coff_arm_adjust_symndx (bfd *obfd ATTRIBUTE_UNUSED,
2158 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED,
2159 1.1 christos bfd *ibfd,
2160 1.10 christos asection *sec,
2161 1.1 christos struct internal_reloc *irel,
2162 1.1 christos bool *adjustedp)
2163 1.1 christos {
2164 1.1 christos if (irel->r_type == ARM_26)
2165 1.1 christos {
2166 1.1 christos struct coff_link_hash_entry *h;
2167 1.1 christos
2168 1.1 christos h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
2169 1.1 christos if (h != NULL
2170 1.1 christos && (h->root.type == bfd_link_hash_defined
2171 1.1 christos || h->root.type == bfd_link_hash_defweak)
2172 1.1 christos && h->root.u.def.section->output_section == sec->output_section)
2173 1.10 christos irel->r_type = ARM_26D;
2174 1.10 christos }
2175 1.1 christos *adjustedp = false;
2176 1.1 christos return true;
2177 1.1 christos }
2178 1.1 christos
2179 1.1 christos /* Called when merging the private data areas of two BFDs.
2180 1.1 christos This is important as it allows us to detect if we are
2181 1.1 christos attempting to merge binaries compiled for different ARM
2182 1.10 christos targets, eg different CPUs or different APCS's. */
2183 1.7 christos
2184 1.1 christos static bool
2185 1.7 christos coff_arm_merge_private_bfd_data (bfd * ibfd, struct bfd_link_info *info)
2186 1.1 christos {
2187 1.1 christos bfd *obfd = info->output_bfd;
2188 1.1 christos BFD_ASSERT (ibfd != NULL && obfd != NULL);
2189 1.10 christos
2190 1.1 christos if (ibfd == obfd)
2191 1.1 christos return true;
2192 1.1 christos
2193 1.1 christos /* If the two formats are different we cannot merge anything.
2194 1.1 christos This is not an error, since it is permissable to change the
2195 1.1 christos input and output formats. */
2196 1.10 christos if ( ibfd->xvec->flavour != bfd_target_coff_flavour
2197 1.1 christos || obfd->xvec->flavour != bfd_target_coff_flavour)
2198 1.1 christos return true;
2199 1.1 christos
2200 1.1 christos /* Determine what should happen if the input ARM architecture
2201 1.10 christos does not match the output ARM architecture. */
2202 1.1 christos if (! bfd_arm_merge_machines (ibfd, obfd))
2203 1.1 christos return false;
2204 1.1 christos
2205 1.1 christos /* Verify that the APCS is the same for the two BFDs. */
2206 1.1 christos if (APCS_SET (ibfd))
2207 1.1 christos {
2208 1.1 christos if (APCS_SET (obfd))
2209 1.1 christos {
2210 1.1 christos /* If the src and dest have different APCS flag bits set, fail. */
2211 1.1 christos if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
2212 1.1 christos {
2213 1.9 christos _bfd_error_handler
2214 1.9 christos /* xgettext: c-format */
2215 1.7 christos (_("error: %pB is compiled for APCS-%d, "
2216 1.7 christos "whereas %pB is compiled for APCS-%d"),
2217 1.1 christos ibfd, APCS_26_FLAG (ibfd) ? 26 : 32,
2218 1.1 christos obfd, APCS_26_FLAG (obfd) ? 26 : 32
2219 1.1 christos );
2220 1.10 christos
2221 1.1 christos bfd_set_error (bfd_error_wrong_format);
2222 1.1 christos return false;
2223 1.1 christos }
2224 1.1 christos
2225 1.1 christos if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
2226 1.1 christos {
2227 1.9 christos if (APCS_FLOAT_FLAG (ibfd))
2228 1.9 christos /* xgettext: c-format */
2229 1.9 christos _bfd_error_handler
2230 1.9 christos (_("error: %pB passes floats in float registers, "
2231 1.1 christos "whereas %pB passes them in integer registers"),
2232 1.1 christos ibfd, obfd);
2233 1.9 christos else
2234 1.9 christos /* xgettext: c-format */
2235 1.9 christos _bfd_error_handler
2236 1.9 christos (_("error: %pB passes floats in integer registers, "
2237 1.1 christos "whereas %pB passes them in float registers"),
2238 1.1 christos ibfd, obfd);
2239 1.10 christos
2240 1.1 christos bfd_set_error (bfd_error_wrong_format);
2241 1.1 christos return false;
2242 1.1 christos }
2243 1.1 christos
2244 1.1 christos if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
2245 1.1 christos {
2246 1.9 christos if (PIC_FLAG (ibfd))
2247 1.9 christos /* xgettext: c-format */
2248 1.9 christos _bfd_error_handler
2249 1.9 christos (_("error: %pB is compiled as position independent code, "
2250 1.1 christos "whereas target %pB is absolute position"),
2251 1.1 christos ibfd, obfd);
2252 1.9 christos else
2253 1.9 christos /* xgettext: c-format */
2254 1.9 christos _bfd_error_handler
2255 1.9 christos (_("error: %pB is compiled as absolute position code, "
2256 1.1 christos "whereas target %pB is position independent"),
2257 1.1 christos ibfd, obfd);
2258 1.10 christos
2259 1.1 christos bfd_set_error (bfd_error_wrong_format);
2260 1.1 christos return false;
2261 1.1 christos }
2262 1.1 christos }
2263 1.1 christos else
2264 1.1 christos {
2265 1.1 christos SET_APCS_FLAGS (obfd, APCS_26_FLAG (ibfd) | APCS_FLOAT_FLAG (ibfd) | PIC_FLAG (ibfd));
2266 1.1 christos
2267 1.1 christos /* Set up the arch and fields as well as these are probably wrong. */
2268 1.1 christos bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2269 1.1 christos }
2270 1.1 christos }
2271 1.1 christos
2272 1.1 christos /* Check the interworking support. */
2273 1.1 christos if (INTERWORK_SET (ibfd))
2274 1.1 christos {
2275 1.1 christos if (INTERWORK_SET (obfd))
2276 1.1 christos {
2277 1.1 christos /* If the src and dest differ in their interworking issue a warning. */
2278 1.1 christos if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd))
2279 1.1 christos {
2280 1.9 christos if (INTERWORK_FLAG (ibfd))
2281 1.9 christos /* xgettext: c-format */
2282 1.7 christos _bfd_error_handler (_("warning: %pB supports interworking, "
2283 1.1 christos "whereas %pB does not"),
2284 1.1 christos ibfd, obfd);
2285 1.9 christos else
2286 1.9 christos /* xgettext: c-format */
2287 1.9 christos _bfd_error_handler
2288 1.9 christos (_("warning: %pB does not support interworking, "
2289 1.1 christos "whereas %pB does"),
2290 1.1 christos ibfd, obfd);
2291 1.1 christos }
2292 1.1 christos }
2293 1.1 christos else
2294 1.1 christos {
2295 1.1 christos SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
2296 1.1 christos }
2297 1.10 christos }
2298 1.1 christos
2299 1.1 christos return true;
2300 1.1 christos }
2301 1.1 christos
2302 1.10 christos /* Display the flags field. */
2303 1.1 christos
2304 1.1 christos static bool
2305 1.1 christos coff_arm_print_private_bfd_data (bfd * abfd, void * ptr)
2306 1.1 christos {
2307 1.1 christos FILE * file = (FILE *) ptr;
2308 1.1 christos
2309 1.1 christos BFD_ASSERT (abfd != NULL && ptr != NULL);
2310 1.1 christos
2311 1.1 christos fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags);
2312 1.1 christos
2313 1.1 christos if (APCS_SET (abfd))
2314 1.1 christos {
2315 1.1 christos /* xgettext: APCS is ARM Procedure Call Standard, it should not be translated. */
2316 1.1 christos fprintf (file, " [APCS-%d]", APCS_26_FLAG (abfd) ? 26 : 32);
2317 1.1 christos
2318 1.1 christos if (APCS_FLOAT_FLAG (abfd))
2319 1.1 christos fprintf (file, _(" [floats passed in float registers]"));
2320 1.1 christos else
2321 1.1 christos fprintf (file, _(" [floats passed in integer registers]"));
2322 1.1 christos
2323 1.1 christos if (PIC_FLAG (abfd))
2324 1.1 christos fprintf (file, _(" [position independent]"));
2325 1.1 christos else
2326 1.1 christos fprintf (file, _(" [absolute position]"));
2327 1.1 christos }
2328 1.1 christos
2329 1.1 christos if (! INTERWORK_SET (abfd))
2330 1.1 christos fprintf (file, _(" [interworking flag not initialised]"));
2331 1.1 christos else if (INTERWORK_FLAG (abfd))
2332 1.1 christos fprintf (file, _(" [interworking supported]"));
2333 1.1 christos else
2334 1.1 christos fprintf (file, _(" [interworking not supported]"));
2335 1.1 christos
2336 1.10 christos fputc ('\n', file);
2337 1.1 christos
2338 1.1 christos return true;
2339 1.1 christos }
2340 1.1 christos
2341 1.1 christos /* Copies the given flags into the coff_tdata.flags field.
2342 1.1 christos Typically these flags come from the f_flags[] field of
2343 1.1 christos the COFF filehdr structure, which contains important,
2344 1.1 christos target specific information.
2345 1.1 christos Note: Although this function is static, it is explicitly
2346 1.10 christos called from both coffcode.h and peicode.h. */
2347 1.1 christos
2348 1.1 christos static bool
2349 1.1 christos _bfd_coff_arm_set_private_flags (bfd * abfd, flagword flags)
2350 1.1 christos {
2351 1.1 christos flagword flag;
2352 1.1 christos
2353 1.1 christos BFD_ASSERT (abfd != NULL);
2354 1.1 christos
2355 1.1 christos flag = (flags & F_APCS26) ? F_APCS_26 : 0;
2356 1.1 christos
2357 1.1 christos /* Make sure that the APCS field has not been initialised to the opposite
2358 1.1 christos value. */
2359 1.1 christos if (APCS_SET (abfd)
2360 1.8 christos && ( (APCS_26_FLAG (abfd) != flag)
2361 1.1 christos || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT))
2362 1.10 christos || (PIC_FLAG (abfd) != (flags & F_PIC))
2363 1.1 christos ))
2364 1.1 christos return false;
2365 1.1 christos
2366 1.1 christos flag |= (flags & (F_APCS_FLOAT | F_PIC));
2367 1.1 christos
2368 1.1 christos SET_APCS_FLAGS (abfd, flag);
2369 1.1 christos
2370 1.1 christos flag = (flags & F_INTERWORK);
2371 1.1 christos
2372 1.1 christos /* If the BFD has already had its interworking flag set, but it
2373 1.1 christos is different from the value that we have been asked to set,
2374 1.1 christos then assume that that merged code will not support interworking
2375 1.1 christos and set the flag accordingly. */
2376 1.1 christos if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag))
2377 1.8 christos {
2378 1.1 christos if (flag)
2379 1.1 christos _bfd_error_handler (_("warning: not setting interworking flag of %pB since it has already been specified as non-interworking"),
2380 1.8 christos abfd);
2381 1.1 christos else
2382 1.1 christos _bfd_error_handler (_("warning: clearing the interworking flag of %pB due to outside request"),
2383 1.1 christos abfd);
2384 1.1 christos flag = 0;
2385 1.1 christos }
2386 1.1 christos
2387 1.10 christos SET_INTERWORK_FLAG (abfd, flag);
2388 1.1 christos
2389 1.1 christos return true;
2390 1.1 christos }
2391 1.1 christos
2392 1.1 christos /* Copy the important parts of the target specific data
2393 1.10 christos from one instance of a BFD to another. */
2394 1.1 christos
2395 1.1 christos static bool
2396 1.1 christos coff_arm_copy_private_bfd_data (bfd * src, bfd * dest)
2397 1.1 christos {
2398 1.1 christos BFD_ASSERT (src != NULL && dest != NULL);
2399 1.10 christos
2400 1.1 christos if (src == dest)
2401 1.1 christos return true;
2402 1.1 christos
2403 1.1 christos /* If the destination is not in the same format as the source, do not do
2404 1.10 christos the copy. */
2405 1.1 christos if (src->xvec != dest->xvec)
2406 1.1 christos return true;
2407 1.1 christos
2408 1.1 christos /* Copy the flags field. */
2409 1.1 christos if (APCS_SET (src))
2410 1.1 christos {
2411 1.1 christos if (APCS_SET (dest))
2412 1.1 christos {
2413 1.10 christos /* If the src and dest have different APCS flag bits set, fail. */
2414 1.1 christos if (APCS_26_FLAG (dest) != APCS_26_FLAG (src))
2415 1.1 christos return false;
2416 1.10 christos
2417 1.1 christos if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src))
2418 1.1 christos return false;
2419 1.10 christos
2420 1.1 christos if (PIC_FLAG (dest) != PIC_FLAG (src))
2421 1.1 christos return false;
2422 1.1 christos }
2423 1.1 christos else
2424 1.1 christos SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src)
2425 1.1 christos | PIC_FLAG (src));
2426 1.1 christos }
2427 1.1 christos
2428 1.1 christos if (INTERWORK_SET (src))
2429 1.1 christos {
2430 1.1 christos if (INTERWORK_SET (dest))
2431 1.1 christos {
2432 1.1 christos /* If the src and dest have different interworking flags then turn
2433 1.1 christos off the interworking bit. */
2434 1.1 christos if (INTERWORK_FLAG (dest) != INTERWORK_FLAG (src))
2435 1.1 christos {
2436 1.1 christos if (INTERWORK_FLAG (dest))
2437 1.9 christos {
2438 1.9 christos /* xgettext:c-format */
2439 1.9 christos _bfd_error_handler
2440 1.9 christos (_("warning: clearing the interworking flag of %pB "
2441 1.9 christos "because non-interworking code in %pB has been "
2442 1.1 christos "linked with it"),
2443 1.1 christos dest, src);
2444 1.1 christos }
2445 1.1 christos
2446 1.1 christos SET_INTERWORK_FLAG (dest, 0);
2447 1.1 christos }
2448 1.1 christos }
2449 1.1 christos else
2450 1.1 christos {
2451 1.1 christos SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src));
2452 1.1 christos }
2453 1.10 christos }
2454 1.1 christos
2455 1.1 christos return true;
2456 1.1 christos }
2457 1.1 christos
2458 1.1 christos /* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
2459 1.1 christos *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h. */
2460 1.1 christos #ifndef LOCAL_LABEL_PREFIX
2461 1.1 christos #define LOCAL_LABEL_PREFIX ""
2462 1.1 christos #endif
2463 1.1 christos #ifndef USER_LABEL_PREFIX
2464 1.1 christos #define USER_LABEL_PREFIX "_"
2465 1.1 christos #endif
2466 1.1 christos
2467 1.1 christos /* Like _bfd_coff_is_local_label_name, but
2468 1.1 christos a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be
2469 1.1 christos non-local.
2470 1.1 christos b) Allow other prefixes than ".", e.g. an empty prefix would cause all
2471 1.10 christos labels of the form Lxxx to be stripped. */
2472 1.8 christos
2473 1.1 christos static bool
2474 1.1 christos coff_arm_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
2475 1.1 christos const char * name)
2476 1.1 christos {
2477 1.1 christos #ifdef USER_LABEL_PREFIX
2478 1.1 christos if (USER_LABEL_PREFIX[0] != 0)
2479 1.1 christos {
2480 1.1 christos size_t len = strlen (USER_LABEL_PREFIX);
2481 1.10 christos
2482 1.1 christos if (strncmp (name, USER_LABEL_PREFIX, len) == 0)
2483 1.1 christos return false;
2484 1.1 christos }
2485 1.1 christos #endif
2486 1.1 christos
2487 1.1 christos #ifdef LOCAL_LABEL_PREFIX
2488 1.1 christos /* If there is a prefix for local labels then look for this.
2489 1.1 christos If the prefix exists, but it is empty, then ignore the test. */
2490 1.1 christos
2491 1.1 christos if (LOCAL_LABEL_PREFIX[0] != 0)
2492 1.1 christos {
2493 1.1 christos size_t len = strlen (LOCAL_LABEL_PREFIX);
2494 1.10 christos
2495 1.1 christos if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0)
2496 1.1 christos return false;
2497 1.1 christos
2498 1.1 christos /* Perform the checks below for the rest of the name. */
2499 1.1 christos name += len;
2500 1.1 christos }
2501 1.1 christos #endif
2502 1.1 christos
2503 1.1 christos return name[0] == 'L';
2504 1.1 christos }
2505 1.1 christos
2506 1.1 christos /* This piece of machinery exists only to guarantee that the bfd that holds
2507 1.1 christos the glue section is written last.
2508 1.1 christos
2509 1.1 christos This does depend on bfd_make_section attaching a new section to the
2510 1.10 christos end of the section list for the bfd. */
2511 1.1 christos
2512 1.1 christos static bool
2513 1.1 christos coff_arm_link_output_has_begun (bfd * sub, struct coff_final_link_info * info)
2514 1.1 christos {
2515 1.1 christos return (sub->output_has_begun
2516 1.1 christos || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner);
2517 1.10 christos }
2518 1.1 christos
2519 1.1 christos static bool
2520 1.1 christos coff_arm_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED,
2521 1.1 christos struct coff_final_link_info * pfinfo)
2522 1.1 christos {
2523 1.1 christos struct coff_arm_link_hash_table * globals;
2524 1.1 christos
2525 1.1 christos globals = coff_arm_hash_table (pfinfo->info);
2526 1.1 christos
2527 1.1 christos BFD_ASSERT (globals != NULL);
2528 1.1 christos
2529 1.1 christos if (globals->bfd_of_glue_owner != NULL)
2530 1.10 christos {
2531 1.1 christos if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner))
2532 1.10 christos return false;
2533 1.1 christos
2534 1.1 christos globals->bfd_of_glue_owner->output_has_begun = true;
2535 1.1 christos }
2536 1.1 christos
2537 1.1 christos return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
2538 1.1 christos }
2539 1.1 christos
2540 1.1 christos #ifndef bfd_pe_print_pdata
2541 1.1 christos #define bfd_pe_print_pdata NULL
2542 1.1 christos #endif
2543 1.1 christos
2544 1.1 christos #include "coffcode.h"
2545 1.3 christos
2546 1.1 christos #ifndef TARGET_LITTLE_SYM
2547 1.1 christos #define TARGET_LITTLE_SYM arm_coff_le_vec
2548 1.1 christos #endif
2549 1.1 christos #ifndef TARGET_LITTLE_NAME
2550 1.1 christos #define TARGET_LITTLE_NAME "coff-arm-little"
2551 1.3 christos #endif
2552 1.1 christos #ifndef TARGET_BIG_SYM
2553 1.1 christos #define TARGET_BIG_SYM arm_coff_be_vec
2554 1.1 christos #endif
2555 1.1 christos #ifndef TARGET_BIG_NAME
2556 1.1 christos #define TARGET_BIG_NAME "coff-arm-big"
2557 1.1 christos #endif
2558 1.1 christos
2559 1.1 christos #ifndef TARGET_UNDERSCORE
2560 1.1 christos #define TARGET_UNDERSCORE 0
2561 1.1 christos #endif
2562 1.1 christos
2563 1.1 christos #ifndef EXTRA_S_FLAGS
2564 1.1 christos #ifdef COFF_WITH_PE
2565 1.1 christos #define EXTRA_S_FLAGS (SEC_CODE | SEC_LINK_ONCE | SEC_LINK_DUPLICATES)
2566 1.1 christos #else
2567 1.1 christos #define EXTRA_S_FLAGS SEC_CODE
2568 1.1 christos #endif
2569 1.1 christos #endif
2570 1.1 christos
2571 1.1 christos /* Forward declaration for use initialising alternative_target field. */
2572 1.1 christos extern const bfd_target TARGET_BIG_SYM ;
2573 1.1 christos
2574 1.1 christos /* Target vectors. */
2575 CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_BIG_SYM, COFF_SWAP_TABLE)
2576 CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_LITTLE_SYM, COFF_SWAP_TABLE)
2577