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