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