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