Back to index

cell-binutils  2.17cvs20070401
elf32-arm.c
Go to the documentation of this file.
00001 /* 32-bit ELF support for ARM
00002    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of BFD, the Binary File Descriptor library.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00020 
00021 #include "bfd.h"
00022 #include "sysdep.h"
00023 #include "libiberty.h"
00024 #include "libbfd.h"
00025 #include "elf-bfd.h"
00026 #include "elf-vxworks.h"
00027 #include "elf/arm.h"
00028 
00029 #ifndef NUM_ELEM
00030 #define NUM_ELEM(a)  (sizeof (a) / (sizeof (a)[0]))
00031 #endif
00032 
00033 /* Return the relocation section associated with NAME.  HTAB is the
00034    bfd's elf32_arm_link_hash_entry.  */
00035 #define RELOC_SECTION(HTAB, NAME) \
00036   ((HTAB)->use_rel ? ".rel" NAME : ".rela" NAME)
00037 
00038 /* Return size of a relocation entry.  HTAB is the bfd's
00039    elf32_arm_link_hash_entry.  */
00040 #define RELOC_SIZE(HTAB) \
00041   ((HTAB)->use_rel \
00042    ? sizeof (Elf32_External_Rel) \
00043    : sizeof (Elf32_External_Rela))
00044 
00045 /* Return function to swap relocations in.  HTAB is the bfd's
00046    elf32_arm_link_hash_entry.  */
00047 #define SWAP_RELOC_IN(HTAB) \
00048   ((HTAB)->use_rel \
00049    ? bfd_elf32_swap_reloc_in \
00050    : bfd_elf32_swap_reloca_in)
00051 
00052 /* Return function to swap relocations out.  HTAB is the bfd's
00053    elf32_arm_link_hash_entry.  */
00054 #define SWAP_RELOC_OUT(HTAB) \
00055   ((HTAB)->use_rel \
00056    ? bfd_elf32_swap_reloc_out \
00057    : bfd_elf32_swap_reloca_out)
00058 
00059 #define elf_info_to_howto               0
00060 #define elf_info_to_howto_rel           elf32_arm_info_to_howto
00061 
00062 #define ARM_ELF_ABI_VERSION        0
00063 #define ARM_ELF_OS_ABI_VERSION            ELFOSABI_ARM
00064 
00065 static struct elf_backend_data elf32_arm_vxworks_bed;
00066 
00067 /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
00068    R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
00069    in that slot.  */
00070 
00071 static reloc_howto_type elf32_arm_howto_table_1[] =
00072 {
00073   /* No relocation */
00074   HOWTO (R_ARM_NONE,        /* type */
00075         0,                  /* rightshift */
00076         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00077         0,                  /* bitsize */
00078         FALSE,                     /* pc_relative */
00079         0,                  /* bitpos */
00080         complain_overflow_dont,/* complain_on_overflow */
00081         bfd_elf_generic_reloc,     /* special_function */
00082         "R_ARM_NONE",              /* name */
00083         FALSE,                     /* partial_inplace */
00084         0,                  /* src_mask */
00085         0,                  /* dst_mask */
00086         FALSE),             /* pcrel_offset */
00087 
00088   HOWTO (R_ARM_PC24,        /* type */
00089         2,                  /* rightshift */
00090         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00091         24,                 /* bitsize */
00092         TRUE,               /* pc_relative */
00093         0,                  /* bitpos */
00094         complain_overflow_signed,/* complain_on_overflow */
00095         bfd_elf_generic_reloc,     /* special_function */
00096         "R_ARM_PC24",              /* name */
00097         FALSE,                     /* partial_inplace */
00098         0x00ffffff,         /* src_mask */
00099         0x00ffffff,         /* dst_mask */
00100         TRUE),                     /* pcrel_offset */
00101 
00102   /* 32 bit absolute */
00103   HOWTO (R_ARM_ABS32,              /* type */
00104         0,                  /* rightshift */
00105         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00106         32,                 /* bitsize */
00107         FALSE,                     /* pc_relative */
00108         0,                  /* bitpos */
00109         complain_overflow_bitfield,/* complain_on_overflow */
00110         bfd_elf_generic_reloc,     /* special_function */
00111         "R_ARM_ABS32",             /* name */
00112         FALSE,                     /* partial_inplace */
00113         0xffffffff,         /* src_mask */
00114         0xffffffff,         /* dst_mask */
00115         FALSE),             /* pcrel_offset */
00116 
00117   /* standard 32bit pc-relative reloc */
00118   HOWTO (R_ARM_REL32,              /* type */
00119         0,                  /* rightshift */
00120         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00121         32,                 /* bitsize */
00122         TRUE,               /* pc_relative */
00123         0,                  /* bitpos */
00124         complain_overflow_bitfield,/* complain_on_overflow */
00125         bfd_elf_generic_reloc,     /* special_function */
00126         "R_ARM_REL32",             /* name */
00127         FALSE,                     /* partial_inplace */
00128         0xffffffff,         /* src_mask */
00129         0xffffffff,         /* dst_mask */
00130         TRUE),                     /* pcrel_offset */
00131 
00132   /* 8 bit absolute - R_ARM_LDR_PC_G0 in AAELF */
00133   HOWTO (R_ARM_LDR_PC_G0,   /* type */
00134         0,                  /* rightshift */
00135         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00136         32,                 /* bitsize */
00137         TRUE,               /* pc_relative */
00138         0,                  /* bitpos */
00139         complain_overflow_dont,/* complain_on_overflow */
00140         bfd_elf_generic_reloc,     /* special_function */
00141         "R_ARM_LDR_PC_G0",     /* name */
00142         FALSE,                     /* partial_inplace */
00143         0xffffffff,         /* src_mask */
00144         0xffffffff,         /* dst_mask */
00145         TRUE),                     /* pcrel_offset */
00146 
00147    /* 16 bit absolute */
00148   HOWTO (R_ARM_ABS16,              /* type */
00149         0,                  /* rightshift */
00150         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00151         16,                 /* bitsize */
00152         FALSE,                     /* pc_relative */
00153         0,                  /* bitpos */
00154         complain_overflow_bitfield,/* complain_on_overflow */
00155         bfd_elf_generic_reloc,     /* special_function */
00156         "R_ARM_ABS16",             /* name */
00157         FALSE,                     /* partial_inplace */
00158         0x0000ffff,         /* src_mask */
00159         0x0000ffff,         /* dst_mask */
00160         FALSE),             /* pcrel_offset */
00161 
00162   /* 12 bit absolute */
00163   HOWTO (R_ARM_ABS12,              /* type */
00164         0,                  /* rightshift */
00165         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00166         12,                 /* bitsize */
00167         FALSE,                     /* pc_relative */
00168         0,                  /* bitpos */
00169         complain_overflow_bitfield,/* complain_on_overflow */
00170         bfd_elf_generic_reloc,     /* special_function */
00171         "R_ARM_ABS12",             /* name */
00172         FALSE,                     /* partial_inplace */
00173         0x00000fff,         /* src_mask */
00174         0x00000fff,         /* dst_mask */
00175         FALSE),             /* pcrel_offset */
00176 
00177   HOWTO (R_ARM_THM_ABS5,    /* type */
00178         6,                  /* rightshift */
00179         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00180         5,                  /* bitsize */
00181         FALSE,                     /* pc_relative */
00182         0,                  /* bitpos */
00183         complain_overflow_bitfield,/* complain_on_overflow */
00184         bfd_elf_generic_reloc,     /* special_function */
00185         "R_ARM_THM_ABS5",   /* name */
00186         FALSE,                     /* partial_inplace */
00187         0x000007e0,         /* src_mask */
00188         0x000007e0,         /* dst_mask */
00189         FALSE),             /* pcrel_offset */
00190 
00191   /* 8 bit absolute */
00192   HOWTO (R_ARM_ABS8,        /* type */
00193         0,                  /* rightshift */
00194         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00195         8,                  /* bitsize */
00196         FALSE,                     /* pc_relative */
00197         0,                  /* bitpos */
00198         complain_overflow_bitfield,/* complain_on_overflow */
00199         bfd_elf_generic_reloc,     /* special_function */
00200         "R_ARM_ABS8",              /* name */
00201         FALSE,                     /* partial_inplace */
00202         0x000000ff,         /* src_mask */
00203         0x000000ff,         /* dst_mask */
00204         FALSE),             /* pcrel_offset */
00205 
00206   HOWTO (R_ARM_SBREL32,            /* type */
00207         0,                  /* rightshift */
00208         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00209         32,                 /* bitsize */
00210         FALSE,                     /* pc_relative */
00211         0,                  /* bitpos */
00212         complain_overflow_dont,/* complain_on_overflow */
00213         bfd_elf_generic_reloc,     /* special_function */
00214         "R_ARM_SBREL32",    /* name */
00215         FALSE,                     /* partial_inplace */
00216         0xffffffff,         /* src_mask */
00217         0xffffffff,         /* dst_mask */
00218         FALSE),             /* pcrel_offset */
00219 
00220   HOWTO (R_ARM_THM_CALL,    /* type */
00221         1,                  /* rightshift */
00222         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00223         25,                 /* bitsize */
00224         TRUE,               /* pc_relative */
00225         0,                  /* bitpos */
00226         complain_overflow_signed,/* complain_on_overflow */
00227         bfd_elf_generic_reloc,     /* special_function */
00228         "R_ARM_THM_CALL",   /* name */
00229         FALSE,                     /* partial_inplace */
00230         0x07ff07ff,         /* src_mask */
00231         0x07ff07ff,         /* dst_mask */
00232         TRUE),                     /* pcrel_offset */
00233 
00234   HOWTO (R_ARM_THM_PC8,             /* type */
00235         1,                  /* rightshift */
00236         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00237         8,                  /* bitsize */
00238         TRUE,               /* pc_relative */
00239         0,                  /* bitpos */
00240         complain_overflow_signed,/* complain_on_overflow */
00241         bfd_elf_generic_reloc,     /* special_function */
00242         "R_ARM_THM_PC8",    /* name */
00243         FALSE,                     /* partial_inplace */
00244         0x000000ff,         /* src_mask */
00245         0x000000ff,         /* dst_mask */
00246         TRUE),                     /* pcrel_offset */
00247 
00248   HOWTO (R_ARM_BREL_ADJ,    /* type */
00249         1,                  /* rightshift */
00250         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00251         32,                 /* bitsize */
00252         FALSE,                     /* pc_relative */
00253         0,                  /* bitpos */
00254         complain_overflow_signed,/* complain_on_overflow */
00255         bfd_elf_generic_reloc,     /* special_function */
00256         "R_ARM_BREL_ADJ",   /* name */
00257         FALSE,                     /* partial_inplace */
00258         0xffffffff,         /* src_mask */
00259         0xffffffff,         /* dst_mask */
00260         FALSE),             /* pcrel_offset */
00261 
00262   HOWTO (R_ARM_SWI24,              /* type */
00263         0,                  /* rightshift */
00264         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00265         0,                  /* bitsize */
00266         FALSE,                     /* pc_relative */
00267         0,                  /* bitpos */
00268         complain_overflow_signed,/* complain_on_overflow */
00269         bfd_elf_generic_reloc,     /* special_function */
00270         "R_ARM_SWI24",             /* name */
00271         FALSE,                     /* partial_inplace */
00272         0x00000000,         /* src_mask */
00273         0x00000000,         /* dst_mask */
00274         FALSE),             /* pcrel_offset */
00275 
00276   HOWTO (R_ARM_THM_SWI8,    /* type */
00277         0,                  /* rightshift */
00278         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00279         0,                  /* bitsize */
00280         FALSE,                     /* pc_relative */
00281         0,                  /* bitpos */
00282         complain_overflow_signed,/* complain_on_overflow */
00283         bfd_elf_generic_reloc,     /* special_function */
00284         "R_ARM_SWI8",              /* name */
00285         FALSE,                     /* partial_inplace */
00286         0x00000000,         /* src_mask */
00287         0x00000000,         /* dst_mask */
00288         FALSE),             /* pcrel_offset */
00289 
00290   /* BLX instruction for the ARM.  */
00291   HOWTO (R_ARM_XPC25,              /* type */
00292         2,                  /* rightshift */
00293         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00294         25,                 /* bitsize */
00295         TRUE,               /* pc_relative */
00296         0,                  /* bitpos */
00297         complain_overflow_signed,/* complain_on_overflow */
00298         bfd_elf_generic_reloc,     /* special_function */
00299         "R_ARM_XPC25",             /* name */
00300         FALSE,                     /* partial_inplace */
00301         0x00ffffff,         /* src_mask */
00302         0x00ffffff,         /* dst_mask */
00303         TRUE),                     /* pcrel_offset */
00304 
00305   /* BLX instruction for the Thumb.  */
00306   HOWTO (R_ARM_THM_XPC22,   /* type */
00307         2,                  /* rightshift */
00308         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00309         22,                 /* bitsize */
00310         TRUE,               /* pc_relative */
00311         0,                  /* bitpos */
00312         complain_overflow_signed,/* complain_on_overflow */
00313         bfd_elf_generic_reloc,     /* special_function */
00314         "R_ARM_THM_XPC22",  /* name */
00315         FALSE,                     /* partial_inplace */
00316         0x07ff07ff,         /* src_mask */
00317         0x07ff07ff,         /* dst_mask */
00318         TRUE),                     /* pcrel_offset */
00319 
00320   /* Dynamic TLS relocations.  */
00321 
00322   HOWTO (R_ARM_TLS_DTPMOD32,       /* type */
00323          0,                     /* rightshift */
00324          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00325          32,                    /* bitsize */
00326          FALSE,                 /* pc_relative */
00327          0,                     /* bitpos */
00328          complain_overflow_bitfield,/* complain_on_overflow */
00329          bfd_elf_generic_reloc, /* special_function */
00330          "R_ARM_TLS_DTPMOD32",     /* name */
00331          TRUE,                     /* partial_inplace */
00332          0xffffffff,        /* src_mask */
00333          0xffffffff,        /* dst_mask */
00334          FALSE),                /* pcrel_offset */
00335 
00336   HOWTO (R_ARM_TLS_DTPOFF32,       /* type */
00337          0,                     /* rightshift */
00338          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00339          32,                    /* bitsize */
00340          FALSE,                 /* pc_relative */
00341          0,                     /* bitpos */
00342          complain_overflow_bitfield,/* complain_on_overflow */
00343          bfd_elf_generic_reloc, /* special_function */
00344          "R_ARM_TLS_DTPOFF32",     /* name */
00345          TRUE,                     /* partial_inplace */
00346          0xffffffff,        /* src_mask */
00347          0xffffffff,        /* dst_mask */
00348          FALSE),                /* pcrel_offset */
00349 
00350   HOWTO (R_ARM_TLS_TPOFF32, /* type */
00351          0,                     /* rightshift */
00352          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00353          32,                    /* bitsize */
00354          FALSE,                 /* pc_relative */
00355          0,                     /* bitpos */
00356          complain_overflow_bitfield,/* complain_on_overflow */
00357          bfd_elf_generic_reloc, /* special_function */
00358          "R_ARM_TLS_TPOFF32",      /* name */
00359          TRUE,                     /* partial_inplace */
00360          0xffffffff,        /* src_mask */
00361          0xffffffff,        /* dst_mask */
00362          FALSE),                /* pcrel_offset */
00363 
00364   /* Relocs used in ARM Linux */
00365 
00366   HOWTO (R_ARM_COPY,        /* type */
00367          0,                     /* rightshift */
00368          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00369          32,                    /* bitsize */
00370          FALSE,                 /* pc_relative */
00371          0,                     /* bitpos */
00372          complain_overflow_bitfield,/* complain_on_overflow */
00373          bfd_elf_generic_reloc, /* special_function */
00374          "R_ARM_COPY",             /* name */
00375          TRUE,                     /* partial_inplace */
00376          0xffffffff,        /* src_mask */
00377          0xffffffff,        /* dst_mask */
00378          FALSE),                /* pcrel_offset */
00379 
00380   HOWTO (R_ARM_GLOB_DAT,    /* type */
00381          0,                     /* rightshift */
00382          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00383          32,                    /* bitsize */
00384          FALSE,                 /* pc_relative */
00385          0,                     /* bitpos */
00386          complain_overflow_bitfield,/* complain_on_overflow */
00387          bfd_elf_generic_reloc, /* special_function */
00388          "R_ARM_GLOB_DAT",  /* name */
00389          TRUE,                     /* partial_inplace */
00390          0xffffffff,        /* src_mask */
00391          0xffffffff,        /* dst_mask */
00392          FALSE),                /* pcrel_offset */
00393 
00394   HOWTO (R_ARM_JUMP_SLOT,   /* type */
00395          0,                     /* rightshift */
00396          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00397          32,                    /* bitsize */
00398          FALSE,                 /* pc_relative */
00399          0,                     /* bitpos */
00400          complain_overflow_bitfield,/* complain_on_overflow */
00401          bfd_elf_generic_reloc, /* special_function */
00402          "R_ARM_JUMP_SLOT", /* name */
00403          TRUE,                     /* partial_inplace */
00404          0xffffffff,        /* src_mask */
00405          0xffffffff,        /* dst_mask */
00406          FALSE),                /* pcrel_offset */
00407 
00408   HOWTO (R_ARM_RELATIVE,    /* type */
00409          0,                     /* rightshift */
00410          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00411          32,                    /* bitsize */
00412          FALSE,                 /* pc_relative */
00413          0,                     /* bitpos */
00414          complain_overflow_bitfield,/* complain_on_overflow */
00415          bfd_elf_generic_reloc, /* special_function */
00416          "R_ARM_RELATIVE",  /* name */
00417          TRUE,                     /* partial_inplace */
00418          0xffffffff,        /* src_mask */
00419          0xffffffff,        /* dst_mask */
00420          FALSE),                /* pcrel_offset */
00421 
00422   HOWTO (R_ARM_GOTOFF32,    /* type */
00423          0,                     /* rightshift */
00424          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00425          32,                    /* bitsize */
00426          FALSE,                 /* pc_relative */
00427          0,                     /* bitpos */
00428          complain_overflow_bitfield,/* complain_on_overflow */
00429          bfd_elf_generic_reloc, /* special_function */
00430          "R_ARM_GOTOFF32",  /* name */
00431          TRUE,                     /* partial_inplace */
00432          0xffffffff,        /* src_mask */
00433          0xffffffff,        /* dst_mask */
00434          FALSE),                /* pcrel_offset */
00435 
00436   HOWTO (R_ARM_GOTPC,              /* type */
00437          0,                     /* rightshift */
00438          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00439          32,                    /* bitsize */
00440          TRUE,                     /* pc_relative */
00441          0,                     /* bitpos */
00442          complain_overflow_bitfield,/* complain_on_overflow */
00443          bfd_elf_generic_reloc, /* special_function */
00444          "R_ARM_GOTPC",            /* name */
00445          TRUE,                     /* partial_inplace */
00446          0xffffffff,        /* src_mask */
00447          0xffffffff,        /* dst_mask */
00448          TRUE),                    /* pcrel_offset */
00449 
00450   HOWTO (R_ARM_GOT32,              /* type */
00451          0,                     /* rightshift */
00452          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00453          32,                    /* bitsize */
00454          FALSE,                    /* pc_relative */
00455          0,                     /* bitpos */
00456          complain_overflow_bitfield,/* complain_on_overflow */
00457          bfd_elf_generic_reloc, /* special_function */
00458          "R_ARM_GOT32",            /* name */
00459          TRUE,                     /* partial_inplace */
00460          0xffffffff,        /* src_mask */
00461          0xffffffff,        /* dst_mask */
00462          FALSE),            /* pcrel_offset */
00463 
00464   HOWTO (R_ARM_PLT32,              /* type */
00465          2,                     /* rightshift */
00466          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00467          24,                    /* bitsize */
00468          TRUE,                     /* pc_relative */
00469          0,                     /* bitpos */
00470          complain_overflow_bitfield,/* complain_on_overflow */
00471          bfd_elf_generic_reloc, /* special_function */
00472          "R_ARM_PLT32",            /* name */
00473          FALSE,                    /* partial_inplace */
00474          0x00ffffff,        /* src_mask */
00475          0x00ffffff,        /* dst_mask */
00476          TRUE),                    /* pcrel_offset */
00477 
00478   HOWTO (R_ARM_CALL,        /* type */
00479         2,                  /* rightshift */
00480         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00481         24,                 /* bitsize */
00482         TRUE,               /* pc_relative */
00483         0,                  /* bitpos */
00484         complain_overflow_signed,/* complain_on_overflow */
00485         bfd_elf_generic_reloc,     /* special_function */
00486         "R_ARM_CALL",              /* name */
00487         FALSE,                     /* partial_inplace */
00488         0x00ffffff,         /* src_mask */
00489         0x00ffffff,         /* dst_mask */
00490         TRUE),                     /* pcrel_offset */
00491 
00492   HOWTO (R_ARM_JUMP24,             /* type */
00493         2,                  /* rightshift */
00494         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00495         24,                 /* bitsize */
00496         TRUE,               /* pc_relative */
00497         0,                  /* bitpos */
00498         complain_overflow_signed,/* complain_on_overflow */
00499         bfd_elf_generic_reloc,     /* special_function */
00500         "R_ARM_JUMP24",     /* name */
00501         FALSE,                     /* partial_inplace */
00502         0x00ffffff,         /* src_mask */
00503         0x00ffffff,         /* dst_mask */
00504         TRUE),                     /* pcrel_offset */
00505 
00506   HOWTO (R_ARM_THM_JUMP24,  /* type */
00507         1,                  /* rightshift */
00508         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00509         24,                 /* bitsize */
00510         TRUE,               /* pc_relative */
00511         0,                  /* bitpos */
00512         complain_overflow_signed,/* complain_on_overflow */
00513         bfd_elf_generic_reloc,     /* special_function */
00514         "R_ARM_THM_JUMP24", /* name */
00515         FALSE,                     /* partial_inplace */
00516         0x07ff2fff,         /* src_mask */
00517         0x07ff2fff,         /* dst_mask */
00518         TRUE),                     /* pcrel_offset */
00519 
00520   HOWTO (R_ARM_BASE_ABS,    /* type */
00521         0,                  /* rightshift */
00522         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00523         32,                 /* bitsize */
00524         FALSE,                     /* pc_relative */
00525         0,                  /* bitpos */
00526         complain_overflow_dont,/* complain_on_overflow */
00527         bfd_elf_generic_reloc,     /* special_function */
00528         "R_ARM_BASE_ABS",   /* name */
00529         FALSE,                     /* partial_inplace */
00530         0xffffffff,         /* src_mask */
00531         0xffffffff,         /* dst_mask */
00532         FALSE),             /* pcrel_offset */
00533 
00534   HOWTO (R_ARM_ALU_PCREL7_0,       /* type */
00535         0,                  /* rightshift */
00536         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00537         12,                 /* bitsize */
00538         TRUE,               /* pc_relative */
00539         0,                  /* bitpos */
00540         complain_overflow_dont,/* complain_on_overflow */
00541         bfd_elf_generic_reloc,     /* special_function */
00542         "R_ARM_ALU_PCREL_7_0",     /* name */
00543         FALSE,                     /* partial_inplace */
00544         0x00000fff,         /* src_mask */
00545         0x00000fff,         /* dst_mask */
00546         TRUE),                     /* pcrel_offset */
00547 
00548   HOWTO (R_ARM_ALU_PCREL15_8,      /* type */
00549         0,                  /* rightshift */
00550         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00551         12,                 /* bitsize */
00552         TRUE,               /* pc_relative */
00553         8,                  /* bitpos */
00554         complain_overflow_dont,/* complain_on_overflow */
00555         bfd_elf_generic_reloc,     /* special_function */
00556         "R_ARM_ALU_PCREL_15_8",/* name */
00557         FALSE,                     /* partial_inplace */
00558         0x00000fff,         /* src_mask */
00559         0x00000fff,         /* dst_mask */
00560         TRUE),                     /* pcrel_offset */
00561 
00562   HOWTO (R_ARM_ALU_PCREL23_15,     /* type */
00563         0,                  /* rightshift */
00564         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00565         12,                 /* bitsize */
00566         TRUE,               /* pc_relative */
00567         16,                 /* bitpos */
00568         complain_overflow_dont,/* complain_on_overflow */
00569         bfd_elf_generic_reloc,     /* special_function */
00570         "R_ARM_ALU_PCREL_23_15",/* name */
00571         FALSE,                     /* partial_inplace */
00572         0x00000fff,         /* src_mask */
00573         0x00000fff,         /* dst_mask */
00574         TRUE),                     /* pcrel_offset */
00575 
00576   HOWTO (R_ARM_LDR_SBREL_11_0,     /* type */
00577         0,                  /* rightshift */
00578         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00579         12,                 /* bitsize */
00580         FALSE,                     /* pc_relative */
00581         0,                  /* bitpos */
00582         complain_overflow_dont,/* complain_on_overflow */
00583         bfd_elf_generic_reloc,     /* special_function */
00584         "R_ARM_LDR_SBREL_11_0",/* name */
00585         FALSE,                     /* partial_inplace */
00586         0x00000fff,         /* src_mask */
00587         0x00000fff,         /* dst_mask */
00588         FALSE),             /* pcrel_offset */
00589 
00590   HOWTO (R_ARM_ALU_SBREL_19_12,    /* type */
00591         0,                  /* rightshift */
00592         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00593         8,                  /* bitsize */
00594         FALSE,                     /* pc_relative */
00595         12,                 /* bitpos */
00596         complain_overflow_dont,/* complain_on_overflow */
00597         bfd_elf_generic_reloc,     /* special_function */
00598         "R_ARM_ALU_SBREL_19_12",/* name */
00599         FALSE,                     /* partial_inplace */
00600         0x000ff000,         /* src_mask */
00601         0x000ff000,         /* dst_mask */
00602         FALSE),             /* pcrel_offset */
00603 
00604   HOWTO (R_ARM_ALU_SBREL_27_20,    /* type */
00605         0,                  /* rightshift */
00606         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00607         8,                  /* bitsize */
00608         FALSE,                     /* pc_relative */
00609         20,                 /* bitpos */
00610         complain_overflow_dont,/* complain_on_overflow */
00611         bfd_elf_generic_reloc,     /* special_function */
00612         "R_ARM_ALU_SBREL_27_20",/* name */
00613         FALSE,                     /* partial_inplace */
00614         0x0ff00000,         /* src_mask */
00615         0x0ff00000,         /* dst_mask */
00616         FALSE),             /* pcrel_offset */
00617 
00618   HOWTO (R_ARM_TARGET1,            /* type */
00619         0,                  /* rightshift */
00620         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00621         32,                 /* bitsize */
00622         FALSE,                     /* pc_relative */
00623         0,                  /* bitpos */
00624         complain_overflow_dont,/* complain_on_overflow */
00625         bfd_elf_generic_reloc,     /* special_function */
00626         "R_ARM_TARGET1",    /* name */
00627         FALSE,                     /* partial_inplace */
00628         0xffffffff,         /* src_mask */
00629         0xffffffff,         /* dst_mask */
00630         FALSE),             /* pcrel_offset */
00631 
00632   HOWTO (R_ARM_ROSEGREL32,  /* type */
00633         0,                  /* rightshift */
00634         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00635         32,                 /* bitsize */
00636         FALSE,                     /* pc_relative */
00637         0,                  /* bitpos */
00638         complain_overflow_dont,/* complain_on_overflow */
00639         bfd_elf_generic_reloc,     /* special_function */
00640         "R_ARM_ROSEGREL32", /* name */
00641         FALSE,                     /* partial_inplace */
00642         0xffffffff,         /* src_mask */
00643         0xffffffff,         /* dst_mask */
00644         FALSE),             /* pcrel_offset */
00645 
00646   HOWTO (R_ARM_V4BX,        /* type */
00647         0,                  /* rightshift */
00648         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00649         32,                 /* bitsize */
00650         FALSE,                     /* pc_relative */
00651         0,                  /* bitpos */
00652         complain_overflow_dont,/* complain_on_overflow */
00653         bfd_elf_generic_reloc,     /* special_function */
00654         "R_ARM_V4BX",              /* name */
00655         FALSE,                     /* partial_inplace */
00656         0xffffffff,         /* src_mask */
00657         0xffffffff,         /* dst_mask */
00658         FALSE),             /* pcrel_offset */
00659 
00660   HOWTO (R_ARM_TARGET2,            /* type */
00661         0,                  /* rightshift */
00662         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00663         32,                 /* bitsize */
00664         FALSE,                     /* pc_relative */
00665         0,                  /* bitpos */
00666         complain_overflow_signed,/* complain_on_overflow */
00667         bfd_elf_generic_reloc,     /* special_function */
00668         "R_ARM_TARGET2",    /* name */
00669         FALSE,                     /* partial_inplace */
00670         0xffffffff,         /* src_mask */
00671         0xffffffff,         /* dst_mask */
00672         TRUE),                     /* pcrel_offset */
00673 
00674   HOWTO (R_ARM_PREL31,             /* type */
00675         0,                  /* rightshift */
00676         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00677         31,                 /* bitsize */
00678         TRUE,               /* pc_relative */
00679         0,                  /* bitpos */
00680         complain_overflow_signed,/* complain_on_overflow */
00681         bfd_elf_generic_reloc,     /* special_function */
00682         "R_ARM_PREL31",     /* name */
00683         FALSE,                     /* partial_inplace */
00684         0x7fffffff,         /* src_mask */
00685         0x7fffffff,         /* dst_mask */
00686         TRUE),                     /* pcrel_offset */
00687 
00688   HOWTO (R_ARM_MOVW_ABS_NC, /* type */
00689         0,                  /* rightshift */
00690         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00691         16,                 /* bitsize */
00692         FALSE,                     /* pc_relative */
00693         0,                  /* bitpos */
00694         complain_overflow_dont,/* complain_on_overflow */
00695         bfd_elf_generic_reloc,     /* special_function */
00696         "R_ARM_MOVW_ABS_NC",       /* name */
00697         FALSE,                     /* partial_inplace */
00698         0x0000ffff,         /* src_mask */
00699         0x0000ffff,         /* dst_mask */
00700         FALSE),             /* pcrel_offset */
00701 
00702   HOWTO (R_ARM_MOVT_ABS,    /* type */
00703         0,                  /* rightshift */
00704         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00705         16,                 /* bitsize */
00706         FALSE,                     /* pc_relative */
00707         0,                  /* bitpos */
00708         complain_overflow_bitfield,/* complain_on_overflow */
00709         bfd_elf_generic_reloc,     /* special_function */
00710         "R_ARM_MOVT_ABS",   /* name */
00711         FALSE,                     /* partial_inplace */
00712         0x0000ffff,         /* src_mask */
00713         0x0000ffff,         /* dst_mask */
00714         FALSE),             /* pcrel_offset */
00715 
00716   HOWTO (R_ARM_MOVW_PREL_NC,       /* type */
00717         0,                  /* rightshift */
00718         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00719         16,                 /* bitsize */
00720         TRUE,               /* pc_relative */
00721         0,                  /* bitpos */
00722         complain_overflow_dont,/* complain_on_overflow */
00723         bfd_elf_generic_reloc,     /* special_function */
00724         "R_ARM_MOVW_PREL_NC",      /* name */
00725         FALSE,                     /* partial_inplace */
00726         0x0000ffff,         /* src_mask */
00727         0x0000ffff,         /* dst_mask */
00728         TRUE),                     /* pcrel_offset */
00729 
00730   HOWTO (R_ARM_MOVT_PREL,   /* type */
00731         0,                  /* rightshift */
00732         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00733         16,                 /* bitsize */
00734         TRUE,               /* pc_relative */
00735         0,                  /* bitpos */
00736         complain_overflow_bitfield,/* complain_on_overflow */
00737         bfd_elf_generic_reloc,     /* special_function */
00738         "R_ARM_MOVT_PREL",  /* name */
00739         FALSE,                     /* partial_inplace */
00740         0x0000ffff,         /* src_mask */
00741         0x0000ffff,         /* dst_mask */
00742         TRUE),                     /* pcrel_offset */
00743 
00744   HOWTO (R_ARM_THM_MOVW_ABS_NC,    /* type */
00745         0,                  /* rightshift */
00746         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00747         16,                 /* bitsize */
00748         FALSE,                     /* pc_relative */
00749         0,                  /* bitpos */
00750         complain_overflow_dont,/* complain_on_overflow */
00751         bfd_elf_generic_reloc,     /* special_function */
00752         "R_ARM_THM_MOVW_ABS_NC",/* name */
00753         FALSE,                     /* partial_inplace */
00754         0x040f70ff,         /* src_mask */
00755         0x040f70ff,         /* dst_mask */
00756         FALSE),             /* pcrel_offset */
00757 
00758   HOWTO (R_ARM_THM_MOVT_ABS,       /* type */
00759         0,                  /* rightshift */
00760         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00761         16,                 /* bitsize */
00762         FALSE,                     /* pc_relative */
00763         0,                  /* bitpos */
00764         complain_overflow_bitfield,/* complain_on_overflow */
00765         bfd_elf_generic_reloc,     /* special_function */
00766         "R_ARM_THM_MOVT_ABS",      /* name */
00767         FALSE,                     /* partial_inplace */
00768         0x040f70ff,         /* src_mask */
00769         0x040f70ff,         /* dst_mask */
00770         FALSE),             /* pcrel_offset */
00771 
00772   HOWTO (R_ARM_THM_MOVW_PREL_NC,/* type */
00773         0,                  /* rightshift */
00774         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00775         16,                 /* bitsize */
00776         TRUE,               /* pc_relative */
00777         0,                  /* bitpos */
00778         complain_overflow_dont,/* complain_on_overflow */
00779         bfd_elf_generic_reloc,     /* special_function */
00780         "R_ARM_THM_MOVW_PREL_NC",/* name */
00781         FALSE,                     /* partial_inplace */
00782         0x040f70ff,         /* src_mask */
00783         0x040f70ff,         /* dst_mask */
00784         TRUE),                     /* pcrel_offset */
00785 
00786   HOWTO (R_ARM_THM_MOVT_PREL,      /* type */
00787         0,                  /* rightshift */
00788         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00789         16,                 /* bitsize */
00790         TRUE,               /* pc_relative */
00791         0,                  /* bitpos */
00792         complain_overflow_bitfield,/* complain_on_overflow */
00793         bfd_elf_generic_reloc,     /* special_function */
00794         "R_ARM_THM_MOVT_PREL",     /* name */
00795         FALSE,                     /* partial_inplace */
00796         0x040f70ff,         /* src_mask */
00797         0x040f70ff,         /* dst_mask */
00798         TRUE),                     /* pcrel_offset */
00799 
00800   HOWTO (R_ARM_THM_JUMP19,  /* type */
00801         1,                  /* rightshift */
00802         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00803         19,                 /* bitsize */
00804         TRUE,               /* pc_relative */
00805         0,                  /* bitpos */
00806         complain_overflow_signed,/* complain_on_overflow */
00807         bfd_elf_generic_reloc, /* special_function */
00808         "R_ARM_THM_JUMP19", /* name */
00809         FALSE,                     /* partial_inplace */
00810         0x043f2fff,         /* src_mask */
00811         0x043f2fff,         /* dst_mask */
00812         TRUE),                     /* pcrel_offset */
00813 
00814   HOWTO (R_ARM_THM_JUMP6,   /* type */
00815         1,                  /* rightshift */
00816         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00817         6,                  /* bitsize */
00818         TRUE,               /* pc_relative */
00819         0,                  /* bitpos */
00820         complain_overflow_unsigned,/* complain_on_overflow */
00821         bfd_elf_generic_reloc,     /* special_function */
00822         "R_ARM_THM_JUMP6",  /* name */
00823         FALSE,                     /* partial_inplace */
00824         0x02f8,             /* src_mask */
00825         0x02f8,             /* dst_mask */
00826         TRUE),                     /* pcrel_offset */
00827 
00828   /* These are declared as 13-bit signed relocations because we can
00829      address -4095 .. 4095(base) by altering ADDW to SUBW or vice
00830      versa.  */
00831   HOWTO (R_ARM_THM_ALU_PREL_11_0,/* type */
00832         0,                  /* rightshift */
00833         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00834         13,                 /* bitsize */
00835         TRUE,               /* pc_relative */
00836         0,                  /* bitpos */
00837         complain_overflow_dont,/* complain_on_overflow */
00838         bfd_elf_generic_reloc,     /* special_function */
00839         "R_ARM_THM_ALU_PREL_11_0",/* name */
00840         FALSE,                     /* partial_inplace */
00841         0xffffffff,         /* src_mask */
00842         0xffffffff,         /* dst_mask */
00843         TRUE),                     /* pcrel_offset */
00844 
00845   HOWTO (R_ARM_THM_PC12,    /* type */
00846         0,                  /* rightshift */
00847         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00848         13,                 /* bitsize */
00849         TRUE,               /* pc_relative */
00850         0,                  /* bitpos */
00851         complain_overflow_dont,/* complain_on_overflow */
00852         bfd_elf_generic_reloc,     /* special_function */
00853         "R_ARM_THM_PC12",   /* name */
00854         FALSE,                     /* partial_inplace */
00855         0xffffffff,         /* src_mask */
00856         0xffffffff,         /* dst_mask */
00857         TRUE),                     /* pcrel_offset */
00858 
00859   HOWTO (R_ARM_ABS32_NOI,   /* type */
00860         0,                  /* rightshift */
00861         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00862         32,                 /* bitsize */
00863         FALSE,                     /* pc_relative */
00864         0,                  /* bitpos */
00865         complain_overflow_dont,/* complain_on_overflow */
00866         bfd_elf_generic_reloc,     /* special_function */
00867         "R_ARM_ABS32_NOI",  /* name */
00868         FALSE,                     /* partial_inplace */
00869         0xffffffff,         /* src_mask */
00870         0xffffffff,         /* dst_mask */
00871         FALSE),             /* pcrel_offset */
00872 
00873   HOWTO (R_ARM_REL32_NOI,   /* type */
00874         0,                  /* rightshift */
00875         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00876         32,                 /* bitsize */
00877         TRUE,               /* pc_relative */
00878         0,                  /* bitpos */
00879         complain_overflow_dont,/* complain_on_overflow */
00880         bfd_elf_generic_reloc,     /* special_function */
00881         "R_ARM_REL32_NOI",  /* name */
00882         FALSE,                     /* partial_inplace */
00883         0xffffffff,         /* src_mask */
00884         0xffffffff,         /* dst_mask */
00885         FALSE),             /* pcrel_offset */
00886 
00887   /* Group relocations.  */
00888 
00889   HOWTO (R_ARM_ALU_PC_G0_NC,       /* type */
00890         0,                  /* rightshift */
00891         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00892         32,                 /* bitsize */
00893         TRUE,               /* pc_relative */
00894         0,                  /* bitpos */
00895         complain_overflow_dont,/* complain_on_overflow */
00896         bfd_elf_generic_reloc,     /* special_function */
00897         "R_ARM_ALU_PC_G0_NC",      /* name */
00898         FALSE,                     /* partial_inplace */
00899         0xffffffff,         /* src_mask */
00900         0xffffffff,         /* dst_mask */
00901         TRUE),                     /* pcrel_offset */
00902 
00903   HOWTO (R_ARM_ALU_PC_G0,          /* type */
00904         0,                  /* rightshift */
00905         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00906         32,                 /* bitsize */
00907         TRUE,               /* pc_relative */
00908         0,                  /* bitpos */
00909         complain_overflow_dont,/* complain_on_overflow */
00910         bfd_elf_generic_reloc,     /* special_function */
00911         "R_ARM_ALU_PC_G0",         /* name */
00912         FALSE,                     /* partial_inplace */
00913         0xffffffff,         /* src_mask */
00914         0xffffffff,         /* dst_mask */
00915         TRUE),                     /* pcrel_offset */
00916 
00917   HOWTO (R_ARM_ALU_PC_G1_NC,       /* type */
00918         0,                  /* rightshift */
00919         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00920         32,                 /* bitsize */
00921         TRUE,               /* pc_relative */
00922         0,                  /* bitpos */
00923         complain_overflow_dont,/* complain_on_overflow */
00924         bfd_elf_generic_reloc,     /* special_function */
00925         "R_ARM_ALU_PC_G1_NC",      /* name */
00926         FALSE,                     /* partial_inplace */
00927         0xffffffff,         /* src_mask */
00928         0xffffffff,         /* dst_mask */
00929         TRUE),                     /* pcrel_offset */
00930 
00931   HOWTO (R_ARM_ALU_PC_G1,          /* type */
00932         0,                  /* rightshift */
00933         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00934         32,                 /* bitsize */
00935         TRUE,               /* pc_relative */
00936         0,                  /* bitpos */
00937         complain_overflow_dont,/* complain_on_overflow */
00938         bfd_elf_generic_reloc,     /* special_function */
00939         "R_ARM_ALU_PC_G1",         /* name */
00940         FALSE,                     /* partial_inplace */
00941         0xffffffff,         /* src_mask */
00942         0xffffffff,         /* dst_mask */
00943         TRUE),                     /* pcrel_offset */
00944 
00945   HOWTO (R_ARM_ALU_PC_G2,          /* type */
00946         0,                  /* rightshift */
00947         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00948         32,                 /* bitsize */
00949         TRUE,               /* pc_relative */
00950         0,                  /* bitpos */
00951         complain_overflow_dont,/* complain_on_overflow */
00952         bfd_elf_generic_reloc,     /* special_function */
00953         "R_ARM_ALU_PC_G2",         /* name */
00954         FALSE,                     /* partial_inplace */
00955         0xffffffff,         /* src_mask */
00956         0xffffffff,         /* dst_mask */
00957         TRUE),                     /* pcrel_offset */
00958 
00959   HOWTO (R_ARM_LDR_PC_G1,          /* type */
00960         0,                  /* rightshift */
00961         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00962         32,                 /* bitsize */
00963         TRUE,               /* pc_relative */
00964         0,                  /* bitpos */
00965         complain_overflow_dont,/* complain_on_overflow */
00966         bfd_elf_generic_reloc,     /* special_function */
00967         "R_ARM_LDR_PC_G1",         /* name */
00968         FALSE,                     /* partial_inplace */
00969         0xffffffff,         /* src_mask */
00970         0xffffffff,         /* dst_mask */
00971         TRUE),                     /* pcrel_offset */
00972 
00973   HOWTO (R_ARM_LDR_PC_G2,          /* type */
00974         0,                  /* rightshift */
00975         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00976         32,                 /* bitsize */
00977         TRUE,               /* pc_relative */
00978         0,                  /* bitpos */
00979         complain_overflow_dont,/* complain_on_overflow */
00980         bfd_elf_generic_reloc,     /* special_function */
00981         "R_ARM_LDR_PC_G2",         /* name */
00982         FALSE,                     /* partial_inplace */
00983         0xffffffff,         /* src_mask */
00984         0xffffffff,         /* dst_mask */
00985         TRUE),                     /* pcrel_offset */
00986 
00987   HOWTO (R_ARM_LDRS_PC_G0,         /* type */
00988         0,                  /* rightshift */
00989         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00990         32,                 /* bitsize */
00991         TRUE,               /* pc_relative */
00992         0,                  /* bitpos */
00993         complain_overflow_dont,/* complain_on_overflow */
00994         bfd_elf_generic_reloc,     /* special_function */
00995         "R_ARM_LDRS_PC_G0",        /* name */
00996         FALSE,                     /* partial_inplace */
00997         0xffffffff,         /* src_mask */
00998         0xffffffff,         /* dst_mask */
00999         TRUE),                     /* pcrel_offset */
01000 
01001   HOWTO (R_ARM_LDRS_PC_G1,         /* type */
01002         0,                  /* rightshift */
01003         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01004         32,                 /* bitsize */
01005         TRUE,               /* pc_relative */
01006         0,                  /* bitpos */
01007         complain_overflow_dont,/* complain_on_overflow */
01008         bfd_elf_generic_reloc,     /* special_function */
01009         "R_ARM_LDRS_PC_G1",        /* name */
01010         FALSE,                     /* partial_inplace */
01011         0xffffffff,         /* src_mask */
01012         0xffffffff,         /* dst_mask */
01013         TRUE),                     /* pcrel_offset */
01014 
01015   HOWTO (R_ARM_LDRS_PC_G2,         /* type */
01016         0,                  /* rightshift */
01017         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01018         32,                 /* bitsize */
01019         TRUE,               /* pc_relative */
01020         0,                  /* bitpos */
01021         complain_overflow_dont,/* complain_on_overflow */
01022         bfd_elf_generic_reloc,     /* special_function */
01023         "R_ARM_LDRS_PC_G2",        /* name */
01024         FALSE,                     /* partial_inplace */
01025         0xffffffff,         /* src_mask */
01026         0xffffffff,         /* dst_mask */
01027         TRUE),                     /* pcrel_offset */
01028 
01029   HOWTO (R_ARM_LDC_PC_G0,          /* type */
01030         0,                  /* rightshift */
01031         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01032         32,                 /* bitsize */
01033         TRUE,               /* pc_relative */
01034         0,                  /* bitpos */
01035         complain_overflow_dont,/* complain_on_overflow */
01036         bfd_elf_generic_reloc,     /* special_function */
01037         "R_ARM_LDC_PC_G0",         /* name */
01038         FALSE,                     /* partial_inplace */
01039         0xffffffff,         /* src_mask */
01040         0xffffffff,         /* dst_mask */
01041         TRUE),                     /* pcrel_offset */
01042 
01043   HOWTO (R_ARM_LDC_PC_G1,          /* type */
01044         0,                  /* rightshift */
01045         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01046         32,                 /* bitsize */
01047         TRUE,               /* pc_relative */
01048         0,                  /* bitpos */
01049         complain_overflow_dont,/* complain_on_overflow */
01050         bfd_elf_generic_reloc,     /* special_function */
01051         "R_ARM_LDC_PC_G1",         /* name */
01052         FALSE,                     /* partial_inplace */
01053         0xffffffff,         /* src_mask */
01054         0xffffffff,         /* dst_mask */
01055         TRUE),                     /* pcrel_offset */
01056 
01057   HOWTO (R_ARM_LDC_PC_G2,          /* type */
01058         0,                  /* rightshift */
01059         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01060         32,                 /* bitsize */
01061         TRUE,               /* pc_relative */
01062         0,                  /* bitpos */
01063         complain_overflow_dont,/* complain_on_overflow */
01064         bfd_elf_generic_reloc,     /* special_function */
01065         "R_ARM_LDC_PC_G2",         /* name */
01066         FALSE,                     /* partial_inplace */
01067         0xffffffff,         /* src_mask */
01068         0xffffffff,         /* dst_mask */
01069         TRUE),                     /* pcrel_offset */
01070 
01071   HOWTO (R_ARM_ALU_SB_G0_NC,       /* type */
01072         0,                  /* rightshift */
01073         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01074         32,                 /* bitsize */
01075         TRUE,               /* pc_relative */
01076         0,                  /* bitpos */
01077         complain_overflow_dont,/* complain_on_overflow */
01078         bfd_elf_generic_reloc,     /* special_function */
01079         "R_ARM_ALU_SB_G0_NC",      /* name */
01080         FALSE,                     /* partial_inplace */
01081         0xffffffff,         /* src_mask */
01082         0xffffffff,         /* dst_mask */
01083         TRUE),                     /* pcrel_offset */
01084 
01085   HOWTO (R_ARM_ALU_SB_G0,          /* type */
01086         0,                  /* rightshift */
01087         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01088         32,                 /* bitsize */
01089         TRUE,               /* pc_relative */
01090         0,                  /* bitpos */
01091         complain_overflow_dont,/* complain_on_overflow */
01092         bfd_elf_generic_reloc,     /* special_function */
01093         "R_ARM_ALU_SB_G0",  /* name */
01094         FALSE,                     /* partial_inplace */
01095         0xffffffff,         /* src_mask */
01096         0xffffffff,         /* dst_mask */
01097         TRUE),                     /* pcrel_offset */
01098 
01099   HOWTO (R_ARM_ALU_SB_G1_NC,       /* type */
01100         0,                  /* rightshift */
01101         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01102         32,                 /* bitsize */
01103         TRUE,               /* pc_relative */
01104         0,                  /* bitpos */
01105         complain_overflow_dont,/* complain_on_overflow */
01106         bfd_elf_generic_reloc,     /* special_function */
01107         "R_ARM_ALU_SB_G1_NC",      /* name */
01108         FALSE,                     /* partial_inplace */
01109         0xffffffff,         /* src_mask */
01110         0xffffffff,         /* dst_mask */
01111         TRUE),                     /* pcrel_offset */
01112 
01113   HOWTO (R_ARM_ALU_SB_G1,          /* type */
01114         0,                  /* rightshift */
01115         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01116         32,                 /* bitsize */
01117         TRUE,               /* pc_relative */
01118         0,                  /* bitpos */
01119         complain_overflow_dont,/* complain_on_overflow */
01120         bfd_elf_generic_reloc,     /* special_function */
01121         "R_ARM_ALU_SB_G1",  /* name */
01122         FALSE,                     /* partial_inplace */
01123         0xffffffff,         /* src_mask */
01124         0xffffffff,         /* dst_mask */
01125         TRUE),                     /* pcrel_offset */
01126 
01127   HOWTO (R_ARM_ALU_SB_G2,          /* type */
01128         0,                  /* rightshift */
01129         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01130         32,                 /* bitsize */
01131         TRUE,               /* pc_relative */
01132         0,                  /* bitpos */
01133         complain_overflow_dont,/* complain_on_overflow */
01134         bfd_elf_generic_reloc,     /* special_function */
01135         "R_ARM_ALU_SB_G2",  /* name */
01136         FALSE,                     /* partial_inplace */
01137         0xffffffff,         /* src_mask */
01138         0xffffffff,         /* dst_mask */
01139         TRUE),                     /* pcrel_offset */
01140 
01141   HOWTO (R_ARM_LDR_SB_G0,          /* type */
01142         0,                  /* rightshift */
01143         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01144         32,                 /* bitsize */
01145         TRUE,               /* pc_relative */
01146         0,                  /* bitpos */
01147         complain_overflow_dont,/* complain_on_overflow */
01148         bfd_elf_generic_reloc,     /* special_function */
01149         "R_ARM_LDR_SB_G0",  /* name */
01150         FALSE,                     /* partial_inplace */
01151         0xffffffff,         /* src_mask */
01152         0xffffffff,         /* dst_mask */
01153         TRUE),                     /* pcrel_offset */
01154 
01155   HOWTO (R_ARM_LDR_SB_G1,          /* type */
01156         0,                  /* rightshift */
01157         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01158         32,                 /* bitsize */
01159         TRUE,               /* pc_relative */
01160         0,                  /* bitpos */
01161         complain_overflow_dont,/* complain_on_overflow */
01162         bfd_elf_generic_reloc,     /* special_function */
01163         "R_ARM_LDR_SB_G1",  /* name */
01164         FALSE,                     /* partial_inplace */
01165         0xffffffff,         /* src_mask */
01166         0xffffffff,         /* dst_mask */
01167         TRUE),                     /* pcrel_offset */
01168 
01169   HOWTO (R_ARM_LDR_SB_G2,          /* type */
01170         0,                  /* rightshift */
01171         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01172         32,                 /* bitsize */
01173         TRUE,               /* pc_relative */
01174         0,                  /* bitpos */
01175         complain_overflow_dont,/* complain_on_overflow */
01176         bfd_elf_generic_reloc,     /* special_function */
01177         "R_ARM_LDR_SB_G2",  /* name */
01178         FALSE,                     /* partial_inplace */
01179         0xffffffff,         /* src_mask */
01180         0xffffffff,         /* dst_mask */
01181         TRUE),                     /* pcrel_offset */
01182 
01183   HOWTO (R_ARM_LDRS_SB_G0,         /* type */
01184         0,                  /* rightshift */
01185         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01186         32,                 /* bitsize */
01187         TRUE,               /* pc_relative */
01188         0,                  /* bitpos */
01189         complain_overflow_dont,/* complain_on_overflow */
01190         bfd_elf_generic_reloc,     /* special_function */
01191         "R_ARM_LDRS_SB_G0",        /* name */
01192         FALSE,                     /* partial_inplace */
01193         0xffffffff,         /* src_mask */
01194         0xffffffff,         /* dst_mask */
01195         TRUE),                     /* pcrel_offset */
01196 
01197   HOWTO (R_ARM_LDRS_SB_G1,         /* type */
01198         0,                  /* rightshift */
01199         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01200         32,                 /* bitsize */
01201         TRUE,               /* pc_relative */
01202         0,                  /* bitpos */
01203         complain_overflow_dont,/* complain_on_overflow */
01204         bfd_elf_generic_reloc,     /* special_function */
01205         "R_ARM_LDRS_SB_G1",        /* name */
01206         FALSE,                     /* partial_inplace */
01207         0xffffffff,         /* src_mask */
01208         0xffffffff,         /* dst_mask */
01209         TRUE),                     /* pcrel_offset */
01210 
01211   HOWTO (R_ARM_LDRS_SB_G2,         /* type */
01212         0,                  /* rightshift */
01213         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01214         32,                 /* bitsize */
01215         TRUE,               /* pc_relative */
01216         0,                  /* bitpos */
01217         complain_overflow_dont,/* complain_on_overflow */
01218         bfd_elf_generic_reloc,     /* special_function */
01219         "R_ARM_LDRS_SB_G2",        /* name */
01220         FALSE,                     /* partial_inplace */
01221         0xffffffff,         /* src_mask */
01222         0xffffffff,         /* dst_mask */
01223         TRUE),                     /* pcrel_offset */
01224 
01225   HOWTO (R_ARM_LDC_SB_G0,          /* type */
01226         0,                  /* rightshift */
01227         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01228         32,                 /* bitsize */
01229         TRUE,               /* pc_relative */
01230         0,                  /* bitpos */
01231         complain_overflow_dont,/* complain_on_overflow */
01232         bfd_elf_generic_reloc,     /* special_function */
01233         "R_ARM_LDC_SB_G0",  /* name */
01234         FALSE,                     /* partial_inplace */
01235         0xffffffff,         /* src_mask */
01236         0xffffffff,         /* dst_mask */
01237         TRUE),                     /* pcrel_offset */
01238 
01239   HOWTO (R_ARM_LDC_SB_G1,          /* type */
01240         0,                  /* rightshift */
01241         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01242         32,                 /* bitsize */
01243         TRUE,               /* pc_relative */
01244         0,                  /* bitpos */
01245         complain_overflow_dont,/* complain_on_overflow */
01246         bfd_elf_generic_reloc,     /* special_function */
01247         "R_ARM_LDC_SB_G1",  /* name */
01248         FALSE,                     /* partial_inplace */
01249         0xffffffff,         /* src_mask */
01250         0xffffffff,         /* dst_mask */
01251         TRUE),                     /* pcrel_offset */
01252 
01253   HOWTO (R_ARM_LDC_SB_G2,          /* type */
01254         0,                  /* rightshift */
01255         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01256         32,                 /* bitsize */
01257         TRUE,               /* pc_relative */
01258         0,                  /* bitpos */
01259         complain_overflow_dont,/* complain_on_overflow */
01260         bfd_elf_generic_reloc,     /* special_function */
01261         "R_ARM_LDC_SB_G2",  /* name */
01262         FALSE,                     /* partial_inplace */
01263         0xffffffff,         /* src_mask */
01264         0xffffffff,         /* dst_mask */
01265         TRUE),                     /* pcrel_offset */
01266 
01267   /* End of group relocations.  */
01268 
01269   HOWTO (R_ARM_MOVW_BREL_NC,       /* type */
01270         0,                  /* rightshift */
01271         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01272         16,                 /* bitsize */
01273         FALSE,                     /* pc_relative */
01274         0,                  /* bitpos */
01275         complain_overflow_dont,/* complain_on_overflow */
01276         bfd_elf_generic_reloc,     /* special_function */
01277         "R_ARM_MOVW_BREL_NC",      /* name */
01278         FALSE,                     /* partial_inplace */
01279         0x0000ffff,         /* src_mask */
01280         0x0000ffff,         /* dst_mask */
01281         FALSE),             /* pcrel_offset */
01282 
01283   HOWTO (R_ARM_MOVT_BREL,   /* type */
01284         0,                  /* rightshift */
01285         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01286         16,                 /* bitsize */
01287         FALSE,                     /* pc_relative */
01288         0,                  /* bitpos */
01289         complain_overflow_bitfield,/* complain_on_overflow */
01290         bfd_elf_generic_reloc,     /* special_function */
01291         "R_ARM_MOVT_BREL",  /* name */
01292         FALSE,                     /* partial_inplace */
01293         0x0000ffff,         /* src_mask */
01294         0x0000ffff,         /* dst_mask */
01295         FALSE),             /* pcrel_offset */
01296 
01297   HOWTO (R_ARM_MOVW_BREL,   /* type */
01298         0,                  /* rightshift */
01299         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01300         16,                 /* bitsize */
01301         FALSE,                     /* pc_relative */
01302         0,                  /* bitpos */
01303         complain_overflow_dont,/* complain_on_overflow */
01304         bfd_elf_generic_reloc,     /* special_function */
01305         "R_ARM_MOVW_BREL",  /* name */
01306         FALSE,                     /* partial_inplace */
01307         0x0000ffff,         /* src_mask */
01308         0x0000ffff,         /* dst_mask */
01309         FALSE),             /* pcrel_offset */
01310 
01311   HOWTO (R_ARM_THM_MOVW_BREL_NC,/* type */
01312         0,                  /* rightshift */
01313         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01314         16,                 /* bitsize */
01315         FALSE,                     /* pc_relative */
01316         0,                  /* bitpos */
01317         complain_overflow_dont,/* complain_on_overflow */
01318         bfd_elf_generic_reloc,     /* special_function */
01319         "R_ARM_THM_MOVW_BREL_NC",/* name */
01320         FALSE,                     /* partial_inplace */
01321         0x040f70ff,         /* src_mask */
01322         0x040f70ff,         /* dst_mask */
01323         FALSE),             /* pcrel_offset */
01324 
01325   HOWTO (R_ARM_THM_MOVT_BREL,      /* type */
01326         0,                  /* rightshift */
01327         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01328         16,                 /* bitsize */
01329         FALSE,                     /* pc_relative */
01330         0,                  /* bitpos */
01331         complain_overflow_bitfield,/* complain_on_overflow */
01332         bfd_elf_generic_reloc,     /* special_function */
01333         "R_ARM_THM_MOVT_BREL",     /* name */
01334         FALSE,                     /* partial_inplace */
01335         0x040f70ff,         /* src_mask */
01336         0x040f70ff,         /* dst_mask */
01337         FALSE),             /* pcrel_offset */
01338 
01339   HOWTO (R_ARM_THM_MOVW_BREL,      /* type */
01340         0,                  /* rightshift */
01341         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01342         16,                 /* bitsize */
01343         FALSE,                     /* pc_relative */
01344         0,                  /* bitpos */
01345         complain_overflow_dont,/* complain_on_overflow */
01346         bfd_elf_generic_reloc,     /* special_function */
01347         "R_ARM_THM_MOVW_BREL",     /* name */
01348         FALSE,                     /* partial_inplace */
01349         0x040f70ff,         /* src_mask */
01350         0x040f70ff,         /* dst_mask */
01351         FALSE),             /* pcrel_offset */
01352 
01353   EMPTY_HOWTO (90),   /* unallocated */
01354   EMPTY_HOWTO (91),
01355   EMPTY_HOWTO (92),
01356   EMPTY_HOWTO (93),
01357 
01358   HOWTO (R_ARM_PLT32_ABS,   /* type */
01359         0,                  /* rightshift */
01360         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01361         32,                 /* bitsize */
01362         FALSE,                     /* pc_relative */
01363         0,                  /* bitpos */
01364         complain_overflow_dont,/* complain_on_overflow */
01365         bfd_elf_generic_reloc,     /* special_function */
01366         "R_ARM_PLT32_ABS",  /* name */
01367         FALSE,                     /* partial_inplace */
01368         0xffffffff,         /* src_mask */
01369         0xffffffff,         /* dst_mask */
01370         FALSE),             /* pcrel_offset */
01371 
01372   HOWTO (R_ARM_GOT_ABS,            /* type */
01373         0,                  /* rightshift */
01374         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01375         32,                 /* bitsize */
01376         FALSE,                     /* pc_relative */
01377         0,                  /* bitpos */
01378         complain_overflow_dont,/* complain_on_overflow */
01379         bfd_elf_generic_reloc,     /* special_function */
01380         "R_ARM_GOT_ABS",    /* name */
01381         FALSE,                     /* partial_inplace */
01382         0xffffffff,         /* src_mask */
01383         0xffffffff,         /* dst_mask */
01384         FALSE),                    /* pcrel_offset */
01385 
01386   HOWTO (R_ARM_GOT_PREL,    /* type */
01387         0,                  /* rightshift */
01388         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01389         32,                 /* bitsize */
01390         TRUE,               /* pc_relative */
01391         0,                  /* bitpos */
01392         complain_overflow_dont,    /* complain_on_overflow */
01393         bfd_elf_generic_reloc,     /* special_function */
01394         "R_ARM_GOT_PREL",   /* name */
01395         FALSE,                     /* partial_inplace */
01396         0xffffffff,         /* src_mask */
01397         0xffffffff,         /* dst_mask */
01398         TRUE),                     /* pcrel_offset */
01399 
01400   HOWTO (R_ARM_GOT_BREL12,  /* type */
01401         0,                  /* rightshift */
01402         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01403         12,                 /* bitsize */
01404         FALSE,                     /* pc_relative */
01405         0,                  /* bitpos */
01406         complain_overflow_bitfield,/* complain_on_overflow */
01407         bfd_elf_generic_reloc,     /* special_function */
01408         "R_ARM_GOT_BREL12", /* name */
01409         FALSE,                     /* partial_inplace */
01410         0x00000fff,         /* src_mask */
01411         0x00000fff,         /* dst_mask */
01412         FALSE),             /* pcrel_offset */
01413 
01414   HOWTO (R_ARM_GOTOFF12,    /* type */
01415         0,                  /* rightshift */
01416         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01417         12,                 /* bitsize */
01418         FALSE,                     /* pc_relative */
01419         0,                  /* bitpos */
01420         complain_overflow_bitfield,/* complain_on_overflow */
01421         bfd_elf_generic_reloc,     /* special_function */
01422         "R_ARM_GOTOFF12",   /* name */
01423         FALSE,                     /* partial_inplace */
01424         0x00000fff,         /* src_mask */
01425         0x00000fff,         /* dst_mask */
01426         FALSE),             /* pcrel_offset */
01427 
01428   EMPTY_HOWTO (R_ARM_GOTRELAX),  /* reserved for future GOT-load optimizations */
01429 
01430   /* GNU extension to record C++ vtable member usage */
01431   HOWTO (R_ARM_GNU_VTENTRY,     /* type */
01432          0,                     /* rightshift */
01433          2,                     /* size (0 = byte, 1 = short, 2 = long) */
01434          0,                     /* bitsize */
01435          FALSE,                 /* pc_relative */
01436          0,                     /* bitpos */
01437          complain_overflow_dont, /* complain_on_overflow */
01438          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
01439          "R_ARM_GNU_VTENTRY",   /* name */
01440          FALSE,                 /* partial_inplace */
01441          0,                     /* src_mask */
01442          0,                     /* dst_mask */
01443          FALSE),                /* pcrel_offset */
01444 
01445   /* GNU extension to record C++ vtable hierarchy */
01446   HOWTO (R_ARM_GNU_VTINHERIT, /* type */
01447          0,                     /* rightshift */
01448          2,                     /* size (0 = byte, 1 = short, 2 = long) */
01449          0,                     /* bitsize */
01450          FALSE,                 /* pc_relative */
01451          0,                     /* bitpos */
01452          complain_overflow_dont, /* complain_on_overflow */
01453          NULL,                  /* special_function */
01454          "R_ARM_GNU_VTINHERIT", /* name */
01455          FALSE,                 /* partial_inplace */
01456          0,                     /* src_mask */
01457          0,                     /* dst_mask */
01458          FALSE),                /* pcrel_offset */
01459 
01460   HOWTO (R_ARM_THM_JUMP11,  /* type */
01461         1,                  /* rightshift */
01462         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01463         11,                 /* bitsize */
01464         TRUE,               /* pc_relative */
01465         0,                  /* bitpos */
01466         complain_overflow_signed,  /* complain_on_overflow */
01467         bfd_elf_generic_reloc,     /* special_function */
01468         "R_ARM_THM_JUMP11", /* name */
01469         FALSE,                     /* partial_inplace */
01470         0x000007ff,         /* src_mask */
01471         0x000007ff,         /* dst_mask */
01472         TRUE),                     /* pcrel_offset */
01473 
01474   HOWTO (R_ARM_THM_JUMP8,   /* type */
01475         1,                  /* rightshift */
01476         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01477         8,                  /* bitsize */
01478         TRUE,               /* pc_relative */
01479         0,                  /* bitpos */
01480         complain_overflow_signed,  /* complain_on_overflow */
01481         bfd_elf_generic_reloc,     /* special_function */
01482         "R_ARM_THM_JUMP8",  /* name */
01483         FALSE,                     /* partial_inplace */
01484         0x000000ff,         /* src_mask */
01485         0x000000ff,         /* dst_mask */
01486         TRUE),                     /* pcrel_offset */
01487 
01488   /* TLS relocations */
01489   HOWTO (R_ARM_TLS_GD32,    /* type */
01490          0,                     /* rightshift */
01491          2,                     /* size (0 = byte, 1 = short, 2 = long) */
01492          32,                    /* bitsize */
01493          FALSE,                 /* pc_relative */
01494          0,                     /* bitpos */
01495          complain_overflow_bitfield,/* complain_on_overflow */
01496          NULL,                     /* special_function */
01497          "R_ARM_TLS_GD32",  /* name */
01498          TRUE,                     /* partial_inplace */
01499          0xffffffff,        /* src_mask */
01500          0xffffffff,        /* dst_mask */
01501          FALSE),                /* pcrel_offset */
01502 
01503   HOWTO (R_ARM_TLS_LDM32,   /* type */
01504          0,                     /* rightshift */
01505          2,                     /* size (0 = byte, 1 = short, 2 = long) */
01506          32,                    /* bitsize */
01507          FALSE,                 /* pc_relative */
01508          0,                     /* bitpos */
01509          complain_overflow_bitfield,/* complain_on_overflow */
01510          bfd_elf_generic_reloc, /* special_function */
01511          "R_ARM_TLS_LDM32", /* name */
01512          TRUE,                     /* partial_inplace */
01513          0xffffffff,        /* src_mask */
01514          0xffffffff,        /* dst_mask */
01515          FALSE),                /* pcrel_offset */
01516 
01517   HOWTO (R_ARM_TLS_LDO32,   /* type */
01518          0,                     /* rightshift */
01519          2,                     /* size (0 = byte, 1 = short, 2 = long) */
01520          32,                    /* bitsize */
01521          FALSE,                 /* pc_relative */
01522          0,                     /* bitpos */
01523          complain_overflow_bitfield,/* complain_on_overflow */
01524          bfd_elf_generic_reloc, /* special_function */
01525          "R_ARM_TLS_LDO32", /* name */
01526          TRUE,                     /* partial_inplace */
01527          0xffffffff,        /* src_mask */
01528          0xffffffff,        /* dst_mask */
01529          FALSE),                /* pcrel_offset */
01530 
01531   HOWTO (R_ARM_TLS_IE32,    /* type */
01532          0,                     /* rightshift */
01533          2,                     /* size (0 = byte, 1 = short, 2 = long) */
01534          32,                    /* bitsize */
01535          FALSE,                  /* pc_relative */
01536          0,                     /* bitpos */
01537          complain_overflow_bitfield,/* complain_on_overflow */
01538          NULL,                     /* special_function */
01539          "R_ARM_TLS_IE32",  /* name */
01540          TRUE,                     /* partial_inplace */
01541          0xffffffff,        /* src_mask */
01542          0xffffffff,        /* dst_mask */
01543          FALSE),                /* pcrel_offset */
01544 
01545   HOWTO (R_ARM_TLS_LE32,    /* type */
01546          0,                     /* rightshift */
01547          2,                     /* size (0 = byte, 1 = short, 2 = long) */
01548          32,                    /* bitsize */
01549          FALSE,                 /* pc_relative */
01550          0,                     /* bitpos */
01551          complain_overflow_bitfield,/* complain_on_overflow */
01552          bfd_elf_generic_reloc, /* special_function */
01553          "R_ARM_TLS_LE32",  /* name */
01554          TRUE,                     /* partial_inplace */
01555          0xffffffff,        /* src_mask */
01556          0xffffffff,        /* dst_mask */
01557          FALSE),                /* pcrel_offset */
01558 
01559   HOWTO (R_ARM_TLS_LDO12,   /* type */
01560         0,                  /* rightshift */
01561         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01562         12,                 /* bitsize */
01563         FALSE,                     /* pc_relative */
01564         0,                  /* bitpos */
01565         complain_overflow_bitfield,/* complain_on_overflow */
01566         bfd_elf_generic_reloc,     /* special_function */
01567         "R_ARM_TLS_LDO12",  /* name */
01568         FALSE,                     /* partial_inplace */
01569         0x00000fff,         /* src_mask */
01570         0x00000fff,         /* dst_mask */
01571         FALSE),             /* pcrel_offset */
01572 
01573   HOWTO (R_ARM_TLS_LE12,    /* type */
01574         0,                  /* rightshift */
01575         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01576         12,                 /* bitsize */
01577         FALSE,                     /* pc_relative */
01578         0,                  /* bitpos */
01579         complain_overflow_bitfield,/* complain_on_overflow */
01580         bfd_elf_generic_reloc,     /* special_function */
01581         "R_ARM_TLS_LE12",   /* name */
01582         FALSE,                     /* partial_inplace */
01583         0x00000fff,         /* src_mask */
01584         0x00000fff,         /* dst_mask */
01585         FALSE),             /* pcrel_offset */
01586 
01587   HOWTO (R_ARM_TLS_IE12GP,  /* type */
01588         0,                  /* rightshift */
01589         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01590         12,                 /* bitsize */
01591         FALSE,                     /* pc_relative */
01592         0,                  /* bitpos */
01593         complain_overflow_bitfield,/* complain_on_overflow */
01594         bfd_elf_generic_reloc,     /* special_function */
01595         "R_ARM_TLS_IE12GP", /* name */
01596         FALSE,                     /* partial_inplace */
01597         0x00000fff,         /* src_mask */
01598         0x00000fff,         /* dst_mask */
01599         FALSE),             /* pcrel_offset */
01600 };
01601 
01602 /* 112-127 private relocations
01603    128 R_ARM_ME_TOO, obsolete
01604    129-255 unallocated in AAELF.
01605 
01606    249-255 extended, currently unused, relocations:  */
01607 
01608 static reloc_howto_type elf32_arm_howto_table_2[4] =
01609 {
01610   HOWTO (R_ARM_RREL32,             /* type */
01611         0,                  /* rightshift */
01612         0,                  /* size (0 = byte, 1 = short, 2 = long) */
01613         0,                  /* bitsize */
01614         FALSE,                     /* pc_relative */
01615         0,                  /* bitpos */
01616         complain_overflow_dont,/* complain_on_overflow */
01617         bfd_elf_generic_reloc,     /* special_function */
01618         "R_ARM_RREL32",     /* name */
01619         FALSE,                     /* partial_inplace */
01620         0,                  /* src_mask */
01621         0,                  /* dst_mask */
01622         FALSE),             /* pcrel_offset */
01623 
01624   HOWTO (R_ARM_RABS32,             /* type */
01625         0,                  /* rightshift */
01626         0,                  /* size (0 = byte, 1 = short, 2 = long) */
01627         0,                  /* bitsize */
01628         FALSE,                     /* pc_relative */
01629         0,                  /* bitpos */
01630         complain_overflow_dont,/* complain_on_overflow */
01631         bfd_elf_generic_reloc,     /* special_function */
01632         "R_ARM_RABS32",     /* name */
01633         FALSE,                     /* partial_inplace */
01634         0,                  /* src_mask */
01635         0,                  /* dst_mask */
01636         FALSE),             /* pcrel_offset */
01637 
01638   HOWTO (R_ARM_RPC24,              /* type */
01639         0,                  /* rightshift */
01640         0,                  /* size (0 = byte, 1 = short, 2 = long) */
01641         0,                  /* bitsize */
01642         FALSE,                     /* pc_relative */
01643         0,                  /* bitpos */
01644         complain_overflow_dont,/* complain_on_overflow */
01645         bfd_elf_generic_reloc,     /* special_function */
01646         "R_ARM_RPC24",             /* name */
01647         FALSE,                     /* partial_inplace */
01648         0,                  /* src_mask */
01649         0,                  /* dst_mask */
01650         FALSE),             /* pcrel_offset */
01651 
01652   HOWTO (R_ARM_RBASE,              /* type */
01653         0,                  /* rightshift */
01654         0,                  /* size (0 = byte, 1 = short, 2 = long) */
01655         0,                  /* bitsize */
01656         FALSE,                     /* pc_relative */
01657         0,                  /* bitpos */
01658         complain_overflow_dont,/* complain_on_overflow */
01659         bfd_elf_generic_reloc,     /* special_function */
01660         "R_ARM_RBASE",             /* name */
01661         FALSE,                     /* partial_inplace */
01662         0,                  /* src_mask */
01663         0,                  /* dst_mask */
01664         FALSE)                     /* pcrel_offset */
01665 };
01666 
01667 static reloc_howto_type *
01668 elf32_arm_howto_from_type (unsigned int r_type)
01669 {
01670   if (r_type < NUM_ELEM (elf32_arm_howto_table_1))
01671     return &elf32_arm_howto_table_1[r_type];
01672 
01673   if (r_type >= R_ARM_RREL32
01674       && r_type < R_ARM_RREL32 + NUM_ELEM (elf32_arm_howto_table_2))
01675     return &elf32_arm_howto_table_2[r_type - R_ARM_RREL32];
01676 
01677   return NULL;
01678 }
01679 
01680 static void
01681 elf32_arm_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, arelent * bfd_reloc,
01682                       Elf_Internal_Rela * elf_reloc)
01683 {
01684   unsigned int r_type;
01685 
01686   r_type = ELF32_R_TYPE (elf_reloc->r_info);
01687   bfd_reloc->howto = elf32_arm_howto_from_type (r_type);
01688 }
01689 
01690 struct elf32_arm_reloc_map
01691   {
01692     bfd_reloc_code_real_type  bfd_reloc_val;
01693     unsigned char             elf_reloc_val;
01694   };
01695 
01696 /* All entries in this list must also be present in elf32_arm_howto_table.  */
01697 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
01698   {
01699     {BFD_RELOC_NONE,                 R_ARM_NONE},
01700     {BFD_RELOC_ARM_PCREL_BRANCH,     R_ARM_PC24},
01701     {BFD_RELOC_ARM_PCREL_CALL,          R_ARM_CALL},
01702     {BFD_RELOC_ARM_PCREL_JUMP,          R_ARM_JUMP24},
01703     {BFD_RELOC_ARM_PCREL_BLX,        R_ARM_XPC25},
01704     {BFD_RELOC_THUMB_PCREL_BLX,      R_ARM_THM_XPC22},
01705     {BFD_RELOC_32,                   R_ARM_ABS32},
01706     {BFD_RELOC_32_PCREL,             R_ARM_REL32},
01707     {BFD_RELOC_8,                    R_ARM_ABS8},
01708     {BFD_RELOC_16,                   R_ARM_ABS16},
01709     {BFD_RELOC_ARM_OFFSET_IMM,       R_ARM_ABS12},
01710     {BFD_RELOC_ARM_THUMB_OFFSET,     R_ARM_THM_ABS5},
01711     {BFD_RELOC_THUMB_PCREL_BRANCH25, R_ARM_THM_JUMP24},
01712     {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_CALL},
01713     {BFD_RELOC_THUMB_PCREL_BRANCH12, R_ARM_THM_JUMP11},
01714     {BFD_RELOC_THUMB_PCREL_BRANCH20, R_ARM_THM_JUMP19},
01715     {BFD_RELOC_THUMB_PCREL_BRANCH9,  R_ARM_THM_JUMP8},
01716     {BFD_RELOC_THUMB_PCREL_BRANCH7,  R_ARM_THM_JUMP6},
01717     {BFD_RELOC_ARM_GLOB_DAT,         R_ARM_GLOB_DAT},
01718     {BFD_RELOC_ARM_JUMP_SLOT,        R_ARM_JUMP_SLOT},
01719     {BFD_RELOC_ARM_RELATIVE,         R_ARM_RELATIVE},
01720     {BFD_RELOC_ARM_GOTOFF,           R_ARM_GOTOFF32},
01721     {BFD_RELOC_ARM_GOTPC,            R_ARM_GOTPC},
01722     {BFD_RELOC_ARM_GOT32,            R_ARM_GOT32},
01723     {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32},
01724     {BFD_RELOC_ARM_TARGET1,      R_ARM_TARGET1},
01725     {BFD_RELOC_ARM_ROSEGREL32,          R_ARM_ROSEGREL32},
01726     {BFD_RELOC_ARM_SBREL32,      R_ARM_SBREL32},
01727     {BFD_RELOC_ARM_PREL31,       R_ARM_PREL31},
01728     {BFD_RELOC_ARM_TARGET2,      R_ARM_TARGET2},
01729     {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32},
01730     {BFD_RELOC_ARM_TLS_GD32,            R_ARM_TLS_GD32},
01731     {BFD_RELOC_ARM_TLS_LDO32,           R_ARM_TLS_LDO32},
01732     {BFD_RELOC_ARM_TLS_LDM32,           R_ARM_TLS_LDM32},
01733     {BFD_RELOC_ARM_TLS_DTPMOD32,     R_ARM_TLS_DTPMOD32},
01734     {BFD_RELOC_ARM_TLS_DTPOFF32,     R_ARM_TLS_DTPOFF32},
01735     {BFD_RELOC_ARM_TLS_TPOFF32,      R_ARM_TLS_TPOFF32},
01736     {BFD_RELOC_ARM_TLS_IE32,         R_ARM_TLS_IE32},
01737     {BFD_RELOC_ARM_TLS_LE32,         R_ARM_TLS_LE32},
01738     {BFD_RELOC_VTABLE_INHERIT,          R_ARM_GNU_VTINHERIT},
01739     {BFD_RELOC_VTABLE_ENTRY,            R_ARM_GNU_VTENTRY},
01740     {BFD_RELOC_ARM_MOVW,         R_ARM_MOVW_ABS_NC},
01741     {BFD_RELOC_ARM_MOVT,         R_ARM_MOVT_ABS},
01742     {BFD_RELOC_ARM_MOVW_PCREL,          R_ARM_MOVW_PREL_NC},
01743     {BFD_RELOC_ARM_MOVT_PCREL,          R_ARM_MOVT_PREL},
01744     {BFD_RELOC_ARM_THUMB_MOVW,          R_ARM_THM_MOVW_ABS_NC},
01745     {BFD_RELOC_ARM_THUMB_MOVT,          R_ARM_THM_MOVT_ABS},
01746     {BFD_RELOC_ARM_THUMB_MOVW_PCREL, R_ARM_THM_MOVW_PREL_NC},
01747     {BFD_RELOC_ARM_THUMB_MOVT_PCREL, R_ARM_THM_MOVT_PREL},
01748     {BFD_RELOC_ARM_ALU_PC_G0_NC, R_ARM_ALU_PC_G0_NC},
01749     {BFD_RELOC_ARM_ALU_PC_G0, R_ARM_ALU_PC_G0},
01750     {BFD_RELOC_ARM_ALU_PC_G1_NC, R_ARM_ALU_PC_G1_NC},
01751     {BFD_RELOC_ARM_ALU_PC_G1, R_ARM_ALU_PC_G1},
01752     {BFD_RELOC_ARM_ALU_PC_G2, R_ARM_ALU_PC_G2},
01753     {BFD_RELOC_ARM_LDR_PC_G0, R_ARM_LDR_PC_G0},
01754     {BFD_RELOC_ARM_LDR_PC_G1, R_ARM_LDR_PC_G1},
01755     {BFD_RELOC_ARM_LDR_PC_G2, R_ARM_LDR_PC_G2},
01756     {BFD_RELOC_ARM_LDRS_PC_G0, R_ARM_LDRS_PC_G0},
01757     {BFD_RELOC_ARM_LDRS_PC_G1, R_ARM_LDRS_PC_G1},
01758     {BFD_RELOC_ARM_LDRS_PC_G2, R_ARM_LDRS_PC_G2},
01759     {BFD_RELOC_ARM_LDC_PC_G0, R_ARM_LDC_PC_G0},
01760     {BFD_RELOC_ARM_LDC_PC_G1, R_ARM_LDC_PC_G1},
01761     {BFD_RELOC_ARM_LDC_PC_G2, R_ARM_LDC_PC_G2},
01762     {BFD_RELOC_ARM_ALU_SB_G0_NC, R_ARM_ALU_SB_G0_NC},
01763     {BFD_RELOC_ARM_ALU_SB_G0, R_ARM_ALU_SB_G0},
01764     {BFD_RELOC_ARM_ALU_SB_G1_NC, R_ARM_ALU_SB_G1_NC},
01765     {BFD_RELOC_ARM_ALU_SB_G1, R_ARM_ALU_SB_G1},
01766     {BFD_RELOC_ARM_ALU_SB_G2, R_ARM_ALU_SB_G2},
01767     {BFD_RELOC_ARM_LDR_SB_G0, R_ARM_LDR_SB_G0},
01768     {BFD_RELOC_ARM_LDR_SB_G1, R_ARM_LDR_SB_G1},
01769     {BFD_RELOC_ARM_LDR_SB_G2, R_ARM_LDR_SB_G2},
01770     {BFD_RELOC_ARM_LDRS_SB_G0, R_ARM_LDRS_SB_G0},
01771     {BFD_RELOC_ARM_LDRS_SB_G1, R_ARM_LDRS_SB_G1},
01772     {BFD_RELOC_ARM_LDRS_SB_G2, R_ARM_LDRS_SB_G2},
01773     {BFD_RELOC_ARM_LDC_SB_G0, R_ARM_LDC_SB_G0},
01774     {BFD_RELOC_ARM_LDC_SB_G1, R_ARM_LDC_SB_G1},
01775     {BFD_RELOC_ARM_LDC_SB_G2, R_ARM_LDC_SB_G2}
01776   };
01777 
01778 static reloc_howto_type *
01779 elf32_arm_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01780                           bfd_reloc_code_real_type code)
01781 {
01782   unsigned int i;
01783   for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
01784     if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
01785       return elf32_arm_howto_from_type (elf32_arm_reloc_map[i].elf_reloc_val);
01786 
01787   return NULL;
01788 }
01789 
01790 static reloc_howto_type *
01791 elf32_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01792                           const char *r_name)
01793 {
01794   unsigned int i;
01795 
01796   for (i = 0;
01797        i < (sizeof (elf32_arm_howto_table_1)
01798            / sizeof (elf32_arm_howto_table_1[0]));
01799        i++)
01800     if (elf32_arm_howto_table_1[i].name != NULL
01801        && strcasecmp (elf32_arm_howto_table_1[i].name, r_name) == 0)
01802       return &elf32_arm_howto_table_1[i];
01803 
01804   for (i = 0;
01805        i < (sizeof (elf32_arm_howto_table_2)
01806            / sizeof (elf32_arm_howto_table_2[0]));
01807        i++)
01808     if (elf32_arm_howto_table_2[i].name != NULL
01809        && strcasecmp (elf32_arm_howto_table_2[i].name, r_name) == 0)
01810       return &elf32_arm_howto_table_2[i];
01811 
01812   return NULL;
01813 }
01814 
01815 /* Support for core dump NOTE sections */
01816 static bfd_boolean
01817 elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
01818 {
01819   int offset;
01820   size_t size;
01821 
01822   switch (note->descsz)
01823     {
01824       default:
01825        return FALSE;
01826 
01827       case 148:             /* Linux/ARM 32-bit*/
01828        /* pr_cursig */
01829        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
01830 
01831        /* pr_pid */
01832        elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
01833 
01834        /* pr_reg */
01835        offset = 72;
01836        size = 72;
01837 
01838        break;
01839     }
01840 
01841   /* Make a ".reg/999" section.  */
01842   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
01843                                      size, note->descpos + offset);
01844 }
01845 
01846 static bfd_boolean
01847 elf32_arm_nabi_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
01848 {
01849   switch (note->descsz)
01850     {
01851       default:
01852        return FALSE;
01853 
01854       case 124:             /* Linux/ARM elf_prpsinfo */
01855        elf_tdata (abfd)->core_program
01856         = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
01857        elf_tdata (abfd)->core_command
01858         = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
01859     }
01860 
01861   /* Note that for some reason, a spurious space is tacked
01862      onto the end of the args in some (at least one anyway)
01863      implementations, so strip it off if it exists.  */
01864 
01865   {
01866     char *command = elf_tdata (abfd)->core_command;
01867     int n = strlen (command);
01868 
01869     if (0 < n && command[n - 1] == ' ')
01870       command[n - 1] = '\0';
01871   }
01872 
01873   return TRUE;
01874 }
01875 
01876 #define TARGET_LITTLE_SYM               bfd_elf32_littlearm_vec
01877 #define TARGET_LITTLE_NAME              "elf32-littlearm"
01878 #define TARGET_BIG_SYM                  bfd_elf32_bigarm_vec
01879 #define TARGET_BIG_NAME                 "elf32-bigarm"
01880 
01881 #define elf_backend_grok_prstatus  elf32_arm_nabi_grok_prstatus
01882 #define elf_backend_grok_psinfo           elf32_arm_nabi_grok_psinfo
01883 
01884 typedef unsigned long int insn32;
01885 typedef unsigned short int insn16;
01886 
01887 /* In lieu of proper flags, assume all EABIv4 or later objects are
01888    interworkable.  */
01889 #define INTERWORK_FLAG(abfd)  \
01890   (EF_ARM_EABI_VERSION (elf_elfheader (abfd)->e_flags) >= EF_ARM_EABI_VER4 \
01891   || (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK))
01892 
01893 /* The linker script knows the section names for placement.
01894    The entry_names are used to do simple name mangling on the stubs.
01895    Given a function name, and its type, the stub can be found. The
01896    name can be changed. The only requirement is the %s be present.  */
01897 #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
01898 #define THUMB2ARM_GLUE_ENTRY_NAME   "__%s_from_thumb"
01899 
01900 #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
01901 #define ARM2THUMB_GLUE_ENTRY_NAME   "__%s_from_arm"
01902 
01903 #define VFP11_ERRATUM_VENEER_SECTION_NAME ".vfp11_veneer"
01904 #define VFP11_ERRATUM_VENEER_ENTRY_NAME   "__vfp11_veneer_%x"
01905 
01906 /* The name of the dynamic interpreter.  This is put in the .interp
01907    section.  */
01908 #define ELF_DYNAMIC_INTERPRETER     "/usr/lib/ld.so.1"
01909 
01910 #ifdef FOUR_WORD_PLT
01911 
01912 /* The first entry in a procedure linkage table looks like
01913    this.  It is set up so that any shared library function that is
01914    called before the relocation has been set up calls the dynamic
01915    linker first.  */
01916 static const bfd_vma elf32_arm_plt0_entry [] =
01917   {
01918     0xe52de004,             /* str   lr, [sp, #-4]! */
01919     0xe59fe010,             /* ldr   lr, [pc, #16]  */
01920     0xe08fe00e,             /* add   lr, pc, lr     */
01921     0xe5bef008,             /* ldr   pc, [lr, #8]!  */
01922   };
01923 
01924 /* Subsequent entries in a procedure linkage table look like
01925    this.  */
01926 static const bfd_vma elf32_arm_plt_entry [] =
01927   {
01928     0xe28fc600,             /* add   ip, pc, #NN */
01929     0xe28cca00,             /* add  ip, ip, #NN  */
01930     0xe5bcf000,             /* ldr  pc, [ip, #NN]! */
01931     0x00000000,             /* unused            */
01932   };
01933 
01934 #else
01935 
01936 /* The first entry in a procedure linkage table looks like
01937    this.  It is set up so that any shared library function that is
01938    called before the relocation has been set up calls the dynamic
01939    linker first.  */
01940 static const bfd_vma elf32_arm_plt0_entry [] =
01941   {
01942     0xe52de004,             /* str   lr, [sp, #-4]! */
01943     0xe59fe004,             /* ldr   lr, [pc, #4]   */
01944     0xe08fe00e,             /* add   lr, pc, lr     */
01945     0xe5bef008,             /* ldr   pc, [lr, #8]!  */
01946     0x00000000,             /* &GOT[0] - .          */
01947   };
01948 
01949 /* Subsequent entries in a procedure linkage table look like
01950    this.  */
01951 static const bfd_vma elf32_arm_plt_entry [] =
01952   {
01953     0xe28fc600,             /* add   ip, pc, #0xNN00000 */
01954     0xe28cca00,             /* add  ip, ip, #0xNN000   */
01955     0xe5bcf000,             /* ldr  pc, [ip, #0xNNN]!  */
01956   };
01957 
01958 #endif
01959 
01960 /* The format of the first entry in the procedure linkage table
01961    for a VxWorks executable.  */
01962 static const bfd_vma elf32_arm_vxworks_exec_plt0_entry[] =
01963   {
01964     0xe52dc008,              /* str    ip,[sp,#-8]!                   */
01965     0xe59fc000,         /* ldr    ip,[pc]               */
01966     0xe59cf008,         /* ldr    pc,[ip,#8]                   */
01967     0x00000000,         /* .long  _GLOBAL_OFFSET_TABLE_        */
01968   };
01969 
01970 /* The format of subsequent entries in a VxWorks executable.  */
01971 static const bfd_vma elf32_arm_vxworks_exec_plt_entry[] =
01972   {
01973     0xe59fc000,         /* ldr    ip,[pc]               */
01974     0xe59cf000,         /* ldr    pc,[ip]               */
01975     0x00000000,         /* .long  @got                         */
01976     0xe59fc000,         /* ldr    ip,[pc]               */
01977     0xea000000,         /* b      _PLT                         */
01978     0x00000000,         /* .long  @pltindex*sizeof(Elf32_Rela) */
01979   };
01980 
01981 /* The format of entries in a VxWorks shared library.  */
01982 static const bfd_vma elf32_arm_vxworks_shared_plt_entry[] =
01983   {
01984     0xe59fc000,         /* ldr    ip,[pc]               */
01985     0xe79cf009,         /* ldr    pc,[ip,r9]                   */
01986     0x00000000,         /* .long  @got                         */
01987     0xe59fc000,         /* ldr    ip,[pc]               */
01988     0xe599f008,         /* ldr    pc,[r9,#8]                   */
01989     0x00000000,         /* .long  @pltindex*sizeof(Elf32_Rela) */
01990   };
01991 
01992 /* An initial stub used if the PLT entry is referenced from Thumb code.  */
01993 #define PLT_THUMB_STUB_SIZE 4
01994 static const bfd_vma elf32_arm_plt_thumb_stub [] =
01995   {
01996     0x4778,          /* bx pc */
01997     0x46c0           /* nop   */
01998   };
01999 
02000 /* The entries in a PLT when using a DLL-based target with multiple
02001    address spaces.  */
02002 static const bfd_vma elf32_arm_symbian_plt_entry [] = 
02003   {
02004     0xe51ff004,         /* ldr   pc, [pc, #-4] */
02005     0x00000000,         /* dcd   R_ARM_GLOB_DAT(X) */
02006   };
02007 
02008 /* Used to build a map of a section.  This is required for mixed-endian
02009    code/data.  */
02010 
02011 typedef struct elf32_elf_section_map
02012 {
02013   bfd_vma vma;
02014   char type;
02015 }
02016 elf32_arm_section_map;
02017 
02018 /* Information about a VFP11 erratum veneer, or a branch to such a veneer.  */
02019 
02020 typedef enum
02021 {
02022   VFP11_ERRATUM_BRANCH_TO_ARM_VENEER,
02023   VFP11_ERRATUM_BRANCH_TO_THUMB_VENEER,
02024   VFP11_ERRATUM_ARM_VENEER,
02025   VFP11_ERRATUM_THUMB_VENEER
02026 }
02027 elf32_vfp11_erratum_type;
02028 
02029 typedef struct elf32_vfp11_erratum_list
02030 {
02031   struct elf32_vfp11_erratum_list *next;
02032   bfd_vma vma;
02033   union
02034   {
02035     struct
02036     {
02037       struct elf32_vfp11_erratum_list *veneer;
02038       unsigned int vfp_insn;
02039     } b;
02040     struct
02041     {
02042       struct elf32_vfp11_erratum_list *branch;
02043       unsigned int id;
02044     } v;
02045   } u;
02046   elf32_vfp11_erratum_type type;
02047 }
02048 elf32_vfp11_erratum_list;
02049 
02050 typedef struct _arm_elf_section_data
02051 {
02052   struct bfd_elf_section_data elf;
02053   unsigned int mapcount;
02054   unsigned int mapsize;
02055   elf32_arm_section_map *map;
02056   unsigned int erratumcount;
02057   elf32_vfp11_erratum_list *erratumlist;
02058 }
02059 _arm_elf_section_data;
02060 
02061 #define elf32_arm_section_data(sec) \
02062   ((_arm_elf_section_data *) elf_section_data (sec))
02063 
02064 /* The size of the thread control block.  */
02065 #define TCB_SIZE     8
02066 
02067 #define NUM_KNOWN_ATTRIBUTES 32
02068 
02069 typedef struct aeabi_attribute
02070 {
02071   int type;
02072   unsigned int i;
02073   char *s;
02074 } aeabi_attribute;
02075 
02076 typedef struct aeabi_attribute_list
02077 {
02078   struct aeabi_attribute_list *next;
02079   int tag;
02080   aeabi_attribute attr;
02081 } aeabi_attribute_list;
02082 
02083 struct elf32_arm_obj_tdata
02084 {
02085   struct elf_obj_tdata root;
02086 
02087   /* tls_type for each local got entry.  */
02088   char *local_got_tls_type;
02089 
02090   aeabi_attribute known_eabi_attributes[NUM_KNOWN_ATTRIBUTES];
02091   aeabi_attribute_list *other_eabi_attributes;
02092 
02093   /* Zero to warn when linking objects with incompatible enum sizes.  */
02094   int no_enum_size_warning;
02095 };
02096 
02097 #define elf32_arm_tdata(abfd) \
02098   ((struct elf32_arm_obj_tdata *) (abfd)->tdata.any)
02099 
02100 #define elf32_arm_local_got_tls_type(abfd) \
02101   (elf32_arm_tdata (abfd)->local_got_tls_type)
02102 
02103 static bfd_boolean
02104 elf32_arm_mkobject (bfd *abfd)
02105 {
02106   if (abfd->tdata.any == NULL)
02107     {
02108       bfd_size_type amt = sizeof (struct elf32_arm_obj_tdata);
02109       abfd->tdata.any = bfd_zalloc (abfd, amt);
02110       if (abfd->tdata.any == NULL)
02111        return FALSE;
02112     }
02113   return bfd_elf_mkobject (abfd);
02114 }
02115 
02116 /* The ARM linker needs to keep track of the number of relocs that it
02117    decides to copy in check_relocs for each symbol.  This is so that
02118    it can discard PC relative relocs if it doesn't need them when
02119    linking with -Bsymbolic.  We store the information in a field
02120    extending the regular ELF linker hash table.  */
02121 
02122 /* This structure keeps track of the number of relocs we have copied
02123    for a given symbol.  */
02124 struct elf32_arm_relocs_copied
02125   {
02126     /* Next section.  */
02127     struct elf32_arm_relocs_copied * next;
02128     /* A section in dynobj.  */
02129     asection * section;
02130     /* Number of relocs copied in this section.  */
02131     bfd_size_type count;
02132     /* Number of PC-relative relocs copied in this section.  */
02133     bfd_size_type pc_count;
02134   };
02135 
02136 #define elf32_arm_hash_entry(ent) ((struct elf32_arm_link_hash_entry *)(ent))
02137 
02138 /* Arm ELF linker hash entry.  */
02139 struct elf32_arm_link_hash_entry
02140   {
02141     struct elf_link_hash_entry root;
02142 
02143     /* Number of PC relative relocs copied for this symbol.  */
02144     struct elf32_arm_relocs_copied * relocs_copied;
02145 
02146     /* We reference count Thumb references to a PLT entry separately,
02147        so that we can emit the Thumb trampoline only if needed.  */
02148     bfd_signed_vma plt_thumb_refcount;
02149 
02150     /* Since PLT entries have variable size if the Thumb prologue is
02151        used, we need to record the index into .got.plt instead of
02152        recomputing it from the PLT offset.  */
02153     bfd_signed_vma plt_got_offset;
02154 
02155 #define GOT_UNKNOWN  0
02156 #define GOT_NORMAL   1
02157 #define GOT_TLS_GD   2
02158 #define GOT_TLS_IE   4
02159     unsigned char tls_type;
02160 
02161     /* The symbol marking the real symbol location for exported thumb
02162        symbols with Arm stubs.  */
02163     struct elf_link_hash_entry *export_glue;
02164   };
02165 
02166 /* Traverse an arm ELF linker hash table.  */
02167 #define elf32_arm_link_hash_traverse(table, func, info)               \
02168   (elf_link_hash_traverse                                      \
02169    (&(table)->root,                                            \
02170     (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func),  \
02171     (info)))
02172 
02173 /* Get the ARM elf linker hash table from a link_info structure.  */
02174 #define elf32_arm_hash_table(info) \
02175   ((struct elf32_arm_link_hash_table *) ((info)->hash))
02176 
02177 /* ARM ELF linker hash table.  */
02178 struct elf32_arm_link_hash_table
02179   {
02180     /* The main hash table.  */
02181     struct elf_link_hash_table root;
02182 
02183     /* The size in bytes of the section containing the Thumb-to-ARM glue.  */
02184     bfd_size_type thumb_glue_size;
02185 
02186     /* The size in bytes of the section containing the ARM-to-Thumb glue.  */
02187     bfd_size_type arm_glue_size;
02188 
02189     /* The size in bytes of the section containing glue for VFP11 erratum
02190        veneers.  */
02191     bfd_size_type vfp11_erratum_glue_size;
02192 
02193     /* An arbitrary input BFD chosen to hold the glue sections.  */
02194     bfd * bfd_of_glue_owner;
02195 
02196     /* Nonzero to output a BE8 image.  */
02197     int byteswap_code;
02198 
02199     /* Zero if R_ARM_TARGET1 means R_ARM_ABS32.
02200        Nonzero if R_ARM_TARGET1 means R_ARM_REL32.  */
02201     int target1_is_rel;
02202 
02203     /* The relocation to use for R_ARM_TARGET2 relocations.  */
02204     int target2_reloc;
02205 
02206     /* Nonzero to fix BX instructions for ARMv4 targets.  */
02207     int fix_v4bx;
02208 
02209     /* Nonzero if the ARM/Thumb BLX instructions are available for use.  */
02210     int use_blx;
02211 
02212     /* What sort of code sequences we should look for which may trigger the
02213        VFP11 denorm erratum.  */
02214     bfd_arm_vfp11_fix vfp11_fix;
02215 
02216     /* Global counter for the number of fixes we have emitted.  */
02217     int num_vfp11_fixes;
02218 
02219     /* Nonzero to force PIC branch veneers.  */
02220     int pic_veneer;
02221 
02222     /* The number of bytes in the initial entry in the PLT.  */
02223     bfd_size_type plt_header_size;
02224 
02225     /* The number of bytes in the subsequent PLT etries.  */
02226     bfd_size_type plt_entry_size;
02227 
02228     /* True if the target system is VxWorks.  */
02229     int vxworks_p;
02230 
02231     /* True if the target system is Symbian OS.  */
02232     int symbian_p;
02233 
02234     /* True if the target uses REL relocations.  */
02235     int use_rel;
02236 
02237     /* Short-cuts to get to dynamic linker sections.  */
02238     asection *sgot;
02239     asection *sgotplt;
02240     asection *srelgot;
02241     asection *splt;
02242     asection *srelplt;
02243     asection *sdynbss;
02244     asection *srelbss;
02245 
02246     /* The (unloaded but important) VxWorks .rela.plt.unloaded section.  */
02247     asection *srelplt2;
02248 
02249     /* Data for R_ARM_TLS_LDM32 relocations.  */
02250     union {
02251       bfd_signed_vma refcount;
02252       bfd_vma offset;
02253     } tls_ldm_got;
02254     
02255     /* Small local sym to section mapping cache.  */
02256     struct sym_sec_cache sym_sec;
02257 
02258     /* For convenience in allocate_dynrelocs.  */
02259     bfd * obfd;
02260   };
02261 
02262 /* Create an entry in an ARM ELF linker hash table.  */
02263 
02264 static struct bfd_hash_entry *
02265 elf32_arm_link_hash_newfunc (struct bfd_hash_entry * entry,
02266                              struct bfd_hash_table * table,
02267                              const char * string)
02268 {
02269   struct elf32_arm_link_hash_entry * ret =
02270     (struct elf32_arm_link_hash_entry *) entry;
02271 
02272   /* Allocate the structure if it has not already been allocated by a
02273      subclass.  */
02274   if (ret == (struct elf32_arm_link_hash_entry *) NULL)
02275     ret = bfd_hash_allocate (table, sizeof (struct elf32_arm_link_hash_entry));
02276   if (ret == NULL)
02277     return (struct bfd_hash_entry *) ret;
02278 
02279   /* Call the allocation method of the superclass.  */
02280   ret = ((struct elf32_arm_link_hash_entry *)
02281         _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
02282                                  table, string));
02283   if (ret != NULL)
02284     {
02285       ret->relocs_copied = NULL;
02286       ret->tls_type = GOT_UNKNOWN;
02287       ret->plt_thumb_refcount = 0;
02288       ret->plt_got_offset = -1;
02289       ret->export_glue = NULL;
02290     }
02291 
02292   return (struct bfd_hash_entry *) ret;
02293 }
02294 
02295 /* Return true if NAME is the name of the relocation section associated
02296    with S.  */
02297 
02298 static bfd_boolean
02299 reloc_section_p (struct elf32_arm_link_hash_table *htab,
02300                const char *name, asection *s)
02301 {
02302   if (htab->use_rel)
02303     return CONST_STRNEQ (name, ".rel") && strcmp (s->name, name + 4) == 0;
02304   else
02305     return CONST_STRNEQ (name, ".rela") && strcmp (s->name, name + 5) == 0;
02306 }
02307 
02308 /* Create .got, .gotplt, and .rel(a).got sections in DYNOBJ, and set up
02309    shortcuts to them in our hash table.  */
02310 
02311 static bfd_boolean
02312 create_got_section (bfd *dynobj, struct bfd_link_info *info)
02313 {
02314   struct elf32_arm_link_hash_table *htab;
02315 
02316   htab = elf32_arm_hash_table (info);
02317   /* BPABI objects never have a GOT, or associated sections.  */
02318   if (htab->symbian_p)
02319     return TRUE;
02320 
02321   if (! _bfd_elf_create_got_section (dynobj, info))
02322     return FALSE;
02323 
02324   htab->sgot = bfd_get_section_by_name (dynobj, ".got");
02325   htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
02326   if (!htab->sgot || !htab->sgotplt)
02327     abort ();
02328 
02329   htab->srelgot = bfd_make_section_with_flags (dynobj,
02330                                           RELOC_SECTION (htab, ".got"),
02331                                           (SEC_ALLOC | SEC_LOAD
02332                                           | SEC_HAS_CONTENTS
02333                                           | SEC_IN_MEMORY
02334                                           | SEC_LINKER_CREATED
02335                                           | SEC_READONLY));
02336   if (htab->srelgot == NULL
02337       || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
02338     return FALSE;
02339   return TRUE;
02340 }
02341 
02342 /* Create .plt, .rel(a).plt, .got, .got.plt, .rel(a).got, .dynbss, and
02343    .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our
02344    hash table.  */
02345 
02346 static bfd_boolean
02347 elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
02348 {
02349   struct elf32_arm_link_hash_table *htab;
02350 
02351   htab = elf32_arm_hash_table (info);
02352   if (!htab->sgot && !create_got_section (dynobj, info))
02353     return FALSE;
02354 
02355   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
02356     return FALSE;
02357 
02358   htab->splt = bfd_get_section_by_name (dynobj, ".plt");
02359   htab->srelplt = bfd_get_section_by_name (dynobj,
02360                                       RELOC_SECTION (htab, ".plt"));
02361   htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
02362   if (!info->shared)
02363     htab->srelbss = bfd_get_section_by_name (dynobj,
02364                                         RELOC_SECTION (htab, ".bss"));
02365 
02366   if (htab->vxworks_p)
02367     {
02368       if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
02369        return FALSE;
02370 
02371       if (info->shared)
02372        {
02373          htab->plt_header_size = 0;
02374          htab->plt_entry_size
02375            = 4 * ARRAY_SIZE (elf32_arm_vxworks_shared_plt_entry);
02376        }
02377       else
02378        {
02379          htab->plt_header_size
02380            = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt0_entry);
02381          htab->plt_entry_size
02382            = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
02383        }
02384     }
02385 
02386   if (!htab->splt 
02387       || !htab->srelplt
02388       || !htab->sdynbss
02389       || (!info->shared && !htab->srelbss))
02390     abort ();
02391 
02392   return TRUE;
02393 }
02394 
02395 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
02396 
02397 static void
02398 elf32_arm_copy_indirect_symbol (struct bfd_link_info *info,
02399                             struct elf_link_hash_entry *dir,
02400                             struct elf_link_hash_entry *ind)
02401 {
02402   struct elf32_arm_link_hash_entry *edir, *eind;
02403 
02404   edir = (struct elf32_arm_link_hash_entry *) dir;
02405   eind = (struct elf32_arm_link_hash_entry *) ind;
02406 
02407   if (eind->relocs_copied != NULL)
02408     {
02409       if (edir->relocs_copied != NULL)
02410        {
02411          struct elf32_arm_relocs_copied **pp;
02412          struct elf32_arm_relocs_copied *p;
02413 
02414          /* Add reloc counts against the indirect sym to the direct sym
02415             list.  Merge any entries against the same section.  */
02416          for (pp = &eind->relocs_copied; (p = *pp) != NULL; )
02417            {
02418              struct elf32_arm_relocs_copied *q;
02419 
02420              for (q = edir->relocs_copied; q != NULL; q = q->next)
02421               if (q->section == p->section)
02422                 {
02423                   q->pc_count += p->pc_count;
02424                   q->count += p->count;
02425                   *pp = p->next;
02426                   break;
02427                 }
02428              if (q == NULL)
02429               pp = &p->next;
02430            }
02431          *pp = edir->relocs_copied;
02432        }
02433 
02434       edir->relocs_copied = eind->relocs_copied;
02435       eind->relocs_copied = NULL;
02436     }
02437 
02438   if (ind->root.type == bfd_link_hash_indirect)
02439     {
02440       /* Copy over PLT info.  */
02441       edir->plt_thumb_refcount += eind->plt_thumb_refcount;
02442       eind->plt_thumb_refcount = 0;
02443 
02444       if (dir->got.refcount <= 0)
02445        {
02446          edir->tls_type = eind->tls_type;
02447          eind->tls_type = GOT_UNKNOWN;
02448        }
02449     }
02450 
02451   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
02452 }
02453 
02454 /* Create an ARM elf linker hash table.  */
02455 
02456 static struct bfd_link_hash_table *
02457 elf32_arm_link_hash_table_create (bfd *abfd)
02458 {
02459   struct elf32_arm_link_hash_table *ret;
02460   bfd_size_type amt = sizeof (struct elf32_arm_link_hash_table);
02461 
02462   ret = bfd_malloc (amt);
02463   if (ret == NULL)
02464     return NULL;
02465 
02466   if (!_bfd_elf_link_hash_table_init (& ret->root, abfd,
02467                                   elf32_arm_link_hash_newfunc,
02468                                   sizeof (struct elf32_arm_link_hash_entry)))
02469     {
02470       free (ret);
02471       return NULL;
02472     }
02473 
02474   ret->sgot = NULL;
02475   ret->sgotplt = NULL;
02476   ret->srelgot = NULL;
02477   ret->splt = NULL;
02478   ret->srelplt = NULL;
02479   ret->sdynbss = NULL;
02480   ret->srelbss = NULL;
02481   ret->srelplt2 = NULL;
02482   ret->thumb_glue_size = 0;
02483   ret->arm_glue_size = 0;
02484   ret->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;
02485   ret->vfp11_erratum_glue_size = 0;
02486   ret->num_vfp11_fixes = 0;
02487   ret->bfd_of_glue_owner = NULL;
02488   ret->byteswap_code = 0;
02489   ret->target1_is_rel = 0;
02490   ret->target2_reloc = R_ARM_NONE;
02491 #ifdef FOUR_WORD_PLT
02492   ret->plt_header_size = 16;
02493   ret->plt_entry_size = 16;
02494 #else
02495   ret->plt_header_size = 20;
02496   ret->plt_entry_size = 12;
02497 #endif
02498   ret->fix_v4bx = 0;
02499   ret->use_blx = 0;
02500   ret->vxworks_p = 0;
02501   ret->symbian_p = 0;
02502   ret->use_rel = 1;
02503   ret->sym_sec.abfd = NULL;
02504   ret->obfd = abfd;
02505   ret->tls_ldm_got.refcount = 0;
02506 
02507   return &ret->root.root;
02508 }
02509 
02510 /* Locate the Thumb encoded calling stub for NAME.  */
02511 
02512 static struct elf_link_hash_entry *
02513 find_thumb_glue (struct bfd_link_info *link_info,
02514                const char *name,
02515                char **error_message)
02516 {
02517   char *tmp_name;
02518   struct elf_link_hash_entry *hash;
02519   struct elf32_arm_link_hash_table *hash_table;
02520 
02521   /* We need a pointer to the armelf specific hash table.  */
02522   hash_table = elf32_arm_hash_table (link_info);
02523 
02524   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
02525                       + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
02526 
02527   BFD_ASSERT (tmp_name);
02528 
02529   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
02530 
02531   hash = elf_link_hash_lookup
02532     (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
02533 
02534   if (hash == NULL)
02535     asprintf (error_message, _("unable to find THUMB glue '%s' for '%s'"),
02536              tmp_name, name);
02537 
02538   free (tmp_name);
02539 
02540   return hash;
02541 }
02542 
02543 /* Locate the ARM encoded calling stub for NAME.  */
02544 
02545 static struct elf_link_hash_entry *
02546 find_arm_glue (struct bfd_link_info *link_info,
02547               const char *name,
02548               char **error_message)
02549 {
02550   char *tmp_name;
02551   struct elf_link_hash_entry *myh;
02552   struct elf32_arm_link_hash_table *hash_table;
02553 
02554   /* We need a pointer to the elfarm specific hash table.  */
02555   hash_table = elf32_arm_hash_table (link_info);
02556 
02557   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
02558                       + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1);
02559 
02560   BFD_ASSERT (tmp_name);
02561 
02562   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
02563 
02564   myh = elf_link_hash_lookup
02565     (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
02566 
02567   if (myh == NULL)
02568     asprintf (error_message, _("unable to find ARM glue '%s' for '%s'"),
02569              tmp_name, name);
02570 
02571   free (tmp_name);
02572 
02573   return myh;
02574 }
02575 
02576 /* ARM->Thumb glue (static images):
02577 
02578    .arm
02579    __func_from_arm:
02580    ldr r12, __func_addr
02581    bx  r12
02582    __func_addr:
02583    .word func    @ behave as if you saw a ARM_32 reloc.  
02584 
02585    (relocatable images)
02586    .arm
02587    __func_from_arm:
02588    ldr r12, __func_offset
02589    add r12, r12, pc
02590    bx  r12
02591    __func_offset:
02592    .word func - .
02593    */
02594 
02595 #define ARM2THUMB_STATIC_GLUE_SIZE 12
02596 static const insn32 a2t1_ldr_insn = 0xe59fc000;
02597 static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
02598 static const insn32 a2t3_func_addr_insn = 0x00000001;
02599 
02600 #define ARM2THUMB_PIC_GLUE_SIZE 16
02601 static const insn32 a2t1p_ldr_insn = 0xe59fc004;
02602 static const insn32 a2t2p_add_pc_insn = 0xe08cc00f;
02603 static const insn32 a2t3p_bx_r12_insn = 0xe12fff1c;
02604 
02605 /* Thumb->ARM:                          Thumb->(non-interworking aware) ARM
02606 
02607    .thumb                               .thumb
02608    .align 2                             .align 2
02609    __func_from_thumb:              __func_from_thumb:
02610    bx pc                                push {r6, lr}
02611    nop                                  ldr  r6, __func_addr
02612    .arm                                         mov  lr, pc
02613    __func_change_to_arm:                        bx   r6
02614    b func                       .arm
02615    __func_back_to_thumb:
02616    ldmia r13! {r6, lr}
02617    bx    lr
02618    __func_addr:
02619    .word        func  */
02620 
02621 #define THUMB2ARM_GLUE_SIZE 8
02622 static const insn16 t2a1_bx_pc_insn = 0x4778;
02623 static const insn16 t2a2_noop_insn = 0x46c0;
02624 static const insn32 t2a3_b_insn = 0xea000000;
02625 
02626 #define VFP11_ERRATUM_VENEER_SIZE 8
02627 
02628 #ifndef ELFARM_NABI_C_INCLUDED
02629 bfd_boolean
02630 bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
02631 {
02632   asection * s;
02633   bfd_byte * foo;
02634   struct elf32_arm_link_hash_table * globals;
02635 
02636   globals = elf32_arm_hash_table (info);
02637 
02638   BFD_ASSERT (globals != NULL);
02639 
02640   if (globals->arm_glue_size != 0)
02641     {
02642       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
02643 
02644       s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
02645                                ARM2THUMB_GLUE_SECTION_NAME);
02646 
02647       BFD_ASSERT (s != NULL);
02648 
02649       foo = bfd_alloc (globals->bfd_of_glue_owner, globals->arm_glue_size);
02650 
02651       BFD_ASSERT (s->size == globals->arm_glue_size);
02652       s->contents = foo;
02653     }
02654 
02655   if (globals->thumb_glue_size != 0)
02656     {
02657       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
02658 
02659       s = bfd_get_section_by_name
02660        (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
02661 
02662       BFD_ASSERT (s != NULL);
02663 
02664       foo = bfd_alloc (globals->bfd_of_glue_owner, globals->thumb_glue_size);
02665 
02666       BFD_ASSERT (s->size == globals->thumb_glue_size);
02667       s->contents = foo;
02668     }
02669   
02670   if (globals->vfp11_erratum_glue_size != 0)
02671     {
02672       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
02673       
02674       s = bfd_get_section_by_name
02675         (globals->bfd_of_glue_owner, VFP11_ERRATUM_VENEER_SECTION_NAME);
02676       
02677       BFD_ASSERT (s != NULL);
02678       
02679       foo = bfd_alloc (globals->bfd_of_glue_owner,
02680                      globals->vfp11_erratum_glue_size);
02681       
02682       BFD_ASSERT (s->size == globals->vfp11_erratum_glue_size);
02683       s->contents = foo;
02684     }
02685 
02686   return TRUE;
02687 }
02688 
02689 /* Allocate space and symbols for calling a Thumb function from Arm mode.
02690    returns the symbol identifying teh stub.  */
02691 static struct elf_link_hash_entry *
02692 record_arm_to_thumb_glue (struct bfd_link_info * link_info,
02693                        struct elf_link_hash_entry * h)
02694 {
02695   const char * name = h->root.root.string;
02696   asection * s;
02697   char * tmp_name;
02698   struct elf_link_hash_entry * myh;
02699   struct bfd_link_hash_entry * bh;
02700   struct elf32_arm_link_hash_table * globals;
02701   bfd_vma val;
02702   bfd_size_type size;
02703 
02704   globals = elf32_arm_hash_table (link_info);
02705 
02706   BFD_ASSERT (globals != NULL);
02707   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
02708 
02709   s = bfd_get_section_by_name
02710     (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
02711 
02712   BFD_ASSERT (s != NULL);
02713 
02714   tmp_name = bfd_malloc ((bfd_size_type) strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1);
02715 
02716   BFD_ASSERT (tmp_name);
02717 
02718   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
02719 
02720   myh = elf_link_hash_lookup
02721     (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
02722 
02723   if (myh != NULL)
02724     {
02725       /* We've already seen this guy.  */
02726       free (tmp_name);
02727       return myh;
02728     }
02729 
02730   /* The only trick here is using hash_table->arm_glue_size as the value.
02731      Even though the section isn't allocated yet, this is where we will be
02732      putting it.  */
02733   bh = NULL;
02734   val = globals->arm_glue_size + 1;
02735   _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
02736                                 tmp_name, BSF_GLOBAL, s, val,
02737                                 NULL, TRUE, FALSE, &bh);
02738 
02739   myh = (struct elf_link_hash_entry *) bh;
02740   myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
02741   myh->forced_local = 1;
02742 
02743   free (tmp_name);
02744 
02745   if (link_info->shared || globals->root.is_relocatable_executable
02746       || globals->pic_veneer)
02747     size = ARM2THUMB_PIC_GLUE_SIZE;
02748   else
02749     size = ARM2THUMB_STATIC_GLUE_SIZE;
02750 
02751   s->size += size;
02752   globals->arm_glue_size += size;
02753 
02754   return myh;
02755 }
02756 
02757 static void
02758 record_thumb_to_arm_glue (struct bfd_link_info *link_info,
02759                        struct elf_link_hash_entry *h)
02760 {
02761   const char *name = h->root.root.string;
02762   asection *s;
02763   char *tmp_name;
02764   struct elf_link_hash_entry *myh;
02765   struct bfd_link_hash_entry *bh;
02766   struct elf32_arm_link_hash_table *hash_table;
02767   bfd_vma val;
02768 
02769   hash_table = elf32_arm_hash_table (link_info);
02770 
02771   BFD_ASSERT (hash_table != NULL);
02772   BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
02773 
02774   s = bfd_get_section_by_name
02775     (hash_table->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
02776 
02777   BFD_ASSERT (s != NULL);
02778 
02779   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
02780                       + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
02781 
02782   BFD_ASSERT (tmp_name);
02783 
02784   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
02785 
02786   myh = elf_link_hash_lookup
02787     (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
02788 
02789   if (myh != NULL)
02790     {
02791       /* We've already seen this guy.  */
02792       free (tmp_name);
02793       return;
02794     }
02795 
02796   bh = NULL;
02797   val = hash_table->thumb_glue_size + 1;
02798   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
02799                                 tmp_name, BSF_GLOBAL, s, val,
02800                                 NULL, TRUE, FALSE, &bh);
02801 
02802   /* If we mark it 'Thumb', the disassembler will do a better job.  */
02803   myh = (struct elf_link_hash_entry *) bh;
02804   myh->type = ELF_ST_INFO (STB_LOCAL, STT_ARM_TFUNC);
02805   myh->forced_local = 1;
02806 
02807   free (tmp_name);
02808 
02809 #define CHANGE_TO_ARM "__%s_change_to_arm"
02810 #define BACK_FROM_ARM "__%s_back_from_arm"
02811 
02812   /* Allocate another symbol to mark where we switch to Arm mode.  */
02813   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
02814                       + strlen (CHANGE_TO_ARM) + 1);
02815 
02816   BFD_ASSERT (tmp_name);
02817 
02818   sprintf (tmp_name, CHANGE_TO_ARM, name);
02819 
02820   bh = NULL;
02821   val = hash_table->thumb_glue_size + 4,
02822   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
02823                                 tmp_name, BSF_LOCAL, s, val,
02824                                 NULL, TRUE, FALSE, &bh);
02825 
02826   free (tmp_name);
02827 
02828   s->size += THUMB2ARM_GLUE_SIZE;
02829   hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
02830 
02831   return;
02832 }
02833 
02834 
02835 /* Add an entry to the code/data map for section SEC.  */
02836 
02837 static void
02838 elf32_arm_section_map_add (asection *sec, char type, bfd_vma vma)
02839 {
02840   struct _arm_elf_section_data *sec_data = elf32_arm_section_data (sec);
02841   unsigned int newidx;
02842   
02843   if (sec_data->map == NULL)
02844     {
02845       sec_data->map = bfd_malloc (sizeof (elf32_arm_section_map));
02846       sec_data->mapcount = 0;
02847       sec_data->mapsize = 1;
02848     }
02849   
02850   newidx = sec_data->mapcount++;
02851   
02852   if (sec_data->mapcount > sec_data->mapsize)
02853     {
02854       sec_data->mapsize *= 2;
02855       sec_data->map = bfd_realloc (sec_data->map, sec_data->mapsize
02856                                  * sizeof (elf32_arm_section_map));
02857     }
02858   
02859   sec_data->map[newidx].vma = vma;
02860   sec_data->map[newidx].type = type;
02861 }
02862 
02863 
02864 /* Record information about a VFP11 denorm-erratum veneer.  Only ARM-mode
02865    veneers are handled for now.  */
02866 
02867 static bfd_vma
02868 record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
02869                              elf32_vfp11_erratum_list *branch,
02870                              bfd *branch_bfd,
02871                              asection *branch_sec,
02872                              unsigned int offset)
02873 {
02874   asection *s;
02875   struct elf32_arm_link_hash_table *hash_table;
02876   char *tmp_name;
02877   struct elf_link_hash_entry *myh;
02878   struct bfd_link_hash_entry *bh;
02879   bfd_vma val;
02880   struct _arm_elf_section_data *sec_data;
02881   int errcount;
02882   elf32_vfp11_erratum_list *newerr;
02883   
02884   hash_table = elf32_arm_hash_table (link_info);
02885   
02886   BFD_ASSERT (hash_table != NULL);
02887   BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
02888   
02889   s = bfd_get_section_by_name
02890     (hash_table->bfd_of_glue_owner, VFP11_ERRATUM_VENEER_SECTION_NAME);
02891   
02892   sec_data = elf32_arm_section_data (s);
02893   
02894   BFD_ASSERT (s != NULL);
02895   
02896   tmp_name = bfd_malloc ((bfd_size_type) strlen
02897                       (VFP11_ERRATUM_VENEER_ENTRY_NAME) + 10);
02898   
02899   BFD_ASSERT (tmp_name);
02900   
02901   sprintf (tmp_name, VFP11_ERRATUM_VENEER_ENTRY_NAME,
02902           hash_table->num_vfp11_fixes);
02903   
02904   myh = elf_link_hash_lookup
02905     (&(hash_table)->root, tmp_name, FALSE, FALSE, FALSE);
02906   
02907   BFD_ASSERT (myh == NULL);
02908   
02909   bh = NULL;
02910   val = hash_table->vfp11_erratum_glue_size;
02911   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
02912                                     tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
02913                                     NULL, TRUE, FALSE, &bh);
02914 
02915   myh = (struct elf_link_hash_entry *) bh;
02916   myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
02917   myh->forced_local = 1;
02918 
02919   /* Link veneer back to calling location.  */
02920   errcount = ++(sec_data->erratumcount);
02921   newerr = bfd_zmalloc (sizeof (elf32_vfp11_erratum_list));
02922   
02923   newerr->type = VFP11_ERRATUM_ARM_VENEER;
02924   newerr->vma = -1;
02925   newerr->u.v.branch = branch;
02926   newerr->u.v.id = hash_table->num_vfp11_fixes;
02927   branch->u.b.veneer = newerr;
02928 
02929   newerr->next = sec_data->erratumlist;
02930   sec_data->erratumlist = newerr;
02931 
02932   /* A symbol for the return from the veneer.  */
02933   sprintf (tmp_name, VFP11_ERRATUM_VENEER_ENTRY_NAME "_r",
02934           hash_table->num_vfp11_fixes);
02935 
02936   myh = elf_link_hash_lookup
02937     (&(hash_table)->root, tmp_name, FALSE, FALSE, FALSE);
02938   
02939   if (myh != NULL)
02940     abort ();
02941 
02942   bh = NULL;
02943   val = offset + 4;
02944   _bfd_generic_link_add_one_symbol (link_info, branch_bfd, tmp_name, BSF_LOCAL,
02945                                 branch_sec, val, NULL, TRUE, FALSE, &bh);
02946   
02947   myh = (struct elf_link_hash_entry *) bh;
02948   myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
02949   myh->forced_local = 1;
02950 
02951   free (tmp_name);
02952   
02953   /* Generate a mapping symbol for the veneer section, and explicitly add an
02954      entry for that symbol to the code/data map for the section.  */
02955   if (hash_table->vfp11_erratum_glue_size == 0)
02956     {
02957       bh = NULL;
02958       /* FIXME: Creates an ARM symbol.  Thumb mode will need attention if it
02959          ever requires this erratum fix.  */
02960       _bfd_generic_link_add_one_symbol (link_info,
02961                                    hash_table->bfd_of_glue_owner, "$a",
02962                                    BSF_LOCAL, s, 0, NULL,
02963                                         TRUE, FALSE, &bh);
02964 
02965       myh = (struct elf_link_hash_entry *) bh;
02966       myh->type = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
02967       myh->forced_local = 1;
02968       
02969       /* The elf32_arm_init_maps function only cares about symbols from input
02970          BFDs.  We must make a note of this generated mapping symbol
02971          ourselves so that code byteswapping works properly in
02972          elf32_arm_write_section.  */
02973       elf32_arm_section_map_add (s, 'a', 0);
02974     }
02975   
02976   s->size += VFP11_ERRATUM_VENEER_SIZE;
02977   hash_table->vfp11_erratum_glue_size += VFP11_ERRATUM_VENEER_SIZE;
02978   hash_table->num_vfp11_fixes++;
02979   
02980   /* The offset of the veneer.  */
02981   return val;
02982 }
02983 
02984 /* Add the glue sections to ABFD.  This function is called from the
02985    linker scripts in ld/emultempl/{armelf}.em.  */
02986 
02987 bfd_boolean
02988 bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
02989                                    struct bfd_link_info *info)
02990 {
02991   flagword flags;
02992   asection *sec;
02993 
02994   /* If we are only performing a partial
02995      link do not bother adding the glue.  */
02996   if (info->relocatable)
02997     return TRUE;
02998 
02999   sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
03000 
03001   if (sec == NULL)
03002     {
03003       /* Note: we do not include the flag SEC_LINKER_CREATED, as this
03004         will prevent elf_link_input_bfd() from processing the contents
03005         of this section.  */
03006       flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03007               | SEC_CODE | SEC_READONLY);
03008 
03009       sec = bfd_make_section_with_flags (abfd,
03010                                     ARM2THUMB_GLUE_SECTION_NAME,
03011                                     flags);
03012 
03013       if (sec == NULL
03014          || !bfd_set_section_alignment (abfd, sec, 2))
03015        return FALSE;
03016 
03017       /* Set the gc mark to prevent the section from being removed by garbage
03018         collection, despite the fact that no relocs refer to this section.  */
03019       sec->gc_mark = 1;
03020     }
03021 
03022   sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
03023 
03024   if (sec == NULL)
03025     {
03026       flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03027               | SEC_CODE | SEC_READONLY);
03028 
03029       sec = bfd_make_section_with_flags (abfd,
03030                                     THUMB2ARM_GLUE_SECTION_NAME,
03031                                     flags);
03032 
03033       if (sec == NULL
03034          || !bfd_set_section_alignment (abfd, sec, 2))
03035        return FALSE;
03036 
03037       sec->gc_mark = 1;
03038     }
03039 
03040   sec = bfd_get_section_by_name (abfd, VFP11_ERRATUM_VENEER_SECTION_NAME);
03041 
03042   if (sec == NULL)
03043     {
03044       flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03045               | SEC_CODE | SEC_READONLY);
03046 
03047       sec = bfd_make_section_with_flags (abfd,
03048                                     VFP11_ERRATUM_VENEER_SECTION_NAME,
03049                                          flags);
03050 
03051       if (sec == NULL
03052          || !bfd_set_section_alignment (abfd, sec, 2))
03053        return FALSE;
03054 
03055       sec->gc_mark = 1;
03056     }
03057 
03058   return TRUE;
03059 }
03060 
03061 /* Select a BFD to be used to hold the sections used by the glue code.
03062    This function is called from the linker scripts in ld/emultempl/
03063    {armelf/pe}.em  */
03064 
03065 bfd_boolean
03066 bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
03067 {
03068   struct elf32_arm_link_hash_table *globals;
03069 
03070   /* If we are only performing a partial link
03071      do not bother getting a bfd to hold the glue.  */
03072   if (info->relocatable)
03073     return TRUE;
03074 
03075   /* Make sure we don't attach the glue sections to a dynamic object.  */
03076   BFD_ASSERT (!(abfd->flags & DYNAMIC));
03077 
03078   globals = elf32_arm_hash_table (info);
03079 
03080   BFD_ASSERT (globals != NULL);
03081 
03082   if (globals->bfd_of_glue_owner != NULL)
03083     return TRUE;
03084 
03085   /* Save the bfd for later use.  */
03086   globals->bfd_of_glue_owner = abfd;
03087 
03088   return TRUE;
03089 }
03090 
03091 static void check_use_blx(struct elf32_arm_link_hash_table *globals)
03092 {
03093   if (elf32_arm_get_eabi_attr_int (globals->obfd, Tag_CPU_arch) > 2)
03094     globals->use_blx = 1;
03095 }
03096 
03097 bfd_boolean
03098 bfd_elf32_arm_process_before_allocation (bfd *abfd,
03099                                     struct bfd_link_info *link_info)
03100 {
03101   Elf_Internal_Shdr *symtab_hdr;
03102   Elf_Internal_Rela *internal_relocs = NULL;
03103   Elf_Internal_Rela *irel, *irelend;
03104   bfd_byte *contents = NULL;
03105 
03106   asection *sec;
03107   struct elf32_arm_link_hash_table *globals;
03108 
03109   /* If we are only performing a partial link do not bother
03110      to construct any glue.  */
03111   if (link_info->relocatable)
03112     return TRUE;
03113 
03114   /* Here we have a bfd that is to be included on the link.  We have a hook
03115      to do reloc rummaging, before section sizes are nailed down.  */
03116   globals = elf32_arm_hash_table (link_info);
03117   check_use_blx (globals);
03118 
03119   BFD_ASSERT (globals != NULL);
03120   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
03121 
03122   if (globals->byteswap_code && !bfd_big_endian (abfd))
03123     {
03124       _bfd_error_handler (_("%B: BE8 images only valid in big-endian mode."),
03125                        abfd);
03126       return FALSE;
03127     }
03128 
03129   /* Rummage around all the relocs and map the glue vectors.  */
03130   sec = abfd->sections;
03131 
03132   if (sec == NULL)
03133     return TRUE;
03134 
03135   for (; sec != NULL; sec = sec->next)
03136     {
03137       if (sec->reloc_count == 0)
03138        continue;
03139 
03140       if ((sec->flags & SEC_EXCLUDE) != 0)
03141        continue;
03142 
03143       symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
03144 
03145       /* Load the relocs.  */
03146       internal_relocs
03147        = _bfd_elf_link_read_relocs (abfd, sec, (void *) NULL,
03148                                  (Elf_Internal_Rela *) NULL, FALSE);
03149 
03150       if (internal_relocs == NULL)
03151        goto error_return;
03152 
03153       irelend = internal_relocs + sec->reloc_count;
03154       for (irel = internal_relocs; irel < irelend; irel++)
03155        {
03156          long r_type;
03157          unsigned long r_index;
03158 
03159          struct elf_link_hash_entry *h;
03160 
03161          r_type = ELF32_R_TYPE (irel->r_info);
03162          r_index = ELF32_R_SYM (irel->r_info);
03163 
03164          /* These are the only relocation types we care about.  */
03165          if (   r_type != R_ARM_PC24
03166              && r_type != R_ARM_PLT32
03167              && r_type != R_ARM_CALL
03168              && r_type != R_ARM_JUMP24
03169              && r_type != R_ARM_THM_CALL)
03170            continue;
03171 
03172          /* Get the section contents if we haven't done so already.  */
03173          if (contents == NULL)
03174            {
03175              /* Get cached copy if it exists.  */
03176              if (elf_section_data (sec)->this_hdr.contents != NULL)
03177               contents = elf_section_data (sec)->this_hdr.contents;
03178              else
03179               {
03180                 /* Go get them off disk.  */
03181                 if (! bfd_malloc_and_get_section (abfd, sec, &contents))
03182                   goto error_return;
03183               }
03184            }
03185 
03186          /* If the relocation is not against a symbol it cannot concern us.  */
03187          h = NULL;
03188 
03189          /* We don't care about local symbols.  */
03190          if (r_index < symtab_hdr->sh_info)
03191            continue;
03192 
03193          /* This is an external symbol.  */
03194          r_index -= symtab_hdr->sh_info;
03195          h = (struct elf_link_hash_entry *)
03196            elf_sym_hashes (abfd)[r_index];
03197 
03198          /* If the relocation is against a static symbol it must be within
03199             the current section and so cannot be a cross ARM/Thumb relocation.  */
03200          if (h == NULL)
03201            continue;
03202 
03203          /* If the call will go through a PLT entry then we do not need
03204             glue.  */
03205          if (globals->splt != NULL && h->plt.offset != (bfd_vma) -1)
03206            continue;
03207 
03208          switch (r_type)
03209            {
03210            case R_ARM_PC24:
03211            case R_ARM_PLT32:
03212            case R_ARM_CALL:
03213            case R_ARM_JUMP24:
03214              /* This one is a call from arm code.  We need to look up
03215                 the target of the call.  If it is a thumb target, we
03216                 insert glue.  */
03217              if (ELF_ST_TYPE(h->type) == STT_ARM_TFUNC
03218                 && !(r_type == R_ARM_CALL && globals->use_blx))
03219               record_arm_to_thumb_glue (link_info, h);
03220              break;
03221 
03222            case R_ARM_THM_CALL:
03223              /* This one is a call from thumb code.  We look
03224                 up the target of the call.  If it is not a thumb
03225                  target, we insert glue.  */
03226              if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC && !globals->use_blx)
03227               record_thumb_to_arm_glue (link_info, h);
03228              break;
03229 
03230            default:
03231              abort ();
03232            }
03233        }
03234 
03235       if (contents != NULL
03236          && elf_section_data (sec)->this_hdr.contents != contents)
03237        free (contents);
03238       contents = NULL;
03239 
03240       if (internal_relocs != NULL
03241          && elf_section_data (sec)->relocs != internal_relocs)
03242        free (internal_relocs);
03243       internal_relocs = NULL;
03244     }
03245 
03246   return TRUE;
03247 
03248 error_return:
03249   if (contents != NULL
03250       && elf_section_data (sec)->this_hdr.contents != contents)
03251     free (contents);
03252   if (internal_relocs != NULL
03253       && elf_section_data (sec)->relocs != internal_relocs)
03254     free (internal_relocs);
03255 
03256   return FALSE;
03257 }
03258 #endif
03259 
03260 
03261 /* Initialise maps of ARM/Thumb/data for input BFDs.  */
03262 
03263 void
03264 bfd_elf32_arm_init_maps (bfd *abfd)
03265 {
03266   Elf_Internal_Sym *isymbuf;
03267   Elf_Internal_Shdr *hdr;
03268   unsigned int i, localsyms;
03269 
03270   if ((abfd->flags & DYNAMIC) != 0)
03271     return;
03272 
03273   hdr = &elf_tdata (abfd)->symtab_hdr;
03274   localsyms = hdr->sh_info;
03275 
03276   /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
03277      should contain the number of local symbols, which should come before any
03278      global symbols.  Mapping symbols are always local.  */
03279   isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL,
03280                               NULL);
03281 
03282   /* No internal symbols read?  Skip this BFD.  */
03283   if (isymbuf == NULL)
03284     return;
03285 
03286   for (i = 0; i < localsyms; i++)
03287     {
03288       Elf_Internal_Sym *isym = &isymbuf[i];
03289       asection *sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
03290       const char *name;
03291       
03292       if (sec != NULL
03293           && ELF_ST_BIND (isym->st_info) == STB_LOCAL)
03294         {
03295           name = bfd_elf_string_from_elf_section (abfd,
03296             hdr->sh_link, isym->st_name);
03297           
03298           if (bfd_is_arm_special_symbol_name (name,
03299                                          BFD_ARM_SPECIAL_SYM_TYPE_MAP))
03300             elf32_arm_section_map_add (sec, name[1], isym->st_value);
03301         }
03302     }
03303 }
03304 
03305 
03306 void
03307 bfd_elf32_arm_set_vfp11_fix (bfd *obfd, struct bfd_link_info *link_info)
03308 {
03309   struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
03310   aeabi_attribute *out_attr = elf32_arm_tdata (obfd)->known_eabi_attributes;
03311   
03312   /* We assume that ARMv7+ does not need the VFP11 denorm erratum fix.  */
03313   if (out_attr[Tag_CPU_arch].i >= TAG_CPU_ARCH_V7)
03314     {
03315       switch (globals->vfp11_fix)
03316         {
03317         case BFD_ARM_VFP11_FIX_DEFAULT:
03318         case BFD_ARM_VFP11_FIX_NONE:
03319           globals->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;
03320           break;
03321         
03322         default:
03323           /* Give a warning, but do as the user requests anyway.  */
03324           (*_bfd_error_handler) (_("%B: warning: selected VFP11 erratum "
03325             "workaround is not necessary for target architecture"), obfd);
03326         }
03327     }
03328   else if (globals->vfp11_fix == BFD_ARM_VFP11_FIX_DEFAULT)
03329     /* For earlier architectures, we might need the workaround, but do not
03330        enable it by default.  If users is running with broken hardware, they
03331        must enable the erratum fix explicitly.  */
03332     globals->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;
03333 }
03334 
03335 
03336 enum bfd_arm_vfp11_pipe {
03337   VFP11_FMAC,
03338   VFP11_LS,
03339   VFP11_DS,
03340   VFP11_BAD
03341 };
03342 
03343 /* Return a VFP register number.  This is encoded as RX:X for single-precision
03344    registers, or X:RX for double-precision registers, where RX is the group of
03345    four bits in the instruction encoding and X is the single extension bit.
03346    RX and X fields are specified using their lowest (starting) bit.  The return
03347    value is:
03348 
03349      0...31: single-precision registers s0...s31
03350      32...63: double-precision registers d0...d31.
03351   
03352    Although X should be zero for VFP11 (encoding d0...d15 only), we might
03353    encounter VFP3 instructions, so we allow the full range for DP registers.  */
03354    
03355 static unsigned int
03356 bfd_arm_vfp11_regno (unsigned int insn, bfd_boolean is_double, unsigned int rx,
03357                      unsigned int x)
03358 {
03359   if (is_double)
03360     return (((insn >> rx) & 0xf) | (((insn >> x) & 1) << 4)) + 32;
03361   else
03362     return (((insn >> rx) & 0xf) << 1) | ((insn >> x) & 1);
03363 }
03364 
03365 /* Set bits in *WMASK according to a register number REG as encoded by
03366    bfd_arm_vfp11_regno().  Ignore d16-d31.  */
03367 
03368 static void
03369 bfd_arm_vfp11_write_mask (unsigned int *wmask, unsigned int reg)
03370 {
03371   if (reg < 32)
03372     *wmask |= 1 << reg;
03373   else if (reg < 48)
03374     *wmask |= 3 << ((reg - 32) * 2);
03375 }
03376 
03377 /* Return TRUE if WMASK overwrites anything in REGS.  */
03378 
03379 static bfd_boolean
03380 bfd_arm_vfp11_antidependency (unsigned int wmask, int *regs, int numregs)
03381 {
03382   int i;
03383   
03384   for (i = 0; i < numregs; i++)
03385     {
03386       unsigned int reg = regs[i];
03387 
03388       if (reg < 32 && (wmask & (1 << reg)) != 0)
03389         return TRUE;
03390       
03391       reg -= 32;
03392 
03393       if (reg >= 16)
03394         continue;
03395       
03396       if ((wmask & (3 << (reg * 2))) != 0)
03397         return TRUE;
03398     }
03399   
03400   return FALSE;
03401 }
03402 
03403 /* In this function, we're interested in two things: finding input registers
03404    for VFP data-processing instructions, and finding the set of registers which
03405    arbitrary VFP instructions may write to.  We use a 32-bit unsigned int to
03406    hold the written set, so FLDM etc. are easy to deal with (we're only
03407    interested in 32 SP registers or 16 dp registers, due to the VFP version
03408    implemented by the chip in question).  DP registers are marked by setting
03409    both SP registers in the write mask).  */
03410 
03411 static enum bfd_arm_vfp11_pipe
03412 bfd_arm_vfp11_insn_decode (unsigned int insn, unsigned int *destmask, int *regs,
03413                            int *numregs)
03414 {
03415   enum bfd_arm_vfp11_pipe pipe = VFP11_BAD;
03416   bfd_boolean is_double = ((insn & 0xf00) == 0xb00) ? 1 : 0;
03417 
03418   if ((insn & 0x0f000e10) == 0x0e000a00)  /* A data-processing insn.  */
03419     {
03420       unsigned int pqrs;
03421       unsigned int fd = bfd_arm_vfp11_regno (insn, is_double, 12, 22);
03422       unsigned int fm = bfd_arm_vfp11_regno (insn, is_double, 0, 5);
03423 
03424       pqrs = ((insn & 0x00800000) >> 20)
03425            | ((insn & 0x00300000) >> 19)
03426            | ((insn & 0x00000040) >> 6);
03427 
03428       switch (pqrs)
03429         {
03430         case 0: /* fmac[sd].  */
03431         case 1: /* fnmac[sd].  */
03432         case 2: /* fmsc[sd].  */
03433         case 3: /* fnmsc[sd].  */
03434           pipe = VFP11_FMAC;
03435           bfd_arm_vfp11_write_mask (destmask, fd);
03436           regs[0] = fd;
03437           regs[1] = bfd_arm_vfp11_regno (insn, is_double, 16, 7);  /* Fn.  */
03438           regs[2] = fm;
03439           *numregs = 3;
03440           break;
03441 
03442         case 4: /* fmul[sd].  */
03443         case 5: /* fnmul[sd].  */
03444         case 6: /* fadd[sd].  */
03445         case 7: /* fsub[sd].  */
03446           pipe = VFP11_FMAC;
03447           goto vfp_binop;
03448 
03449         case 8: /* fdiv[sd].  */
03450           pipe = VFP11_DS;
03451           vfp_binop:
03452           bfd_arm_vfp11_write_mask (destmask, fd);
03453           regs[0] = bfd_arm_vfp11_regno (insn, is_double, 16, 7);   /* Fn.  */
03454           regs[1] = fm;
03455           *numregs = 2;
03456           break;
03457 
03458         case 15: /* extended opcode.  */
03459           {
03460             unsigned int extn = ((insn >> 15) & 0x1e)
03461                               | ((insn >> 7) & 1);
03462 
03463             switch (extn)
03464               {
03465               case 0: /* fcpy[sd].  */
03466               case 1: /* fabs[sd].  */
03467               case 2: /* fneg[sd].  */
03468               case 8: /* fcmp[sd].  */
03469               case 9: /* fcmpe[sd].  */
03470               case 10: /* fcmpz[sd].  */
03471               case 11: /* fcmpez[sd].  */
03472               case 16: /* fuito[sd].  */
03473               case 17: /* fsito[sd].  */
03474               case 24: /* ftoui[sd].  */
03475               case 25: /* ftouiz[sd].  */
03476               case 26: /* ftosi[sd].  */
03477               case 27: /* ftosiz[sd].  */
03478                 /* These instructions will not bounce due to underflow.  */
03479                 *numregs = 0;
03480                 pipe = VFP11_FMAC;
03481                 break;
03482 
03483               case 3: /* fsqrt[sd].  */
03484                 /* fsqrt cannot underflow, but it can (perhaps) overwrite
03485                    registers to cause the erratum in previous instructions.  */
03486                 bfd_arm_vfp11_write_mask (destmask, fd);
03487                 pipe = VFP11_DS;
03488                 break;
03489 
03490               case 15: /* fcvt{ds,sd}.  */
03491                 {
03492                   int rnum = 0;
03493 
03494                   bfd_arm_vfp11_write_mask (destmask, fd);
03495 
03496                 /* Only FCVTSD can underflow.  */
03497                   if ((insn & 0x100) != 0)
03498                     regs[rnum++] = fm;
03499 
03500                   *numregs = rnum;
03501 
03502                   pipe = VFP11_FMAC;
03503                 }
03504                 break;
03505 
03506               default:
03507                 return VFP11_BAD;
03508               }
03509           }
03510           break;
03511 
03512         default:
03513           return VFP11_BAD;
03514         }
03515     }
03516   /* Two-register transfer.  */
03517   else if ((insn & 0x0fe00ed0) == 0x0c400a10)
03518     {
03519       unsigned int fm = bfd_arm_vfp11_regno (insn, is_double, 0, 5);
03520       
03521       if ((insn & 0x100000) == 0)
03522        {
03523           if (is_double)
03524             bfd_arm_vfp11_write_mask (destmask, fm);
03525           else
03526             {
03527               bfd_arm_vfp11_write_mask (destmask, fm);
03528               bfd_arm_vfp11_write_mask (destmask, fm + 1);
03529             }
03530        }
03531 
03532       pipe = VFP11_LS;
03533     }
03534   else if ((insn & 0x0e100e00) == 0x0c100a00)  /* A load insn.  */
03535     {
03536       int fd = bfd_arm_vfp11_regno (insn, is_double, 12, 22);
03537       unsigned int puw = ((insn >> 21) & 0x1) | (((insn >> 23) & 3) << 1);
03538       
03539       switch (puw)
03540         {
03541         case 0: /* Two-reg transfer.  We should catch these above.  */
03542           abort ();
03543         
03544         case 2: /* fldm[sdx].  */
03545         case 3:
03546         case 5:
03547           {
03548             unsigned int i, offset = insn & 0xff;
03549 
03550             if (is_double)
03551               offset >>= 1;
03552 
03553             for (i = fd; i < fd + offset; i++)
03554               bfd_arm_vfp11_write_mask (destmask, i);
03555           }
03556           break;
03557         
03558         case 4: /* fld[sd].  */
03559         case 6:
03560           bfd_arm_vfp11_write_mask (destmask, fd);
03561           break;
03562         
03563         default:
03564           return VFP11_BAD;
03565         }
03566 
03567       pipe = VFP11_LS;
03568     }
03569   /* Single-register transfer. Note L==0.  */
03570   else if ((insn & 0x0f100e10) == 0x0e000a10)
03571     {
03572       unsigned int opcode = (insn >> 21) & 7;
03573       unsigned int fn = bfd_arm_vfp11_regno (insn, is_double, 16, 7);
03574 
03575       switch (opcode)
03576         {
03577         case 0: /* fmsr/fmdlr.  */
03578         case 1: /* fmdhr.  */
03579           /* Mark fmdhr and fmdlr as writing to the whole of the DP
03580              destination register.  I don't know if this is exactly right,
03581              but it is the conservative choice.  */
03582           bfd_arm_vfp11_write_mask (destmask, fn);
03583           break;
03584 
03585         case 7: /* fmxr.  */
03586           break;
03587         }
03588 
03589       pipe = VFP11_LS;
03590     }
03591 
03592   return pipe;
03593 }
03594 
03595 
03596 static int elf32_arm_compare_mapping (const void * a, const void * b);
03597 
03598 
03599 /* Look for potentially-troublesome code sequences which might trigger the
03600    VFP11 denormal/antidependency erratum.  See, e.g., the ARM1136 errata sheet
03601    (available from ARM) for details of the erratum.  A short version is
03602    described in ld.texinfo.  */
03603 
03604 bfd_boolean
03605 bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info)
03606 {
03607   asection *sec;
03608   bfd_byte *contents = NULL;
03609   int state = 0;
03610   int regs[3], numregs = 0;
03611   struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
03612   int use_vector = (globals->vfp11_fix == BFD_ARM_VFP11_FIX_VECTOR);
03613   
03614   /* We use a simple FSM to match troublesome VFP11 instruction sequences.
03615      The states transition as follows:
03616      
03617        0 -> 1 (vector) or 0 -> 2 (scalar)
03618            A VFP FMAC-pipeline instruction has been seen. Fill
03619            regs[0]..regs[numregs-1] with its input operands. Remember this
03620            instruction in 'first_fmac'.
03621 
03622        1 -> 2
03623            Any instruction, except for a VFP instruction which overwrites
03624            regs[*].
03625        
03626        1 -> 3 [ -> 0 ]  or
03627        2 -> 3 [ -> 0 ]
03628            A VFP instruction has been seen which overwrites any of regs[*].
03629            We must make a veneer!  Reset state to 0 before examining next
03630            instruction.
03631        
03632        2 -> 0
03633            If we fail to match anything in state 2, reset to state 0 and reset
03634            the instruction pointer to the instruction after 'first_fmac'.
03635 
03636      If the VFP11 vector mode is in use, there must be at least two unrelated
03637      instructions between anti-dependent VFP11 instructions to properly avoid
03638      triggering the erratum, hence the use of the extra state 1.
03639   */
03640 
03641   /* If we are only performing a partial link do not bother
03642      to construct any glue.  */
03643   if (link_info->relocatable)
03644     return TRUE;
03645 
03646   /* We should have chosen a fix type by the time we get here.  */
03647   BFD_ASSERT (globals->vfp11_fix != BFD_ARM_VFP11_FIX_DEFAULT);
03648 
03649   if (globals->vfp11_fix == BFD_ARM_VFP11_FIX_NONE)
03650     return TRUE;
03651   
03652   for (sec = abfd->sections; sec != NULL; sec = sec->next)
03653     {
03654       unsigned int i, span, first_fmac = 0, veneer_of_insn = 0;
03655       struct _arm_elf_section_data *sec_data;
03656 
03657       /* If we don't have executable progbits, we're not interested in this
03658          section.  Also skip if section is to be excluded.  */
03659       if (elf_section_type (sec) != SHT_PROGBITS
03660           || (elf_section_flags (sec) & SHF_EXECINSTR) == 0
03661           || (sec->flags & SEC_EXCLUDE) != 0
03662           || strcmp (sec->name, VFP11_ERRATUM_VENEER_SECTION_NAME) == 0)
03663         continue;
03664 
03665       sec_data = elf32_arm_section_data (sec);
03666       
03667       if (sec_data->mapcount == 0)
03668         continue;
03669       
03670       if (elf_section_data (sec)->this_hdr.contents != NULL)
03671        contents = elf_section_data (sec)->this_hdr.contents;
03672       else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
03673        goto error_return;
03674 
03675       qsort (sec_data->map, sec_data->mapcount, sizeof (elf32_arm_section_map),
03676             elf32_arm_compare_mapping);
03677 
03678       for (span = 0; span < sec_data->mapcount; span++)
03679         {
03680           unsigned int span_start = sec_data->map[span].vma;
03681           unsigned int span_end = (span == sec_data->mapcount - 1)
03682                               ? sec->size : sec_data->map[span + 1].vma;
03683           char span_type = sec_data->map[span].type;
03684           
03685           /* FIXME: Only ARM mode is supported at present.  We may need to
03686              support Thumb-2 mode also at some point.  */
03687           if (span_type != 'a')
03688             continue;
03689 
03690           for (i = span_start; i < span_end;)
03691             {
03692               unsigned int next_i = i + 4;
03693               unsigned int insn = bfd_big_endian (abfd)
03694                 ? (contents[i] << 24)
03695                   | (contents[i + 1] << 16)
03696                   | (contents[i + 2] << 8)
03697                   | contents[i + 3]
03698                 : (contents[i + 3] << 24)
03699                   | (contents[i + 2] << 16)
03700                   | (contents[i + 1] << 8)
03701                   | contents[i];
03702               unsigned int writemask = 0;
03703               enum bfd_arm_vfp11_pipe pipe;
03704 
03705               switch (state)
03706                 {
03707                 case 0:
03708                   pipe = bfd_arm_vfp11_insn_decode (insn, &writemask, regs,
03709                                                     &numregs);
03710                   /* I'm assuming the VFP11 erratum can trigger with denorm
03711                      operands on either the FMAC or the DS pipeline. This might
03712                      lead to slightly overenthusiastic veneer insertion.  */
03713                   if (pipe == VFP11_FMAC || pipe == VFP11_DS)
03714                     {
03715                       state = use_vector ? 1 : 2;
03716                       first_fmac = i;
03717                       veneer_of_insn = insn;
03718                     }
03719                   break;
03720 
03721                 case 1:
03722                   {
03723                     int other_regs[3], other_numregs;
03724                     pipe = bfd_arm_vfp11_insn_decode (insn, &writemask,
03725                                                 other_regs,
03726                                                       &other_numregs);
03727                     if (pipe != VFP11_BAD
03728                         && bfd_arm_vfp11_antidependency (writemask, regs,
03729                                                   numregs))
03730                       state = 3;
03731                     else
03732                       state = 2;
03733                   }
03734                   break;
03735 
03736                 case 2:
03737                   {
03738                     int other_regs[3], other_numregs;
03739                     pipe = bfd_arm_vfp11_insn_decode (insn, &writemask,
03740                                                 other_regs,
03741                                                       &other_numregs);
03742                     if (pipe != VFP11_BAD
03743                         && bfd_arm_vfp11_antidependency (writemask, regs,
03744                                                   numregs))
03745                       state = 3;
03746                     else
03747                       {
03748                         state = 0;
03749                         next_i = first_fmac + 4;
03750                       }
03751                   }
03752                   break;
03753 
03754                 case 3:
03755                   abort ();  /* Should be unreachable.  */
03756                 }
03757 
03758               if (state == 3)
03759                 {
03760                   elf32_vfp11_erratum_list *newerr
03761                     = bfd_zmalloc (sizeof (elf32_vfp11_erratum_list));
03762                   int errcount;
03763 
03764                   errcount = ++(elf32_arm_section_data (sec)->erratumcount);
03765 
03766                   newerr->u.b.vfp_insn = veneer_of_insn;
03767 
03768                   switch (span_type)
03769                     {
03770                     case 'a':
03771                       newerr->type = VFP11_ERRATUM_BRANCH_TO_ARM_VENEER;
03772                       break;
03773                     
03774                     default:
03775                       abort ();
03776                     }
03777 
03778                   record_vfp11_erratum_veneer (link_info, newerr, abfd, sec,
03779                                           first_fmac);
03780 
03781                   newerr->vma = -1;
03782 
03783                   newerr->next = sec_data->erratumlist;
03784                   sec_data->erratumlist = newerr;
03785 
03786                   state = 0;
03787                 }
03788 
03789               i = next_i;
03790             }
03791         }
03792       
03793       if (contents != NULL
03794           && elf_section_data (sec)->this_hdr.contents != contents)
03795         free (contents);
03796       contents = NULL;
03797     }
03798 
03799   return TRUE;
03800 
03801 error_return:
03802   if (contents != NULL
03803       && elf_section_data (sec)->this_hdr.contents != contents)
03804     free (contents);
03805   
03806   return FALSE;
03807 }
03808 
03809 /* Find virtual-memory addresses for VFP11 erratum veneers and return locations
03810    after sections have been laid out, using specially-named symbols.  */
03811 
03812 void
03813 bfd_elf32_arm_vfp11_fix_veneer_locations (bfd *abfd,
03814                                      struct bfd_link_info *link_info)
03815 {
03816   asection *sec;
03817   struct elf32_arm_link_hash_table *globals;
03818   char *tmp_name;
03819   
03820   if (link_info->relocatable)
03821     return;
03822   
03823   globals = elf32_arm_hash_table (link_info);
03824   
03825   tmp_name = bfd_malloc ((bfd_size_type) strlen
03826                         (VFP11_ERRATUM_VENEER_ENTRY_NAME) + 10);
03827 
03828   for (sec = abfd->sections; sec != NULL; sec = sec->next)
03829     {
03830       struct _arm_elf_section_data *sec_data = elf32_arm_section_data (sec);
03831       elf32_vfp11_erratum_list *errnode = sec_data->erratumlist;
03832       
03833       for (; errnode != NULL; errnode = errnode->next)
03834         {
03835           struct elf_link_hash_entry *myh;
03836           bfd_vma vma;
03837 
03838           switch (errnode->type)
03839             {
03840             case VFP11_ERRATUM_BRANCH_TO_ARM_VENEER:
03841             case VFP11_ERRATUM_BRANCH_TO_THUMB_VENEER:
03842               /* Find veneer symbol.  */
03843               sprintf (tmp_name, VFP11_ERRATUM_VENEER_ENTRY_NAME,
03844                      errnode->u.b.veneer->u.v.id);
03845 
03846               myh = elf_link_hash_lookup
03847                 (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
03848 
03849               if (myh == NULL)
03850                 (*_bfd_error_handler) (_("%B: unable to find VFP11 veneer "
03851                                     "`%s'"), abfd, tmp_name);
03852 
03853               vma = myh->root.u.def.section->output_section->vma
03854                     + myh->root.u.def.section->output_offset
03855                     + myh->root.u.def.value;
03856 
03857               errnode->u.b.veneer->vma = vma;
03858               break;
03859 
03860            case VFP11_ERRATUM_ARM_VENEER:
03861             case VFP11_ERRATUM_THUMB_VENEER:
03862               /* Find return location.  */
03863               sprintf (tmp_name, VFP11_ERRATUM_VENEER_ENTRY_NAME "_r",
03864                        errnode->u.v.id);
03865 
03866               myh = elf_link_hash_lookup
03867                 (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
03868 
03869               if (myh == NULL)
03870                 (*_bfd_error_handler) (_("%B: unable to find VFP11 veneer "
03871                                     "`%s'"), abfd, tmp_name);
03872 
03873               vma = myh->root.u.def.section->output_section->vma
03874                     + myh->root.u.def.section->output_offset
03875                     + myh->root.u.def.value;
03876 
03877               errnode->u.v.branch->vma = vma;
03878               break;
03879             
03880             default:
03881               abort ();
03882             }
03883         }
03884     }
03885   
03886   free (tmp_name);
03887 }
03888 
03889 
03890 /* Set target relocation values needed during linking.  */
03891 
03892 void
03893 bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
03894                              struct bfd_link_info *link_info,
03895                              int target1_is_rel,
03896                              char * target2_type,
03897                                  int fix_v4bx,
03898                              int use_blx,
03899                                  bfd_arm_vfp11_fix vfp11_fix,
03900                              int no_enum_warn, int pic_veneer)
03901 {
03902   struct elf32_arm_link_hash_table *globals;
03903 
03904   globals = elf32_arm_hash_table (link_info);
03905 
03906   globals->target1_is_rel = target1_is_rel;
03907   if (strcmp (target2_type, "rel") == 0)
03908     globals->target2_reloc = R_ARM_REL32;
03909   else if (strcmp (target2_type, "abs") == 0)
03910     globals->target2_reloc = R_ARM_ABS32;
03911   else if (strcmp (target2_type, "got-rel") == 0)
03912     globals->target2_reloc = R_ARM_GOT_PREL;
03913   else
03914     {
03915       _bfd_error_handler (_("Invalid TARGET2 relocation type '%s'."),
03916                        target2_type);
03917     }
03918   globals->fix_v4bx = fix_v4bx;
03919   globals->use_blx |= use_blx;
03920   globals->vfp11_fix = vfp11_fix;
03921   globals->pic_veneer = pic_veneer;
03922 
03923   elf32_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
03924 }
03925 
03926 /* The thumb form of a long branch is a bit finicky, because the offset
03927    encoding is split over two fields, each in it's own instruction. They
03928    can occur in any order. So given a thumb form of long branch, and an
03929    offset, insert the offset into the thumb branch and return finished
03930    instruction.
03931 
03932    It takes two thumb instructions to encode the target address. Each has
03933    11 bits to invest. The upper 11 bits are stored in one (identified by
03934    H-0.. see below), the lower 11 bits are stored in the other (identified
03935    by H-1).
03936 
03937    Combine together and shifted left by 1 (it's a half word address) and
03938    there you have it.
03939 
03940    Op: 1111 = F,
03941    H-0, upper address-0 = 000
03942    Op: 1111 = F,
03943    H-1, lower address-0 = 800
03944 
03945    They can be ordered either way, but the arm tools I've seen always put
03946    the lower one first. It probably doesn't matter. krk@cygnus.com
03947 
03948    XXX:  Actually the order does matter.  The second instruction (H-1)
03949    moves the computed address into the PC, so it must be the second one
03950    in the sequence.  The problem, however is that whilst little endian code
03951    stores the instructions in HI then LOW order, big endian code does the
03952    reverse.  nickc@cygnus.com.  */
03953 
03954 #define LOW_HI_ORDER      0xF800F000
03955 #define HI_LOW_ORDER      0xF000F800
03956 
03957 static insn32
03958 insert_thumb_branch (insn32 br_insn, int rel_off)
03959 {
03960   unsigned int low_bits;
03961   unsigned int high_bits;
03962 
03963   BFD_ASSERT ((rel_off & 1) != 1);
03964 
03965   rel_off >>= 1;                          /* Half word aligned address.  */
03966   low_bits = rel_off & 0x000007FF;        /* The bottom 11 bits.  */
03967   high_bits = (rel_off >> 11) & 0x000007FF;      /* The top 11 bits.  */
03968 
03969   if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
03970     br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
03971   else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
03972     br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
03973   else
03974     /* FIXME: abort is probably not the right call. krk@cygnus.com  */
03975     abort (); /* Error - not a valid branch instruction form.  */
03976 
03977   return br_insn;
03978 }
03979 
03980 
03981 /* Store an Arm insn into an output section not processed by
03982    elf32_arm_write_section.  */
03983 
03984 static void
03985 put_arm_insn (struct elf32_arm_link_hash_table *htab,
03986             bfd * output_bfd, bfd_vma val, void * ptr)
03987 {
03988     if (htab->byteswap_code != bfd_little_endian (output_bfd))
03989       bfd_putl32 (val, ptr);
03990     else
03991       bfd_putb32 (val, ptr);
03992 }
03993 
03994 
03995 /* Store a 16-bit Thumb insn into an output section not processed by
03996    elf32_arm_write_section.  */
03997 
03998 static void
03999 put_thumb_insn (struct elf32_arm_link_hash_table *htab,
04000               bfd * output_bfd, bfd_vma val, void * ptr)
04001 {
04002     if (htab->byteswap_code != bfd_little_endian (output_bfd))
04003       bfd_putl16 (val, ptr);
04004     else
04005       bfd_putb16 (val, ptr);
04006 }
04007 
04008 
04009 /* Thumb code calling an ARM function.  */
04010 
04011 static int
04012 elf32_thumb_to_arm_stub (struct bfd_link_info * info,
04013                       const char *           name,
04014                       bfd *                  input_bfd,
04015                       bfd *                  output_bfd,
04016                       asection *             input_section,
04017                       bfd_byte *             hit_data,
04018                       asection *             sym_sec,
04019                       bfd_vma                offset,
04020                       bfd_signed_vma         addend,
04021                       bfd_vma                val,
04022                       char **error_message)
04023 {
04024   asection * s = 0;
04025   bfd_vma my_offset;
04026   unsigned long int tmp;
04027   long int ret_offset;
04028   struct elf_link_hash_entry * myh;
04029   struct elf32_arm_link_hash_table * globals;
04030 
04031   myh = find_thumb_glue (info, name, error_message);
04032   if (myh == NULL)
04033     return FALSE;
04034 
04035   globals = elf32_arm_hash_table (info);
04036 
04037   BFD_ASSERT (globals != NULL);
04038   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
04039 
04040   my_offset = myh->root.u.def.value;
04041 
04042   s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
04043                             THUMB2ARM_GLUE_SECTION_NAME);
04044 
04045   BFD_ASSERT (s != NULL);
04046   BFD_ASSERT (s->contents != NULL);
04047   BFD_ASSERT (s->output_section != NULL);
04048 
04049   if ((my_offset & 0x01) == 0x01)
04050     {
04051       if (sym_sec != NULL
04052          && sym_sec->owner != NULL
04053          && !INTERWORK_FLAG (sym_sec->owner))
04054        {
04055          (*_bfd_error_handler)
04056            (_("%B(%s): warning: interworking not enabled.\n"
04057               "  first occurrence: %B: thumb call to arm"),
04058             sym_sec->owner, input_bfd, name);
04059 
04060          return FALSE;
04061        }
04062 
04063       --my_offset;
04064       myh->root.u.def.value = my_offset;
04065 
04066       put_thumb_insn (globals, output_bfd, (bfd_vma) t2a1_bx_pc_insn,
04067                     s->contents + my_offset);
04068 
04069       put_thumb_insn (globals, output_bfd, (bfd_vma) t2a2_noop_insn,
04070                     s->contents + my_offset + 2);
04071 
04072       ret_offset =
04073        /* Address of destination of the stub.  */
04074        ((bfd_signed_vma) val)
04075        - ((bfd_signed_vma)
04076           /* Offset from the start of the current section
04077              to the start of the stubs.  */
04078           (s->output_offset
04079            /* Offset of the start of this stub from the start of the stubs.  */
04080            + my_offset
04081            /* Address of the start of the current section.  */
04082            + s->output_section->vma)
04083           /* The branch instruction is 4 bytes into the stub.  */
04084           + 4
04085           /* ARM branches work from the pc of the instruction + 8.  */
04086           + 8);
04087 
04088       put_arm_insn (globals, output_bfd,
04089                   (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
04090                   s->contents + my_offset + 4);
04091     }
04092 
04093   BFD_ASSERT (my_offset <= globals->thumb_glue_size);
04094 
04095   /* Now go back and fix up the original BL insn to point to here.  */
04096   ret_offset =
04097     /* Address of where the stub is located.  */
04098     (s->output_section->vma + s->output_offset + my_offset)
04099      /* Address of where the BL is located.  */
04100     - (input_section->output_section->vma + input_section->output_offset
04101        + offset)
04102     /* Addend in the relocation.  */
04103     - addend
04104     /* Biassing for PC-relative addressing.  */
04105     - 8;
04106 
04107   tmp = bfd_get_32 (input_bfd, hit_data
04108                   - input_section->vma);
04109 
04110   bfd_put_32 (output_bfd,
04111              (bfd_vma) insert_thumb_branch (tmp, ret_offset),
04112              hit_data - input_section->vma);
04113 
04114   return TRUE;
04115 }
04116 
04117 /* Populate an Arm to Thumb stub.  Returns the stub symbol.  */
04118 
04119 static struct elf_link_hash_entry *
04120 elf32_arm_create_thumb_stub (struct bfd_link_info * info,
04121                           const char *           name,
04122                           bfd *                  input_bfd,
04123                           bfd *                  output_bfd,
04124                           asection *             sym_sec,
04125                           bfd_vma                val,
04126                           asection            *s,
04127                           char **error_message)
04128 {
04129   bfd_vma my_offset;
04130   long int ret_offset;
04131   struct elf_link_hash_entry * myh;
04132   struct elf32_arm_link_hash_table * globals;
04133 
04134   myh = find_arm_glue (info, name, error_message);
04135   if (myh == NULL)
04136     return NULL;
04137 
04138   globals = elf32_arm_hash_table (info);
04139 
04140   BFD_ASSERT (globals != NULL);
04141   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
04142 
04143   my_offset = myh->root.u.def.value;
04144 
04145   if ((my_offset & 0x01) == 0x01)
04146     {
04147       if (sym_sec != NULL
04148          && sym_sec->owner != NULL
04149          && !INTERWORK_FLAG (sym_sec->owner))
04150        {
04151          (*_bfd_error_handler)
04152            (_("%B(%s): warning: interworking not enabled.\n"
04153               "  first occurrence: %B: arm call to thumb"),
04154             sym_sec->owner, input_bfd, name);
04155        }
04156 
04157       --my_offset;
04158       myh->root.u.def.value = my_offset;
04159 
04160       if (info->shared || globals->root.is_relocatable_executable
04161          || globals->pic_veneer)
04162        {
04163          /* For relocatable objects we can't use absolute addresses,
04164             so construct the address from a relative offset.  */
04165          /* TODO: If the offset is small it's probably worth
04166             constructing the address with adds.  */
04167          put_arm_insn (globals, output_bfd, (bfd_vma) a2t1p_ldr_insn,
04168                      s->contents + my_offset);
04169          put_arm_insn (globals, output_bfd, (bfd_vma) a2t2p_add_pc_insn,
04170                      s->contents + my_offset + 4);
04171          put_arm_insn (globals, output_bfd, (bfd_vma) a2t3p_bx_r12_insn,
04172                      s->contents + my_offset + 8);
04173          /* Adjust the offset by 4 for the position of the add,
04174             and 8 for the pipeline offset.  */
04175          ret_offset = (val - (s->output_offset
04176                             + s->output_section->vma
04177                             + my_offset + 12))
04178                      | 1;
04179          bfd_put_32 (output_bfd, ret_offset,
04180                     s->contents + my_offset + 12);
04181        }
04182       else
04183        {
04184          put_arm_insn (globals, output_bfd, (bfd_vma) a2t1_ldr_insn,
04185                      s->contents + my_offset);
04186 
04187          put_arm_insn (globals, output_bfd, (bfd_vma) a2t2_bx_r12_insn,
04188                      s->contents + my_offset + 4);
04189 
04190          /* It's a thumb address.  Add the low order bit.  */
04191          bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
04192                     s->contents + my_offset + 8);
04193        }
04194     }
04195 
04196   BFD_ASSERT (my_offset <= globals->arm_glue_size);
04197 
04198   return myh;
04199 }
04200 
04201 /* Arm code calling a Thumb function.  */
04202 
04203 static int
04204 elf32_arm_to_thumb_stub (struct bfd_link_info * info,
04205                       const char *           name,
04206                       bfd *                  input_bfd,
04207                       bfd *                  output_bfd,
04208                       asection *             input_section,
04209                       bfd_byte *             hit_data,
04210                       asection *             sym_sec,
04211                       bfd_vma                offset,
04212                       bfd_signed_vma         addend,
04213                       bfd_vma                val,
04214                       char **error_message)
04215 {
04216   unsigned long int tmp;
04217   bfd_vma my_offset;
04218   asection * s;
04219   long int ret_offset;
04220   struct elf_link_hash_entry * myh;
04221   struct elf32_arm_link_hash_table * globals;
04222 
04223   globals = elf32_arm_hash_table (info);
04224 
04225   BFD_ASSERT (globals != NULL);
04226   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
04227 
04228   s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
04229                             ARM2THUMB_GLUE_SECTION_NAME);
04230   BFD_ASSERT (s != NULL);
04231   BFD_ASSERT (s->contents != NULL);
04232   BFD_ASSERT (s->output_section != NULL);
04233 
04234   myh = elf32_arm_create_thumb_stub (info, name, input_bfd, output_bfd,
04235                                  sym_sec, val, s, error_message);
04236   if (!myh)
04237     return FALSE;
04238 
04239   my_offset = myh->root.u.def.value;
04240   tmp = bfd_get_32 (input_bfd, hit_data);
04241   tmp = tmp & 0xFF000000;
04242 
04243   /* Somehow these are both 4 too far, so subtract 8.  */
04244   ret_offset = (s->output_offset
04245               + my_offset
04246               + s->output_section->vma
04247               - (input_section->output_offset
04248                  + input_section->output_section->vma
04249                  + offset + addend)
04250               - 8);
04251 
04252   tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
04253 
04254   bfd_put_32 (output_bfd, (bfd_vma) tmp, hit_data - input_section->vma);
04255 
04256   return TRUE;
04257 }
04258 
04259 /* Populate Arm stub for an exported Thumb function.  */
04260 
04261 static bfd_boolean
04262 elf32_arm_to_thumb_export_stub (struct elf_link_hash_entry *h, void * inf)
04263 {
04264   struct bfd_link_info * info = (struct bfd_link_info *) inf;
04265   asection * s;
04266   struct elf_link_hash_entry * myh;
04267   struct elf32_arm_link_hash_entry *eh;
04268   struct elf32_arm_link_hash_table * globals;
04269   asection *sec;
04270   bfd_vma val;
04271   char *error_message;
04272 
04273   eh = elf32_arm_hash_entry(h);
04274   /* Allocate stubs for exported Thumb functions on v4t.  */
04275   if (eh->export_glue == NULL)
04276     return TRUE;
04277 
04278   globals = elf32_arm_hash_table (info);
04279 
04280   BFD_ASSERT (globals != NULL);
04281   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
04282 
04283   s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
04284                             ARM2THUMB_GLUE_SECTION_NAME);
04285   BFD_ASSERT (s != NULL);
04286   BFD_ASSERT (s->contents != NULL);
04287   BFD_ASSERT (s->output_section != NULL);
04288 
04289   sec = eh->export_glue->root.u.def.section;
04290 
04291   BFD_ASSERT (sec->output_section != NULL);
04292 
04293   val = eh->export_glue->root.u.def.value + sec->output_offset
04294        + sec->output_section->vma;
04295   myh = elf32_arm_create_thumb_stub (info, h->root.root.string,
04296                                  h->root.u.def.section->owner,
04297                                  globals->obfd, sec, val, s,
04298                                  &error_message);
04299   BFD_ASSERT (myh);
04300   return TRUE;
04301 }
04302 
04303 /* Generate Arm stubs for exported Thumb symbols.  */
04304 static void
04305 elf32_arm_begin_write_processing (bfd *abfd ATTRIBUTE_UNUSED, 
04306                               struct bfd_link_info *link_info)
04307 {
04308   struct elf32_arm_link_hash_table * globals;
04309 
04310   if (!link_info)
04311     return;
04312 
04313   globals = elf32_arm_hash_table (link_info);
04314   /* If blx is available then exported Thumb symbols are OK and there is
04315      nothing to do.  */
04316   if (globals->use_blx)
04317     return;
04318 
04319   elf_link_hash_traverse (&globals->root, elf32_arm_to_thumb_export_stub,
04320                        link_info);
04321 }
04322 
04323 /* Some relocations map to different relocations depending on the
04324    target.  Return the real relocation.  */
04325 static int
04326 arm_real_reloc_type (struct elf32_arm_link_hash_table * globals,
04327                    int r_type)
04328 {
04329   switch (r_type)
04330     {
04331     case R_ARM_TARGET1:
04332       if (globals->target1_is_rel)
04333        return R_ARM_REL32;
04334       else
04335        return R_ARM_ABS32;
04336 
04337     case R_ARM_TARGET2:
04338       return globals->target2_reloc;
04339 
04340     default:
04341       return r_type;
04342     }
04343 }
04344 
04345 /* Return the base VMA address which should be subtracted from real addresses
04346    when resolving @dtpoff relocation.
04347    This is PT_TLS segment p_vaddr.  */
04348 
04349 static bfd_vma
04350 dtpoff_base (struct bfd_link_info *info)
04351 {
04352   /* If tls_sec is NULL, we should have signalled an error already.  */
04353   if (elf_hash_table (info)->tls_sec == NULL)
04354     return 0;
04355   return elf_hash_table (info)->tls_sec->vma;
04356 }
04357 
04358 /* Return the relocation value for @tpoff relocation
04359    if STT_TLS virtual address is ADDRESS.  */
04360 
04361 static bfd_vma
04362 tpoff (struct bfd_link_info *info, bfd_vma address)
04363 {
04364   struct elf_link_hash_table *htab = elf_hash_table (info);
04365   bfd_vma base;
04366 
04367   /* If tls_sec is NULL, we should have signalled an error already.  */
04368   if (htab->tls_sec == NULL)
04369     return 0;
04370   base = align_power ((bfd_vma) TCB_SIZE, htab->tls_sec->alignment_power);
04371   return address - htab->tls_sec->vma + base;
04372 }
04373 
04374 /* Perform an R_ARM_ABS12 relocation on the field pointed to by DATA.
04375    VALUE is the relocation value.  */
04376 
04377 static bfd_reloc_status_type
04378 elf32_arm_abs12_reloc (bfd *abfd, void *data, bfd_vma value)
04379 {
04380   if (value > 0xfff)
04381     return bfd_reloc_overflow;
04382 
04383   value |= bfd_get_32 (abfd, data) & 0xfffff000;
04384   bfd_put_32 (abfd, value, data);
04385   return bfd_reloc_ok;
04386 }
04387 
04388 /* For a given value of n, calculate the value of G_n as required to
04389    deal with group relocations.  We return it in the form of an
04390    encoded constant-and-rotation, together with the final residual.  If n is
04391    specified as less than zero, then final_residual is filled with the
04392    input value and no further action is performed.  */
04393 
04394 static bfd_vma
04395 calculate_group_reloc_mask (bfd_vma value, int n, bfd_vma *final_residual)
04396 {
04397   int current_n;
04398   bfd_vma g_n;
04399   bfd_vma encoded_g_n = 0;
04400   bfd_vma residual = value; /* Also known as Y_n.  */
04401 
04402   for (current_n = 0; current_n <= n; current_n++)
04403     {
04404       int shift;
04405 
04406       /* Calculate which part of the value to mask.  */
04407       if (residual == 0)
04408         shift = 0;
04409       else
04410         {
04411           int msb;
04412 
04413           /* Determine the most significant bit in the residual and
04414              align the resulting value to a 2-bit boundary.  */
04415           for (msb = 30; msb >= 0; msb -= 2)
04416             if (residual & (3 << msb))
04417               break;
04418 
04419           /* The desired shift is now (msb - 6), or zero, whichever
04420              is the greater.  */
04421           shift = msb - 6;
04422           if (shift < 0)
04423             shift = 0;
04424         }
04425 
04426       /* Calculate g_n in 32-bit as well as encoded constant+rotation form.  */
04427       g_n = residual & (0xff << shift);
04428       encoded_g_n = (g_n >> shift)
04429                     | ((g_n <= 0xff ? 0 : (32 - shift) / 2) << 8);
04430 
04431       /* Calculate the residual for the next time around.  */
04432       residual &= ~g_n;
04433     }
04434 
04435   *final_residual = residual;
04436 
04437   return encoded_g_n;
04438 }
04439 
04440 /* Given an ARM instruction, determine whether it is an ADD or a SUB.
04441    Returns 1 if it is an ADD, -1 if it is a SUB, and 0 otherwise.  */
04442 static int
04443 identify_add_or_sub(bfd_vma insn)
04444 {
04445   int opcode = insn & 0x1e00000;
04446 
04447   if (opcode == 1 << 23) /* ADD */
04448     return 1;
04449 
04450   if (opcode == 1 << 22) /* SUB */
04451     return -1;
04452 
04453   return 0;
04454 }
04455 
04456 /* Determine if we're dealing with a Thumb-2 object.  */
04457 
04458 static int using_thumb2 (struct elf32_arm_link_hash_table *globals)
04459 {
04460   int arch = elf32_arm_get_eabi_attr_int (globals->obfd, Tag_CPU_arch);
04461   return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
04462 }
04463 
04464 /* Perform a relocation as part of a final link.  */
04465 
04466 static bfd_reloc_status_type
04467 elf32_arm_final_link_relocate (reloc_howto_type *           howto,
04468                             bfd *                        input_bfd,
04469                             bfd *                        output_bfd,
04470                             asection *                   input_section,
04471                             bfd_byte *                   contents,
04472                             Elf_Internal_Rela *          rel,
04473                             bfd_vma                      value,
04474                             struct bfd_link_info *       info,
04475                             asection *                   sym_sec,
04476                             const char *                 sym_name,
04477                             int                       sym_flags,
04478                             struct elf_link_hash_entry * h,
04479                             bfd_boolean *                unresolved_reloc_p,
04480                             char **error_message)
04481 {
04482   unsigned long                 r_type = howto->type;
04483   unsigned long                 r_symndx;
04484   bfd_byte *                    hit_data = contents + rel->r_offset;
04485   bfd *                         dynobj = NULL;
04486   Elf_Internal_Shdr *           symtab_hdr;
04487   struct elf_link_hash_entry ** sym_hashes;
04488   bfd_vma *                     local_got_offsets;
04489   asection *                    sgot = NULL;
04490   asection *                    splt = NULL;
04491   asection *                    sreloc = NULL;
04492   bfd_vma                       addend;
04493   bfd_signed_vma                signed_addend;
04494   struct elf32_arm_link_hash_table * globals;
04495 
04496   globals = elf32_arm_hash_table (info);
04497 
04498   /* Some relocation type map to different relocations depending on the
04499      target.  We pick the right one here.  */
04500   r_type = arm_real_reloc_type (globals, r_type);
04501   if (r_type != howto->type)
04502     howto = elf32_arm_howto_from_type (r_type);
04503 
04504   /* If the start address has been set, then set the EF_ARM_HASENTRY
04505      flag.  Setting this more than once is redundant, but the cost is
04506      not too high, and it keeps the code simple.
04507 
04508      The test is done  here, rather than somewhere else, because the
04509      start address is only set just before the final link commences.
04510 
04511      Note - if the user deliberately sets a start address of 0, the
04512      flag will not be set.  */
04513   if (bfd_get_start_address (output_bfd) != 0)
04514     elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
04515 
04516   dynobj = elf_hash_table (info)->dynobj;
04517   if (dynobj)
04518     {
04519       sgot = bfd_get_section_by_name (dynobj, ".got");
04520       splt = bfd_get_section_by_name (dynobj, ".plt");
04521     }
04522   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
04523   sym_hashes = elf_sym_hashes (input_bfd);
04524   local_got_offsets = elf_local_got_offsets (input_bfd);
04525   r_symndx = ELF32_R_SYM (rel->r_info);
04526 
04527   if (globals->use_rel)
04528     {
04529       addend = bfd_get_32 (input_bfd, hit_data) & howto->src_mask;
04530 
04531       if (addend & ((howto->src_mask + 1) >> 1))
04532        {
04533          signed_addend = -1;
04534          signed_addend &= ~ howto->src_mask;
04535          signed_addend |= addend;
04536        }
04537       else
04538        signed_addend = addend;
04539     }
04540   else
04541     addend = signed_addend = rel->r_addend;
04542 
04543   switch (r_type)
04544     {
04545     case R_ARM_NONE:
04546       /* We don't need to find a value for this symbol.  It's just a
04547         marker.  */
04548       *unresolved_reloc_p = FALSE;
04549       return bfd_reloc_ok;
04550 
04551     case R_ARM_ABS12:
04552       if (!globals->vxworks_p)
04553        return elf32_arm_abs12_reloc (input_bfd, hit_data, value + addend);
04554 
04555     case R_ARM_PC24:
04556     case R_ARM_ABS32:
04557     case R_ARM_ABS32_NOI:
04558     case R_ARM_REL32:
04559     case R_ARM_REL32_NOI:
04560     case R_ARM_CALL:
04561     case R_ARM_JUMP24:
04562     case R_ARM_XPC25:
04563     case R_ARM_PREL31:
04564     case R_ARM_PLT32:
04565       /* Handle relocations which should use the PLT entry.  ABS32/REL32
04566         will use the symbol's value, which may point to a PLT entry, but we
04567         don't need to handle that here.  If we created a PLT entry, all
04568         branches in this object should go to it.  */
04569       if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32
04570            && r_type != R_ARM_ABS32_NOI && r_type != R_ARM_REL32_NOI)
04571          && h != NULL
04572          && splt != NULL
04573          && h->plt.offset != (bfd_vma) -1)
04574        {
04575          /* If we've created a .plt section, and assigned a PLT entry to
04576             this function, it should not be known to bind locally.  If
04577             it were, we would have cleared the PLT entry.  */
04578          BFD_ASSERT (!SYMBOL_CALLS_LOCAL (info, h));
04579 
04580          value = (splt->output_section->vma
04581                  + splt->output_offset
04582                  + h->plt.offset);
04583          *unresolved_reloc_p = FALSE;
04584          return _bfd_final_link_relocate (howto, input_bfd, input_section,
04585                                       contents, rel->r_offset, value,
04586                                       rel->r_addend);
04587        }
04588 
04589       /* When generating a shared object or relocatable executable, these
04590         relocations are copied into the output file to be resolved at
04591         run time.  */
04592       if ((info->shared || globals->root.is_relocatable_executable)
04593          && (input_section->flags & SEC_ALLOC)
04594          && ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI)
04595              || !SYMBOL_CALLS_LOCAL (info, h))
04596          && (h == NULL
04597              || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
04598              || h->root.type != bfd_link_hash_undefweak)
04599          && r_type != R_ARM_PC24
04600          && r_type != R_ARM_CALL
04601          && r_type != R_ARM_JUMP24
04602          && r_type != R_ARM_PREL31
04603          && r_type != R_ARM_PLT32)
04604        {
04605          Elf_Internal_Rela outrel;
04606          bfd_byte *loc;
04607          bfd_boolean skip, relocate;
04608 
04609          *unresolved_reloc_p = FALSE;
04610 
04611          if (sreloc == NULL)
04612            {
04613              const char * name;
04614 
04615              name = (bfd_elf_string_from_elf_section
04616                     (input_bfd,
04617                      elf_elfheader (input_bfd)->e_shstrndx,
04618                      elf_section_data (input_section)->rel_hdr.sh_name));
04619              if (name == NULL)
04620               return bfd_reloc_notsupported;
04621 
04622              BFD_ASSERT (reloc_section_p (globals, name, input_section));
04623 
04624              sreloc = bfd_get_section_by_name (dynobj, name);
04625              BFD_ASSERT (sreloc != NULL);
04626            }
04627 
04628          skip = FALSE;
04629          relocate = FALSE;
04630 
04631          outrel.r_addend = addend;
04632          outrel.r_offset =
04633            _bfd_elf_section_offset (output_bfd, info, input_section,
04634                                  rel->r_offset);
04635          if (outrel.r_offset == (bfd_vma) -1)
04636            skip = TRUE;
04637          else if (outrel.r_offset == (bfd_vma) -2)
04638            skip = TRUE, relocate = TRUE;
04639          outrel.r_offset += (input_section->output_section->vma
04640                            + input_section->output_offset);
04641 
04642          if (skip)
04643            memset (&outrel, 0, sizeof outrel);
04644          else if (h != NULL
04645                  && h->dynindx != -1
04646                  && (!info->shared
04647                      || !info->symbolic
04648                      || !h->def_regular))
04649            outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
04650          else
04651            {
04652              int symbol;
04653 
04654              /* This symbol is local, or marked to become local.  */
04655              if (sym_flags == STT_ARM_TFUNC)
04656               value |= 1;
04657              if (globals->symbian_p)
04658               {
04659                 asection *osec;
04660 
04661                 /* On Symbian OS, the data segment and text segement
04662                    can be relocated independently.  Therefore, we
04663                    must indicate the segment to which this
04664                    relocation is relative.  The BPABI allows us to
04665                    use any symbol in the right segment; we just use
04666                    the section symbol as it is convenient.  (We
04667                    cannot use the symbol given by "h" directly as it
04668                    will not appear in the dynamic symbol table.)
04669 
04670                    Note that the dynamic linker ignores the section
04671                    symbol value, so we don't subtract osec->vma
04672                    from the emitted reloc addend.  */
04673                 if (sym_sec)
04674                   osec = sym_sec->output_section;
04675                 else
04676                   osec = input_section->output_section;
04677                 symbol = elf_section_data (osec)->dynindx;
04678                 if (symbol == 0)
04679                   {
04680                     struct elf_link_hash_table *htab = elf_hash_table (info);
04681 
04682                     if ((osec->flags & SEC_READONLY) == 0
04683                        && htab->data_index_section != NULL)
04684                      osec = htab->data_index_section;
04685                     else
04686                      osec = htab->text_index_section;
04687                     symbol = elf_section_data (osec)->dynindx;
04688                   }
04689                 BFD_ASSERT (symbol != 0);
04690               }
04691              else
04692               /* On SVR4-ish systems, the dynamic loader cannot
04693                  relocate the text and data segments independently,
04694                  so the symbol does not matter.  */
04695               symbol = 0;
04696              outrel.r_info = ELF32_R_INFO (symbol, R_ARM_RELATIVE);
04697              if (globals->use_rel)
04698               relocate = TRUE;
04699              else
04700               outrel.r_addend += value;
04701            }
04702 
04703          loc = sreloc->contents;
04704          loc += sreloc->reloc_count++ * RELOC_SIZE (globals);
04705          SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
04706 
04707          /* If this reloc is against an external symbol, we do not want to
04708             fiddle with the addend.  Otherwise, we need to include the symbol
04709             value so that it becomes an addend for the dynamic reloc.  */
04710          if (! relocate)
04711            return bfd_reloc_ok;
04712 
04713          return _bfd_final_link_relocate (howto, input_bfd, input_section,
04714                                       contents, rel->r_offset, value,
04715                                       (bfd_vma) 0);
04716        }
04717       else switch (r_type)
04718        {
04719        case R_ARM_ABS12:
04720          return elf32_arm_abs12_reloc (input_bfd, hit_data, value + addend);
04721 
04722        case R_ARM_XPC25:      /* Arm BLX instruction.  */
04723        case R_ARM_CALL:
04724        case R_ARM_JUMP24:
04725        case R_ARM_PC24:       /* Arm B/BL instruction */
04726        case R_ARM_PLT32:
04727          if (r_type == R_ARM_XPC25)
04728            {
04729              /* Check for Arm calling Arm function.  */
04730              /* FIXME: Should we translate the instruction into a BL
04731                instruction instead ?  */
04732              if (sym_flags != STT_ARM_TFUNC)
04733               (*_bfd_error_handler)
04734                 (_("\%B: Warning: Arm BLX instruction targets Arm function '%s'."),
04735                  input_bfd,
04736                  h ? h->root.root.string : "(local)");
04737            }
04738          else if (r_type != R_ARM_CALL || !globals->use_blx)
04739            {
04740              /* Check for Arm calling Thumb function.  */
04741              if (sym_flags == STT_ARM_TFUNC)
04742               {
04743                 if (elf32_arm_to_thumb_stub (info, sym_name, input_bfd,
04744                                           output_bfd, input_section,
04745                                           hit_data, sym_sec, rel->r_offset,
04746                                           signed_addend, value,
04747                                           error_message))
04748                   return bfd_reloc_ok;
04749                 else
04750                   return bfd_reloc_dangerous;
04751               }
04752            }
04753 
04754          /* The ARM ELF ABI says that this reloc is computed as: S - P + A
04755             where:
04756              S is the address of the symbol in the relocation.
04757              P is address of the instruction being relocated.
04758              A is the addend (extracted from the instruction) in bytes.
04759 
04760             S is held in 'value'.
04761             P is the base address of the section containing the
04762               instruction plus the offset of the reloc into that
04763               section, ie:
04764                (input_section->output_section->vma +
04765                 input_section->output_offset +
04766                 rel->r_offset).
04767             A is the addend, converted into bytes, ie:
04768                (signed_addend * 4)
04769 
04770             Note: None of these operations have knowledge of the pipeline
04771             size of the processor, thus it is up to the assembler to
04772             encode this information into the addend.  */
04773          value -= (input_section->output_section->vma
04774                   + input_section->output_offset);
04775          value -= rel->r_offset;
04776          if (globals->use_rel)
04777            value += (signed_addend << howto->size);
04778          else
04779            /* RELA addends do not have to be adjusted by howto->size.  */
04780            value += signed_addend;
04781 
04782          signed_addend = value;
04783          signed_addend >>= howto->rightshift;
04784 
04785          /* It is not an error for an undefined weak reference to be
04786             out of range.  Any program that branches to such a symbol
04787             is going to crash anyway, so there is no point worrying
04788             about getting the destination exactly right.  */
04789          if (! h || h->root.type != bfd_link_hash_undefweak)
04790            {
04791              /* Perform a signed range check.  */
04792              if (   signed_addend >   ((bfd_signed_vma)  (howto->dst_mask >> 1))
04793                 || signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
04794               return bfd_reloc_overflow;
04795            }
04796 
04797          addend = (value & 2);
04798 
04799          value = (signed_addend & howto->dst_mask)
04800            | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
04801 
04802          /* Set the H bit in the BLX instruction.  */
04803          if (sym_flags == STT_ARM_TFUNC)
04804            {
04805              if (addend)
04806               value |= (1 << 24);
04807              else
04808               value &= ~(bfd_vma)(1 << 24);
04809            }
04810          if (r_type == R_ARM_CALL)
04811            {
04812              /* Select the correct instruction (BL or BLX).  */
04813              if (sym_flags == STT_ARM_TFUNC)
04814               value |= (1 << 28);
04815              else
04816               {
04817                 value &= ~(bfd_vma)(1 << 28);
04818                 value |= (1 << 24);
04819               }
04820            }
04821          break;
04822 
04823        case R_ARM_ABS32:
04824          value += addend;
04825          if (sym_flags == STT_ARM_TFUNC)
04826            value |= 1;
04827          break;
04828 
04829        case R_ARM_ABS32_NOI:
04830          value += addend;
04831          break;
04832 
04833        case R_ARM_REL32:
04834          value += addend;
04835          if (sym_flags == STT_ARM_TFUNC)
04836            value |= 1;
04837          value -= (input_section->output_section->vma
04838                   + input_section->output_offset + rel->r_offset);
04839          break;
04840 
04841        case R_ARM_REL32_NOI:
04842          value += addend;
04843          value -= (input_section->output_section->vma
04844                   + input_section->output_offset + rel->r_offset);
04845          break;
04846 
04847        case R_ARM_PREL31:
04848          value -= (input_section->output_section->vma
04849                   + input_section->output_offset + rel->r_offset);
04850          value += signed_addend;
04851          if (! h || h->root.type != bfd_link_hash_undefweak)
04852            {
04853              /* Check for overflow */
04854              if ((value ^ (value >> 1)) & (1 << 30))
04855               return bfd_reloc_overflow;
04856            }
04857          value &= 0x7fffffff;
04858          value |= (bfd_get_32 (input_bfd, hit_data) & 0x80000000);
04859          if (sym_flags == STT_ARM_TFUNC)
04860            value |= 1;
04861          break;
04862        }
04863 
04864       bfd_put_32 (input_bfd, value, hit_data);
04865       return bfd_reloc_ok;
04866 
04867     case R_ARM_ABS8:
04868       value += addend;
04869       if ((long) value > 0x7f || (long) value < -0x80)
04870        return bfd_reloc_overflow;
04871 
04872       bfd_put_8 (input_bfd, value, hit_data);
04873       return bfd_reloc_ok;
04874 
04875     case R_ARM_ABS16:
04876       value += addend;
04877 
04878       if ((long) value > 0x7fff || (long) value < -0x8000)
04879        return bfd_reloc_overflow;
04880 
04881       bfd_put_16 (input_bfd, value, hit_data);
04882       return bfd_reloc_ok;
04883 
04884     case R_ARM_THM_ABS5:
04885       /* Support ldr and str instructions for the thumb.  */
04886       if (globals->use_rel)
04887        {
04888          /* Need to refetch addend.  */
04889          addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
04890          /* ??? Need to determine shift amount from operand size.  */
04891          addend >>= howto->rightshift;
04892        }
04893       value += addend;
04894 
04895       /* ??? Isn't value unsigned?  */
04896       if ((long) value > 0x1f || (long) value < -0x10)
04897        return bfd_reloc_overflow;
04898 
04899       /* ??? Value needs to be properly shifted into place first.  */
04900       value |= bfd_get_16 (input_bfd, hit_data) & 0xf83f;
04901       bfd_put_16 (input_bfd, value, hit_data);
04902       return bfd_reloc_ok;
04903 
04904     case R_ARM_THM_ALU_PREL_11_0:
04905       /* Corresponds to: addw.w reg, pc, #offset (and similarly for subw).  */
04906       {
04907        bfd_vma insn;
04908        bfd_signed_vma relocation;
04909 
04910        insn = (bfd_get_16 (input_bfd, hit_data) << 16)
04911              | bfd_get_16 (input_bfd, hit_data + 2);
04912 
04913         if (globals->use_rel)
04914           {
04915             signed_addend = (insn & 0xff) | ((insn & 0x7000) >> 4)
04916                           | ((insn & (1 << 26)) >> 15);
04917             if (insn & 0xf00000)
04918               signed_addend = -signed_addend;
04919           }
04920 
04921        relocation = value + signed_addend;
04922        relocation -= (input_section->output_section->vma
04923                      + input_section->output_offset
04924                      + rel->r_offset);
04925 
04926         value = abs (relocation);
04927 
04928         if (value >= 0x1000)
04929           return bfd_reloc_overflow;
04930 
04931        insn = (insn & 0xfb0f8f00) | (value & 0xff)
04932              | ((value & 0x700) << 4)
04933              | ((value & 0x800) << 15);
04934         if (relocation < 0)
04935           insn |= 0xa00000;
04936 
04937        bfd_put_16 (input_bfd, insn >> 16, hit_data);
04938        bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
04939 
04940         return bfd_reloc_ok;
04941       }
04942 
04943     case R_ARM_THM_PC12:
04944       /* Corresponds to: ldr.w reg, [pc, #offset].  */
04945       {
04946        bfd_vma insn;
04947        bfd_signed_vma relocation;
04948 
04949        insn = (bfd_get_16 (input_bfd, hit_data) << 16)
04950              | bfd_get_16 (input_bfd, hit_data + 2);
04951 
04952         if (globals->use_rel)
04953           {
04954             signed_addend = insn & 0xfff;
04955             if (!(insn & (1 << 23)))
04956               signed_addend = -signed_addend;
04957           }
04958 
04959        relocation = value + signed_addend;
04960        relocation -= (input_section->output_section->vma
04961                      + input_section->output_offset
04962                      + rel->r_offset);
04963 
04964         value = abs (relocation);
04965 
04966         if (value >= 0x1000)
04967           return bfd_reloc_overflow;
04968 
04969        insn = (insn & 0xff7ff000) | value;
04970         if (relocation >= 0)
04971           insn |= (1 << 23);
04972 
04973        bfd_put_16 (input_bfd, insn >> 16, hit_data);
04974        bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
04975 
04976         return bfd_reloc_ok;
04977       }
04978 
04979     case R_ARM_THM_XPC22:
04980     case R_ARM_THM_CALL:
04981       /* Thumb BL (branch long instruction).  */
04982       {
04983        bfd_vma relocation;
04984         bfd_vma reloc_sign;
04985        bfd_boolean overflow = FALSE;
04986        bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
04987        bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
04988        bfd_signed_vma reloc_signed_max;
04989        bfd_signed_vma reloc_signed_min;
04990        bfd_vma check;
04991        bfd_signed_vma signed_check;
04992        int bitsize;
04993        int thumb2 = using_thumb2 (globals);
04994 
04995        /* Fetch the addend.  We use the Thumb-2 encoding (backwards compatible
04996            with Thumb-1) involving the J1 and J2 bits.  */
04997        if (globals->use_rel)
04998          {
04999             bfd_vma s = (upper_insn & (1 << 10)) >> 10;
05000             bfd_vma upper = upper_insn & 0x3ff;
05001             bfd_vma lower = lower_insn & 0x7ff;
05002            bfd_vma j1 = (lower_insn & (1 << 13)) >> 13;
05003            bfd_vma j2 = (lower_insn & (1 << 11)) >> 11;
05004             bfd_vma i1 = j1 ^ s ? 0 : 1;
05005             bfd_vma i2 = j2 ^ s ? 0 : 1;
05006 
05007             addend = (i1 << 23) | (i2 << 22) | (upper << 12) | (lower << 1);
05008             /* Sign extend.  */
05009             addend = (addend | ((s ? 0 : 1) << 24)) - (1 << 24);
05010 
05011            signed_addend = addend;
05012          }
05013 
05014        if (r_type == R_ARM_THM_XPC22)
05015          {
05016            /* Check for Thumb to Thumb call.  */
05017            /* FIXME: Should we translate the instruction into a BL
05018               instruction instead ?  */
05019            if (sym_flags == STT_ARM_TFUNC)
05020              (*_bfd_error_handler)
05021               (_("%B: Warning: Thumb BLX instruction targets thumb function '%s'."),
05022                input_bfd,
05023                h ? h->root.root.string : "(local)");
05024          }
05025        else
05026          {
05027            /* If it is not a call to Thumb, assume call to Arm.
05028               If it is a call relative to a section name, then it is not a
05029               function call at all, but rather a long jump.  Calls through
05030               the PLT do not require stubs.  */
05031            if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION
05032               && (h == NULL || splt == NULL
05033                   || h->plt.offset == (bfd_vma) -1))
05034              {
05035               if (globals->use_blx)
05036                 {
05037                   /* Convert BL to BLX.  */
05038                   lower_insn = (lower_insn & ~0x1000) | 0x0800;
05039                 }
05040               else if (elf32_thumb_to_arm_stub
05041                   (info, sym_name, input_bfd, output_bfd, input_section,
05042                    hit_data, sym_sec, rel->r_offset, signed_addend, value,
05043                    error_message))
05044                 return bfd_reloc_ok;
05045               else
05046                 return bfd_reloc_dangerous;
05047              }
05048            else if (sym_flags == STT_ARM_TFUNC && globals->use_blx)
05049              {
05050               /* Make sure this is a BL.  */
05051               lower_insn |= 0x1800;
05052              }
05053          }
05054 
05055        /* Handle calls via the PLT.  */
05056        if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
05057          {
05058            value = (splt->output_section->vma
05059                    + splt->output_offset
05060                    + h->plt.offset);
05061            if (globals->use_blx)
05062              {
05063               /* If the Thumb BLX instruction is available, convert the
05064                  BL to a BLX instruction to call the ARM-mode PLT entry.  */
05065               lower_insn = (lower_insn & ~0x1000) | 0x0800;
05066              }
05067            else
05068              /* Target the Thumb stub before the ARM PLT entry.  */
05069              value -= PLT_THUMB_STUB_SIZE;
05070            *unresolved_reloc_p = FALSE;
05071          }
05072 
05073        relocation = value + signed_addend;
05074 
05075        relocation -= (input_section->output_section->vma
05076                      + input_section->output_offset
05077                      + rel->r_offset);
05078 
05079        check = relocation >> howto->rightshift;
05080 
05081        /* If this is a signed value, the rightshift just dropped
05082           leading 1 bits (assuming twos complement).  */
05083        if ((bfd_signed_vma) relocation >= 0)
05084          signed_check = check;
05085        else
05086          signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
05087 
05088        /* Calculate the permissable maximum and minimum values for
05089           this relocation according to whether we're relocating for
05090           Thumb-2 or not.  */
05091        bitsize = howto->bitsize;
05092        if (!thumb2)
05093          bitsize -= 2;
05094        reloc_signed_max = ((1 << (bitsize - 1)) - 1) >> howto->rightshift;
05095        reloc_signed_min = ~reloc_signed_max;
05096 
05097        /* Assumes two's complement.  */
05098        if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
05099          overflow = TRUE;
05100 
05101        if ((lower_insn & 0x1800) == 0x0800)
05102          /* For a BLX instruction, make sure that the relocation is rounded up
05103             to a word boundary.  This follows the semantics of the instruction
05104             which specifies that bit 1 of the target address will come from bit
05105             1 of the base address.  */
05106          relocation = (relocation + 2) & ~ 3;
05107 
05108        /* Put RELOCATION back into the insn.  Assumes two's complement.
05109           We use the Thumb-2 encoding, which is safe even if dealing with
05110           a Thumb-1 instruction by virtue of our overflow check above.  */
05111         reloc_sign = (signed_check < 0) ? 1 : 0;
05112        upper_insn = (upper_insn & ~(bfd_vma) 0x7ff)
05113                      | ((relocation >> 12) & 0x3ff)
05114                      | (reloc_sign << 10);
05115        lower_insn = (lower_insn & ~(bfd_vma) 0x2fff) 
05116                      | (((!((relocation >> 23) & 1)) ^ reloc_sign) << 13)
05117                      | (((!((relocation >> 22) & 1)) ^ reloc_sign) << 11)
05118                      | ((relocation >> 1) & 0x7ff);
05119 
05120        /* Put the relocated value back in the object file:  */
05121        bfd_put_16 (input_bfd, upper_insn, hit_data);
05122        bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
05123 
05124        return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
05125       }
05126       break;
05127 
05128     case R_ARM_THM_JUMP24:
05129       /* Thumb32 unconditional branch instruction.  */
05130       {
05131        bfd_vma relocation;
05132        bfd_boolean overflow = FALSE;
05133        bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
05134        bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
05135        bfd_signed_vma reloc_signed_max = ((1 << (howto->bitsize - 1)) - 1) >> howto->rightshift;
05136        bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
05137        bfd_vma check;
05138        bfd_signed_vma signed_check;
05139 
05140        /* Need to refetch the addend, reconstruct the top three bits, and glue the
05141           two pieces together.  */
05142        if (globals->use_rel)
05143          {
05144            bfd_vma S  = (upper_insn & 0x0400) >> 10;
05145            bfd_vma hi = (upper_insn & 0x03ff);
05146            bfd_vma I1 = (lower_insn & 0x2000) >> 13;
05147            bfd_vma I2 = (lower_insn & 0x0800) >> 11;
05148            bfd_vma lo = (lower_insn & 0x07ff);
05149 
05150            I1 = !(I1 ^ S);
05151            I2 = !(I2 ^ S);
05152            S  = !S;
05153 
05154            signed_addend = (S << 24) | (I1 << 23) | (I2 << 22) | (hi << 12) | (lo << 1);
05155            signed_addend -= (1 << 24); /* Sign extend.  */
05156          }
05157 
05158        /* ??? Should handle interworking?  GCC might someday try to
05159           use this for tail calls.  */
05160 
05161        relocation = value + signed_addend;
05162        relocation -= (input_section->output_section->vma
05163                      + input_section->output_offset
05164                      + rel->r_offset);
05165 
05166        check = relocation >> howto->rightshift;
05167 
05168        /* If this is a signed value, the rightshift just dropped
05169           leading 1 bits (assuming twos complement).  */
05170        if ((bfd_signed_vma) relocation >= 0)
05171          signed_check = check;
05172        else
05173          signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
05174 
05175        /* Assumes two's complement.  */
05176        if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
05177          overflow = TRUE;
05178 
05179        /* Put RELOCATION back into the insn.  */
05180        {
05181          bfd_vma S  = (relocation & 0x01000000) >> 24;
05182          bfd_vma I1 = (relocation & 0x00800000) >> 23;
05183          bfd_vma I2 = (relocation & 0x00400000) >> 22;
05184          bfd_vma hi = (relocation & 0x003ff000) >> 12;
05185          bfd_vma lo = (relocation & 0x00000ffe) >>  1;
05186 
05187          I1 = !(I1 ^ S);
05188          I2 = !(I2 ^ S);
05189 
05190          upper_insn = (upper_insn & (bfd_vma) 0xf800) | (S << 10) | hi;
05191          lower_insn = (lower_insn & (bfd_vma) 0xd000) | (I1 << 13) | (I2 << 11) | lo;
05192        }
05193 
05194        /* Put the relocated value back in the object file:  */
05195        bfd_put_16 (input_bfd, upper_insn, hit_data);
05196        bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
05197 
05198        return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
05199       }
05200 
05201     case R_ARM_THM_JUMP19:
05202       /* Thumb32 conditional branch instruction.  */
05203       {
05204        bfd_vma relocation;
05205        bfd_boolean overflow = FALSE;
05206        bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
05207        bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
05208        bfd_signed_vma reloc_signed_max = ((1 << (howto->bitsize - 1)) - 1) >> howto->rightshift;
05209        bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
05210        bfd_vma check;
05211        bfd_signed_vma signed_check;
05212 
05213        /* Need to refetch the addend, reconstruct the top three bits,
05214           and squish the two 11 bit pieces together.  */
05215        if (globals->use_rel)
05216          {
05217            bfd_vma S     = (upper_insn & 0x0400) >> 10;
05218            bfd_vma upper = (upper_insn & 0x001f);
05219            bfd_vma J1    = (lower_insn & 0x2000) >> 13;
05220            bfd_vma J2    = (lower_insn & 0x0800) >> 11;
05221            bfd_vma lower = (lower_insn & 0x07ff);
05222 
05223            upper |= J2 << 6;
05224            upper |= J1 << 7;
05225            upper |= ~S << 8;
05226            upper -= 0x0100; /* Sign extend.  */
05227 
05228            addend = (upper << 12) | (lower << 1);
05229            signed_addend = addend;
05230          }
05231 
05232        /* ??? Should handle interworking?  GCC might someday try to
05233           use this for tail calls.  */
05234 
05235        relocation = value + signed_addend;
05236        relocation -= (input_section->output_section->vma
05237                      + input_section->output_offset
05238                      + rel->r_offset);
05239 
05240        check = relocation >> howto->rightshift;
05241 
05242        /* If this is a signed value, the rightshift just dropped
05243           leading 1 bits (assuming twos complement).  */
05244        if ((bfd_signed_vma) relocation >= 0)
05245          signed_check = check;
05246        else
05247          signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
05248 
05249        /* Assumes two's complement.  */
05250        if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
05251          overflow = TRUE;
05252 
05253        /* Put RELOCATION back into the insn.  */
05254        {
05255          bfd_vma S  = (relocation & 0x00100000) >> 20;
05256          bfd_vma J2 = (relocation & 0x00080000) >> 19;
05257          bfd_vma J1 = (relocation & 0x00040000) >> 18;
05258          bfd_vma hi = (relocation & 0x0003f000) >> 12;
05259          bfd_vma lo = (relocation & 0x00000ffe) >>  1;
05260 
05261          upper_insn = (upper_insn & 0xfb30) | (S << 10) | hi;
05262          lower_insn = (lower_insn & 0xd000) | (J1 << 13) | (J2 << 11) | lo;
05263        }
05264 
05265        /* Put the relocated value back in the object file:  */
05266        bfd_put_16 (input_bfd, upper_insn, hit_data);
05267        bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
05268 
05269        return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
05270       }
05271 
05272     case R_ARM_THM_JUMP11:
05273     case R_ARM_THM_JUMP8:
05274     case R_ARM_THM_JUMP6:
05275       /* Thumb B (branch) instruction).  */
05276       {
05277        bfd_signed_vma relocation;
05278        bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
05279        bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
05280        bfd_signed_vma signed_check;
05281 
05282        /* CZB cannot jump backward.  */
05283        if (r_type == R_ARM_THM_JUMP6)
05284          reloc_signed_min = 0;
05285 
05286        if (globals->use_rel)
05287          {
05288            /* Need to refetch addend.  */
05289            addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
05290            if (addend & ((howto->src_mask + 1) >> 1))
05291              {
05292               signed_addend = -1;
05293               signed_addend &= ~ howto->src_mask;
05294               signed_addend |= addend;
05295              }
05296            else
05297              signed_addend = addend;
05298            /* The value in the insn has been right shifted.  We need to
05299               undo this, so that we can perform the address calculation
05300               in terms of bytes.  */
05301            signed_addend <<= howto->rightshift;
05302          }
05303        relocation = value + signed_addend;
05304 
05305        relocation -= (input_section->output_section->vma
05306                      + input_section->output_offset
05307                      + rel->r_offset);
05308 
05309        relocation >>= howto->rightshift;
05310        signed_check = relocation;
05311 
05312        if (r_type == R_ARM_THM_JUMP6)
05313          relocation = ((relocation & 0x0020) << 4) | ((relocation & 0x001f) << 3);
05314        else
05315          relocation &= howto->dst_mask;
05316        relocation |= (bfd_get_16 (input_bfd, hit_data) & (~ howto->dst_mask));
05317 
05318        bfd_put_16 (input_bfd, relocation, hit_data);
05319 
05320        /* Assumes two's complement.  */
05321        if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
05322          return bfd_reloc_overflow;
05323 
05324        return bfd_reloc_ok;
05325       }
05326 
05327     case R_ARM_ALU_PCREL7_0:
05328     case R_ARM_ALU_PCREL15_8:
05329     case R_ARM_ALU_PCREL23_15:
05330       {
05331        bfd_vma insn;
05332        bfd_vma relocation;
05333 
05334        insn = bfd_get_32 (input_bfd, hit_data);
05335        if (globals->use_rel)
05336          {
05337            /* Extract the addend.  */
05338            addend = (insn & 0xff) << ((insn & 0xf00) >> 7);
05339            signed_addend = addend;
05340          }
05341        relocation = value + signed_addend;
05342 
05343        relocation -= (input_section->output_section->vma
05344                      + input_section->output_offset
05345                      + rel->r_offset);
05346        insn = (insn & ~0xfff)
05347               | ((howto->bitpos << 7) & 0xf00)
05348               | ((relocation >> howto->bitpos) & 0xff);
05349        bfd_put_32 (input_bfd, value, hit_data);
05350       }
05351       return bfd_reloc_ok;
05352 
05353     case R_ARM_GNU_VTINHERIT:
05354     case R_ARM_GNU_VTENTRY:
05355       return bfd_reloc_ok;
05356 
05357     case R_ARM_GOTOFF32:
05358       /* Relocation is relative to the start of the
05359          global offset table.  */
05360 
05361       BFD_ASSERT (sgot != NULL);
05362       if (sgot == NULL)
05363         return bfd_reloc_notsupported;
05364 
05365       /* If we are addressing a Thumb function, we need to adjust the
05366         address by one, so that attempts to call the function pointer will
05367         correctly interpret it as Thumb code.  */
05368       if (sym_flags == STT_ARM_TFUNC)
05369        value += 1;
05370 
05371       /* Note that sgot->output_offset is not involved in this
05372          calculation.  We always want the start of .got.  If we
05373          define _GLOBAL_OFFSET_TABLE in a different way, as is
05374          permitted by the ABI, we might have to change this
05375          calculation.  */
05376       value -= sgot->output_section->vma;
05377       return _bfd_final_link_relocate (howto, input_bfd, input_section,
05378                                    contents, rel->r_offset, value,
05379                                    rel->r_addend);
05380 
05381     case R_ARM_GOTPC:
05382       /* Use global offset table as symbol value.  */
05383       BFD_ASSERT (sgot != NULL);
05384 
05385       if (sgot == NULL)
05386         return bfd_reloc_notsupported;
05387 
05388       *unresolved_reloc_p = FALSE;
05389       value = sgot->output_section->vma;
05390       return _bfd_final_link_relocate (howto, input_bfd, input_section,
05391                                    contents, rel->r_offset, value,
05392                                    rel->r_addend);
05393 
05394     case R_ARM_GOT32:
05395     case R_ARM_GOT_PREL:
05396       /* Relocation is to the entry for this symbol in the
05397          global offset table.  */
05398       if (sgot == NULL)
05399        return bfd_reloc_notsupported;
05400 
05401       if (h != NULL)
05402        {
05403          bfd_vma off;
05404          bfd_boolean dyn;
05405 
05406          off = h->got.offset;
05407          BFD_ASSERT (off != (bfd_vma) -1);
05408          dyn = globals->root.dynamic_sections_created;
05409 
05410          if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
05411              || (info->shared
05412                 && SYMBOL_REFERENCES_LOCAL (info, h))
05413              || (ELF_ST_VISIBILITY (h->other)
05414                 && h->root.type == bfd_link_hash_undefweak))
05415            {
05416              /* This is actually a static link, or it is a -Bsymbolic link
05417                and the symbol is defined locally.  We must initialize this
05418                entry in the global offset table.  Since the offset must
05419                always be a multiple of 4, we use the least significant bit
05420                to record whether we have initialized it already.
05421 
05422                When doing a dynamic link, we create a .rel(a).got relocation
05423                entry to initialize the value.  This is done in the
05424                finish_dynamic_symbol routine.  */
05425              if ((off & 1) != 0)
05426               off &= ~1;
05427              else
05428               {
05429                 /* If we are addressing a Thumb function, we need to
05430                    adjust the address by one, so that attempts to
05431                    call the function pointer will correctly
05432                    interpret it as Thumb code.  */
05433                 if (sym_flags == STT_ARM_TFUNC)
05434                   value |= 1;
05435 
05436                 bfd_put_32 (output_bfd, value, sgot->contents + off);
05437                 h->got.offset |= 1;
05438               }
05439            }
05440          else
05441            *unresolved_reloc_p = FALSE;
05442 
05443          value = sgot->output_offset + off;
05444        }
05445       else
05446        {
05447          bfd_vma off;
05448 
05449          BFD_ASSERT (local_got_offsets != NULL &&
05450                     local_got_offsets[r_symndx] != (bfd_vma) -1);
05451 
05452          off = local_got_offsets[r_symndx];
05453 
05454          /* The offset must always be a multiple of 4.  We use the
05455             least significant bit to record whether we have already
05456             generated the necessary reloc.  */
05457          if ((off & 1) != 0)
05458            off &= ~1;
05459          else
05460            {
05461              /* If we are addressing a Thumb function, we need to
05462                adjust the address by one, so that attempts to
05463                call the function pointer will correctly
05464                interpret it as Thumb code.  */
05465              if (sym_flags == STT_ARM_TFUNC)
05466               value |= 1;
05467 
05468              if (globals->use_rel)
05469               bfd_put_32 (output_bfd, value, sgot->contents + off);
05470 
05471              if (info->shared)
05472               {
05473                 asection * srelgot;
05474                 Elf_Internal_Rela outrel;
05475                 bfd_byte *loc;
05476 
05477                 srelgot = (bfd_get_section_by_name
05478                           (dynobj, RELOC_SECTION (globals, ".got")));
05479                 BFD_ASSERT (srelgot != NULL);
05480 
05481                 outrel.r_addend = addend + value;
05482                 outrel.r_offset = (sgot->output_section->vma
05483                                  + sgot->output_offset
05484                                  + off);
05485                 outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
05486                 loc = srelgot->contents;
05487                 loc += srelgot->reloc_count++ * RELOC_SIZE (globals);
05488                 SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
05489               }
05490 
05491              local_got_offsets[r_symndx] |= 1;
05492            }
05493 
05494          value = sgot->output_offset + off;
05495        }
05496       if (r_type != R_ARM_GOT32)
05497        value += sgot->output_section->vma;
05498 
05499       return _bfd_final_link_relocate (howto, input_bfd, input_section,
05500                                    contents, rel->r_offset, value,
05501                                    rel->r_addend);
05502 
05503     case R_ARM_TLS_LDO32:
05504       value = value - dtpoff_base (info);
05505 
05506       return _bfd_final_link_relocate (howto, input_bfd, input_section,
05507                                    contents, rel->r_offset, value,
05508                                    rel->r_addend);
05509 
05510     case R_ARM_TLS_LDM32:
05511       {
05512        bfd_vma off;
05513 
05514        if (globals->sgot == NULL)
05515          abort ();
05516 
05517        off = globals->tls_ldm_got.offset;
05518 
05519        if ((off & 1) != 0)
05520          off &= ~1;
05521        else
05522          {
05523            /* If we don't know the module number, create a relocation
05524               for it.  */
05525            if (info->shared)
05526              {
05527               Elf_Internal_Rela outrel;
05528               bfd_byte *loc;
05529 
05530               if (globals->srelgot == NULL)
05531                 abort ();
05532 
05533               outrel.r_addend = 0;
05534               outrel.r_offset = (globals->sgot->output_section->vma
05535                                + globals->sgot->output_offset + off);
05536               outrel.r_info = ELF32_R_INFO (0, R_ARM_TLS_DTPMOD32);
05537 
05538               if (globals->use_rel)
05539                 bfd_put_32 (output_bfd, outrel.r_addend,
05540                            globals->sgot->contents + off);
05541 
05542               loc = globals->srelgot->contents;
05543               loc += globals->srelgot->reloc_count++ * RELOC_SIZE (globals);
05544               SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
05545              }
05546            else
05547              bfd_put_32 (output_bfd, 1, globals->sgot->contents + off);
05548 
05549            globals->tls_ldm_got.offset |= 1;
05550          }
05551 
05552        value = globals->sgot->output_section->vma + globals->sgot->output_offset + off 
05553          - (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
05554 
05555        return _bfd_final_link_relocate (howto, input_bfd, input_section,
05556                                     contents, rel->r_offset, value,
05557                                     rel->r_addend);
05558       }
05559 
05560     case R_ARM_TLS_GD32:
05561     case R_ARM_TLS_IE32:
05562       {
05563        bfd_vma off;
05564        int indx;
05565        char tls_type;
05566 
05567        if (globals->sgot == NULL)
05568          abort ();
05569 
05570        indx = 0;
05571        if (h != NULL)
05572          {
05573            bfd_boolean dyn;
05574            dyn = globals->root.dynamic_sections_created;
05575            if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
05576               && (!info->shared
05577                   || !SYMBOL_REFERENCES_LOCAL (info, h)))
05578              {
05579               *unresolved_reloc_p = FALSE;
05580               indx = h->dynindx;
05581              }
05582            off = h->got.offset;
05583            tls_type = ((struct elf32_arm_link_hash_entry *) h)->tls_type;
05584          }
05585        else
05586          {
05587            if (local_got_offsets == NULL)
05588              abort ();
05589            off = local_got_offsets[r_symndx];
05590            tls_type = elf32_arm_local_got_tls_type (input_bfd)[r_symndx];
05591          }
05592 
05593        if (tls_type == GOT_UNKNOWN)
05594          abort ();
05595 
05596        if ((off & 1) != 0)
05597          off &= ~1;
05598        else
05599          {
05600            bfd_boolean need_relocs = FALSE;
05601            Elf_Internal_Rela outrel;
05602            bfd_byte *loc = NULL;
05603            int cur_off = off;
05604 
05605            /* The GOT entries have not been initialized yet.  Do it
05606               now, and emit any relocations.  If both an IE GOT and a
05607               GD GOT are necessary, we emit the GD first.  */
05608 
05609            if ((info->shared || indx != 0)
05610               && (h == NULL
05611                   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
05612                   || h->root.type != bfd_link_hash_undefweak))
05613              {
05614               need_relocs = TRUE;
05615               if (globals->srelgot == NULL)
05616                 abort ();
05617               loc = globals->srelgot->contents;
05618               loc += globals->srelgot->reloc_count * RELOC_SIZE (globals);
05619              }
05620 
05621            if (tls_type & GOT_TLS_GD)
05622              {
05623               if (need_relocs)
05624                 {
05625                   outrel.r_addend = 0;
05626                   outrel.r_offset = (globals->sgot->output_section->vma
05627                                    + globals->sgot->output_offset
05628                                    + cur_off);
05629                   outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DTPMOD32);
05630 
05631                   if (globals->use_rel)
05632                     bfd_put_32 (output_bfd, outrel.r_addend,
05633                               globals->sgot->contents + cur_off);
05634 
05635                   SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
05636                   globals->srelgot->reloc_count++;
05637                   loc += RELOC_SIZE (globals);
05638 
05639                   if (indx == 0)
05640                     bfd_put_32 (output_bfd, value - dtpoff_base (info),
05641                               globals->sgot->contents + cur_off + 4);
05642                   else
05643                     {
05644                      outrel.r_addend = 0;
05645                      outrel.r_info = ELF32_R_INFO (indx,
05646                                                 R_ARM_TLS_DTPOFF32);
05647                      outrel.r_offset += 4;
05648 
05649                      if (globals->use_rel)
05650                        bfd_put_32 (output_bfd, outrel.r_addend,
05651                                   globals->sgot->contents + cur_off + 4);
05652 
05653 
05654                      SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
05655                      globals->srelgot->reloc_count++;
05656                      loc += RELOC_SIZE (globals);
05657                     }
05658                 }
05659               else
05660                 {
05661                   /* If we are not emitting relocations for a
05662                      general dynamic reference, then we must be in a
05663                      static link or an executable link with the
05664                      symbol binding locally.  Mark it as belonging
05665                      to module 1, the executable.  */
05666                   bfd_put_32 (output_bfd, 1,
05667                             globals->sgot->contents + cur_off);
05668                   bfd_put_32 (output_bfd, value - dtpoff_base (info),
05669                             globals->sgot->contents + cur_off + 4);
05670                 }
05671 
05672               cur_off += 8;
05673              }
05674 
05675            if (tls_type & GOT_TLS_IE)
05676              {
05677               if (need_relocs)
05678                 {
05679                   if (indx == 0)
05680                     outrel.r_addend = value - dtpoff_base (info);
05681                   else
05682                     outrel.r_addend = 0;
05683                   outrel.r_offset = (globals->sgot->output_section->vma
05684                                    + globals->sgot->output_offset
05685                                    + cur_off);
05686                   outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_TPOFF32);
05687 
05688                   if (globals->use_rel)
05689                     bfd_put_32 (output_bfd, outrel.r_addend,
05690                               globals->sgot->contents + cur_off);
05691 
05692                   SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
05693                   globals->srelgot->reloc_count++;
05694                   loc += RELOC_SIZE (globals);
05695                 }
05696               else
05697                 bfd_put_32 (output_bfd, tpoff (info, value),
05698                            globals->sgot->contents + cur_off);
05699               cur_off += 4;
05700              }
05701 
05702            if (h != NULL)
05703              h->got.offset |= 1;
05704            else
05705              local_got_offsets[r_symndx] |= 1;
05706          }
05707 
05708        if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32)
05709          off += 8;
05710        value = globals->sgot->output_section->vma + globals->sgot->output_offset + off 
05711          - (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
05712 
05713        return _bfd_final_link_relocate (howto, input_bfd, input_section,
05714                                     contents, rel->r_offset, value,
05715                                     rel->r_addend);
05716       }
05717 
05718     case R_ARM_TLS_LE32:
05719       if (info->shared)
05720        {
05721          (*_bfd_error_handler)
05722            (_("%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"),
05723             input_bfd, input_section,
05724             (long) rel->r_offset, howto->name);
05725          return FALSE;        
05726        }
05727       else
05728        value = tpoff (info, value);
05729       
05730       return _bfd_final_link_relocate (howto, input_bfd, input_section,
05731                                    contents, rel->r_offset, value,
05732                                    rel->r_addend);
05733 
05734     case R_ARM_V4BX:
05735       if (globals->fix_v4bx)
05736         {
05737           bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
05738 
05739           /* Ensure that we have a BX instruction.  */
05740           BFD_ASSERT ((insn & 0x0ffffff0) == 0x012fff10);
05741 
05742           /* Preserve Rm (lowest four bits) and the condition code
05743              (highest four bits). Other bits encode MOV PC,Rm.  */
05744           insn = (insn & 0xf000000f) | 0x01a0f000;
05745 
05746           bfd_put_32 (input_bfd, insn, hit_data);
05747         }
05748       return bfd_reloc_ok;
05749 
05750     case R_ARM_MOVW_ABS_NC:
05751     case R_ARM_MOVT_ABS:
05752     case R_ARM_MOVW_PREL_NC:
05753     case R_ARM_MOVT_PREL:
05754     /* Until we properly support segment-base-relative addressing then
05755        we assume the segment base to be zero, as for the group relocations.
05756        Thus R_ARM_MOVW_BREL_NC has the same semantics as R_ARM_MOVW_ABS_NC
05757        and R_ARM_MOVT_BREL has the same semantics as R_ARM_MOVT_ABS.  */
05758     case R_ARM_MOVW_BREL_NC:
05759     case R_ARM_MOVW_BREL:
05760     case R_ARM_MOVT_BREL:
05761       {
05762        bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
05763 
05764        if (globals->use_rel)
05765          {
05766            addend = ((insn >> 4) & 0xf000) | (insn & 0xfff);
05767            signed_addend = (addend ^ 0x10000) - 0x10000;
05768          }
05769 
05770        value += signed_addend;
05771 
05772        if (r_type == R_ARM_MOVW_PREL_NC || r_type == R_ARM_MOVT_PREL)
05773          value -= (input_section->output_section->vma
05774                   + input_section->output_offset + rel->r_offset);
05775 
05776        if (r_type == R_ARM_MOVW_BREL && value >= 0x10000)
05777           return bfd_reloc_overflow;
05778 
05779        if (sym_flags == STT_ARM_TFUNC)
05780          value |= 1;
05781 
05782        if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL
05783             || r_type == R_ARM_MOVT_BREL)
05784          value >>= 16;
05785 
05786        insn &= 0xfff0f000;
05787        insn |= value & 0xfff;
05788        insn |= (value & 0xf000) << 4;
05789        bfd_put_32 (input_bfd, insn, hit_data);
05790       }
05791       return bfd_reloc_ok;
05792 
05793     case R_ARM_THM_MOVW_ABS_NC:
05794     case R_ARM_THM_MOVT_ABS:
05795     case R_ARM_THM_MOVW_PREL_NC:
05796     case R_ARM_THM_MOVT_PREL:
05797     /* Until we properly support segment-base-relative addressing then
05798        we assume the segment base to be zero, as for the above relocations.
05799        Thus R_ARM_THM_MOVW_BREL_NC has the same semantics as
05800        R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_BREL has the same semantics
05801        as R_ARM_THM_MOVT_ABS.  */
05802     case R_ARM_THM_MOVW_BREL_NC:
05803     case R_ARM_THM_MOVW_BREL:
05804     case R_ARM_THM_MOVT_BREL:
05805       {
05806        bfd_vma insn;
05807        
05808        insn = bfd_get_16 (input_bfd, hit_data) << 16;
05809        insn |= bfd_get_16 (input_bfd, hit_data + 2);
05810 
05811        if (globals->use_rel)
05812          {
05813            addend = ((insn >> 4)  & 0xf000)
05814                  | ((insn >> 15) & 0x0800)
05815                  | ((insn >> 4)  & 0x0700)
05816                  | (insn         & 0x00ff);
05817            signed_addend = (addend ^ 0x10000) - 0x10000;
05818          }
05819 
05820        value += signed_addend;
05821 
05822        if (r_type == R_ARM_THM_MOVW_PREL_NC || r_type == R_ARM_THM_MOVT_PREL)
05823          value -= (input_section->output_section->vma
05824                   + input_section->output_offset + rel->r_offset);
05825 
05826        if (r_type == R_ARM_THM_MOVW_BREL && value >= 0x10000)
05827           return bfd_reloc_overflow;
05828 
05829        if (sym_flags == STT_ARM_TFUNC)
05830          value |= 1;
05831 
05832        if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL
05833             || r_type == R_ARM_THM_MOVT_BREL)
05834          value >>= 16;
05835 
05836        insn &= 0xfbf08f00;
05837        insn |= (value & 0xf000) << 4;
05838        insn |= (value & 0x0800) << 15;
05839        insn |= (value & 0x0700) << 4;
05840        insn |= (value & 0x00ff);
05841 
05842        bfd_put_16 (input_bfd, insn >> 16, hit_data);
05843        bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
05844       }
05845       return bfd_reloc_ok;
05846 
05847     case R_ARM_ALU_PC_G0_NC:
05848     case R_ARM_ALU_PC_G1_NC:
05849     case R_ARM_ALU_PC_G0:
05850     case R_ARM_ALU_PC_G1:
05851     case R_ARM_ALU_PC_G2:
05852     case R_ARM_ALU_SB_G0_NC:
05853     case R_ARM_ALU_SB_G1_NC:
05854     case R_ARM_ALU_SB_G0:
05855     case R_ARM_ALU_SB_G1:
05856     case R_ARM_ALU_SB_G2:
05857       {
05858        bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
05859         bfd_vma pc = input_section->output_section->vma
05860                    + input_section->output_offset + rel->r_offset;
05861         /* sb should be the origin of the *segment* containing the symbol.
05862            It is not clear how to obtain this OS-dependent value, so we
05863            make an arbitrary choice of zero.  */
05864         bfd_vma sb = 0;
05865         bfd_vma residual;
05866         bfd_vma g_n;
05867        bfd_signed_vma signed_value;
05868         int group = 0;
05869 
05870         /* Determine which group of bits to select.  */
05871         switch (r_type)
05872           {
05873           case R_ARM_ALU_PC_G0_NC:
05874           case R_ARM_ALU_PC_G0:
05875           case R_ARM_ALU_SB_G0_NC:
05876           case R_ARM_ALU_SB_G0:
05877             group = 0;
05878             break;
05879 
05880           case R_ARM_ALU_PC_G1_NC:
05881           case R_ARM_ALU_PC_G1:
05882           case R_ARM_ALU_SB_G1_NC:
05883           case R_ARM_ALU_SB_G1:
05884             group = 1;
05885             break;
05886 
05887           case R_ARM_ALU_PC_G2:
05888           case R_ARM_ALU_SB_G2:
05889             group = 2;
05890             break;
05891 
05892           default:
05893             abort();
05894           }
05895 
05896         /* If REL, extract the addend from the insn.  If RELA, it will
05897            have already been fetched for us.  */
05898        if (globals->use_rel)
05899           {
05900             int negative;
05901             bfd_vma constant = insn & 0xff;
05902             bfd_vma rotation = (insn & 0xf00) >> 8;
05903 
05904             if (rotation == 0)
05905               signed_addend = constant;
05906             else
05907               {
05908                 /* Compensate for the fact that in the instruction, the
05909                    rotation is stored in multiples of 2 bits.  */
05910                 rotation *= 2;
05911 
05912                 /* Rotate "constant" right by "rotation" bits.  */
05913                 signed_addend = (constant >> rotation) |
05914                                 (constant << (8 * sizeof (bfd_vma) - rotation));
05915               }
05916 
05917             /* Determine if the instruction is an ADD or a SUB.
05918                (For REL, this determines the sign of the addend.)  */
05919             negative = identify_add_or_sub (insn);
05920             if (negative == 0)
05921               {
05922                 (*_bfd_error_handler)
05923                   (_("%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"),
05924                   input_bfd, input_section,
05925                   (long) rel->r_offset, howto->name);
05926                 return bfd_reloc_overflow;         
05927              }
05928 
05929             signed_addend *= negative;
05930           }
05931 
05932        /* Compute the value (X) to go in the place.  */
05933         if (r_type == R_ARM_ALU_PC_G0_NC
05934             || r_type == R_ARM_ALU_PC_G1_NC
05935             || r_type == R_ARM_ALU_PC_G0
05936             || r_type == R_ARM_ALU_PC_G1
05937             || r_type == R_ARM_ALU_PC_G2)
05938           /* PC relative.  */
05939           signed_value = value - pc + signed_addend;
05940         else
05941           /* Section base relative.  */
05942           signed_value = value - sb + signed_addend;
05943 
05944         /* If the target symbol is a Thumb function, then set the
05945            Thumb bit in the address.  */
05946        if (sym_flags == STT_ARM_TFUNC)
05947          signed_value |= 1;
05948 
05949         /* Calculate the value of the relevant G_n, in encoded
05950            constant-with-rotation format.  */
05951         g_n = calculate_group_reloc_mask (abs (signed_value), group,
05952                                           &residual);
05953 
05954         /* Check for overflow if required.  */
05955         if ((r_type == R_ARM_ALU_PC_G0
05956              || r_type == R_ARM_ALU_PC_G1
05957              || r_type == R_ARM_ALU_PC_G2
05958              || r_type == R_ARM_ALU_SB_G0
05959              || r_type == R_ARM_ALU_SB_G1
05960              || r_type == R_ARM_ALU_SB_G2) && residual != 0)
05961           {
05962             (*_bfd_error_handler)
05963               (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
05964               input_bfd, input_section,
05965               (long) rel->r_offset, abs (signed_value), howto->name);
05966             return bfd_reloc_overflow;
05967           }
05968 
05969         /* Mask out the value and the ADD/SUB part of the opcode; take care
05970            not to destroy the S bit.  */
05971         insn &= 0xff1ff000;
05972 
05973         /* Set the opcode according to whether the value to go in the
05974            place is negative.  */
05975         if (signed_value < 0)
05976           insn |= 1 << 22;
05977         else
05978           insn |= 1 << 23;
05979 
05980         /* Encode the offset.  */
05981         insn |= g_n;
05982 
05983        bfd_put_32 (input_bfd, insn, hit_data);
05984       }
05985       return bfd_reloc_ok;
05986 
05987     case R_ARM_LDR_PC_G0:
05988     case R_ARM_LDR_PC_G1:
05989     case R_ARM_LDR_PC_G2:
05990     case R_ARM_LDR_SB_G0:
05991     case R_ARM_LDR_SB_G1:
05992     case R_ARM_LDR_SB_G2:
05993       {
05994        bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
05995         bfd_vma pc = input_section->output_section->vma
05996                    + input_section->output_offset + rel->r_offset;
05997         bfd_vma sb = 0; /* See note above.  */
05998         bfd_vma residual;
05999        bfd_signed_vma signed_value;
06000         int group = 0;
06001 
06002         /* Determine which groups of bits to calculate.  */
06003         switch (r_type)
06004           {
06005           case R_ARM_LDR_PC_G0:
06006           case R_ARM_LDR_SB_G0:
06007             group = 0;
06008             break;
06009 
06010           case R_ARM_LDR_PC_G1:
06011           case R_ARM_LDR_SB_G1:
06012             group = 1;
06013             break;
06014 
06015           case R_ARM_LDR_PC_G2:
06016           case R_ARM_LDR_SB_G2:
06017             group = 2;
06018             break;
06019 
06020           default:
06021             abort();
06022           }
06023 
06024         /* If REL, extract the addend from the insn.  If RELA, it will
06025            have already been fetched for us.  */
06026        if (globals->use_rel)
06027           {
06028             int negative = (insn & (1 << 23)) ? 1 : -1;
06029             signed_addend = negative * (insn & 0xfff);
06030           }
06031 
06032        /* Compute the value (X) to go in the place.  */
06033         if (r_type == R_ARM_LDR_PC_G0
06034             || r_type == R_ARM_LDR_PC_G1
06035             || r_type == R_ARM_LDR_PC_G2)
06036           /* PC relative.  */
06037           signed_value = value - pc + signed_addend;
06038         else
06039           /* Section base relative.  */
06040           signed_value = value - sb + signed_addend;
06041 
06042         /* Calculate the value of the relevant G_{n-1} to obtain
06043            the residual at that stage.  */
06044         calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
06045 
06046         /* Check for overflow.  */
06047         if (residual >= 0x1000)
06048           {
06049             (*_bfd_error_handler)
06050               (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
06051               input_bfd, input_section,
06052               (long) rel->r_offset, abs (signed_value), howto->name);
06053             return bfd_reloc_overflow;
06054           }
06055 
06056         /* Mask out the value and U bit.  */
06057         insn &= 0xff7ff000;
06058 
06059         /* Set the U bit if the value to go in the place is non-negative.  */
06060         if (signed_value >= 0)
06061           insn |= 1 << 23;
06062 
06063         /* Encode the offset.  */
06064         insn |= residual;
06065 
06066        bfd_put_32 (input_bfd, insn, hit_data);
06067       }
06068       return bfd_reloc_ok;
06069 
06070     case R_ARM_LDRS_PC_G0:
06071     case R_ARM_LDRS_PC_G1:
06072     case R_ARM_LDRS_PC_G2:
06073     case R_ARM_LDRS_SB_G0:
06074     case R_ARM_LDRS_SB_G1:
06075     case R_ARM_LDRS_SB_G2:
06076       {
06077        bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
06078         bfd_vma pc = input_section->output_section->vma
06079                    + input_section->output_offset + rel->r_offset;
06080         bfd_vma sb = 0; /* See note above.  */
06081         bfd_vma residual;
06082        bfd_signed_vma signed_value;
06083         int group = 0;
06084 
06085         /* Determine which groups of bits to calculate.  */
06086         switch (r_type)
06087           {
06088           case R_ARM_LDRS_PC_G0:
06089           case R_ARM_LDRS_SB_G0:
06090             group = 0;
06091             break;
06092 
06093           case R_ARM_LDRS_PC_G1:
06094           case R_ARM_LDRS_SB_G1:
06095             group = 1;
06096             break;
06097 
06098           case R_ARM_LDRS_PC_G2:
06099           case R_ARM_LDRS_SB_G2:
06100             group = 2;
06101             break;
06102 
06103           default:
06104             abort();
06105           }
06106 
06107         /* If REL, extract the addend from the insn.  If RELA, it will
06108            have already been fetched for us.  */
06109        if (globals->use_rel)
06110           {
06111             int negative = (insn & (1 << 23)) ? 1 : -1;
06112             signed_addend = negative * (((insn & 0xf00) >> 4) + (insn & 0xf));
06113           }
06114 
06115        /* Compute the value (X) to go in the place.  */
06116         if (r_type == R_ARM_LDRS_PC_G0
06117             || r_type == R_ARM_LDRS_PC_G1
06118             || r_type == R_ARM_LDRS_PC_G2)
06119           /* PC relative.  */
06120           signed_value = value - pc + signed_addend;
06121         else
06122           /* Section base relative.  */
06123           signed_value = value - sb + signed_addend;
06124 
06125         /* Calculate the value of the relevant G_{n-1} to obtain
06126            the residual at that stage.  */
06127         calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
06128 
06129         /* Check for overflow.  */
06130         if (residual >= 0x100)
06131           {
06132             (*_bfd_error_handler)
06133               (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
06134               input_bfd, input_section,
06135               (long) rel->r_offset, abs (signed_value), howto->name);
06136             return bfd_reloc_overflow;
06137           }
06138 
06139         /* Mask out the value and U bit.  */
06140         insn &= 0xff7ff0f0;
06141 
06142         /* Set the U bit if the value to go in the place is non-negative.  */
06143         if (signed_value >= 0)
06144           insn |= 1 << 23;
06145 
06146         /* Encode the offset.  */
06147         insn |= ((residual & 0xf0) << 4) | (residual & 0xf);
06148 
06149        bfd_put_32 (input_bfd, insn, hit_data);
06150       }
06151       return bfd_reloc_ok;
06152 
06153     case R_ARM_LDC_PC_G0:
06154     case R_ARM_LDC_PC_G1:
06155     case R_ARM_LDC_PC_G2:
06156     case R_ARM_LDC_SB_G0:
06157     case R_ARM_LDC_SB_G1:
06158     case R_ARM_LDC_SB_G2:
06159       {
06160        bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
06161         bfd_vma pc = input_section->output_section->vma
06162                    + input_section->output_offset + rel->r_offset;
06163         bfd_vma sb = 0; /* See note above.  */
06164         bfd_vma residual;
06165        bfd_signed_vma signed_value;
06166         int group = 0;
06167 
06168         /* Determine which groups of bits to calculate.  */
06169         switch (r_type)
06170           {
06171           case R_ARM_LDC_PC_G0:
06172           case R_ARM_LDC_SB_G0:
06173             group = 0;
06174             break;
06175 
06176           case R_ARM_LDC_PC_G1:
06177           case R_ARM_LDC_SB_G1:
06178             group = 1;
06179             break;
06180 
06181           case R_ARM_LDC_PC_G2:
06182           case R_ARM_LDC_SB_G2:
06183             group = 2;
06184             break;
06185 
06186           default:
06187             abort();
06188           }
06189 
06190         /* If REL, extract the addend from the insn.  If RELA, it will
06191            have already been fetched for us.  */
06192        if (globals->use_rel)
06193           {
06194             int negative = (insn & (1 << 23)) ? 1 : -1;
06195             signed_addend = negative * ((insn & 0xff) << 2);
06196           }
06197 
06198        /* Compute the value (X) to go in the place.  */
06199         if (r_type == R_ARM_LDC_PC_G0
06200             || r_type == R_ARM_LDC_PC_G1
06201             || r_type == R_ARM_LDC_PC_G2)
06202           /* PC relative.  */
06203           signed_value = value - pc + signed_addend;
06204         else
06205           /* Section base relative.  */
06206           signed_value = value - sb + signed_addend;
06207 
06208         /* Calculate the value of the relevant G_{n-1} to obtain
06209            the residual at that stage.  */
06210         calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
06211 
06212         /* Check for overflow.  (The absolute value to go in the place must be
06213            divisible by four and, after having been divided by four, must
06214            fit in eight bits.)  */
06215         if ((residual & 0x3) != 0 || residual >= 0x400)
06216           {
06217             (*_bfd_error_handler)
06218               (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
06219               input_bfd, input_section,
06220               (long) rel->r_offset, abs (signed_value), howto->name);
06221             return bfd_reloc_overflow;
06222           }
06223 
06224         /* Mask out the value and U bit.  */
06225         insn &= 0xff7fff00;
06226 
06227         /* Set the U bit if the value to go in the place is non-negative.  */
06228         if (signed_value >= 0)
06229           insn |= 1 << 23;
06230 
06231         /* Encode the offset.  */
06232         insn |= residual >> 2;
06233 
06234        bfd_put_32 (input_bfd, insn, hit_data);
06235       }
06236       return bfd_reloc_ok;
06237 
06238     default:
06239       return bfd_reloc_notsupported;
06240     }
06241 }
06242 
06243 
06244 static int
06245 uleb128_size (unsigned int i)
06246 {
06247   int size;
06248   size = 1;
06249   while (i >= 0x80)
06250     {
06251       i >>= 7;
06252       size++;
06253     }
06254   return size;
06255 }
06256 
06257 /* Return TRUE if the attribute has the default value (0/"").  */
06258 static bfd_boolean
06259 is_default_attr (aeabi_attribute *attr)
06260 {
06261   if ((attr->type & 1) && attr->i != 0)
06262     return FALSE;
06263   if ((attr->type & 2) && attr->s && *attr->s)
06264     return FALSE;
06265 
06266   return TRUE;
06267 }
06268 
06269 /* Return the size of a single attribute.  */
06270 static bfd_vma
06271 eabi_attr_size(int tag, aeabi_attribute *attr)
06272 {
06273   bfd_vma size;
06274 
06275   if (is_default_attr (attr))
06276     return 0;
06277 
06278   size = uleb128_size (tag);
06279   if (attr->type & 1)
06280     size += uleb128_size (attr->i);
06281   if (attr->type & 2)
06282     size += strlen ((char *)attr->s) + 1;
06283   return size;
06284 }
06285   
06286 /* Returns the size of the eabi object attributess section.  */
06287 bfd_vma
06288 elf32_arm_eabi_attr_size (bfd *abfd)
06289 {
06290   bfd_vma size;
06291   aeabi_attribute *attr;
06292   aeabi_attribute_list *list;
06293   int i;
06294 
06295   attr = elf32_arm_tdata (abfd)->known_eabi_attributes;
06296   size = 16; /* 'A' <size> "aeabi" 0x1 <size>.  */
06297   for (i = 4; i < NUM_KNOWN_ATTRIBUTES; i++)
06298     size += eabi_attr_size (i, &attr[i]);
06299 
06300   for (list = elf32_arm_tdata (abfd)->other_eabi_attributes;
06301        list;
06302        list = list->next)
06303     size += eabi_attr_size (list->tag, &list->attr);
06304 
06305   return size;
06306 }
06307 
06308 static bfd_byte *
06309 write_uleb128 (bfd_byte *p, unsigned int val)
06310 {
06311   bfd_byte c;
06312   do
06313     {
06314       c = val & 0x7f;
06315       val >>= 7;
06316       if (val)
06317        c |= 0x80;
06318       *(p++) = c;
06319     }
06320   while (val);
06321   return p;
06322 }
06323 
06324 /* Write attribute ATTR to butter P, and return a pointer to the following
06325    byte.  */
06326 static bfd_byte *
06327 write_eabi_attribute (bfd_byte *p, int tag, aeabi_attribute *attr)
06328 {
06329   /* Suppress default entries.  */
06330   if (is_default_attr(attr))
06331     return p;
06332 
06333   p = write_uleb128 (p, tag);
06334   if (attr->type & 1)
06335     p = write_uleb128 (p, attr->i);
06336   if (attr->type & 2)
06337     {
06338       int len;
06339 
06340       len = strlen (attr->s) + 1;
06341       memcpy (p, attr->s, len);
06342       p += len;
06343     }
06344 
06345   return p;
06346 }
06347 
06348 /* Write the contents of the eabi attributes section to p.  */
06349 void
06350 elf32_arm_set_eabi_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size)
06351 {
06352   bfd_byte *p;
06353   aeabi_attribute *attr;
06354   aeabi_attribute_list *list;
06355   int i;
06356 
06357   p = contents;
06358   *(p++) = 'A';
06359   bfd_put_32 (abfd, size - 1, p);
06360   p += 4;
06361   memcpy (p, "aeabi", 6);
06362   p += 6;
06363   *(p++) = Tag_File;
06364   bfd_put_32 (abfd, size - 11, p);
06365   p += 4;
06366 
06367   attr = elf32_arm_tdata (abfd)->known_eabi_attributes;
06368   for (i = 4; i < NUM_KNOWN_ATTRIBUTES; i++)
06369     p = write_eabi_attribute (p, i, &attr[i]);
06370 
06371   for (list = elf32_arm_tdata (abfd)->other_eabi_attributes;
06372        list;
06373        list = list->next)
06374     p = write_eabi_attribute (p, list->tag, &list->attr);
06375 }
06376 
06377 /* Override final_link to handle EABI object attribute sections.  */
06378 
06379 static bfd_boolean
06380 elf32_arm_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
06381 {
06382   asection *o;
06383   struct bfd_link_order *p;
06384   asection *attr_section = NULL;
06385   bfd_byte *contents;
06386   bfd_vma size = 0;
06387 
06388   /* elf32_arm_merge_private_bfd_data will already have merged the
06389      object attributes.  Remove the input sections from the link, and set
06390      the contents of the output secton.  */
06391   for (o = abfd->sections; o != NULL; o = o->next)
06392     {
06393       if (strcmp (o->name, ".ARM.attributes") == 0)
06394        {
06395          for (p = o->map_head.link_order; p != NULL; p = p->next)
06396            {
06397              asection *input_section;
06398 
06399              if (p->type != bfd_indirect_link_order)
06400               continue;
06401              input_section = p->u.indirect.section;
06402              /* Hack: reset the SEC_HAS_CONTENTS flag so that
06403                elf_link_input_bfd ignores this section.  */
06404              input_section->flags &= ~SEC_HAS_CONTENTS;
06405            }
06406            
06407          size = elf32_arm_eabi_attr_size (abfd);
06408          bfd_set_section_size (abfd, o, size);
06409          attr_section = o;
06410          /* Skip this section later on.  */
06411          o->map_head.link_order = NULL;
06412        }
06413     }
06414   /* Invoke the ELF linker to do all the work.  */
06415   if (!bfd_elf_final_link (abfd, info))
06416     return FALSE;
06417 
06418   if (attr_section)
06419     {
06420       contents = bfd_malloc(size);
06421       if (contents == NULL)
06422        return FALSE;
06423       elf32_arm_set_eabi_attr_contents (abfd, contents, size);
06424       bfd_set_section_contents (abfd, attr_section, contents, 0, size);
06425       free (contents);
06426     }
06427   return TRUE;
06428 }
06429 
06430 
06431 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS.  */
06432 static void
06433 arm_add_to_rel (bfd *              abfd,
06434               bfd_byte *         address,
06435               reloc_howto_type * howto,
06436               bfd_signed_vma     increment)
06437 {
06438   bfd_signed_vma addend;
06439 
06440   if (howto->type == R_ARM_THM_CALL)
06441     {
06442       int upper_insn, lower_insn;
06443       int upper, lower;
06444 
06445       upper_insn = bfd_get_16 (abfd, address);
06446       lower_insn = bfd_get_16 (abfd, address + 2);
06447       upper = upper_insn & 0x7ff;
06448       lower = lower_insn & 0x7ff;
06449 
06450       addend = (upper << 12) | (lower << 1);
06451       addend += increment;
06452       addend >>= 1;
06453 
06454       upper_insn = (upper_insn & 0xf800) | ((addend >> 11) & 0x7ff);
06455       lower_insn = (lower_insn & 0xf800) | (addend & 0x7ff);
06456 
06457       bfd_put_16 (abfd, (bfd_vma) upper_insn, address);
06458       bfd_put_16 (abfd, (bfd_vma) lower_insn, address + 2);
06459     }
06460   else
06461     {
06462       bfd_vma        contents;
06463 
06464       contents = bfd_get_32 (abfd, address);
06465 
06466       /* Get the (signed) value from the instruction.  */
06467       addend = contents & howto->src_mask;
06468       if (addend & ((howto->src_mask + 1) >> 1))
06469        {
06470          bfd_signed_vma mask;
06471 
06472          mask = -1;
06473          mask &= ~ howto->src_mask;
06474          addend |= mask;
06475        }
06476 
06477       /* Add in the increment, (which is a byte value).  */
06478       switch (howto->type)
06479        {
06480        default:
06481          addend += increment;
06482          break;
06483 
06484        case R_ARM_PC24:
06485        case R_ARM_PLT32:
06486        case R_ARM_CALL:
06487        case R_ARM_JUMP24:
06488          addend <<= howto->size;
06489          addend += increment;
06490 
06491          /* Should we check for overflow here ?  */
06492 
06493          /* Drop any undesired bits.  */
06494          addend >>= howto->rightshift;
06495          break;
06496        }
06497 
06498       contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask);
06499 
06500       bfd_put_32 (abfd, contents, address);
06501     }
06502 }
06503 
06504 #define IS_ARM_TLS_RELOC(R_TYPE)   \
06505   ((R_TYPE) == R_ARM_TLS_GD32             \
06506    || (R_TYPE) == R_ARM_TLS_LDO32  \
06507    || (R_TYPE) == R_ARM_TLS_LDM32  \
06508    || (R_TYPE) == R_ARM_TLS_DTPOFF32      \
06509    || (R_TYPE) == R_ARM_TLS_DTPMOD32      \
06510    || (R_TYPE) == R_ARM_TLS_TPOFF32       \
06511    || (R_TYPE) == R_ARM_TLS_LE32   \
06512    || (R_TYPE) == R_ARM_TLS_IE32)
06513 
06514 /* Relocate an ARM ELF section.  */
06515 static bfd_boolean
06516 elf32_arm_relocate_section (bfd *                  output_bfd,
06517                          struct bfd_link_info * info,
06518                          bfd *                  input_bfd,
06519                          asection *             input_section,
06520                          bfd_byte *             contents,
06521                          Elf_Internal_Rela *    relocs,
06522                          Elf_Internal_Sym *     local_syms,
06523                          asection **            local_sections)
06524 {
06525   Elf_Internal_Shdr *symtab_hdr;
06526   struct elf_link_hash_entry **sym_hashes;
06527   Elf_Internal_Rela *rel;
06528   Elf_Internal_Rela *relend;
06529   const char *name;
06530   struct elf32_arm_link_hash_table * globals;
06531 
06532   globals = elf32_arm_hash_table (info);
06533 
06534   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
06535   sym_hashes = elf_sym_hashes (input_bfd);
06536 
06537   rel = relocs;
06538   relend = relocs + input_section->reloc_count;
06539   for (; rel < relend; rel++)
06540     {
06541       int                          r_type;
06542       reloc_howto_type *           howto;
06543       unsigned long                r_symndx;
06544       Elf_Internal_Sym *           sym;
06545       asection *                   sec;
06546       struct elf_link_hash_entry * h;
06547       bfd_vma                      relocation;
06548       bfd_reloc_status_type        r;
06549       arelent                      bfd_reloc;
06550       char                         sym_type;
06551       bfd_boolean                  unresolved_reloc = FALSE;
06552       char *error_message = NULL;
06553 
06554       r_symndx = ELF32_R_SYM (rel->r_info);
06555       r_type   = ELF32_R_TYPE (rel->r_info);
06556       r_type   = arm_real_reloc_type (globals, r_type);
06557 
06558       if (   r_type == R_ARM_GNU_VTENTRY
06559           || r_type == R_ARM_GNU_VTINHERIT)
06560         continue;
06561 
06562       bfd_reloc.howto = elf32_arm_howto_from_type (r_type);
06563       howto = bfd_reloc.howto;
06564 
06565       h = NULL;
06566       sym = NULL;
06567       sec = NULL;
06568 
06569       if (r_symndx < symtab_hdr->sh_info)
06570        {
06571          sym = local_syms + r_symndx;
06572          sym_type = ELF32_ST_TYPE (sym->st_info);
06573          sec = local_sections[r_symndx];
06574          if (globals->use_rel)
06575            {
06576              relocation = (sec->output_section->vma
06577                          + sec->output_offset
06578                          + sym->st_value);
06579              if (!info->relocatable
06580                 && (sec->flags & SEC_MERGE)
06581                 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
06582               {
06583                 asection *msec;
06584                 bfd_vma addend, value;
06585 
06586                 if (howto->rightshift)
06587                   {
06588                     (*_bfd_error_handler)
06589                      (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
06590                       input_bfd, input_section,
06591                       (long) rel->r_offset, howto->name);
06592                     return FALSE;
06593                   }
06594 
06595                 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
06596 
06597                 /* Get the (signed) value from the instruction.  */
06598                 addend = value & howto->src_mask;
06599                 if (addend & ((howto->src_mask + 1) >> 1))
06600                   {
06601                     bfd_signed_vma mask;
06602 
06603                     mask = -1;
06604                     mask &= ~ howto->src_mask;
06605                     addend |= mask;
06606                   }
06607                 msec = sec;
06608                 addend =
06609                   _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
06610                   - relocation;
06611                 addend += msec->output_section->vma + msec->output_offset;
06612                 value = (value & ~ howto->dst_mask) | (addend & howto->dst_mask);
06613                 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
06614               }
06615            }
06616          else
06617            relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
06618        }
06619       else
06620        {
06621          bfd_boolean warned;
06622 
06623          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
06624                                r_symndx, symtab_hdr, sym_hashes,
06625                                h, sec, relocation,
06626                                unresolved_reloc, warned);
06627 
06628          sym_type = h->type;
06629        }
06630 
06631       if (sec != NULL && elf_discarded_section (sec))
06632        {
06633          /* For relocs against symbols from removed linkonce sections,
06634             or sections discarded by a linker script, we just want the
06635             section contents zeroed.  Avoid any special processing.  */
06636          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
06637          rel->r_info = 0;
06638          rel->r_addend = 0;
06639          continue;
06640        }
06641 
06642       if (info->relocatable)
06643        {
06644          /* This is a relocatable link.  We don't have to change
06645             anything, unless the reloc is against a section symbol,
06646             in which case we have to adjust according to where the
06647             section symbol winds up in the output section.  */
06648          if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
06649            {
06650              if (globals->use_rel)
06651               arm_add_to_rel (input_bfd, contents + rel->r_offset,
06652                             howto, (bfd_signed_vma) sec->output_offset);
06653              else
06654               rel->r_addend += sec->output_offset;
06655            }
06656          continue;
06657        }
06658 
06659       if (h != NULL)
06660        name = h->root.root.string;
06661       else
06662        {
06663          name = (bfd_elf_string_from_elf_section
06664                 (input_bfd, symtab_hdr->sh_link, sym->st_name));
06665          if (name == NULL || *name == '\0')
06666            name = bfd_section_name (input_bfd, sec);
06667        }
06668 
06669       if (r_symndx != 0
06670          && r_type != R_ARM_NONE
06671          && (h == NULL
06672              || h->root.type == bfd_link_hash_defined
06673              || h->root.type == bfd_link_hash_defweak)
06674          && IS_ARM_TLS_RELOC (r_type) != (sym_type == STT_TLS))
06675        {
06676          (*_bfd_error_handler)
06677            ((sym_type == STT_TLS
06678              ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
06679              : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
06680             input_bfd,
06681             input_section,
06682             (long) rel->r_offset,
06683             howto->name,
06684             name);
06685        }
06686 
06687       r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
06688                                     input_section, contents, rel,
06689                                     relocation, info, sec, name,
06690                                     (h ? ELF_ST_TYPE (h->type) :
06691                                      ELF_ST_TYPE (sym->st_info)), h,
06692                                     &unresolved_reloc, &error_message);
06693 
06694       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
06695         because such sections are not SEC_ALLOC and thus ld.so will
06696         not process them.  */
06697       if (unresolved_reloc
06698           && !((input_section->flags & SEC_DEBUGGING) != 0
06699                && h->def_dynamic))
06700        {
06701          (*_bfd_error_handler)
06702            (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
06703             input_bfd,
06704             input_section,
06705             (long) rel->r_offset,
06706             howto->name,
06707             h->root.root.string);
06708          return FALSE;
06709        }
06710 
06711       if (r != bfd_reloc_ok)
06712        {
06713          switch (r)
06714            {
06715            case bfd_reloc_overflow:
06716              /* If the overflowing reloc was to an undefined symbol,
06717                we have already printed one error message and there
06718                is no point complaining again.  */
06719              if ((! h ||
06720                  h->root.type != bfd_link_hash_undefined)
06721                 && (!((*info->callbacks->reloc_overflow)
06722                      (info, (h ? &h->root : NULL), name, howto->name,
06723                       (bfd_vma) 0, input_bfd, input_section,
06724                       rel->r_offset))))
06725                 return FALSE;
06726              break;
06727 
06728            case bfd_reloc_undefined:
06729              if (!((*info->callbacks->undefined_symbol)
06730                   (info, name, input_bfd, input_section,
06731                    rel->r_offset, TRUE)))
06732               return FALSE;
06733              break;
06734 
06735            case bfd_reloc_outofrange:
06736              error_message = _("out of range");
06737              goto common_error;
06738 
06739            case bfd_reloc_notsupported:
06740              error_message = _("unsupported relocation");
06741              goto common_error;
06742 
06743            case bfd_reloc_dangerous:
06744              /* error_message should already be set.  */
06745              goto common_error;
06746 
06747            default:
06748              error_message = _("unknown error");
06749              /* fall through */
06750 
06751            common_error:
06752              BFD_ASSERT (error_message != NULL);
06753              if (!((*info->callbacks->reloc_dangerous)
06754                   (info, error_message, input_bfd, input_section,
06755                    rel->r_offset)))
06756               return FALSE;
06757              break;
06758            }
06759        }
06760     }
06761 
06762   return TRUE;
06763 }
06764 
06765 /* Allocate/find an object attribute.  */
06766 static aeabi_attribute *
06767 elf32_arm_new_eabi_attr (bfd *abfd, int tag)
06768 {
06769   aeabi_attribute *attr;
06770   aeabi_attribute_list *list;
06771   aeabi_attribute_list *p;
06772   aeabi_attribute_list **lastp;
06773 
06774 
06775   if (tag < NUM_KNOWN_ATTRIBUTES)
06776     {
06777       /* Knwon tags are preallocated.  */
06778       attr = &elf32_arm_tdata (abfd)->known_eabi_attributes[tag];
06779     }
06780   else
06781     {
06782       /* Create a new tag.  */
06783       list = (aeabi_attribute_list *)
06784        bfd_alloc (abfd, sizeof (aeabi_attribute_list));
06785       memset (list, 0, sizeof (aeabi_attribute_list));
06786       list->tag = tag;
06787       /* Keep the tag list in order.  */
06788       lastp = &elf32_arm_tdata (abfd)->other_eabi_attributes;
06789       for (p = *lastp; p; p = p->next)
06790        {
06791          if (tag < p->tag)
06792            break;
06793          lastp = &p->next;
06794        }
06795       list->next = *lastp;
06796       *lastp = list;
06797       attr = &list->attr;
06798     }
06799 
06800   return attr;
06801 }
06802 
06803 int
06804 elf32_arm_get_eabi_attr_int (bfd *abfd, int tag)
06805 {
06806   aeabi_attribute_list *p;
06807 
06808   if (tag < NUM_KNOWN_ATTRIBUTES)
06809     {
06810       /* Knwon tags are preallocated.  */
06811       return elf32_arm_tdata (abfd)->known_eabi_attributes[tag].i;
06812     }
06813   else
06814     {
06815       for (p = elf32_arm_tdata (abfd)->other_eabi_attributes;
06816           p;
06817           p = p->next)
06818        {
06819          if (tag == p->tag)
06820            return p->attr.i;
06821          if (tag < p->tag)
06822            break;
06823        }
06824       return 0;
06825     }
06826 }
06827 
06828 void
06829 elf32_arm_add_eabi_attr_int (bfd *abfd, int tag, unsigned int i)
06830 {
06831   aeabi_attribute *attr;
06832 
06833   attr = elf32_arm_new_eabi_attr (abfd, tag);
06834   attr->type = 1;
06835   attr->i = i;
06836 }
06837 
06838 static char *
06839 attr_strdup (bfd *abfd, const char * s)
06840 {
06841   char * p;
06842   int len;
06843   
06844   len = strlen (s) + 1;
06845   p = (char *)bfd_alloc(abfd, len);
06846   return memcpy (p, s, len);
06847 }
06848 
06849 void
06850 elf32_arm_add_eabi_attr_string (bfd *abfd, int tag, const char *s)
06851 {
06852   aeabi_attribute *attr;
06853 
06854   attr = elf32_arm_new_eabi_attr (abfd, tag);
06855   attr->type = 2;
06856   attr->s = attr_strdup (abfd, s);
06857 }
06858 
06859 void
06860 elf32_arm_add_eabi_attr_compat (bfd *abfd, unsigned int i, const char *s)
06861 {
06862   aeabi_attribute_list *list;
06863   aeabi_attribute_list *p;
06864   aeabi_attribute_list **lastp;
06865 
06866   list = (aeabi_attribute_list *)
06867     bfd_alloc (abfd, sizeof (aeabi_attribute_list));
06868   memset (list, 0, sizeof (aeabi_attribute_list));
06869   list->tag = Tag_compatibility;
06870   list->attr.type = 3;
06871   list->attr.i = i;
06872   list->attr.s = attr_strdup (abfd, s);
06873 
06874   lastp = &elf32_arm_tdata (abfd)->other_eabi_attributes;
06875   for (p = *lastp; p; p = p->next)
06876     {
06877       int cmp;
06878       if (p->tag != Tag_compatibility)
06879        break;
06880       cmp = strcmp(s, p->attr.s);
06881       if (cmp < 0 || (cmp == 0 && i < p->attr.i))
06882        break;
06883       lastp = &p->next;
06884     }
06885   list->next = *lastp;
06886   *lastp = list;
06887 }
06888 
06889 /* Set the right machine number.  */
06890 
06891 static bfd_boolean
06892 elf32_arm_object_p (bfd *abfd)
06893 {
06894   unsigned int mach;
06895 
06896   mach = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION);
06897 
06898   if (mach != bfd_mach_arm_unknown)
06899     bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
06900 
06901   else if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT)
06902     bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_ep9312);
06903 
06904   else
06905     bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
06906 
06907   return TRUE;
06908 }
06909 
06910 /* Function to keep ARM specific flags in the ELF header.  */
06911 
06912 static bfd_boolean
06913 elf32_arm_set_private_flags (bfd *abfd, flagword flags)
06914 {
06915   if (elf_flags_init (abfd)
06916       && elf_elfheader (abfd)->e_flags != flags)
06917     {
06918       if (EF_ARM_EABI_VERSION (flags) == EF_ARM_EABI_UNKNOWN)
06919        {
06920          if (flags & EF_ARM_INTERWORK)
06921            (*_bfd_error_handler)
06922              (_("Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"),
06923               abfd);
06924          else
06925            _bfd_error_handler
06926              (_("Warning: Clearing the interworking flag of %B due to outside request"),
06927               abfd);
06928        }
06929     }
06930   else
06931     {
06932       elf_elfheader (abfd)->e_flags = flags;
06933       elf_flags_init (abfd) = TRUE;
06934     }
06935 
06936   return TRUE;
06937 }
06938 
06939 /* Copy the eabi object attribute from IBFD to OBFD.  */
06940 static void
06941 copy_eabi_attributes (bfd *ibfd, bfd *obfd)
06942 {
06943   aeabi_attribute *in_attr;
06944   aeabi_attribute *out_attr;
06945   aeabi_attribute_list *list;
06946   int i;
06947 
06948   in_attr = &elf32_arm_tdata (ibfd)->known_eabi_attributes[4];
06949   out_attr = &elf32_arm_tdata (obfd)->known_eabi_attributes[4];
06950   for (i = 4; i < NUM_KNOWN_ATTRIBUTES; i++)
06951     {
06952       out_attr->i = in_attr->i;
06953       if (in_attr->s && *in_attr->s)
06954        out_attr->s = attr_strdup (obfd, in_attr->s);
06955       in_attr++;
06956       out_attr++;
06957     }
06958 
06959   for (list = elf32_arm_tdata (ibfd)->other_eabi_attributes;
06960        list;
06961        list = list->next)
06962     {
06963       in_attr = &list->attr;
06964       switch (in_attr->type)
06965        {
06966        case 1:
06967          elf32_arm_add_eabi_attr_int (obfd, list->tag, in_attr->i);
06968          break;
06969        case 2:
06970          elf32_arm_add_eabi_attr_string (obfd, list->tag, in_attr->s);
06971          break;
06972        case 3:
06973          elf32_arm_add_eabi_attr_compat (obfd, in_attr->i, in_attr->s);
06974          break;
06975        default:
06976          abort();
06977        }
06978     }
06979 }
06980 
06981 
06982 /* Copy backend specific data from one object module to another.  */
06983 
06984 static bfd_boolean
06985 elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
06986 {
06987   flagword in_flags;
06988   flagword out_flags;
06989 
06990   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
06991       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
06992     return TRUE;
06993 
06994   in_flags  = elf_elfheader (ibfd)->e_flags;
06995   out_flags = elf_elfheader (obfd)->e_flags;
06996 
06997   if (elf_flags_init (obfd)
06998       && EF_ARM_EABI_VERSION (out_flags) == EF_ARM_EABI_UNKNOWN
06999       && in_flags != out_flags)
07000     {
07001       /* Cannot mix APCS26 and APCS32 code.  */
07002       if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
07003        return FALSE;
07004 
07005       /* Cannot mix float APCS and non-float APCS code.  */
07006       if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
07007        return FALSE;
07008 
07009       /* If the src and dest have different interworking flags
07010          then turn off the interworking bit.  */
07011       if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
07012        {
07013          if (out_flags & EF_ARM_INTERWORK)
07014            _bfd_error_handler
07015              (_("Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"),
07016               obfd, ibfd);
07017 
07018          in_flags &= ~EF_ARM_INTERWORK;
07019        }
07020 
07021       /* Likewise for PIC, though don't warn for this case.  */
07022       if ((in_flags & EF_ARM_PIC) != (out_flags & EF_ARM_PIC))
07023        in_flags &= ~EF_ARM_PIC;
07024     }
07025 
07026   elf_elfheader (obfd)->e_flags = in_flags;
07027   elf_flags_init (obfd) = TRUE;
07028 
07029   /* Also copy the EI_OSABI field.  */
07030   elf_elfheader (obfd)->e_ident[EI_OSABI] =
07031     elf_elfheader (ibfd)->e_ident[EI_OSABI];
07032 
07033   /* Copy EABI object attributes.  */
07034   copy_eabi_attributes (ibfd, obfd);
07035 
07036   return TRUE;
07037 }
07038 
07039 /* Values for Tag_ABI_PCS_R9_use.  */
07040 enum
07041 {
07042   AEABI_R9_V6,
07043   AEABI_R9_SB,
07044   AEABI_R9_TLS,
07045   AEABI_R9_unused
07046 };
07047 
07048 /* Values for Tag_ABI_PCS_RW_data.  */
07049 enum
07050 {
07051   AEABI_PCS_RW_data_absolute,
07052   AEABI_PCS_RW_data_PCrel,
07053   AEABI_PCS_RW_data_SBrel,
07054   AEABI_PCS_RW_data_unused
07055 };
07056 
07057 /* Values for Tag_ABI_enum_size.  */
07058 enum
07059 {
07060   AEABI_enum_unused,
07061   AEABI_enum_short,
07062   AEABI_enum_wide,
07063   AEABI_enum_forced_wide
07064 };
07065 
07066 /* Merge EABI object attributes from IBFD into OBFD.  Raise an error if there
07067    are conflicting attributes.  */
07068 static bfd_boolean
07069 elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
07070 {
07071   aeabi_attribute *in_attr;
07072   aeabi_attribute *out_attr;
07073   aeabi_attribute_list *in_list;
07074   aeabi_attribute_list *out_list;
07075   /* Some tags have 0 = don't care, 1 = strong requirement,
07076      2 = weak requirement.  */
07077   static const int order_312[3] = {3, 1, 2};
07078   int i;
07079 
07080   if (!elf32_arm_tdata (obfd)->known_eabi_attributes[0].i)
07081     {
07082       /* This is the first object.  Copy the attributes.  */
07083       copy_eabi_attributes (ibfd, obfd);
07084 
07085       /* Use the Tag_null value to indicate the attributes have been
07086         initialized.  */
07087       elf32_arm_tdata (obfd)->known_eabi_attributes[0].i = 1;
07088 
07089       return TRUE;
07090     }
07091 
07092   in_attr = elf32_arm_tdata (ibfd)->known_eabi_attributes;
07093   out_attr = elf32_arm_tdata (obfd)->known_eabi_attributes;
07094   /* This needs to happen before Tag_ABI_FP_number_model is merged.  */
07095   if (in_attr[Tag_ABI_VFP_args].i != out_attr[Tag_ABI_VFP_args].i)
07096     {
07097       /* Ignore mismatches if teh object doesn't use floating point.  */
07098       if (out_attr[Tag_ABI_FP_number_model].i == 0)
07099        out_attr[Tag_ABI_VFP_args].i = in_attr[Tag_ABI_VFP_args].i;
07100       else if (in_attr[Tag_ABI_FP_number_model].i != 0)
07101        {
07102          _bfd_error_handler
07103            (_("ERROR: %B uses VFP register arguments, %B does not"),
07104             ibfd, obfd);
07105          return FALSE;
07106        }
07107     }
07108 
07109   for (i = 4; i < NUM_KNOWN_ATTRIBUTES; i++)
07110     {
07111       /* Merge this attribute with existing attributes.  */
07112       switch (i)
07113        {
07114        case Tag_CPU_raw_name:
07115        case Tag_CPU_name:
07116          /* Use whichever has the greatest architecture requirements.  We
07117             won't necessarily have both the above tags, so make sure input
07118             name is non-NULL.  */
07119          if (in_attr[Tag_CPU_arch].i > out_attr[Tag_CPU_arch].i
07120              && in_attr[i].s)
07121            out_attr[i].s = attr_strdup(obfd, in_attr[i].s);
07122          break;
07123 
07124        case Tag_ABI_optimization_goals:
07125        case Tag_ABI_FP_optimization_goals:
07126          /* Use the first value seen.  */
07127          break;
07128 
07129        case Tag_CPU_arch:
07130        case Tag_ARM_ISA_use:
07131        case Tag_THUMB_ISA_use:
07132        case Tag_VFP_arch:
07133        case Tag_WMMX_arch:
07134        case Tag_NEON_arch:
07135          /* ??? Do NEON and WMMX conflict?  */
07136        case Tag_ABI_FP_rounding:
07137        case Tag_ABI_FP_denormal:
07138        case Tag_ABI_FP_exceptions:
07139        case Tag_ABI_FP_user_exceptions:
07140        case Tag_ABI_FP_number_model:
07141        case Tag_ABI_align8_preserved:
07142        case Tag_ABI_HardFP_use:
07143          /* Use the largest value specified.  */
07144          if (in_attr[i].i > out_attr[i].i)
07145            out_attr[i].i = in_attr[i].i;
07146          break;
07147 
07148        case Tag_CPU_arch_profile:
07149          /* Warn if conflicting architecture profiles used.  */
07150          if (out_attr[i].i && in_attr[i].i && in_attr[i].i != out_attr[i].i)
07151            {
07152              _bfd_error_handler
07153               (_("ERROR: %B: Conflicting architecture profiles %c/%c"),
07154                ibfd, in_attr[i].i, out_attr[i].i);
07155              return FALSE;
07156            }
07157          if (in_attr[i].i)
07158            out_attr[i].i = in_attr[i].i;
07159          break;
07160        case Tag_PCS_config:
07161          if (out_attr[i].i == 0)
07162            out_attr[i].i = in_attr[i].i;
07163          else if (in_attr[i].i != 0 && out_attr[i].i != 0)
07164            {
07165              /* It's sometimes ok to mix different configs, so this is only
07166                 a warning.  */
07167              _bfd_error_handler
07168               (_("Warning: %B: Conflicting platform configuration"), ibfd);
07169            }
07170          break;
07171        case Tag_ABI_PCS_R9_use:
07172          if (in_attr[i].i != out_attr[i].i
07173              && out_attr[i].i != AEABI_R9_unused
07174              && in_attr[i].i != AEABI_R9_unused)
07175            {
07176              _bfd_error_handler
07177               (_("ERROR: %B: Conflicting use of R9"), ibfd);
07178              return FALSE;
07179            }
07180          if (out_attr[i].i == AEABI_R9_unused)
07181            out_attr[i].i = in_attr[i].i;
07182          break;
07183        case Tag_ABI_PCS_RW_data:
07184          if (in_attr[i].i == AEABI_PCS_RW_data_SBrel
07185              && out_attr[Tag_ABI_PCS_R9_use].i != AEABI_R9_SB
07186              && out_attr[Tag_ABI_PCS_R9_use].i != AEABI_R9_unused)
07187            {
07188              _bfd_error_handler
07189               (_("ERROR: %B: SB relative addressing conflicts with use of R9"),
07190                ibfd);
07191              return FALSE;
07192            }
07193          /* Use the smallest value specified.  */
07194          if (in_attr[i].i < out_attr[i].i)
07195            out_attr[i].i = in_attr[i].i;
07196          break;
07197        case Tag_ABI_PCS_RO_data:
07198          /* Use the smallest value specified.  */
07199          if (in_attr[i].i < out_attr[i].i)
07200            out_attr[i].i = in_attr[i].i;
07201          break;
07202        case Tag_ABI_PCS_GOT_use:
07203          if (in_attr[i].i > 2 || out_attr[i].i > 2
07204              || order_312[in_attr[i].i] < order_312[out_attr[i].i])
07205            out_attr[i].i = in_attr[i].i;
07206          break;
07207        case Tag_ABI_PCS_wchar_t:
07208          if (out_attr[i].i && in_attr[i].i && out_attr[i].i != in_attr[i].i)
07209            {
07210              _bfd_error_handler
07211               (_("ERROR: %B: Conflicting definitions of wchar_t"), ibfd);
07212              return FALSE;
07213            }
07214          if (in_attr[i].i)
07215            out_attr[i].i = in_attr[i].i;
07216          break;
07217        case Tag_ABI_align8_needed:
07218          /* ??? Check against Tag_ABI_align8_preserved.  */
07219          if (in_attr[i].i > 2 || out_attr[i].i > 2
07220              || order_312[in_attr[i].i] < order_312[out_attr[i].i])
07221            out_attr[i].i = in_attr[i].i;
07222          break;
07223        case Tag_ABI_enum_size:
07224          if (in_attr[i].i != AEABI_enum_unused)
07225            {
07226              if (out_attr[i].i == AEABI_enum_unused
07227                 || out_attr[i].i == AEABI_enum_forced_wide)
07228               {
07229                 /* The existing object is compatible with anything.
07230                    Use whatever requirements the new object has.  */
07231                 out_attr[i].i = in_attr[i].i;
07232               }
07233              else if (in_attr[i].i != AEABI_enum_forced_wide
07234                      && out_attr[i].i != in_attr[i].i
07235                      && !elf32_arm_tdata (obfd)->no_enum_size_warning)
07236               {
07237                 const char *aeabi_enum_names[] =
07238                   { "", "variable-size", "32-bit", "" };
07239                 _bfd_error_handler
07240                   (_("warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"),
07241                    ibfd, aeabi_enum_names[in_attr[i].i],
07242                    aeabi_enum_names[out_attr[i].i]);
07243               }
07244            }
07245          break;
07246        case Tag_ABI_VFP_args:
07247          /* Aready done.  */
07248          break;
07249        case Tag_ABI_WMMX_args:
07250          if (in_attr[i].i != out_attr[i].i)
07251            {
07252              _bfd_error_handler
07253               (_("ERROR: %B uses iWMMXt register arguments, %B does not"),
07254                ibfd, obfd);
07255              return FALSE;
07256            }
07257          break;
07258        default: /* All known attributes should be explicitly covered.   */
07259          abort ();
07260        }
07261     }
07262 
07263   in_list = elf32_arm_tdata (ibfd)->other_eabi_attributes;
07264   out_list = elf32_arm_tdata (ibfd)->other_eabi_attributes;
07265   while (in_list && in_list->tag == Tag_compatibility)
07266     {
07267       in_attr = &in_list->attr;
07268       if (in_attr->i == 0)
07269        continue;
07270       if (in_attr->i == 1)
07271        {
07272          _bfd_error_handler
07273            (_("ERROR: %B: Must be processed by '%s' toolchain"),
07274             ibfd, in_attr->s);
07275          return FALSE;
07276        }
07277       if (!out_list || out_list->tag != Tag_compatibility
07278          || strcmp (in_attr->s, out_list->attr.s) != 0)
07279        {
07280          /* Add this compatibility tag to the output.  */
07281          elf32_arm_add_eabi_attr_compat (obfd, in_attr->i, in_attr->s);
07282          continue;
07283        }
07284       out_attr = &out_list->attr;
07285       /* Check all the input tags with the same identifier.  */
07286       for (;;)
07287        {
07288          if (out_list->tag != Tag_compatibility
07289              || in_attr->i != out_attr->i
07290              || strcmp (in_attr->s, out_attr->s) != 0)
07291            {
07292              _bfd_error_handler
07293               (_("ERROR: %B: Incompatible object tag '%s':%d"),
07294                ibfd, in_attr->s, in_attr->i);
07295              return FALSE;
07296            }
07297          in_list = in_list->next;
07298          if (in_list->tag != Tag_compatibility
07299              || strcmp (in_attr->s, in_list->attr.s) != 0)
07300            break;
07301          in_attr = &in_list->attr;
07302          out_list = out_list->next;
07303          if (out_list)
07304            out_attr = &out_list->attr;
07305        }
07306 
07307       /* Check the output doesn't have extra tags with this identifier.  */
07308       if (out_list && out_list->tag == Tag_compatibility
07309          && strcmp (in_attr->s, out_list->attr.s) == 0)
07310        {
07311          _bfd_error_handler
07312            (_("ERROR: %B: Incompatible object tag '%s':%d"),
07313             ibfd, in_attr->s, out_list->attr.i);
07314          return FALSE;
07315        }
07316     }
07317 
07318   for (; in_list; in_list = in_list->next)
07319     {
07320       if ((in_list->tag & 128) < 64)
07321        {
07322          _bfd_error_handler
07323            (_("Warning: %B: Unknown EABI object attribute %d"),
07324             ibfd, in_list->tag);
07325          break;
07326        }
07327     }
07328   return TRUE;
07329 }
07330 
07331 
07332 /* Return TRUE if the two EABI versions are incompatible.  */
07333 
07334 static bfd_boolean
07335 elf32_arm_versions_compatible (unsigned iver, unsigned over)
07336 {
07337   /* v4 and v5 are the same spec before and after it was released,
07338      so allow mixing them.  */
07339   if ((iver == EF_ARM_EABI_VER4 && over == EF_ARM_EABI_VER5)
07340       || (iver == EF_ARM_EABI_VER5 && over == EF_ARM_EABI_VER4))
07341     return TRUE;
07342 
07343   return (iver == over);
07344 }
07345 
07346 /* Merge backend specific data from an object file to the output
07347    object file when linking.  */
07348 
07349 static bfd_boolean
07350 elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
07351 {
07352   flagword out_flags;
07353   flagword in_flags;
07354   bfd_boolean flags_compatible = TRUE;
07355   asection *sec;
07356 
07357   /* Check if we have the same endianess.  */
07358   if (! _bfd_generic_verify_endian_match (ibfd, obfd))
07359     return FALSE;
07360 
07361   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
07362       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
07363     return TRUE;
07364 
07365   if (!elf32_arm_merge_eabi_attributes (ibfd, obfd))
07366     return FALSE;
07367 
07368   /* The input BFD must have had its flags initialised.  */
07369   /* The following seems bogus to me -- The flags are initialized in
07370      the assembler but I don't think an elf_flags_init field is
07371      written into the object.  */
07372   /* BFD_ASSERT (elf_flags_init (ibfd)); */
07373 
07374   in_flags  = elf_elfheader (ibfd)->e_flags;
07375   out_flags = elf_elfheader (obfd)->e_flags;
07376 
07377   if (!elf_flags_init (obfd))
07378     {
07379       /* If the input is the default architecture and had the default
07380         flags then do not bother setting the flags for the output
07381         architecture, instead allow future merges to do this.  If no
07382         future merges ever set these flags then they will retain their
07383          uninitialised values, which surprise surprise, correspond
07384          to the default values.  */
07385       if (bfd_get_arch_info (ibfd)->the_default
07386          && elf_elfheader (ibfd)->e_flags == 0)
07387        return TRUE;
07388 
07389       elf_flags_init (obfd) = TRUE;
07390       elf_elfheader (obfd)->e_flags = in_flags;
07391 
07392       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
07393          && bfd_get_arch_info (obfd)->the_default)
07394        return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
07395 
07396       return TRUE;
07397     }
07398 
07399   /* Determine what should happen if the input ARM architecture
07400      does not match the output ARM architecture.  */
07401   if (! bfd_arm_merge_machines (ibfd, obfd))
07402     return FALSE;
07403 
07404   /* Identical flags must be compatible.  */
07405   if (in_flags == out_flags)
07406     return TRUE;
07407 
07408   /* Check to see if the input BFD actually contains any sections.  If
07409      not, its flags may not have been initialised either, but it
07410      cannot actually cause any incompatiblity.  Do not short-circuit
07411      dynamic objects; their section list may be emptied by
07412     elf_link_add_object_symbols.
07413 
07414     Also check to see if there are no code sections in the input.
07415     In this case there is no need to check for code specific flags.
07416     XXX - do we need to worry about floating-point format compatability
07417     in data sections ?  */
07418   if (!(ibfd->flags & DYNAMIC))
07419     {
07420       bfd_boolean null_input_bfd = TRUE;
07421       bfd_boolean only_data_sections = TRUE;
07422 
07423       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
07424        {
07425          /* Ignore synthetic glue sections.  */
07426          if (strcmp (sec->name, ".glue_7")
07427              && strcmp (sec->name, ".glue_7t"))
07428            {
07429              if ((bfd_get_section_flags (ibfd, sec)
07430                  & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
07431                 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
07432               only_data_sections = FALSE;
07433 
07434              null_input_bfd = FALSE;
07435              break;
07436            }
07437        }
07438 
07439       if (null_input_bfd || only_data_sections)
07440        return TRUE;
07441     }
07442 
07443   /* Complain about various flag mismatches.  */
07444   if (!elf32_arm_versions_compatible (EF_ARM_EABI_VERSION (in_flags),
07445                                   EF_ARM_EABI_VERSION (out_flags)))
07446     {
07447       _bfd_error_handler
07448        (_("ERROR: Source object %B has EABI version %d, but target %B has EABI version %d"),
07449         ibfd, obfd,
07450         (in_flags & EF_ARM_EABIMASK) >> 24,
07451         (out_flags & EF_ARM_EABIMASK) >> 24);
07452       return FALSE;
07453     }
07454 
07455   /* Not sure what needs to be checked for EABI versions >= 1.  */
07456   /* VxWorks libraries do not use these flags.  */
07457   if (get_elf_backend_data (obfd) != &elf32_arm_vxworks_bed
07458       && get_elf_backend_data (ibfd) != &elf32_arm_vxworks_bed
07459       && EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN)
07460     {
07461       if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
07462        {
07463          _bfd_error_handler
07464            (_("ERROR: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"),
07465             ibfd, obfd,
07466             in_flags & EF_ARM_APCS_26 ? 26 : 32,
07467             out_flags & EF_ARM_APCS_26 ? 26 : 32);
07468          flags_compatible = FALSE;
07469        }
07470 
07471       if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
07472        {
07473          if (in_flags & EF_ARM_APCS_FLOAT)
07474            _bfd_error_handler
07475              (_("ERROR: %B passes floats in float registers, whereas %B passes them in integer registers"),
07476               ibfd, obfd);
07477          else
07478            _bfd_error_handler
07479              (_("ERROR: %B passes floats in integer registers, whereas %B passes them in float registers"),
07480               ibfd, obfd);
07481 
07482          flags_compatible = FALSE;
07483        }
07484 
07485       if ((in_flags & EF_ARM_VFP_FLOAT) != (out_flags & EF_ARM_VFP_FLOAT))
07486        {
07487          if (in_flags & EF_ARM_VFP_FLOAT)
07488            _bfd_error_handler
07489              (_("ERROR: %B uses VFP instructions, whereas %B does not"),
07490               ibfd, obfd);
07491          else
07492            _bfd_error_handler
07493              (_("ERROR: %B uses FPA instructions, whereas %B does not"),
07494               ibfd, obfd);
07495 
07496          flags_compatible = FALSE;
07497        }
07498 
07499       if ((in_flags & EF_ARM_MAVERICK_FLOAT) != (out_flags & EF_ARM_MAVERICK_FLOAT))
07500        {
07501          if (in_flags & EF_ARM_MAVERICK_FLOAT)
07502            _bfd_error_handler
07503              (_("ERROR: %B uses Maverick instructions, whereas %B does not"),
07504               ibfd, obfd);
07505          else
07506            _bfd_error_handler
07507              (_("ERROR: %B does not use Maverick instructions, whereas %B does"),
07508               ibfd, obfd);
07509 
07510          flags_compatible = FALSE;
07511        }
07512 
07513 #ifdef EF_ARM_SOFT_FLOAT
07514       if ((in_flags & EF_ARM_SOFT_FLOAT) != (out_flags & EF_ARM_SOFT_FLOAT))
07515        {
07516          /* We can allow interworking between code that is VFP format
07517             layout, and uses either soft float or integer regs for
07518             passing floating point arguments and results.  We already
07519             know that the APCS_FLOAT flags match; similarly for VFP
07520             flags.  */
07521          if ((in_flags & EF_ARM_APCS_FLOAT) != 0
07522              || (in_flags & EF_ARM_VFP_FLOAT) == 0)
07523            {
07524              if (in_flags & EF_ARM_SOFT_FLOAT)
07525               _bfd_error_handler
07526                 (_("ERROR: %B uses software FP, whereas %B uses hardware FP"),
07527                  ibfd, obfd);
07528              else
07529               _bfd_error_handler
07530                 (_("ERROR: %B uses hardware FP, whereas %B uses software FP"),
07531                  ibfd, obfd);
07532 
07533              flags_compatible = FALSE;
07534            }
07535        }
07536 #endif
07537 
07538       /* Interworking mismatch is only a warning.  */
07539       if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
07540        {
07541          if (in_flags & EF_ARM_INTERWORK)
07542            {
07543              _bfd_error_handler
07544               (_("Warning: %B supports interworking, whereas %B does not"),
07545                ibfd, obfd);
07546            }
07547          else
07548            {
07549              _bfd_error_handler
07550               (_("Warning: %B does not support interworking, whereas %B does"),
07551                ibfd, obfd);
07552            }
07553        }
07554     }
07555 
07556   return flags_compatible;
07557 }
07558 
07559 /* Display the flags field.  */
07560 
07561 static bfd_boolean
07562 elf32_arm_print_private_bfd_data (bfd *abfd, void * ptr)
07563 {
07564   FILE * file = (FILE *) ptr;
07565   unsigned long flags;
07566 
07567   BFD_ASSERT (abfd != NULL && ptr != NULL);
07568 
07569   /* Print normal ELF private data.  */
07570   _bfd_elf_print_private_bfd_data (abfd, ptr);
07571 
07572   flags = elf_elfheader (abfd)->e_flags;
07573   /* Ignore init flag - it may not be set, despite the flags field
07574      containing valid data.  */
07575 
07576   /* xgettext:c-format */
07577   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
07578 
07579   switch (EF_ARM_EABI_VERSION (flags))
07580     {
07581     case EF_ARM_EABI_UNKNOWN:
07582       /* The following flag bits are GNU extensions and not part of the
07583         official ARM ELF extended ABI.  Hence they are only decoded if
07584         the EABI version is not set.  */
07585       if (flags & EF_ARM_INTERWORK)
07586        fprintf (file, _(" [interworking enabled]"));
07587 
07588       if (flags & EF_ARM_APCS_26)
07589        fprintf (file, " [APCS-26]");
07590       else
07591        fprintf (file, " [APCS-32]");
07592 
07593       if (flags & EF_ARM_VFP_FLOAT)
07594        fprintf (file, _(" [VFP float format]"));
07595       else if (flags & EF_ARM_MAVERICK_FLOAT)
07596        fprintf (file, _(" [Maverick float format]"));
07597       else
07598        fprintf (file, _(" [FPA float format]"));
07599 
07600       if (flags & EF_ARM_APCS_FLOAT)
07601        fprintf (file, _(" [floats passed in float registers]"));
07602 
07603       if (flags & EF_ARM_PIC)
07604        fprintf (file, _(" [position independent]"));
07605 
07606       if (flags & EF_ARM_NEW_ABI)
07607        fprintf (file, _(" [new ABI]"));
07608 
07609       if (flags & EF_ARM_OLD_ABI)
07610        fprintf (file, _(" [old ABI]"));
07611 
07612       if (flags & EF_ARM_SOFT_FLOAT)
07613        fprintf (file, _(" [software FP]"));
07614 
07615       flags &= ~(EF_ARM_INTERWORK | EF_ARM_APCS_26 | EF_ARM_APCS_FLOAT
07616                | EF_ARM_PIC | EF_ARM_NEW_ABI | EF_ARM_OLD_ABI
07617                | EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT
07618                | EF_ARM_MAVERICK_FLOAT);
07619       break;
07620 
07621     case EF_ARM_EABI_VER1:
07622       fprintf (file, _(" [Version1 EABI]"));
07623 
07624       if (flags & EF_ARM_SYMSARESORTED)
07625        fprintf (file, _(" [sorted symbol table]"));
07626       else
07627        fprintf (file, _(" [unsorted symbol table]"));
07628 
07629       flags &= ~ EF_ARM_SYMSARESORTED;
07630       break;
07631 
07632     case EF_ARM_EABI_VER2:
07633       fprintf (file, _(" [Version2 EABI]"));
07634 
07635       if (flags & EF_ARM_SYMSARESORTED)
07636        fprintf (file, _(" [sorted symbol table]"));
07637       else
07638        fprintf (file, _(" [unsorted symbol table]"));
07639 
07640       if (flags & EF_ARM_DYNSYMSUSESEGIDX)
07641        fprintf (file, _(" [dynamic symbols use segment index]"));
07642 
07643       if (flags & EF_ARM_MAPSYMSFIRST)
07644        fprintf (file, _(" [mapping symbols precede others]"));
07645 
07646       flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX
07647                | EF_ARM_MAPSYMSFIRST);
07648       break;
07649 
07650     case EF_ARM_EABI_VER3:
07651       fprintf (file, _(" [Version3 EABI]"));
07652       break;
07653 
07654     case EF_ARM_EABI_VER4:
07655       fprintf (file, _(" [Version4 EABI]"));
07656       goto eabi;
07657 
07658     case EF_ARM_EABI_VER5:
07659       fprintf (file, _(" [Version5 EABI]"));
07660     eabi:
07661       if (flags & EF_ARM_BE8)
07662        fprintf (file, _(" [BE8]"));
07663 
07664       if (flags & EF_ARM_LE8)
07665        fprintf (file, _(" [LE8]"));
07666 
07667       flags &= ~(EF_ARM_LE8 | EF_ARM_BE8);
07668       break;
07669 
07670     default:
07671       fprintf (file, _(" <EABI version unrecognised>"));
07672       break;
07673     }
07674 
07675   flags &= ~ EF_ARM_EABIMASK;
07676 
07677   if (flags & EF_ARM_RELEXEC)
07678     fprintf (file, _(" [relocatable executable]"));
07679 
07680   if (flags & EF_ARM_HASENTRY)
07681     fprintf (file, _(" [has entry point]"));
07682 
07683   flags &= ~ (EF_ARM_RELEXEC | EF_ARM_HASENTRY);
07684 
07685   if (flags)
07686     fprintf (file, _("<Unrecognised flag bits set>"));
07687 
07688   fputc ('\n', file);
07689 
07690   return TRUE;
07691 }
07692 
07693 static int
07694 elf32_arm_get_symbol_type (Elf_Internal_Sym * elf_sym, int type)
07695 {
07696   switch (ELF_ST_TYPE (elf_sym->st_info))
07697     {
07698     case STT_ARM_TFUNC:
07699       return ELF_ST_TYPE (elf_sym->st_info);
07700 
07701     case STT_ARM_16BIT:
07702       /* If the symbol is not an object, return the STT_ARM_16BIT flag.
07703         This allows us to distinguish between data used by Thumb instructions
07704         and non-data (which is probably code) inside Thumb regions of an
07705         executable.  */
07706       if (type != STT_OBJECT && type != STT_TLS)
07707        return ELF_ST_TYPE (elf_sym->st_info);
07708       break;
07709 
07710     default:
07711       break;
07712     }
07713 
07714   return type;
07715 }
07716 
07717 static asection *
07718 elf32_arm_gc_mark_hook (asection *sec,
07719                      struct bfd_link_info *info,
07720                      Elf_Internal_Rela *rel,
07721                      struct elf_link_hash_entry *h,
07722                      Elf_Internal_Sym *sym)
07723 {
07724   if (h != NULL)
07725     switch (ELF32_R_TYPE (rel->r_info))
07726       {
07727       case R_ARM_GNU_VTINHERIT:
07728       case R_ARM_GNU_VTENTRY:
07729        return NULL;
07730       }
07731 
07732   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
07733 }
07734 
07735 /* Update the got entry reference counts for the section being removed.  */
07736 
07737 static bfd_boolean
07738 elf32_arm_gc_sweep_hook (bfd *                     abfd,
07739                       struct bfd_link_info *    info,
07740                       asection *                sec,
07741                       const Elf_Internal_Rela * relocs)
07742 {
07743   Elf_Internal_Shdr *symtab_hdr;
07744   struct elf_link_hash_entry **sym_hashes;
07745   bfd_signed_vma *local_got_refcounts;
07746   const Elf_Internal_Rela *rel, *relend;
07747   struct elf32_arm_link_hash_table * globals;
07748 
07749   globals = elf32_arm_hash_table (info);
07750 
07751   elf_section_data (sec)->local_dynrel = NULL;
07752 
07753   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
07754   sym_hashes = elf_sym_hashes (abfd);
07755   local_got_refcounts = elf_local_got_refcounts (abfd);
07756 
07757   relend = relocs + sec->reloc_count;
07758   for (rel = relocs; rel < relend; rel++)
07759     {
07760       unsigned long r_symndx;
07761       struct elf_link_hash_entry *h = NULL;
07762       int r_type;
07763 
07764       r_symndx = ELF32_R_SYM (rel->r_info);
07765       if (r_symndx >= symtab_hdr->sh_info)
07766        {
07767          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
07768          while (h->root.type == bfd_link_hash_indirect
07769                || h->root.type == bfd_link_hash_warning)
07770            h = (struct elf_link_hash_entry *) h->root.u.i.link;
07771        }
07772 
07773       r_type = ELF32_R_TYPE (rel->r_info);
07774       r_type = arm_real_reloc_type (globals, r_type);
07775       switch (r_type)
07776        {
07777        case R_ARM_GOT32:
07778        case R_ARM_GOT_PREL:
07779        case R_ARM_TLS_GD32:
07780        case R_ARM_TLS_IE32:
07781          if (h != NULL)
07782            {
07783              if (h->got.refcount > 0)
07784               h->got.refcount -= 1;
07785            }
07786          else if (local_got_refcounts != NULL)
07787            {
07788              if (local_got_refcounts[r_symndx] > 0)
07789               local_got_refcounts[r_symndx] -= 1;
07790            }
07791          break;
07792 
07793        case R_ARM_TLS_LDM32:
07794          elf32_arm_hash_table (info)->tls_ldm_got.refcount -= 1;
07795          break;
07796 
07797        case R_ARM_ABS32:
07798        case R_ARM_ABS32_NOI:
07799        case R_ARM_REL32:
07800        case R_ARM_REL32_NOI:
07801        case R_ARM_PC24:
07802        case R_ARM_PLT32:
07803        case R_ARM_CALL:
07804        case R_ARM_JUMP24:
07805        case R_ARM_PREL31:
07806        case R_ARM_THM_CALL:
07807        case R_ARM_MOVW_ABS_NC:
07808        case R_ARM_MOVT_ABS:
07809        case R_ARM_MOVW_PREL_NC:
07810        case R_ARM_MOVT_PREL:
07811        case R_ARM_THM_MOVW_ABS_NC:
07812        case R_ARM_THM_MOVT_ABS:
07813        case R_ARM_THM_MOVW_PREL_NC:
07814        case R_ARM_THM_MOVT_PREL:
07815          /* Should the interworking branches be here also?  */
07816 
07817          if (h != NULL)
07818            {
07819              struct elf32_arm_link_hash_entry *eh;
07820              struct elf32_arm_relocs_copied **pp;
07821              struct elf32_arm_relocs_copied *p;
07822 
07823              eh = (struct elf32_arm_link_hash_entry *) h;
07824 
07825              if (h->plt.refcount > 0)
07826               {
07827                 h->plt.refcount -= 1;
07828                 if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_CALL)
07829                   eh->plt_thumb_refcount--;
07830               }
07831 
07832              if (r_type == R_ARM_ABS32
07833                 || r_type == R_ARM_REL32
07834                   || r_type == R_ARM_ABS32_NOI
07835                   || r_type == R_ARM_REL32_NOI)
07836               {
07837                 for (pp = &eh->relocs_copied; (p = *pp) != NULL;
07838                      pp = &p->next)
07839                 if (p->section == sec)
07840                   {
07841                     p->count -= 1;
07842                     if (ELF32_R_TYPE (rel->r_info) == R_ARM_REL32
07843                           || ELF32_R_TYPE (rel->r_info) == R_ARM_REL32_NOI)
07844                      p->pc_count -= 1;
07845                     if (p->count == 0)
07846                      *pp = p->next;
07847                     break;
07848                   }
07849               }
07850            }
07851          break;
07852 
07853        default:
07854          break;
07855        }
07856     }
07857 
07858   return TRUE;
07859 }
07860 
07861 /* Look through the relocs for a section during the first phase.  */
07862 
07863 static bfd_boolean
07864 elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
07865                      asection *sec, const Elf_Internal_Rela *relocs)
07866 {
07867   Elf_Internal_Shdr *symtab_hdr;
07868   struct elf_link_hash_entry **sym_hashes;
07869   struct elf_link_hash_entry **sym_hashes_end;
07870   const Elf_Internal_Rela *rel;
07871   const Elf_Internal_Rela *rel_end;
07872   bfd *dynobj;
07873   asection *sreloc;
07874   bfd_vma *local_got_offsets;
07875   struct elf32_arm_link_hash_table *htab;
07876 
07877   if (info->relocatable)
07878     return TRUE;
07879 
07880   htab = elf32_arm_hash_table (info);
07881   sreloc = NULL;
07882 
07883   /* Create dynamic sections for relocatable executables so that we can
07884      copy relocations.  */
07885   if (htab->root.is_relocatable_executable
07886       && ! htab->root.dynamic_sections_created)
07887     {
07888       if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
07889        return FALSE;
07890     }
07891 
07892   dynobj = elf_hash_table (info)->dynobj;
07893   local_got_offsets = elf_local_got_offsets (abfd);
07894 
07895   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
07896   sym_hashes = elf_sym_hashes (abfd);
07897   sym_hashes_end = sym_hashes
07898     + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
07899 
07900   if (!elf_bad_symtab (abfd))
07901     sym_hashes_end -= symtab_hdr->sh_info;
07902 
07903   rel_end = relocs + sec->reloc_count;
07904   for (rel = relocs; rel < rel_end; rel++)
07905     {
07906       struct elf_link_hash_entry *h;
07907       struct elf32_arm_link_hash_entry *eh;
07908       unsigned long r_symndx;
07909       int r_type;
07910 
07911       r_symndx = ELF32_R_SYM (rel->r_info);
07912       r_type = ELF32_R_TYPE (rel->r_info);
07913       r_type = arm_real_reloc_type (htab, r_type);
07914 
07915       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
07916        {
07917          (*_bfd_error_handler) (_("%B: bad symbol index: %d"), abfd,
07918                              r_symndx);
07919          return FALSE;
07920        }
07921 
07922       if (r_symndx < symtab_hdr->sh_info)
07923         h = NULL;
07924       else
07925        {
07926          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
07927          while (h->root.type == bfd_link_hash_indirect
07928                || h->root.type == bfd_link_hash_warning)
07929            h = (struct elf_link_hash_entry *) h->root.u.i.link;
07930        }
07931 
07932       eh = (struct elf32_arm_link_hash_entry *) h;
07933 
07934       switch (r_type)
07935         {
07936          case R_ARM_GOT32:
07937          case R_ARM_GOT_PREL:
07938          case R_ARM_TLS_GD32:
07939          case R_ARM_TLS_IE32:
07940            /* This symbol requires a global offset table entry.  */
07941            {
07942              int tls_type, old_tls_type;
07943 
07944              switch (r_type)
07945               {
07946               case R_ARM_TLS_GD32: tls_type = GOT_TLS_GD; break;
07947               case R_ARM_TLS_IE32: tls_type = GOT_TLS_IE; break;
07948               default: tls_type = GOT_NORMAL; break;
07949               }
07950 
07951              if (h != NULL)
07952               {
07953                 h->got.refcount++;
07954                 old_tls_type = elf32_arm_hash_entry (h)->tls_type;
07955               }
07956              else
07957               {
07958                 bfd_signed_vma *local_got_refcounts;
07959 
07960                 /* This is a global offset table entry for a local symbol.  */
07961                 local_got_refcounts = elf_local_got_refcounts (abfd);
07962                 if (local_got_refcounts == NULL)
07963                   {
07964                     bfd_size_type size;
07965                     
07966                     size = symtab_hdr->sh_info;
07967                     size *= (sizeof (bfd_signed_vma) + sizeof(char));
07968                     local_got_refcounts = bfd_zalloc (abfd, size);
07969                     if (local_got_refcounts == NULL)
07970                      return FALSE;
07971                     elf_local_got_refcounts (abfd) = local_got_refcounts;
07972                     elf32_arm_local_got_tls_type (abfd)
07973                      = (char *) (local_got_refcounts + symtab_hdr->sh_info);
07974                   }
07975                 local_got_refcounts[r_symndx] += 1;
07976                 old_tls_type = elf32_arm_local_got_tls_type (abfd) [r_symndx];
07977               }
07978 
07979              /* We will already have issued an error message if there is a
07980                TLS / non-TLS mismatch, based on the symbol type.  We don't
07981                support any linker relaxations.  So just combine any TLS
07982                types needed.  */
07983              if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL
07984                 && tls_type != GOT_NORMAL)
07985               tls_type |= old_tls_type;
07986 
07987              if (old_tls_type != tls_type)
07988               {
07989                 if (h != NULL)
07990                   elf32_arm_hash_entry (h)->tls_type = tls_type;
07991                 else
07992                   elf32_arm_local_got_tls_type (abfd) [r_symndx] = tls_type;
07993               }
07994            }
07995            /* Fall through */
07996 
07997          case R_ARM_TLS_LDM32:
07998            if (r_type == R_ARM_TLS_LDM32)
07999               htab->tls_ldm_got.refcount++;
08000            /* Fall through */
08001 
08002          case R_ARM_GOTOFF32:
08003          case R_ARM_GOTPC:
08004            if (htab->sgot == NULL)
08005              {
08006               if (htab->root.dynobj == NULL)
08007                 htab->root.dynobj = abfd;
08008               if (!create_got_section (htab->root.dynobj, info))
08009                 return FALSE;
08010              }
08011            break;
08012 
08013          case R_ARM_ABS12:
08014            /* VxWorks uses dynamic R_ARM_ABS12 relocations for
08015               ldr __GOTT_INDEX__ offsets.  */
08016            if (!htab->vxworks_p)
08017              break;
08018            /* Fall through */
08019 
08020          case R_ARM_ABS32:
08021          case R_ARM_ABS32_NOI:
08022          case R_ARM_REL32:
08023          case R_ARM_REL32_NOI:
08024          case R_ARM_PC24:
08025          case R_ARM_PLT32:
08026          case R_ARM_CALL:
08027          case R_ARM_JUMP24:
08028          case R_ARM_PREL31:
08029          case R_ARM_THM_CALL:
08030          case R_ARM_MOVW_ABS_NC:
08031          case R_ARM_MOVT_ABS:
08032          case R_ARM_MOVW_PREL_NC:
08033          case R_ARM_MOVT_PREL:
08034          case R_ARM_THM_MOVW_ABS_NC:
08035          case R_ARM_THM_MOVT_ABS:
08036          case R_ARM_THM_MOVW_PREL_NC:
08037          case R_ARM_THM_MOVT_PREL:
08038            /* Should the interworking branches be listed here?  */
08039            if (h != NULL)
08040              {
08041               /* If this reloc is in a read-only section, we might
08042                  need a copy reloc.  We can't check reliably at this
08043                  stage whether the section is read-only, as input
08044                  sections have not yet been mapped to output sections.
08045                  Tentatively set the flag for now, and correct in
08046                  adjust_dynamic_symbol.  */
08047               if (!info->shared)
08048                 h->non_got_ref = 1;
08049 
08050               /* We may need a .plt entry if the function this reloc
08051                  refers to is in a different object.  We can't tell for
08052                  sure yet, because something later might force the
08053                  symbol local.  */
08054               if (r_type != R_ARM_ABS32
08055                     && r_type != R_ARM_REL32
08056                     && r_type != R_ARM_ABS32_NOI
08057                     && r_type != R_ARM_REL32_NOI)
08058                 h->needs_plt = 1;
08059 
08060               /* If we create a PLT entry, this relocation will reference
08061                  it, even if it's an ABS32 relocation.  */
08062               h->plt.refcount += 1;
08063 
08064               if (r_type == R_ARM_THM_CALL)
08065                 eh->plt_thumb_refcount += 1;
08066              }
08067 
08068            /* If we are creating a shared library or relocatable executable,
08069               and this is a reloc against a global symbol, or a non PC
08070               relative reloc against a local symbol, then we need to copy
08071               the reloc into the shared library.  However, if we are linking
08072               with -Bsymbolic, we do not need to copy a reloc against a
08073                global symbol which is defined in an object we are
08074                including in the link (i.e., DEF_REGULAR is set).  At
08075                this point we have not seen all the input files, so it is
08076                possible that DEF_REGULAR is not set now but will be set
08077                later (it is never cleared).  We account for that
08078                possibility below by storing information in the
08079                relocs_copied field of the hash table entry.  */
08080            if ((info->shared || htab->root.is_relocatable_executable)
08081               && (sec->flags & SEC_ALLOC) != 0
08082               && ((r_type == R_ARM_ABS32 || r_type == R_ARM_ABS32_NOI)
08083                   || (h != NULL && ! h->needs_plt
08084                      && (! info->symbolic || ! h->def_regular))))
08085              {
08086               struct elf32_arm_relocs_copied *p, **head;
08087 
08088                /* When creating a shared object, we must copy these
08089                    reloc types into the output file.  We create a reloc
08090                    section in dynobj and make room for this reloc.  */
08091                if (sreloc == NULL)
08092                 {
08093                   const char * name;
08094 
08095                   name = (bfd_elf_string_from_elf_section
08096                          (abfd,
08097                           elf_elfheader (abfd)->e_shstrndx,
08098                           elf_section_data (sec)->rel_hdr.sh_name));
08099                   if (name == NULL)
08100                     return FALSE;
08101 
08102                   BFD_ASSERT (reloc_section_p (htab, name, sec));
08103 
08104                   sreloc = bfd_get_section_by_name (dynobj, name);
08105                   if (sreloc == NULL)
08106                     {
08107                       flagword flags;
08108 
08109                       flags = (SEC_HAS_CONTENTS | SEC_READONLY
08110                               | SEC_IN_MEMORY | SEC_LINKER_CREATED);
08111                       if ((sec->flags & SEC_ALLOC) != 0
08112                          /* BPABI objects never have dynamic
08113                             relocations mapped.  */
08114                          && !htab->symbian_p)
08115                        flags |= SEC_ALLOC | SEC_LOAD;
08116                       sreloc = bfd_make_section_with_flags (dynobj,
08117                                                        name,
08118                                                        flags);
08119                       if (sreloc == NULL
08120                          || ! bfd_set_section_alignment (dynobj, sreloc, 2))
08121                        return FALSE;
08122                     }
08123 
08124                   elf_section_data (sec)->sreloc = sreloc;
08125                 }
08126 
08127               /* If this is a global symbol, we count the number of
08128                  relocations we need for this symbol.  */
08129               if (h != NULL)
08130                 {
08131                   head = &((struct elf32_arm_link_hash_entry *) h)->relocs_copied;
08132                 }
08133               else
08134                 {
08135                   /* Track dynamic relocs needed for local syms too.
08136                      We really need local syms available to do this
08137                      easily.  Oh well.  */
08138 
08139                   asection *s;
08140                   void *vpp;
08141 
08142                   s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
08143                                              sec, r_symndx);
08144                   if (s == NULL)
08145                     return FALSE;
08146 
08147                   vpp = &elf_section_data (s)->local_dynrel;
08148                   head = (struct elf32_arm_relocs_copied **) vpp;
08149                 }
08150 
08151               p = *head;
08152               if (p == NULL || p->section != sec)
08153                 {
08154                   bfd_size_type amt = sizeof *p;
08155 
08156                   p = bfd_alloc (htab->root.dynobj, amt);
08157                   if (p == NULL)
08158                     return FALSE;
08159                   p->next = *head;
08160                   *head = p;
08161                   p->section = sec;
08162                   p->count = 0;
08163                   p->pc_count = 0;
08164                 }
08165 
08166               if (r_type == R_ARM_REL32 || r_type == R_ARM_REL32_NOI)
08167                 p->pc_count += 1;
08168               p->count += 1;
08169              }
08170            break;
08171 
08172         /* This relocation describes the C++ object vtable hierarchy.
08173            Reconstruct it for later use during GC.  */
08174         case R_ARM_GNU_VTINHERIT:
08175           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
08176             return FALSE;
08177           break;
08178 
08179         /* This relocation describes which C++ vtable entries are actually
08180            used.  Record for later use during GC.  */
08181         case R_ARM_GNU_VTENTRY:
08182           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
08183             return FALSE;
08184           break;
08185         }
08186     }
08187 
08188   return TRUE;
08189 }
08190 
08191 /* Unwinding tables are not referenced directly.  This pass marks them as
08192    required if the corresponding code section is marked.  */
08193 
08194 static bfd_boolean
08195 elf32_arm_gc_mark_extra_sections(struct bfd_link_info *info,
08196                              elf_gc_mark_hook_fn gc_mark_hook)
08197 {
08198   bfd *sub;
08199   Elf_Internal_Shdr **elf_shdrp;
08200   bfd_boolean again;
08201 
08202   /* Marking EH data may cause additional code sections to be marked,
08203      requiring multiple passes.  */
08204   again = TRUE;
08205   while (again)
08206     {
08207       again = FALSE;
08208       for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
08209        {
08210          asection *o;
08211 
08212          if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
08213            continue;
08214 
08215          elf_shdrp = elf_elfsections (sub);
08216          for (o = sub->sections; o != NULL; o = o->next)
08217            {
08218              Elf_Internal_Shdr *hdr;
08219              hdr = &elf_section_data (o)->this_hdr;
08220              if (hdr->sh_type == SHT_ARM_EXIDX && hdr->sh_link
08221                 && !o->gc_mark
08222                 && elf_shdrp[hdr->sh_link]->bfd_section->gc_mark)
08223               {
08224                 again = TRUE;
08225                 if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
08226                   return FALSE;
08227               }
08228            }
08229        }
08230     }
08231 
08232   return TRUE;
08233 }
08234 
08235 /* Treat mapping symbols as special target symbols.  */
08236 
08237 static bfd_boolean
08238 elf32_arm_is_target_special_symbol (bfd * abfd ATTRIBUTE_UNUSED, asymbol * sym)
08239 {
08240   return bfd_is_arm_special_symbol_name (sym->name,
08241                                     BFD_ARM_SPECIAL_SYM_TYPE_ANY);
08242 }
08243 
08244 /* This is a copy of elf_find_function() from elf.c except that
08245    ARM mapping symbols are ignored when looking for function names
08246    and STT_ARM_TFUNC is considered to a function type.  */
08247 
08248 static bfd_boolean
08249 arm_elf_find_function (bfd *         abfd ATTRIBUTE_UNUSED,
08250                      asection *    section,
08251                      asymbol **    symbols,
08252                      bfd_vma       offset,
08253                      const char ** filename_ptr,
08254                      const char ** functionname_ptr)
08255 {
08256   const char * filename = NULL;
08257   asymbol * func = NULL;
08258   bfd_vma low_func = 0;
08259   asymbol ** p;
08260 
08261   for (p = symbols; *p != NULL; p++)
08262     {
08263       elf_symbol_type *q;
08264 
08265       q = (elf_symbol_type *) *p;
08266 
08267       switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
08268        {
08269        default:
08270          break;
08271        case STT_FILE:
08272          filename = bfd_asymbol_name (&q->symbol);
08273          break;
08274        case STT_FUNC:
08275        case STT_ARM_TFUNC:
08276        case STT_NOTYPE:
08277          /* Skip mapping symbols.  */
08278          if ((q->symbol.flags & BSF_LOCAL)
08279              && bfd_is_arm_special_symbol_name (q->symbol.name,
08280                   BFD_ARM_SPECIAL_SYM_TYPE_ANY))
08281            continue;
08282          /* Fall through.  */
08283          if (bfd_get_section (&q->symbol) == section
08284              && q->symbol.value >= low_func
08285              && q->symbol.value <= offset)
08286            {
08287              func = (asymbol *) q;
08288              low_func = q->symbol.value;
08289            }
08290          break;
08291        }
08292     }
08293 
08294   if (func == NULL)
08295     return FALSE;
08296 
08297