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