Coverage Report

Created: 2025-06-24 06:45

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