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