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