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
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 (symbol->section == &bfd_und_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 (symbol->section == &bfd_und_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_malloc (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 ret->thumb_glue_size = 0;
935 1.1 christos ret->arm_glue_size = 0;
936 1.1 christos ret->bfd_of_glue_owner = NULL;
937 1.1 christos
938 1.1 christos return & ret->root.root;
939 1.1 christos }
940 1.1 christos
941 1.1 christos static bfd_boolean
942 1.1 christos arm_emit_base_file_entry (struct bfd_link_info *info,
943 1.1 christos bfd *output_bfd,
944 1.1 christos asection *input_section,
945 1.1 christos bfd_vma reloc_offset)
946 1.1 christos {
947 1.1 christos bfd_vma addr = (reloc_offset
948 1.1 christos - input_section->vma
949 1.1 christos + input_section->output_offset
950 1.1 christos + input_section->output_section->vma);
951 1.1 christos
952 1.1 christos if (coff_data (output_bfd)->pe)
953 1.1 christos addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
954 1.1 christos if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
955 1.1 christos return TRUE;
956 1.1 christos
957 1.1 christos bfd_set_error (bfd_error_system_call);
958 1.1 christos return FALSE;
959 1.1 christos }
960 1.1 christos
961 1.1 christos #ifndef ARM_WINCE
963 1.1 christos /* The thumb form of a long branch is a bit finicky, because the offset
964 1.1 christos encoding is split over two fields, each in it's own instruction. They
965 1.1 christos can occur in any order. So given a thumb form of long branch, and an
966 1.1 christos offset, insert the offset into the thumb branch and return finished
967 1.1 christos instruction.
968 1.1 christos
969 1.1 christos It takes two thumb instructions to encode the target address. Each has
970 1.1 christos 11 bits to invest. The upper 11 bits are stored in one (identified by
971 1.1 christos H-0.. see below), the lower 11 bits are stored in the other (identified
972 1.1 christos by H-1).
973 1.1 christos
974 1.1 christos Combine together and shifted left by 1 (it's a half word address) and
975 1.1 christos there you have it.
976 1.1 christos
977 1.1 christos Op: 1111 = F,
978 1.1 christos H-0, upper address-0 = 000
979 1.1 christos Op: 1111 = F,
980 1.1 christos H-1, lower address-0 = 800
981 1.1 christos
982 1.1 christos They can be ordered either way, but the arm tools I've seen always put
983 1.1 christos the lower one first. It probably doesn't matter. krk (at) cygnus.com
984 1.1 christos
985 1.1 christos XXX: Actually the order does matter. The second instruction (H-1)
986 1.1 christos moves the computed address into the PC, so it must be the second one
987 1.1 christos in the sequence. The problem, however is that whilst little endian code
988 1.1 christos stores the instructions in HI then LOW order, big endian code does the
989 1.1 christos reverse. nickc (at) cygnus.com. */
990 1.1 christos
991 1.1 christos #define LOW_HI_ORDER 0xF800F000
992 1.1 christos #define HI_LOW_ORDER 0xF000F800
993 1.1 christos
994 1.1 christos static insn32
995 1.1 christos insert_thumb_branch (insn32 br_insn, int rel_off)
996 1.1 christos {
997 1.1 christos unsigned int low_bits;
998 1.1 christos unsigned int high_bits;
999 1.1 christos
1000 1.1 christos BFD_ASSERT ((rel_off & 1) != 1);
1001 1.1 christos
1002 1.1 christos rel_off >>= 1; /* Half word aligned address. */
1003 1.1 christos low_bits = rel_off & 0x000007FF; /* The bottom 11 bits. */
1004 1.1 christos high_bits = (rel_off >> 11) & 0x000007FF; /* The top 11 bits. */
1005 1.1 christos
1006 1.1 christos if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
1007 1.1 christos br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
1008 1.1 christos else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
1009 1.1 christos br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
1010 1.1 christos else
1011 1.1 christos /* FIXME: the BFD library should never abort except for internal errors
1012 1.1 christos - it should return an error status. */
1013 1.1 christos abort (); /* Error - not a valid branch instruction form. */
1014 1.1 christos
1015 1.1 christos return br_insn;
1016 1.1 christos }
1017 1.1 christos
1018 1.1 christos
1019 1.1 christos static struct coff_link_hash_entry *
1021 1.1 christos find_thumb_glue (struct bfd_link_info *info,
1022 1.1 christos const char *name,
1023 1.1 christos bfd *input_bfd)
1024 1.1 christos {
1025 1.1 christos char *tmp_name;
1026 1.1 christos struct coff_link_hash_entry *myh;
1027 1.1 christos bfd_size_type amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1028 1.1 christos
1029 1.1 christos tmp_name = bfd_malloc (amt);
1030 1.1 christos
1031 1.1 christos BFD_ASSERT (tmp_name);
1032 1.1 christos
1033 1.1 christos sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1034 1.1 christos
1035 1.1 christos myh = coff_link_hash_lookup
1036 1.1 christos (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE);
1037 1.1 christos
1038 1.1 christos if (myh == NULL)
1039 1.1 christos /* xgettext:c-format */
1040 1.1 christos _bfd_error_handler (_("%B: unable to find THUMB glue '%s' for `%s'"),
1041 1.1 christos input_bfd, tmp_name, name);
1042 1.1 christos
1043 1.1 christos free (tmp_name);
1044 1.1 christos
1045 1.1 christos return myh;
1046 1.1 christos }
1047 1.1 christos #endif /* not ARM_WINCE */
1048 1.1 christos
1049 1.1 christos static struct coff_link_hash_entry *
1050 1.1 christos find_arm_glue (struct bfd_link_info *info,
1051 1.1 christos const char *name,
1052 1.1 christos bfd *input_bfd)
1053 1.1 christos {
1054 1.1 christos char *tmp_name;
1055 1.1 christos struct coff_link_hash_entry * myh;
1056 1.1 christos bfd_size_type amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1057 1.1 christos
1058 1.1 christos tmp_name = bfd_malloc (amt);
1059 1.1 christos
1060 1.1 christos BFD_ASSERT (tmp_name);
1061 1.1 christos
1062 1.1 christos sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1063 1.1 christos
1064 1.1 christos myh = coff_link_hash_lookup
1065 1.1 christos (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE);
1066 1.1 christos
1067 1.1 christos if (myh == NULL)
1068 1.1 christos /* xgettext:c-format */
1069 1.1 christos _bfd_error_handler (_("%B: unable to find ARM glue '%s' for `%s'"),
1070 1.1 christos input_bfd, tmp_name, name);
1071 1.1 christos
1072 1.1 christos free (tmp_name);
1073 1.1 christos
1074 1.1 christos return myh;
1075 1.1 christos }
1076 1.1 christos
1077 1.1 christos /*
1078 1.1 christos ARM->Thumb glue:
1079 1.1 christos
1080 1.1 christos .arm
1081 1.1 christos __func_from_arm:
1082 1.1 christos ldr r12, __func_addr
1083 1.1 christos bx r12
1084 1.1 christos __func_addr:
1085 1.1 christos .word func @ behave as if you saw a ARM_32 reloc
1086 1.1 christos */
1087 1.1 christos
1088 1.1 christos #define ARM2THUMB_GLUE_SIZE 12
1089 1.1 christos static const insn32 a2t1_ldr_insn = 0xe59fc000;
1090 1.1 christos static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
1091 1.1 christos static const insn32 a2t3_func_addr_insn = 0x00000001;
1092 1.1 christos
1093 1.1 christos /*
1094 1.1 christos Thumb->ARM: Thumb->(non-interworking aware) ARM
1095 1.1 christos
1096 1.1 christos .thumb .thumb
1097 1.1 christos .align 2 .align 2
1098 1.1 christos __func_from_thumb: __func_from_thumb:
1099 1.1 christos bx pc push {r6, lr}
1100 1.1 christos nop ldr r6, __func_addr
1101 1.1 christos .arm mov lr, pc
1102 1.1 christos __func_change_to_arm: bx r6
1103 1.1 christos b func .arm
1104 1.1 christos __func_back_to_thumb:
1105 1.1 christos ldmia r13! {r6, lr}
1106 1.1 christos bx lr
1107 1.1 christos __func_addr:
1108 1.1 christos .word func
1109 1.1 christos */
1110 1.1 christos
1111 1.1 christos #define THUMB2ARM_GLUE_SIZE (globals->support_old_code ? 20 : 8)
1112 1.1 christos #ifndef ARM_WINCE
1113 1.1 christos static const insn16 t2a1_bx_pc_insn = 0x4778;
1114 1.1 christos static const insn16 t2a2_noop_insn = 0x46c0;
1115 1.1 christos static const insn32 t2a3_b_insn = 0xea000000;
1116 1.1 christos
1117 1.1 christos static const insn16 t2a1_push_insn = 0xb540;
1118 1.1 christos static const insn16 t2a2_ldr_insn = 0x4e03;
1119 1.1 christos static const insn16 t2a3_mov_insn = 0x46fe;
1120 1.1 christos static const insn16 t2a4_bx_insn = 0x4730;
1121 1.1 christos static const insn32 t2a5_pop_insn = 0xe8bd4040;
1122 1.1 christos static const insn32 t2a6_bx_insn = 0xe12fff1e;
1123 1.1 christos #endif
1124 1.1 christos
1125 1.1 christos /* TODO:
1126 1.1 christos We should really create new local (static) symbols in destination
1127 1.1 christos object for each stub we create. We should also create local
1128 1.1 christos (static) symbols within the stubs when switching between ARM and
1129 1.1 christos Thumb code. This will ensure that the debugger and disassembler
1130 1.1 christos can present a better view of stubs.
1131 1.1 christos
1132 1.1 christos We can treat stubs like literal sections, and for the THUMB9 ones
1133 1.1 christos (short addressing range) we should be able to insert the stubs
1134 1.1 christos between sections. i.e. the simplest approach (since relocations
1135 1.1 christos are done on a section basis) is to dump the stubs at the end of
1136 1.1 christos processing a section. That way we can always try and minimise the
1137 1.1 christos offset to and from a stub. However, this does not map well onto
1138 1.1 christos the way that the linker/BFD does its work: mapping all input
1139 1.1 christos sections to output sections via the linker script before doing
1140 1.1 christos all the processing.
1141 1.1 christos
1142 1.1 christos Unfortunately it may be easier to just to disallow short range
1143 1.1 christos Thumb->ARM stubs (i.e. no conditional inter-working branches,
1144 1.1 christos only branch-and-link (BL) calls. This will simplify the processing
1145 1.1 christos since we can then put all of the stubs into their own section.
1146 1.1 christos
1147 1.1 christos TODO:
1148 1.1 christos On a different subject, rather than complaining when a
1149 1.1 christos branch cannot fit in the number of bits available for the
1150 1.1 christos instruction we should generate a trampoline stub (needed to
1151 1.1 christos address the complete 32bit address space). */
1152 1.1 christos
1153 1.1 christos /* The standard COFF backend linker does not cope with the special
1154 1.1 christos Thumb BRANCH23 relocation. The alternative would be to split the
1155 1.1 christos BRANCH23 into seperate HI23 and LO23 relocations. However, it is a
1156 1.1 christos bit simpler simply providing our own relocation driver. */
1157 1.1 christos
1158 1.1 christos /* The reloc processing routine for the ARM/Thumb COFF linker. NOTE:
1159 1.1 christos This code is a very slightly modified copy of
1160 1.1 christos _bfd_coff_generic_relocate_section. It would be a much more
1161 1.1 christos maintainable solution to have a MACRO that could be expanded within
1162 1.1 christos _bfd_coff_generic_relocate_section that would only be provided for
1163 1.1 christos ARM/Thumb builds. It is only the code marked THUMBEXTENSION that
1164 1.1 christos is different from the original. */
1165 1.1 christos
1166 1.1 christos static bfd_boolean
1167 1.1 christos coff_arm_relocate_section (bfd *output_bfd,
1168 1.1 christos struct bfd_link_info *info,
1169 1.1 christos bfd *input_bfd,
1170 1.1 christos asection *input_section,
1171 1.1 christos bfd_byte *contents,
1172 1.1 christos struct internal_reloc *relocs,
1173 1.1 christos struct internal_syment *syms,
1174 1.1 christos asection **sections)
1175 1.1 christos {
1176 1.1 christos struct internal_reloc * rel;
1177 1.1 christos struct internal_reloc * relend;
1178 1.1 christos #ifndef ARM_WINCE
1179 1.1 christos bfd_vma high_address = bfd_get_section_limit (input_bfd, input_section);
1180 1.1 christos #endif
1181 1.1 christos
1182 1.1 christos rel = relocs;
1183 1.1 christos relend = rel + input_section->reloc_count;
1184 1.1 christos
1185 1.1 christos for (; rel < relend; rel++)
1186 1.1 christos {
1187 1.1 christos int done = 0;
1188 1.1 christos long symndx;
1189 1.1 christos struct coff_link_hash_entry * h;
1190 1.1 christos struct internal_syment * sym;
1191 1.1 christos bfd_vma addend;
1192 1.1 christos bfd_vma val;
1193 1.1 christos reloc_howto_type * howto;
1194 1.1 christos bfd_reloc_status_type rstat;
1195 1.1 christos bfd_vma h_val;
1196 1.1 christos
1197 1.1 christos symndx = rel->r_symndx;
1198 1.1 christos
1199 1.1 christos if (symndx == -1)
1200 1.1 christos {
1201 1.1 christos h = NULL;
1202 1.1 christos sym = NULL;
1203 1.1 christos }
1204 1.1 christos else
1205 1.1 christos {
1206 1.1 christos h = obj_coff_sym_hashes (input_bfd)[symndx];
1207 1.1 christos sym = syms + symndx;
1208 1.1 christos }
1209 1.1 christos
1210 1.1 christos /* COFF treats common symbols in one of two ways. Either the
1211 1.1 christos size of the symbol is included in the section contents, or it
1212 1.1 christos is not. We assume that the size is not included, and force
1213 1.1 christos the rtype_to_howto function to adjust the addend as needed. */
1214 1.1 christos
1215 1.1 christos if (sym != NULL && sym->n_scnum != 0)
1216 1.1 christos addend = - sym->n_value;
1217 1.1 christos else
1218 1.1 christos addend = 0;
1219 1.1 christos
1220 1.1 christos howto = coff_rtype_to_howto (input_bfd, input_section, rel, h,
1221 1.1 christos sym, &addend);
1222 1.1 christos if (howto == NULL)
1223 1.1 christos return FALSE;
1224 1.1 christos
1225 1.1 christos /* The relocation_section function will skip pcrel_offset relocs
1226 1.1 christos when doing a relocatable link. However, we want to convert
1227 1.1 christos ARM_26 to ARM_26D relocs if possible. We return a fake howto in
1228 1.1 christos this case without pcrel_offset set, and adjust the addend to
1229 1.1 christos compensate. 'partial_inplace' is also set, since we want 'done'
1230 1.1 christos relocations to be reflected in section's data. */
1231 1.1 christos if (rel->r_type == ARM_26
1232 1.1 christos && h != NULL
1233 1.1 christos && info->relocatable
1234 1.1 christos && (h->root.type == bfd_link_hash_defined
1235 1.1 christos || h->root.type == bfd_link_hash_defweak)
1236 1.1 christos && (h->root.u.def.section->output_section
1237 1.1 christos == input_section->output_section))
1238 1.1 christos {
1239 1.1 christos static reloc_howto_type fake_arm26_reloc =
1240 1.1 christos HOWTO (ARM_26,
1241 1.1 christos 2,
1242 1.1 christos 2,
1243 1.1 christos 24,
1244 1.1 christos TRUE,
1245 1.1 christos 0,
1246 1.1 christos complain_overflow_signed,
1247 1.1 christos aoutarm_fix_pcrel_26 ,
1248 1.1 christos "ARM_26",
1249 1.1 christos TRUE,
1250 1.1 christos 0x00ffffff,
1251 1.1 christos 0x00ffffff,
1252 1.1 christos FALSE);
1253 1.1 christos
1254 1.1 christos addend -= rel->r_vaddr - input_section->vma;
1255 1.1 christos #ifdef ARM_WINCE
1256 1.1 christos /* FIXME: I don't know why, but the hack is necessary for correct
1257 1.1 christos generation of bl's instruction offset. */
1258 1.1 christos addend -= 8;
1259 1.1 christos #endif
1260 1.1 christos howto = & fake_arm26_reloc;
1261 1.1 christos }
1262 1.1 christos
1263 1.1 christos #ifdef ARM_WINCE
1264 1.1 christos /* MS ARM-CE makes the reloc relative to the opcode's pc, not
1265 1.1 christos the next opcode's pc, so is off by one. */
1266 1.1 christos if (howto->pc_relative && !info->relocatable)
1267 1.1 christos addend -= 8;
1268 1.1 christos #endif
1269 1.1 christos
1270 1.1 christos /* If we are doing a relocatable link, then we can just ignore
1271 1.1 christos a PC relative reloc that is pcrel_offset. It will already
1272 1.1 christos have the correct value. If this is not a relocatable link,
1273 1.1 christos then we should ignore the symbol value. */
1274 1.1 christos if (howto->pc_relative && howto->pcrel_offset)
1275 1.1 christos {
1276 1.1 christos if (info->relocatable)
1277 1.1 christos continue;
1278 1.1 christos /* FIXME - it is not clear which targets need this next test
1279 1.1 christos and which do not. It is known that it is needed for the
1280 1.1 christos VxWorks and EPOC-PE targets, but it is also known that it
1281 1.1 christos was suppressed for other ARM targets. This ought to be
1282 1.1 christos sorted out one day. */
1283 1.1 christos #ifdef ARM_COFF_BUGFIX
1284 1.1 christos /* We must not ignore the symbol value. If the symbol is
1285 1.1 christos within the same section, the relocation should have already
1286 1.1 christos been fixed, but if it is not, we'll be handed a reloc into
1287 1.1 christos the beginning of the symbol's section, so we must not cancel
1288 1.1 christos out the symbol's value, otherwise we'll be adding it in
1289 1.1 christos twice. */
1290 1.1 christos if (sym != NULL && sym->n_scnum != 0)
1291 1.1 christos addend += sym->n_value;
1292 1.1 christos #endif
1293 1.1 christos }
1294 1.1 christos
1295 1.1 christos val = 0;
1296 1.1 christos
1297 1.1 christos if (h == NULL)
1298 1.1 christos {
1299 1.1 christos asection *sec;
1300 1.1 christos
1301 1.1 christos if (symndx == -1)
1302 1.1 christos {
1303 1.1 christos sec = bfd_abs_section_ptr;
1304 1.1 christos val = 0;
1305 1.1 christos }
1306 1.1 christos else
1307 1.1 christos {
1308 1.1 christos sec = sections[symndx];
1309 1.1 christos val = (sec->output_section->vma
1310 1.1 christos + sec->output_offset
1311 1.1 christos + sym->n_value
1312 1.1 christos - sec->vma);
1313 1.1 christos }
1314 1.1 christos }
1315 1.1 christos else
1316 1.1 christos {
1317 1.1 christos /* We don't output the stubs if we are generating a
1318 1.1 christos relocatable output file, since we may as well leave the
1319 1.1 christos stub generation to the final linker pass. If we fail to
1320 1.1 christos verify that the name is defined, we'll try to build stubs
1321 1.1 christos for an undefined name... */
1322 1.1 christos if (! info->relocatable
1323 1.1 christos && ( h->root.type == bfd_link_hash_defined
1324 1.1 christos || h->root.type == bfd_link_hash_defweak))
1325 1.1 christos {
1326 1.1 christos asection * h_sec = h->root.u.def.section;
1327 1.1 christos const char * name = h->root.root.string;
1328 1.1 christos
1329 1.1 christos /* h locates the symbol referenced in the reloc. */
1330 1.1 christos h_val = (h->root.u.def.value
1331 1.1 christos + h_sec->output_section->vma
1332 1.1 christos + h_sec->output_offset);
1333 1.1 christos
1334 1.1 christos if (howto->type == ARM_26)
1335 1.1 christos {
1336 1.1 christos if ( h->symbol_class == C_THUMBSTATFUNC
1337 1.1 christos || h->symbol_class == C_THUMBEXTFUNC)
1338 1.1 christos {
1339 1.1 christos /* Arm code calling a Thumb function. */
1340 1.1 christos unsigned long int tmp;
1341 1.1 christos bfd_vma my_offset;
1342 1.1 christos asection * s;
1343 1.1 christos long int ret_offset;
1344 1.1 christos struct coff_link_hash_entry * myh;
1345 1.1 christos struct coff_arm_link_hash_table * globals;
1346 1.1 christos
1347 1.1 christos myh = find_arm_glue (info, name, input_bfd);
1348 1.1 christos if (myh == NULL)
1349 1.1 christos return FALSE;
1350 1.1 christos
1351 1.1 christos globals = coff_arm_hash_table (info);
1352 1.1 christos
1353 1.1 christos BFD_ASSERT (globals != NULL);
1354 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1355 1.1 christos
1356 1.1 christos my_offset = myh->root.u.def.value;
1357 1.1 christos
1358 1.1 christos s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1359 1.1 christos ARM2THUMB_GLUE_SECTION_NAME);
1360 1.1 christos BFD_ASSERT (s != NULL);
1361 1.1 christos BFD_ASSERT (s->contents != NULL);
1362 1.1 christos BFD_ASSERT (s->output_section != NULL);
1363 1.1 christos
1364 1.1 christos if ((my_offset & 0x01) == 0x01)
1365 1.1 christos {
1366 1.1 christos if (h_sec->owner != NULL
1367 1.1 christos && INTERWORK_SET (h_sec->owner)
1368 1.1 christos && ! INTERWORK_FLAG (h_sec->owner))
1369 1.1 christos _bfd_error_handler
1370 1.1 christos /* xgettext:c-format */
1371 1.1 christos (_("%B(%s): warning: interworking not enabled.\n"
1372 1.1 christos " first occurrence: %B: arm call to thumb"),
1373 1.1 christos h_sec->owner, input_bfd, name);
1374 1.1 christos
1375 1.1 christos --my_offset;
1376 1.1 christos myh->root.u.def.value = my_offset;
1377 1.1 christos
1378 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn,
1379 1.1 christos s->contents + my_offset);
1380 1.1 christos
1381 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) a2t2_bx_r12_insn,
1382 1.1 christos s->contents + my_offset + 4);
1383 1.1 christos
1384 1.1 christos /* It's a thumb address. Add the low order bit. */
1385 1.1 christos bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
1386 1.1 christos s->contents + my_offset + 8);
1387 1.1 christos
1388 1.1 christos if (info->base_file
1389 1.1 christos && !arm_emit_base_file_entry (info, output_bfd,
1390 1.1 christos s, my_offset + 8))
1391 1.1 christos return FALSE;
1392 1.1 christos }
1393 1.1 christos
1394 1.1 christos BFD_ASSERT (my_offset <= globals->arm_glue_size);
1395 1.1 christos
1396 1.1 christos tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1397 1.1 christos - input_section->vma);
1398 1.1 christos
1399 1.1 christos tmp = tmp & 0xFF000000;
1400 1.1 christos
1401 1.1 christos /* Somehow these are both 4 too far, so subtract 8. */
1402 1.1 christos ret_offset =
1403 1.1 christos s->output_offset
1404 1.1 christos + my_offset
1405 1.1 christos + s->output_section->vma
1406 1.1 christos - (input_section->output_offset
1407 1.1 christos + input_section->output_section->vma
1408 1.1 christos + rel->r_vaddr)
1409 1.1 christos - 8;
1410 1.1 christos
1411 1.1 christos tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1412 1.1 christos
1413 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) tmp,
1414 1.1 christos contents + rel->r_vaddr - input_section->vma);
1415 1.1 christos done = 1;
1416 1.1 christos }
1417 1.1 christos }
1418 1.1 christos
1419 1.1 christos #ifndef ARM_WINCE
1420 1.1 christos /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */
1421 1.1 christos else if (howto->type == ARM_THUMB23)
1422 1.1 christos {
1423 1.1 christos if ( h->symbol_class == C_EXT
1424 1.1 christos || h->symbol_class == C_STAT
1425 1.1 christos || h->symbol_class == C_LABEL)
1426 1.1 christos {
1427 1.1 christos /* Thumb code calling an ARM function. */
1428 1.1 christos asection * s = 0;
1429 1.1 christos bfd_vma my_offset;
1430 1.1 christos unsigned long int tmp;
1431 1.1 christos long int ret_offset;
1432 1.1 christos struct coff_link_hash_entry * myh;
1433 1.1 christos struct coff_arm_link_hash_table * globals;
1434 1.1 christos
1435 1.1 christos myh = find_thumb_glue (info, name, input_bfd);
1436 1.1 christos if (myh == NULL)
1437 1.1 christos return FALSE;
1438 1.1 christos
1439 1.1 christos globals = coff_arm_hash_table (info);
1440 1.1 christos
1441 1.1 christos BFD_ASSERT (globals != NULL);
1442 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1443 1.1 christos
1444 1.1 christos my_offset = myh->root.u.def.value;
1445 1.1 christos
1446 1.1 christos s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1447 1.1 christos THUMB2ARM_GLUE_SECTION_NAME);
1448 1.1 christos
1449 1.1 christos BFD_ASSERT (s != NULL);
1450 1.1 christos BFD_ASSERT (s->contents != NULL);
1451 1.1 christos BFD_ASSERT (s->output_section != NULL);
1452 1.1 christos
1453 1.1 christos if ((my_offset & 0x01) == 0x01)
1454 1.1 christos {
1455 1.1 christos if (h_sec->owner != NULL
1456 1.1 christos && INTERWORK_SET (h_sec->owner)
1457 1.1 christos && ! INTERWORK_FLAG (h_sec->owner)
1458 1.1 christos && ! globals->support_old_code)
1459 1.1 christos _bfd_error_handler
1460 1.1 christos /* xgettext:c-format */
1461 1.1 christos (_("%B(%s): warning: interworking not enabled.\n"
1462 1.1 christos " first occurrence: %B: thumb call to arm\n"
1463 1.1 christos " consider relinking with --support-old-code enabled"),
1464 1.1 christos h_sec->owner, input_bfd, name);
1465 1.1 christos
1466 1.1 christos -- my_offset;
1467 1.1 christos myh->root.u.def.value = my_offset;
1468 1.1 christos
1469 1.1 christos if (globals->support_old_code)
1470 1.1 christos {
1471 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a1_push_insn,
1472 1.1 christos s->contents + my_offset);
1473 1.1 christos
1474 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a2_ldr_insn,
1475 1.1 christos s->contents + my_offset + 2);
1476 1.1 christos
1477 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a3_mov_insn,
1478 1.1 christos s->contents + my_offset + 4);
1479 1.1 christos
1480 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a4_bx_insn,
1481 1.1 christos s->contents + my_offset + 6);
1482 1.1 christos
1483 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) t2a5_pop_insn,
1484 1.1 christos s->contents + my_offset + 8);
1485 1.1 christos
1486 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) t2a6_bx_insn,
1487 1.1 christos s->contents + my_offset + 12);
1488 1.1 christos
1489 1.1 christos /* Store the address of the function in the last word of the stub. */
1490 1.1 christos bfd_put_32 (output_bfd, h_val,
1491 1.1 christos s->contents + my_offset + 16);
1492 1.1 christos
1493 1.1 christos if (info->base_file
1494 1.1 christos && !arm_emit_base_file_entry (info,
1495 1.1 christos output_bfd, s,
1496 1.1 christos my_offset + 16))
1497 1.1 christos return FALSE;
1498 1.1 christos }
1499 1.1 christos else
1500 1.1 christos {
1501 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn,
1502 1.1 christos s->contents + my_offset);
1503 1.1 christos
1504 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn,
1505 1.1 christos s->contents + my_offset + 2);
1506 1.1 christos
1507 1.1 christos ret_offset =
1508 1.1 christos /* Address of destination of the stub. */
1509 1.1 christos ((bfd_signed_vma) h_val)
1510 1.1 christos - ((bfd_signed_vma)
1511 1.1 christos /* Offset from the start of the current section to the start of the stubs. */
1512 1.1 christos (s->output_offset
1513 1.1 christos /* Offset of the start of this stub from the start of the stubs. */
1514 1.1 christos + my_offset
1515 1.1 christos /* Address of the start of the current section. */
1516 1.1 christos + s->output_section->vma)
1517 1.1 christos /* The branch instruction is 4 bytes into the stub. */
1518 1.1 christos + 4
1519 1.1 christos /* ARM branches work from the pc of the instruction + 8. */
1520 1.1 christos + 8);
1521 1.1 christos
1522 1.1 christos bfd_put_32 (output_bfd,
1523 1.1 christos (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1524 1.1 christos s->contents + my_offset + 4);
1525 1.1 christos
1526 1.1 christos }
1527 1.1 christos }
1528 1.1 christos
1529 1.1 christos BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1530 1.1 christos
1531 1.1 christos /* Now go back and fix up the original BL insn to point
1532 1.1 christos to here. */
1533 1.1 christos ret_offset =
1534 1.1 christos s->output_offset
1535 1.1 christos + my_offset
1536 1.1 christos - (input_section->output_offset
1537 1.1 christos + rel->r_vaddr)
1538 1.1 christos -4;
1539 1.1 christos
1540 1.1 christos tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1541 1.1 christos - input_section->vma);
1542 1.1 christos
1543 1.1 christos bfd_put_32 (output_bfd,
1544 1.1 christos (bfd_vma) insert_thumb_branch (tmp,
1545 1.1 christos ret_offset),
1546 1.1 christos contents + rel->r_vaddr - input_section->vma);
1547 1.1 christos
1548 1.1 christos done = 1;
1549 1.1 christos }
1550 1.1 christos }
1551 1.1 christos #endif
1552 1.1 christos }
1553 1.1 christos
1554 1.1 christos /* If the relocation type and destination symbol does not
1555 1.1 christos fall into one of the above categories, then we can just
1556 1.1 christos perform a direct link. */
1557 1.1 christos
1558 1.1 christos if (done)
1559 1.1 christos rstat = bfd_reloc_ok;
1560 1.1 christos else
1561 1.1 christos if ( h->root.type == bfd_link_hash_defined
1562 1.1 christos || h->root.type == bfd_link_hash_defweak)
1563 1.1 christos {
1564 1.1 christos asection *sec;
1565 1.1 christos
1566 1.1 christos sec = h->root.u.def.section;
1567 1.1 christos val = (h->root.u.def.value
1568 1.1 christos + sec->output_section->vma
1569 1.1 christos + sec->output_offset);
1570 1.1 christos }
1571 1.1 christos
1572 1.1 christos else if (! info->relocatable)
1573 1.1 christos {
1574 1.1 christos if (! ((*info->callbacks->undefined_symbol)
1575 1.1 christos (info, h->root.root.string, input_bfd, input_section,
1576 1.1 christos rel->r_vaddr - input_section->vma, TRUE)))
1577 1.1 christos return FALSE;
1578 1.1 christos }
1579 1.1 christos }
1580 1.1 christos
1581 1.1 christos /* Emit a reloc if the backend thinks it needs it. */
1582 1.1 christos if (info->base_file
1583 1.1 christos && sym
1584 1.1 christos && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)
1585 1.1 christos && !arm_emit_base_file_entry (info, output_bfd, input_section,
1586 1.1 christos rel->r_vaddr))
1587 1.1 christos return FALSE;
1588 1.1 christos
1589 1.1 christos if (done)
1590 1.1 christos rstat = bfd_reloc_ok;
1591 1.1 christos #ifndef ARM_WINCE
1592 1.1 christos /* Only perform this fix during the final link, not a relocatable link. */
1593 1.1 christos else if (! info->relocatable
1594 1.1 christos && howto->type == ARM_THUMB23)
1595 1.1 christos {
1596 1.1 christos /* This is pretty much a copy of what the default
1597 1.1 christos _bfd_final_link_relocate and _bfd_relocate_contents
1598 1.1 christos routines do to perform a relocation, with special
1599 1.1 christos processing for the split addressing of the Thumb BL
1600 1.1 christos instruction. Again, it would probably be simpler adding a
1601 1.1 christos ThumbBRANCH23 specific macro expansion into the default
1602 1.1 christos code. */
1603 1.1 christos
1604 1.1 christos bfd_vma address = rel->r_vaddr - input_section->vma;
1605 1.1 christos
1606 1.1 christos if (address > high_address)
1607 1.1 christos rstat = bfd_reloc_outofrange;
1608 1.1 christos else
1609 1.1 christos {
1610 1.1 christos bfd_vma relocation = val + addend;
1611 1.1 christos int size = bfd_get_reloc_size (howto);
1612 1.1 christos bfd_boolean overflow = FALSE;
1613 1.1 christos bfd_byte *location = contents + address;
1614 1.1 christos bfd_vma x = bfd_get_32 (input_bfd, location);
1615 1.1 christos bfd_vma src_mask = 0x007FFFFE;
1616 1.1 christos bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1617 1.1 christos bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1618 1.1 christos bfd_vma check;
1619 1.1 christos bfd_signed_vma signed_check;
1620 1.1 christos bfd_vma add;
1621 1.1 christos bfd_signed_vma signed_add;
1622 1.1 christos
1623 1.1 christos BFD_ASSERT (size == 4);
1624 1.1 christos
1625 1.1 christos /* howto->pc_relative should be TRUE for type 14 BRANCH23. */
1626 1.1 christos relocation -= (input_section->output_section->vma
1627 1.1 christos + input_section->output_offset);
1628 1.1 christos
1629 1.1 christos /* howto->pcrel_offset should be TRUE for type 14 BRANCH23. */
1630 1.1 christos relocation -= address;
1631 1.1 christos
1632 1.1 christos /* No need to negate the relocation with BRANCH23. */
1633 1.1 christos /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23. */
1634 1.1 christos /* howto->rightshift == 1 */
1635 1.1 christos
1636 1.1 christos /* Drop unwanted bits from the value we are relocating to. */
1637 1.1 christos check = relocation >> howto->rightshift;
1638 1.1 christos
1639 1.1 christos /* If this is a signed value, the rightshift just dropped
1640 1.1 christos leading 1 bits (assuming twos complement). */
1641 1.1 christos if ((bfd_signed_vma) relocation >= 0)
1642 1.1 christos signed_check = check;
1643 1.1 christos else
1644 1.1 christos signed_check = (check
1645 1.1 christos | ((bfd_vma) - 1
1646 1.1 christos & ~((bfd_vma) - 1 >> howto->rightshift)));
1647 1.1 christos
1648 1.1 christos /* Get the value from the object file. */
1649 1.1 christos if (bfd_big_endian (input_bfd))
1650 1.1 christos add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
1651 1.1 christos else
1652 1.1 christos add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
1653 1.1 christos
1654 1.1 christos /* Get the value from the object file with an appropriate sign.
1655 1.1 christos The expression involving howto->src_mask isolates the upper
1656 1.1 christos bit of src_mask. If that bit is set in the value we are
1657 1.1 christos adding, it is negative, and we subtract out that number times
1658 1.1 christos two. If src_mask includes the highest possible bit, then we
1659 1.1 christos can not get the upper bit, but that does not matter since
1660 1.1 christos signed_add needs no adjustment to become negative in that
1661 1.1 christos case. */
1662 1.1 christos signed_add = add;
1663 1.1 christos
1664 1.1 christos if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
1665 1.1 christos signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
1666 1.1 christos
1667 1.1 christos /* howto->bitpos == 0 */
1668 1.1 christos /* Add the value from the object file, shifted so that it is a
1669 1.1 christos straight number. */
1670 1.1 christos signed_check += signed_add;
1671 1.1 christos relocation += signed_add;
1672 1.1 christos
1673 1.1 christos BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
1674 1.1 christos
1675 1.1 christos /* Assumes two's complement. */
1676 1.1 christos if ( signed_check > reloc_signed_max
1677 1.1 christos || signed_check < reloc_signed_min)
1678 1.1 christos overflow = TRUE;
1679 1.1 christos
1680 1.1 christos /* Put the relocation into the correct bits.
1681 1.1 christos For a BLX instruction, make sure that the relocation is rounded up
1682 1.1 christos to a word boundary. This follows the semantics of the instruction
1683 1.1 christos which specifies that bit 1 of the target address will come from bit
1684 1.1 christos 1 of the base address. */
1685 1.1 christos if (bfd_big_endian (input_bfd))
1686 1.1 christos {
1687 1.1 christos if ((x & 0x1800) == 0x0800 && (relocation & 0x02))
1688 1.1 christos relocation += 2;
1689 1.1 christos relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
1690 1.1 christos }
1691 1.1 christos else
1692 1.1 christos {
1693 1.1 christos if ((x & 0x18000000) == 0x08000000 && (relocation & 0x02))
1694 1.1 christos relocation += 2;
1695 1.1 christos relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1696 1.1 christos }
1697 1.1 christos
1698 1.1 christos /* Add the relocation to the correct bits of X. */
1699 1.1 christos x = ((x & ~howto->dst_mask) | relocation);
1700 1.1 christos
1701 1.1 christos /* Put the relocated value back in the object file. */
1702 1.1 christos bfd_put_32 (input_bfd, x, location);
1703 1.1 christos
1704 1.1 christos rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
1705 1.1 christos }
1706 1.1 christos }
1707 1.1 christos #endif
1708 1.1 christos else
1709 1.1 christos if (info->relocatable && ! howto->partial_inplace)
1710 1.1 christos rstat = bfd_reloc_ok;
1711 1.1 christos else
1712 1.1 christos rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
1713 1.1 christos contents,
1714 1.1 christos rel->r_vaddr - input_section->vma,
1715 1.1 christos val, addend);
1716 1.1 christos /* Only perform this fix during the final link, not a relocatable link. */
1717 1.1 christos if (! info->relocatable
1718 1.1 christos && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
1719 1.1 christos {
1720 1.1 christos /* Determine if we need to set the bottom bit of a relocated address
1721 1.1 christos because the address is the address of a Thumb code symbol. */
1722 1.1 christos int patchit = FALSE;
1723 1.1 christos
1724 1.1 christos if (h != NULL
1725 1.1 christos && ( h->symbol_class == C_THUMBSTATFUNC
1726 1.1 christos || h->symbol_class == C_THUMBEXTFUNC))
1727 1.1 christos {
1728 1.1 christos patchit = TRUE;
1729 1.1 christos }
1730 1.1 christos else if (sym != NULL
1731 1.1 christos && sym->n_scnum > N_UNDEF)
1732 1.1 christos {
1733 1.1 christos /* No hash entry - use the symbol instead. */
1734 1.1 christos if ( sym->n_sclass == C_THUMBSTATFUNC
1735 1.1 christos || sym->n_sclass == C_THUMBEXTFUNC)
1736 1.1 christos patchit = TRUE;
1737 1.1 christos }
1738 1.1 christos
1739 1.1 christos if (patchit)
1740 1.1 christos {
1741 1.1 christos bfd_byte * location = contents + rel->r_vaddr - input_section->vma;
1742 1.1 christos bfd_vma x = bfd_get_32 (input_bfd, location);
1743 1.1 christos
1744 1.1 christos bfd_put_32 (input_bfd, x | 1, location);
1745 1.1 christos }
1746 1.1 christos }
1747 1.1 christos
1748 1.1 christos switch (rstat)
1749 1.1 christos {
1750 1.1 christos default:
1751 1.1 christos abort ();
1752 1.1 christos case bfd_reloc_ok:
1753 1.1 christos break;
1754 1.1 christos case bfd_reloc_outofrange:
1755 1.1 christos (*_bfd_error_handler)
1756 1.1 christos (_("%B: bad reloc address 0x%lx in section `%A'"),
1757 1.1 christos input_bfd, input_section, (unsigned long) rel->r_vaddr);
1758 1.1 christos return FALSE;
1759 1.1 christos case bfd_reloc_overflow:
1760 1.1 christos {
1761 1.1 christos const char *name;
1762 1.1 christos char buf[SYMNMLEN + 1];
1763 1.1 christos
1764 1.1 christos if (symndx == -1)
1765 1.1 christos name = "*ABS*";
1766 1.1 christos else if (h != NULL)
1767 1.1 christos name = NULL;
1768 1.1 christos else
1769 1.1 christos {
1770 1.1 christos name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1771 1.1 christos if (name == NULL)
1772 1.1 christos return FALSE;
1773 1.1 christos }
1774 1.1 christos
1775 1.1 christos if (! ((*info->callbacks->reloc_overflow)
1776 1.1 christos (info, (h ? &h->root : NULL), name, howto->name,
1777 1.1 christos (bfd_vma) 0, input_bfd, input_section,
1778 1.1 christos rel->r_vaddr - input_section->vma)))
1779 1.1 christos return FALSE;
1780 1.1 christos }
1781 1.1 christos }
1782 1.1 christos }
1783 1.1 christos
1784 1.1 christos return TRUE;
1785 1.1 christos }
1786 1.1 christos
1787 1.1 christos #ifndef COFF_IMAGE_WITH_PE
1788 1.1 christos
1789 1.1 christos bfd_boolean
1790 1.1 christos bfd_arm_allocate_interworking_sections (struct bfd_link_info * info)
1791 1.1 christos {
1792 1.1 christos asection * s;
1793 1.1 christos bfd_byte * foo;
1794 1.1 christos struct coff_arm_link_hash_table * globals;
1795 1.1 christos
1796 1.1 christos globals = coff_arm_hash_table (info);
1797 1.1 christos
1798 1.1 christos BFD_ASSERT (globals != NULL);
1799 1.1 christos
1800 1.1 christos if (globals->arm_glue_size != 0)
1801 1.1 christos {
1802 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1803 1.1 christos
1804 1.1 christos s = bfd_get_section_by_name
1805 1.1 christos (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1806 1.1 christos
1807 1.1 christos BFD_ASSERT (s != NULL);
1808 1.1 christos
1809 1.1 christos foo = bfd_alloc (globals->bfd_of_glue_owner, globals->arm_glue_size);
1810 1.1 christos
1811 1.1 christos s->size = globals->arm_glue_size;
1812 1.1 christos s->contents = foo;
1813 1.1 christos }
1814 1.1 christos
1815 1.1 christos if (globals->thumb_glue_size != 0)
1816 1.1 christos {
1817 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1818 1.1 christos
1819 1.1 christos s = bfd_get_section_by_name
1820 1.1 christos (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1821 1.1 christos
1822 1.1 christos BFD_ASSERT (s != NULL);
1823 1.1 christos
1824 1.1 christos foo = bfd_alloc (globals->bfd_of_glue_owner, globals->thumb_glue_size);
1825 1.1 christos
1826 1.1 christos s->size = globals->thumb_glue_size;
1827 1.1 christos s->contents = foo;
1828 1.1 christos }
1829 1.1 christos
1830 1.1 christos return TRUE;
1831 1.1 christos }
1832 1.1 christos
1833 1.1 christos static void
1834 1.1 christos record_arm_to_thumb_glue (struct bfd_link_info * info,
1835 1.1 christos struct coff_link_hash_entry * h)
1836 1.1 christos {
1837 1.1 christos const char * name = h->root.root.string;
1838 1.1 christos register asection * s;
1839 1.1 christos char * tmp_name;
1840 1.1 christos struct coff_link_hash_entry * myh;
1841 1.1 christos struct bfd_link_hash_entry * bh;
1842 1.1 christos struct coff_arm_link_hash_table * globals;
1843 1.1 christos bfd_vma val;
1844 1.1 christos bfd_size_type amt;
1845 1.1 christos
1846 1.1 christos globals = coff_arm_hash_table (info);
1847 1.1 christos
1848 1.1 christos BFD_ASSERT (globals != NULL);
1849 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1850 1.1 christos
1851 1.1 christos s = bfd_get_section_by_name
1852 1.1 christos (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1853 1.1 christos
1854 1.1 christos BFD_ASSERT (s != NULL);
1855 1.1 christos
1856 1.1 christos amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1857 1.1 christos tmp_name = bfd_malloc (amt);
1858 1.1 christos
1859 1.1 christos BFD_ASSERT (tmp_name);
1860 1.1 christos
1861 1.1 christos sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1862 1.1 christos
1863 1.1 christos myh = coff_link_hash_lookup
1864 1.1 christos (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE);
1865 1.1 christos
1866 1.1 christos if (myh != NULL)
1867 1.1 christos {
1868 1.1 christos free (tmp_name);
1869 1.1 christos /* We've already seen this guy. */
1870 1.1 christos return;
1871 1.1 christos }
1872 1.1 christos
1873 1.1 christos /* The only trick here is using globals->arm_glue_size as the value. Even
1874 1.1 christos though the section isn't allocated yet, this is where we will be putting
1875 1.1 christos it. */
1876 1.1 christos bh = NULL;
1877 1.1 christos val = globals->arm_glue_size + 1;
1878 1.1 christos bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1879 1.1 christos BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh);
1880 1.1 christos
1881 1.1 christos free (tmp_name);
1882 1.1 christos
1883 1.1 christos globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
1884 1.1 christos
1885 1.1 christos return;
1886 1.1 christos }
1887 1.1 christos
1888 1.1 christos #ifndef ARM_WINCE
1889 1.1 christos static void
1890 1.1 christos record_thumb_to_arm_glue (struct bfd_link_info * info,
1891 1.1 christos struct coff_link_hash_entry * h)
1892 1.1 christos {
1893 1.1 christos const char * name = h->root.root.string;
1894 1.1 christos asection * s;
1895 1.1 christos char * tmp_name;
1896 1.1 christos struct coff_link_hash_entry * myh;
1897 1.1 christos struct bfd_link_hash_entry * bh;
1898 1.1 christos struct coff_arm_link_hash_table * globals;
1899 1.1 christos bfd_vma val;
1900 1.1 christos bfd_size_type amt;
1901 1.1 christos
1902 1.1 christos globals = coff_arm_hash_table (info);
1903 1.1 christos
1904 1.1 christos BFD_ASSERT (globals != NULL);
1905 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1906 1.1 christos
1907 1.1 christos s = bfd_get_section_by_name
1908 1.1 christos (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1909 1.1 christos
1910 1.1 christos BFD_ASSERT (s != NULL);
1911 1.1 christos
1912 1.1 christos amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1913 1.1 christos tmp_name = bfd_malloc (amt);
1914 1.1 christos
1915 1.1 christos BFD_ASSERT (tmp_name);
1916 1.1 christos
1917 1.1 christos sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1918 1.1 christos
1919 1.1 christos myh = coff_link_hash_lookup
1920 1.1 christos (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE);
1921 1.1 christos
1922 1.1 christos if (myh != NULL)
1923 1.1 christos {
1924 1.1 christos free (tmp_name);
1925 1.1 christos /* We've already seen this guy. */
1926 1.1 christos return;
1927 1.1 christos }
1928 1.1 christos
1929 1.1 christos bh = NULL;
1930 1.1 christos val = globals->thumb_glue_size + 1;
1931 1.1 christos bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1932 1.1 christos BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh);
1933 1.1 christos
1934 1.1 christos /* If we mark it 'thumb', the disassembler will do a better job. */
1935 1.1 christos myh = (struct coff_link_hash_entry *) bh;
1936 1.1 christos myh->symbol_class = C_THUMBEXTFUNC;
1937 1.1 christos
1938 1.1 christos free (tmp_name);
1939 1.1 christos
1940 1.1 christos /* Allocate another symbol to mark where we switch to arm mode. */
1941 1.1 christos
1942 1.1 christos #define CHANGE_TO_ARM "__%s_change_to_arm"
1943 1.1 christos #define BACK_FROM_ARM "__%s_back_from_arm"
1944 1.1 christos
1945 1.1 christos amt = strlen (name) + strlen (CHANGE_TO_ARM) + 1;
1946 1.1 christos tmp_name = bfd_malloc (amt);
1947 1.1 christos
1948 1.1 christos BFD_ASSERT (tmp_name);
1949 1.1 christos
1950 1.1 christos sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
1951 1.1 christos
1952 1.1 christos bh = NULL;
1953 1.1 christos val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
1954 1.1 christos bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1955 1.1 christos BSF_LOCAL, s, val, NULL, TRUE, FALSE, &bh);
1956 1.1 christos
1957 1.1 christos free (tmp_name);
1958 1.1 christos
1959 1.1 christos globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
1960 1.1 christos
1961 1.1 christos return;
1962 1.1 christos }
1963 1.1 christos #endif /* not ARM_WINCE */
1964 1.1 christos
1965 1.1 christos /* Select a BFD to be used to hold the sections used by the glue code.
1966 1.1 christos This function is called from the linker scripts in ld/emultempl/
1967 1.1 christos {armcoff/pe}.em */
1968 1.1 christos
1969 1.1 christos bfd_boolean
1970 1.1 christos bfd_arm_get_bfd_for_interworking (bfd * abfd,
1971 1.1 christos struct bfd_link_info * info)
1972 1.1 christos {
1973 1.1 christos struct coff_arm_link_hash_table * globals;
1974 1.1 christos flagword flags;
1975 1.1 christos asection * sec;
1976 1.1 christos
1977 1.1 christos /* If we are only performing a partial link do not bother
1978 1.1 christos getting a bfd to hold the glue. */
1979 1.1 christos if (info->relocatable)
1980 1.1 christos return TRUE;
1981 1.1 christos
1982 1.1 christos globals = coff_arm_hash_table (info);
1983 1.1 christos
1984 1.1 christos BFD_ASSERT (globals != NULL);
1985 1.1 christos
1986 1.1 christos if (globals->bfd_of_glue_owner != NULL)
1987 1.1 christos return TRUE;
1988 1.1 christos
1989 1.1 christos sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1990 1.1 christos
1991 1.1 christos if (sec == NULL)
1992 1.1 christos {
1993 1.1 christos flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1994 1.1 christos | SEC_CODE | SEC_READONLY);
1995 1.1 christos sec = bfd_make_section_with_flags (abfd, ARM2THUMB_GLUE_SECTION_NAME,
1996 1.1 christos flags);
1997 1.1 christos if (sec == NULL
1998 1.1 christos || ! bfd_set_section_alignment (abfd, sec, 2))
1999 1.1 christos return FALSE;
2000 1.1 christos }
2001 1.1 christos
2002 1.1 christos sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
2003 1.1 christos
2004 1.1 christos if (sec == NULL)
2005 1.1 christos {
2006 1.1 christos flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
2007 1.1 christos | SEC_CODE | SEC_READONLY);
2008 1.1 christos sec = bfd_make_section_with_flags (abfd, THUMB2ARM_GLUE_SECTION_NAME,
2009 1.1 christos flags);
2010 1.1 christos
2011 1.1 christos if (sec == NULL
2012 1.1 christos || ! bfd_set_section_alignment (abfd, sec, 2))
2013 1.1 christos return FALSE;
2014 1.1 christos }
2015 1.1 christos
2016 1.1 christos /* Save the bfd for later use. */
2017 1.1 christos globals->bfd_of_glue_owner = abfd;
2018 1.1 christos
2019 1.1 christos return TRUE;
2020 1.1 christos }
2021 1.1 christos
2022 1.1 christos bfd_boolean
2023 1.1 christos bfd_arm_process_before_allocation (bfd * abfd,
2024 1.1 christos struct bfd_link_info * info,
2025 1.1 christos int support_old_code)
2026 1.1 christos {
2027 1.1 christos asection * sec;
2028 1.1 christos struct coff_arm_link_hash_table * globals;
2029 1.1 christos
2030 1.1 christos /* If we are only performing a partial link do not bother
2031 1.1 christos to construct any glue. */
2032 1.1 christos if (info->relocatable)
2033 1.1 christos return TRUE;
2034 1.1 christos
2035 1.1 christos /* Here we have a bfd that is to be included on the link. We have a hook
2036 1.1 christos to do reloc rummaging, before section sizes are nailed down. */
2037 1.1 christos _bfd_coff_get_external_symbols (abfd);
2038 1.1 christos
2039 1.1 christos globals = coff_arm_hash_table (info);
2040 1.1 christos
2041 1.1 christos BFD_ASSERT (globals != NULL);
2042 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
2043 1.1 christos
2044 1.1 christos globals->support_old_code = support_old_code;
2045 1.1 christos
2046 1.1 christos /* Rummage around all the relocs and map the glue vectors. */
2047 1.1 christos sec = abfd->sections;
2048 1.1 christos
2049 1.1 christos if (sec == NULL)
2050 1.1 christos return TRUE;
2051 1.1 christos
2052 1.1 christos for (; sec != NULL; sec = sec->next)
2053 1.1 christos {
2054 1.1 christos struct internal_reloc * i;
2055 1.1 christos struct internal_reloc * rel;
2056 1.1 christos
2057 1.1 christos if (sec->reloc_count == 0)
2058 1.1 christos continue;
2059 1.1 christos
2060 1.1 christos /* Load the relocs. */
2061 1.1 christos /* FIXME: there may be a storage leak here. */
2062 1.1 christos i = _bfd_coff_read_internal_relocs (abfd, sec, 1, 0, 0, 0);
2063 1.1 christos
2064 1.1 christos BFD_ASSERT (i != 0);
2065 1.1 christos
2066 1.1 christos for (rel = i; rel < i + sec->reloc_count; ++rel)
2067 1.1 christos {
2068 1.1 christos unsigned short r_type = rel->r_type;
2069 1.1 christos long symndx;
2070 1.1 christos struct coff_link_hash_entry * h;
2071 1.1 christos
2072 1.1 christos symndx = rel->r_symndx;
2073 1.1 christos
2074 1.1 christos /* If the relocation is not against a symbol it cannot concern us. */
2075 1.1 christos if (symndx == -1)
2076 1.1 christos continue;
2077 1.1 christos
2078 1.1 christos /* If the index is outside of the range of our table, something has gone wrong. */
2079 1.1 christos if (symndx >= obj_conv_table_size (abfd))
2080 1.1 christos {
2081 1.1 christos _bfd_error_handler (_("%B: illegal symbol index in reloc: %d"),
2082 1.1 christos abfd, symndx);
2083 1.1 christos continue;
2084 1.1 christos }
2085 1.1 christos
2086 1.1 christos h = obj_coff_sym_hashes (abfd)[symndx];
2087 1.1 christos
2088 1.1 christos /* If the relocation is against a static symbol it must be within
2089 1.1 christos the current section and so cannot be a cross ARM/Thumb relocation. */
2090 1.1 christos if (h == NULL)
2091 1.1 christos continue;
2092 1.1 christos
2093 1.1 christos switch (r_type)
2094 1.1 christos {
2095 1.1 christos case ARM_26:
2096 1.1 christos /* This one is a call from arm code. We need to look up
2097 1.1 christos the target of the call. If it is a thumb target, we
2098 1.1 christos insert glue. */
2099 1.1 christos
2100 1.1 christos if (h->symbol_class == C_THUMBEXTFUNC)
2101 1.1 christos record_arm_to_thumb_glue (info, h);
2102 1.1 christos break;
2103 1.1 christos
2104 1.1 christos #ifndef ARM_WINCE
2105 1.1 christos case ARM_THUMB23:
2106 1.1 christos /* This one is a call from thumb code. We used to look
2107 1.1 christos for ARM_THUMB9 and ARM_THUMB12 as well. We need to look
2108 1.1 christos up the target of the call. If it is an arm target, we
2109 1.1 christos insert glue. If the symbol does not exist it will be
2110 1.1 christos given a class of C_EXT and so we will generate a stub
2111 1.1 christos for it. This is not really a problem, since the link
2112 1.1 christos is doomed anyway. */
2113 1.1 christos
2114 1.1 christos switch (h->symbol_class)
2115 1.1 christos {
2116 1.1 christos case C_EXT:
2117 1.1 christos case C_STAT:
2118 1.1 christos case C_LABEL:
2119 1.1 christos record_thumb_to_arm_glue (info, h);
2120 1.1 christos break;
2121 1.1 christos default:
2122 1.1 christos ;
2123 1.1 christos }
2124 1.1 christos break;
2125 1.1 christos #endif
2126 1.1 christos
2127 1.1 christos default:
2128 1.1 christos break;
2129 1.1 christos }
2130 1.1 christos }
2131 1.1 christos }
2132 1.1 christos
2133 1.1 christos return TRUE;
2134 1.1 christos }
2135 1.1 christos
2136 1.1 christos #endif /* ! defined (COFF_IMAGE_WITH_PE) */
2137 1.1 christos
2138 1.1 christos #define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup
2139 1.1 christos #define coff_bfd_reloc_name_lookup coff_arm_reloc_name_lookup
2140 1.1 christos #define coff_relocate_section coff_arm_relocate_section
2141 1.1 christos #define coff_bfd_is_local_label_name coff_arm_is_local_label_name
2142 1.1 christos #define coff_adjust_symndx coff_arm_adjust_symndx
2143 1.1 christos #define coff_link_output_has_begun coff_arm_link_output_has_begun
2144 1.1 christos #define coff_final_link_postscript coff_arm_final_link_postscript
2145 1.1 christos #define coff_bfd_merge_private_bfd_data coff_arm_merge_private_bfd_data
2146 1.1 christos #define coff_bfd_print_private_bfd_data coff_arm_print_private_bfd_data
2147 1.1 christos #define coff_bfd_set_private_flags _bfd_coff_arm_set_private_flags
2148 1.1 christos #define coff_bfd_copy_private_bfd_data coff_arm_copy_private_bfd_data
2149 1.1 christos #define coff_bfd_link_hash_table_create coff_arm_link_hash_table_create
2150 1.1 christos
2151 1.1 christos /* When doing a relocatable link, we want to convert ARM_26 relocs
2152 1.1 christos into ARM_26D relocs. */
2153 1.1 christos
2154 1.1 christos static bfd_boolean
2155 1.1 christos coff_arm_adjust_symndx (bfd *obfd ATTRIBUTE_UNUSED,
2156 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED,
2157 1.1 christos bfd *ibfd,
2158 1.1 christos asection *sec,
2159 1.1 christos struct internal_reloc *irel,
2160 1.1 christos bfd_boolean *adjustedp)
2161 1.1 christos {
2162 1.1 christos if (irel->r_type == ARM_26)
2163 1.1 christos {
2164 1.1 christos struct coff_link_hash_entry *h;
2165 1.1 christos
2166 1.1 christos h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
2167 1.1 christos if (h != NULL
2168 1.1 christos && (h->root.type == bfd_link_hash_defined
2169 1.1 christos || h->root.type == bfd_link_hash_defweak)
2170 1.1 christos && h->root.u.def.section->output_section == sec->output_section)
2171 1.1 christos irel->r_type = ARM_26D;
2172 1.1 christos }
2173 1.1 christos *adjustedp = FALSE;
2174 1.1 christos return TRUE;
2175 1.1 christos }
2176 1.1 christos
2177 1.1 christos /* Called when merging the private data areas of two BFDs.
2178 1.1 christos This is important as it allows us to detect if we are
2179 1.1 christos attempting to merge binaries compiled for different ARM
2180 1.1 christos targets, eg different CPUs or different APCS's. */
2181 1.1 christos
2182 1.1 christos static bfd_boolean
2183 1.1 christos coff_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
2184 1.1 christos {
2185 1.1 christos BFD_ASSERT (ibfd != NULL && obfd != NULL);
2186 1.1 christos
2187 1.1 christos if (ibfd == obfd)
2188 1.1 christos return TRUE;
2189 1.1 christos
2190 1.1 christos /* If the two formats are different we cannot merge anything.
2191 1.1 christos This is not an error, since it is permissable to change the
2192 1.1 christos input and output formats. */
2193 1.1 christos if ( ibfd->xvec->flavour != bfd_target_coff_flavour
2194 1.1 christos || obfd->xvec->flavour != bfd_target_coff_flavour)
2195 1.1 christos return TRUE;
2196 1.1 christos
2197 1.1 christos /* Determine what should happen if the input ARM architecture
2198 1.1 christos does not match the output ARM architecture. */
2199 1.1 christos if (! bfd_arm_merge_machines (ibfd, obfd))
2200 1.1 christos return FALSE;
2201 1.1 christos
2202 1.1 christos /* Verify that the APCS is the same for the two BFDs. */
2203 1.1 christos if (APCS_SET (ibfd))
2204 1.1 christos {
2205 1.1 christos if (APCS_SET (obfd))
2206 1.1 christos {
2207 1.1 christos /* If the src and dest have different APCS flag bits set, fail. */
2208 1.1 christos if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
2209 1.1 christos {
2210 1.1 christos _bfd_error_handler
2211 1.1 christos /* xgettext: c-format */
2212 1.1 christos (_("error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"),
2213 1.1 christos ibfd, obfd,
2214 1.1 christos APCS_26_FLAG (ibfd) ? 26 : 32,
2215 1.1 christos APCS_26_FLAG (obfd) ? 26 : 32
2216 1.1 christos );
2217 1.1 christos
2218 1.1 christos bfd_set_error (bfd_error_wrong_format);
2219 1.1 christos return FALSE;
2220 1.1 christos }
2221 1.1 christos
2222 1.1 christos if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
2223 1.1 christos {
2224 1.1 christos const char *msg;
2225 1.1 christos
2226 1.1 christos if (APCS_FLOAT_FLAG (ibfd))
2227 1.1 christos /* xgettext: c-format */
2228 1.1 christos msg = _("error: %B passes floats in float registers, whereas %B passes them in integer registers");
2229 1.1 christos else
2230 1.1 christos /* xgettext: c-format */
2231 1.1 christos msg = _("error: %B passes floats in integer registers, whereas %B passes them in float registers");
2232 1.1 christos
2233 1.1 christos _bfd_error_handler (msg, ibfd, obfd);
2234 1.1 christos
2235 1.1 christos bfd_set_error (bfd_error_wrong_format);
2236 1.1 christos return FALSE;
2237 1.1 christos }
2238 1.1 christos
2239 1.1 christos if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
2240 1.1 christos {
2241 1.1 christos const char * msg;
2242 1.1 christos
2243 1.1 christos if (PIC_FLAG (ibfd))
2244 1.1 christos /* xgettext: c-format */
2245 1.1 christos msg = _("error: %B is compiled as position independent code, whereas target %B is absolute position");
2246 1.1 christos else
2247 1.1 christos /* xgettext: c-format */
2248 1.1 christos msg = _("error: %B is compiled as absolute position code, whereas target %B is position independent");
2249 1.1 christos _bfd_error_handler (msg, ibfd, obfd);
2250 1.1 christos
2251 1.1 christos bfd_set_error (bfd_error_wrong_format);
2252 1.1 christos return FALSE;
2253 1.1 christos }
2254 1.1 christos }
2255 1.1 christos else
2256 1.1 christos {
2257 1.1 christos SET_APCS_FLAGS (obfd, APCS_26_FLAG (ibfd) | APCS_FLOAT_FLAG (ibfd) | PIC_FLAG (ibfd));
2258 1.1 christos
2259 1.1 christos /* Set up the arch and fields as well as these are probably wrong. */
2260 1.1 christos bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2261 1.1 christos }
2262 1.1 christos }
2263 1.1 christos
2264 1.1 christos /* Check the interworking support. */
2265 1.1 christos if (INTERWORK_SET (ibfd))
2266 1.1 christos {
2267 1.1 christos if (INTERWORK_SET (obfd))
2268 1.1 christos {
2269 1.1 christos /* If the src and dest differ in their interworking issue a warning. */
2270 1.1 christos if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd))
2271 1.1 christos {
2272 1.1 christos const char * msg;
2273 1.1 christos
2274 1.1 christos if (INTERWORK_FLAG (ibfd))
2275 1.1 christos /* xgettext: c-format */
2276 1.1 christos msg = _("Warning: %B supports interworking, whereas %B does not");
2277 1.1 christos else
2278 1.1 christos /* xgettext: c-format */
2279 1.1 christos msg = _("Warning: %B does not support interworking, whereas %B does");
2280 1.1 christos
2281 1.1 christos _bfd_error_handler (msg, ibfd, obfd);
2282 1.1 christos }
2283 1.1 christos }
2284 1.1 christos else
2285 1.1 christos {
2286 1.1 christos SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
2287 1.1 christos }
2288 1.1 christos }
2289 1.1 christos
2290 1.1 christos return TRUE;
2291 1.1 christos }
2292 1.1 christos
2293 1.1 christos /* Display the flags field. */
2294 1.1 christos
2295 1.1 christos static bfd_boolean
2296 1.1 christos coff_arm_print_private_bfd_data (bfd * abfd, void * ptr)
2297 1.1 christos {
2298 1.1 christos FILE * file = (FILE *) ptr;
2299 1.1 christos
2300 1.1 christos BFD_ASSERT (abfd != NULL && ptr != NULL);
2301 1.1 christos
2302 1.1 christos /* xgettext:c-format */
2303 1.1 christos fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags);
2304 1.1 christos
2305 1.1 christos if (APCS_SET (abfd))
2306 1.1 christos {
2307 1.1 christos /* xgettext: APCS is ARM Procedure Call Standard, it should not be translated. */
2308 1.1 christos fprintf (file, " [APCS-%d]", APCS_26_FLAG (abfd) ? 26 : 32);
2309 1.1 christos
2310 1.1 christos if (APCS_FLOAT_FLAG (abfd))
2311 1.1 christos fprintf (file, _(" [floats passed in float registers]"));
2312 1.1 christos else
2313 1.1 christos fprintf (file, _(" [floats passed in integer registers]"));
2314 1.1 christos
2315 1.1 christos if (PIC_FLAG (abfd))
2316 1.1 christos fprintf (file, _(" [position independent]"));
2317 1.1 christos else
2318 1.1 christos fprintf (file, _(" [absolute position]"));
2319 1.1 christos }
2320 1.1 christos
2321 1.1 christos if (! INTERWORK_SET (abfd))
2322 1.1 christos fprintf (file, _(" [interworking flag not initialised]"));
2323 1.1 christos else if (INTERWORK_FLAG (abfd))
2324 1.1 christos fprintf (file, _(" [interworking supported]"));
2325 1.1 christos else
2326 1.1 christos fprintf (file, _(" [interworking not supported]"));
2327 1.1 christos
2328 1.1 christos fputc ('\n', file);
2329 1.1 christos
2330 1.1 christos return TRUE;
2331 1.1 christos }
2332 1.1 christos
2333 1.1 christos /* Copies the given flags into the coff_tdata.flags field.
2334 1.1 christos Typically these flags come from the f_flags[] field of
2335 1.1 christos the COFF filehdr structure, which contains important,
2336 1.1 christos target specific information.
2337 1.1 christos Note: Although this function is static, it is explicitly
2338 1.1 christos called from both coffcode.h and peicode.h. */
2339 1.1 christos
2340 1.1 christos static bfd_boolean
2341 1.1 christos _bfd_coff_arm_set_private_flags (bfd * abfd, flagword flags)
2342 1.1 christos {
2343 1.1 christos flagword flag;
2344 1.1 christos
2345 1.1 christos BFD_ASSERT (abfd != NULL);
2346 1.1 christos
2347 1.1 christos flag = (flags & F_APCS26) ? F_APCS_26 : 0;
2348 1.1 christos
2349 1.1 christos /* Make sure that the APCS field has not been initialised to the opposite
2350 1.1 christos value. */
2351 1.1 christos if (APCS_SET (abfd)
2352 1.1 christos && ( (APCS_26_FLAG (abfd) != flag)
2353 1.1 christos || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT))
2354 1.1 christos || (PIC_FLAG (abfd) != (flags & F_PIC))
2355 1.1 christos ))
2356 1.1 christos return FALSE;
2357 1.1 christos
2358 1.1 christos flag |= (flags & (F_APCS_FLOAT | F_PIC));
2359 1.1 christos
2360 1.1 christos SET_APCS_FLAGS (abfd, flag);
2361 1.1 christos
2362 1.1 christos flag = (flags & F_INTERWORK);
2363 1.1 christos
2364 1.1 christos /* If the BFD has already had its interworking flag set, but it
2365 1.1 christos is different from the value that we have been asked to set,
2366 1.1 christos then assume that that merged code will not support interworking
2367 1.1 christos and set the flag accordingly. */
2368 1.1 christos if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag))
2369 1.1 christos {
2370 1.1 christos if (flag)
2371 1.1 christos /* xgettext: c-format */
2372 1.1 christos _bfd_error_handler (_("Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"),
2373 1.1 christos abfd);
2374 1.1 christos else
2375 1.1 christos /* xgettext: c-format */
2376 1.1 christos _bfd_error_handler (_("Warning: Clearing the interworking flag of %B due to outside request"),
2377 1.1 christos abfd);
2378 1.1 christos flag = 0;
2379 1.1 christos }
2380 1.1 christos
2381 1.1 christos SET_INTERWORK_FLAG (abfd, flag);
2382 1.1 christos
2383 1.1 christos return TRUE;
2384 1.1 christos }
2385 1.1 christos
2386 1.1 christos /* Copy the important parts of the target specific data
2387 1.1 christos from one instance of a BFD to another. */
2388 1.1 christos
2389 1.1 christos static bfd_boolean
2390 1.1 christos coff_arm_copy_private_bfd_data (bfd * src, bfd * dest)
2391 1.1 christos {
2392 1.1 christos BFD_ASSERT (src != NULL && dest != NULL);
2393 1.1 christos
2394 1.1 christos if (src == dest)
2395 1.1 christos return TRUE;
2396 1.1 christos
2397 1.1 christos /* If the destination is not in the same format as the source, do not do
2398 1.1 christos the copy. */
2399 1.1 christos if (src->xvec != dest->xvec)
2400 1.1 christos return TRUE;
2401 1.1 christos
2402 1.1 christos /* Copy the flags field. */
2403 1.1 christos if (APCS_SET (src))
2404 1.1 christos {
2405 1.1 christos if (APCS_SET (dest))
2406 1.1 christos {
2407 1.1 christos /* If the src and dest have different APCS flag bits set, fail. */
2408 1.1 christos if (APCS_26_FLAG (dest) != APCS_26_FLAG (src))
2409 1.1 christos return FALSE;
2410 1.1 christos
2411 1.1 christos if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src))
2412 1.1 christos return FALSE;
2413 1.1 christos
2414 1.1 christos if (PIC_FLAG (dest) != PIC_FLAG (src))
2415 1.1 christos return FALSE;
2416 1.1 christos }
2417 1.1 christos else
2418 1.1 christos SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src)
2419 1.1 christos | PIC_FLAG (src));
2420 1.1 christos }
2421 1.1 christos
2422 1.1 christos if (INTERWORK_SET (src))
2423 1.1 christos {
2424 1.1 christos if (INTERWORK_SET (dest))
2425 1.1 christos {
2426 1.1 christos /* If the src and dest have different interworking flags then turn
2427 1.1 christos off the interworking bit. */
2428 1.1 christos if (INTERWORK_FLAG (dest) != INTERWORK_FLAG (src))
2429 1.1 christos {
2430 1.1 christos if (INTERWORK_FLAG (dest))
2431 1.1 christos {
2432 1.1 christos /* xgettext:c-format */
2433 1.1 christos _bfd_error_handler (("\
2434 1.1 christos Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"),
2435 1.1 christos dest, src);
2436 1.1 christos }
2437 1.1 christos
2438 1.1 christos SET_INTERWORK_FLAG (dest, 0);
2439 1.1 christos }
2440 1.1 christos }
2441 1.1 christos else
2442 1.1 christos {
2443 1.1 christos SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src));
2444 1.1 christos }
2445 1.1 christos }
2446 1.1 christos
2447 1.1 christos return TRUE;
2448 1.1 christos }
2449 1.1 christos
2450 1.1 christos /* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
2451 1.1 christos *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h. */
2452 1.1 christos #ifndef LOCAL_LABEL_PREFIX
2453 1.1 christos #define LOCAL_LABEL_PREFIX ""
2454 1.1 christos #endif
2455 1.1 christos #ifndef USER_LABEL_PREFIX
2456 1.1 christos #define USER_LABEL_PREFIX "_"
2457 1.1 christos #endif
2458 1.1 christos
2459 1.1 christos /* Like _bfd_coff_is_local_label_name, but
2460 1.1 christos a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be
2461 1.1 christos non-local.
2462 1.1 christos b) Allow other prefixes than ".", e.g. an empty prefix would cause all
2463 1.1 christos labels of the form Lxxx to be stripped. */
2464 1.1 christos
2465 1.1 christos static bfd_boolean
2466 1.1 christos coff_arm_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
2467 1.1 christos const char * name)
2468 1.1 christos {
2469 1.1 christos #ifdef USER_LABEL_PREFIX
2470 1.1 christos if (USER_LABEL_PREFIX[0] != 0)
2471 1.1 christos {
2472 1.1 christos size_t len = strlen (USER_LABEL_PREFIX);
2473 1.1 christos
2474 1.1 christos if (strncmp (name, USER_LABEL_PREFIX, len) == 0)
2475 1.1 christos return FALSE;
2476 1.1 christos }
2477 1.1 christos #endif
2478 1.1 christos
2479 1.1 christos #ifdef LOCAL_LABEL_PREFIX
2480 1.1 christos /* If there is a prefix for local labels then look for this.
2481 1.1 christos If the prefix exists, but it is empty, then ignore the test. */
2482 1.1 christos
2483 1.1 christos if (LOCAL_LABEL_PREFIX[0] != 0)
2484 1.1 christos {
2485 1.1 christos size_t len = strlen (LOCAL_LABEL_PREFIX);
2486 1.1 christos
2487 1.1 christos if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0)
2488 1.1 christos return FALSE;
2489 1.1 christos
2490 1.1 christos /* Perform the checks below for the rest of the name. */
2491 1.1 christos name += len;
2492 1.1 christos }
2493 1.1 christos #endif
2494 1.1 christos
2495 1.1 christos return name[0] == 'L';
2496 1.1 christos }
2497 1.1 christos
2498 1.1 christos /* This piece of machinery exists only to guarantee that the bfd that holds
2499 1.1 christos the glue section is written last.
2500 1.1 christos
2501 1.1 christos This does depend on bfd_make_section attaching a new section to the
2502 1.1 christos end of the section list for the bfd. */
2503 1.1 christos
2504 1.1 christos static bfd_boolean
2505 1.1 christos coff_arm_link_output_has_begun (bfd * sub, struct coff_final_link_info * info)
2506 1.1 christos {
2507 1.1 christos return (sub->output_has_begun
2508 1.1 christos || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner);
2509 1.1 christos }
2510 1.1 christos
2511 1.1 christos static bfd_boolean
2512 1.1 christos coff_arm_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED,
2513 1.1 christos struct coff_final_link_info * pfinfo)
2514 1.1 christos {
2515 1.1 christos struct coff_arm_link_hash_table * globals;
2516 1.1 christos
2517 1.1 christos globals = coff_arm_hash_table (pfinfo->info);
2518 1.1 christos
2519 1.1 christos BFD_ASSERT (globals != NULL);
2520 1.1 christos
2521 1.1 christos if (globals->bfd_of_glue_owner != NULL)
2522 1.1 christos {
2523 1.1 christos if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner))
2524 1.1 christos return FALSE;
2525 1.1 christos
2526 1.1 christos globals->bfd_of_glue_owner->output_has_begun = TRUE;
2527 1.1 christos }
2528 1.1 christos
2529 1.1 christos return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
2530 1.1 christos }
2531 1.1 christos
2532 1.1 christos #ifndef bfd_pe_print_pdata
2533 1.1 christos #define bfd_pe_print_pdata NULL
2534 1.1 christos #endif
2535 1.1 christos
2536 1.1 christos #include "coffcode.h"
2537 1.1 christos
2538 1.1 christos #ifndef TARGET_LITTLE_SYM
2539 1.1 christos #define TARGET_LITTLE_SYM armcoff_little_vec
2540 1.1 christos #endif
2541 1.1 christos #ifndef TARGET_LITTLE_NAME
2542 1.1 christos #define TARGET_LITTLE_NAME "coff-arm-little"
2543 1.1 christos #endif
2544 1.1 christos #ifndef TARGET_BIG_SYM
2545 1.1 christos #define TARGET_BIG_SYM armcoff_big_vec
2546 1.1 christos #endif
2547 1.1 christos #ifndef TARGET_BIG_NAME
2548 1.1 christos #define TARGET_BIG_NAME "coff-arm-big"
2549 1.1 christos #endif
2550 1.1 christos
2551 1.1 christos #ifndef TARGET_UNDERSCORE
2552 1.1 christos #define TARGET_UNDERSCORE 0
2553 1.1 christos #endif
2554 1.1 christos
2555 1.1 christos #ifndef EXTRA_S_FLAGS
2556 1.1 christos #ifdef COFF_WITH_PE
2557 1.1 christos #define EXTRA_S_FLAGS (SEC_CODE | SEC_LINK_ONCE | SEC_LINK_DUPLICATES)
2558 1.1 christos #else
2559 1.1 christos #define EXTRA_S_FLAGS SEC_CODE
2560 1.1 christos #endif
2561 1.1 christos #endif
2562 1.1 christos
2563 1.1 christos /* Forward declaration for use initialising alternative_target field. */
2564 1.1 christos extern const bfd_target TARGET_BIG_SYM ;
2565 1.1 christos
2566 1.1 christos /* Target vectors. */
2567 CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_BIG_SYM, COFF_SWAP_TABLE)
2568 CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_LITTLE_SYM, COFF_SWAP_TABLE)
2569