OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [coff-arm.c] - Blame information for rev 1776

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.