Develop and Download Open Source Software

Browse Subversion Repository

Diff of /trunk/bfd/elf32-arm.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 20 by monabuilder, Sun Dec 28 03:31:28 2008 UTC revision 21 by monamour, Mon Jul 27 20:34:36 2009 UTC
# Line 1  Line 1 
1  /* 32-bit ELF support for ARM  /* 32-bit ELF support for ARM
2     Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,     Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3     2008 Free Software Foundation, Inc.     2008, 2009  Free Software Foundation, Inc.
4    
5     This file is part of BFD, the Binary File Descriptor library.     This file is part of BFD, the Binary File Descriptor library.
6    
# Line 20  Line 20 
20     MA 02110-1301, USA.  */     MA 02110-1301, USA.  */
21    
22  #include "sysdep.h"  #include "sysdep.h"
23    #include <limits.h>
24    
25  #include "bfd.h"  #include "bfd.h"
26  #include "libiberty.h"  #include "libiberty.h"
27  #include "libbfd.h"  #include "libbfd.h"
# Line 61  Line 63 
63    
64  static struct elf_backend_data elf32_arm_vxworks_bed;  static struct elf_backend_data elf32_arm_vxworks_bed;
65    
66    static bfd_boolean elf32_arm_write_section (bfd *output_bfd,
67                                                struct bfd_link_info *link_info,
68                                                asection *sec,
69                                                bfd_byte *contents);
70    
71  /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.  /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
72     R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO     R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
73     in that slot.  */     in that slot.  */
# Line 1881  typedef unsigned short int insn16; Line 1888  typedef unsigned short int insn16;
1888     interworkable.  */     interworkable.  */
1889  #define INTERWORK_FLAG(abfd)  \  #define INTERWORK_FLAG(abfd)  \
1890    (EF_ARM_EABI_VERSION (elf_elfheader (abfd)->e_flags) >= EF_ARM_EABI_VER4 \    (EF_ARM_EABI_VERSION (elf_elfheader (abfd)->e_flags) >= EF_ARM_EABI_VER4 \
1891    || (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK))    || (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK) \
1892      || ((abfd)->flags & BFD_LINKER_CREATED))
1893    
1894  /* The linker script knows the section names for placement.  /* The linker script knows the section names for placement.
1895     The entry_names are used to do simple name mangling on the stubs.     The entry_names are used to do simple name mangling on the stubs.
# Line 2010  static const bfd_vma elf32_arm_symbian_p Line 2018  static const bfd_vma elf32_arm_symbian_p
2018  #define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4)  #define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4)
2019  #define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4)  #define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4)
2020    
2021  static const bfd_vma arm_long_branch_stub[] =  enum stub_insn_type
2022    {    {
2023      0xe51ff004,         /* ldr   pc, [pc, #-4] */      THUMB16_TYPE = 1,
2024      0x00000000,         /* dcd   R_ARM_ABS32(X) */      THUMB32_TYPE,
2025        ARM_TYPE,
2026        DATA_TYPE
2027      };
2028    
2029    #define THUMB16_INSN(X)         {(X), THUMB16_TYPE, R_ARM_NONE, 0}
2030    /* A bit of a hack.  A Thumb conditional branch, in which the proper condition
2031       is inserted in arm_build_one_stub().  */
2032    #define THUMB16_BCOND_INSN(X)   {(X), THUMB16_TYPE, R_ARM_NONE, 1}
2033    #define THUMB32_INSN(X)         {(X), THUMB32_TYPE, R_ARM_NONE, 0}
2034    #define THUMB32_B_INSN(X, Z)    {(X), THUMB32_TYPE, R_ARM_THM_JUMP24, (Z)}
2035    #define ARM_INSN(X)             {(X), ARM_TYPE, R_ARM_NONE, 0}
2036    #define ARM_REL_INSN(X, Z)      {(X), ARM_TYPE, R_ARM_JUMP24, (Z)}
2037    #define DATA_WORD(X,Y,Z)        {(X), DATA_TYPE, (Y), (Z)}
2038    
2039    typedef struct
2040    {
2041      bfd_vma data;
2042      enum stub_insn_type type;
2043      unsigned int r_type;
2044      int reloc_addend;
2045    }  insn_sequence;
2046    
2047    /* Arm/Thumb -> Arm/Thumb long branch stub. On V5T and above, use blx
2048       to reach the stub if necessary.  */
2049    static const insn_sequence elf32_arm_stub_long_branch_any_any[] =
2050      {
2051        ARM_INSN(0xe51ff004),            /* ldr   pc, [pc, #-4] */
2052        DATA_WORD(0, R_ARM_ABS32, 0),    /* dcd   R_ARM_ABS32(X) */
2053      };
2054    
2055    /* V4T Arm -> Thumb long branch stub. Used on V4T where blx is not
2056       available.  */
2057    static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb[] =
2058      {
2059        ARM_INSN(0xe59fc000),            /* ldr   ip, [pc, #0] */
2060        ARM_INSN(0xe12fff1c),            /* bx    ip */
2061        DATA_WORD(0, R_ARM_ABS32, 0),    /* dcd   R_ARM_ABS32(X) */
2062      };
2063    
2064    /* Thumb -> Thumb long branch stub. Used on M-profile architectures.  */
2065    static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] =
2066      {
2067        THUMB16_INSN(0xb401),             /* push {r0} */
2068        THUMB16_INSN(0x4802),             /* ldr  r0, [pc, #8] */
2069        THUMB16_INSN(0x4684),             /* mov  ip, r0 */
2070        THUMB16_INSN(0xbc01),             /* pop  {r0} */
2071        THUMB16_INSN(0x4760),             /* bx   ip */
2072        THUMB16_INSN(0xbf00),             /* nop */
2073        DATA_WORD(0, R_ARM_ABS32, 0),     /* dcd  R_ARM_ABS32(X) */
2074      };
2075    
2076    /* V4T Thumb -> Thumb long branch stub. Using the stack is not
2077       allowed.  */
2078    static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb[] =
2079      {
2080        THUMB16_INSN(0x4778),             /* bx   pc */
2081        THUMB16_INSN(0x46c0),             /* nop */
2082        ARM_INSN(0xe59fc000),             /* ldr  ip, [pc, #0] */
2083        ARM_INSN(0xe12fff1c),             /* bx   ip */
2084        DATA_WORD(0, R_ARM_ABS32, 0),     /* dcd  R_ARM_ABS32(X) */
2085      };
2086    
2087    /* V4T Thumb -> ARM long branch stub. Used on V4T where blx is not
2088       available.  */
2089    static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm[] =
2090      {
2091        THUMB16_INSN(0x4778),             /* bx   pc */
2092        THUMB16_INSN(0x46c0),             /* nop   */
2093        ARM_INSN(0xe51ff004),             /* ldr   pc, [pc, #-4] */
2094        DATA_WORD(0, R_ARM_ABS32, 0),     /* dcd   R_ARM_ABS32(X) */
2095      };
2096    
2097    /* V4T Thumb -> ARM short branch stub. Shorter variant of the above
2098       one, when the destination is close enough.  */
2099    static const insn_sequence elf32_arm_stub_short_branch_v4t_thumb_arm[] =
2100      {
2101        THUMB16_INSN(0x4778),             /* bx   pc */
2102        THUMB16_INSN(0x46c0),             /* nop   */
2103        ARM_REL_INSN(0xea000000, -8),     /* b    (X-8) */
2104      };
2105    
2106    /* ARM/Thumb -> ARM long branch stub, PIC.  On V5T and above, use
2107       blx to reach the stub if necessary.  */
2108    static const insn_sequence elf32_arm_stub_long_branch_any_arm_pic[] =
2109      {
2110        ARM_INSN(0xe59fc000),             /* ldr   r12, [pc] */
2111        ARM_INSN(0xe08ff00c),             /* add   pc, pc, ip */
2112        DATA_WORD(0, R_ARM_REL32, -4),    /* dcd   R_ARM_REL32(X-4) */
2113    };    };
2114    
2115  static const bfd_vma arm_thumb_v4t_long_branch_stub[] =  /* ARM/Thumb -> Thumb long branch stub, PIC.  On V5T and above, use
2116       blx to reach the stub if necessary.  We can not add into pc;
2117       it is not guaranteed to mode switch (different in ARMv6 and
2118       ARMv7).  */
2119    static const insn_sequence elf32_arm_stub_long_branch_any_thumb_pic[] =
2120    {    {
2121      0xe59fc000,         /* ldr   ip, [pc, #0] */      ARM_INSN(0xe59fc004),             /* ldr   r12, [pc, #4] */
2122      0xe12fff1c,         /* bx    ip */      ARM_INSN(0xe08fc00c),             /* add   ip, pc, ip */
2123      0x00000000,         /* dcd   R_ARM_ABS32(X) */      ARM_INSN(0xe12fff1c),             /* bx    ip */
2124        DATA_WORD(0, R_ARM_REL32, 0),     /* dcd   R_ARM_REL32(X) */
2125    };    };
2126    
2127  static const bfd_vma arm_thumb_thumb_long_branch_stub[] =  /* V4T ARM -> ARM long branch stub, PIC.  */
2128    static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] =
2129    {    {
2130      0x4e02b540,         /* push {r6, lr} */      ARM_INSN(0xe59fc004),             /* ldr   ip, [pc, #4] */
2131                          /* ldr  r6, [pc, #8] */      ARM_INSN(0xe08fc00c),             /* add   ip, pc, ip */
2132      0x473046fe,         /* mov  lr, pc */      ARM_INSN(0xe12fff1c),             /* bx    ip */
2133                          /* bx   r6 */      DATA_WORD(0, R_ARM_REL32, 0),     /* dcd   R_ARM_REL32(X) */
     0xbf00bd40,         /* pop  {r6, pc} */  
                         /* nop */  
     0x00000000,         /* dcd  R_ARM_ABS32(X) */  
2134    };    };
2135    
2136  static const bfd_vma arm_thumb_arm_v4t_long_branch_stub[] =  /* V4T Thumb -> ARM long branch stub, PIC.  */
2137    static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] =
2138    {    {
2139      0x4e03b540,         /* push {r6, lr} */      THUMB16_INSN(0x4778),             /* bx   pc */
2140                          /* ldr  r6, [pc, #12] */      THUMB16_INSN(0x46c0),             /* nop  */
2141      0x473046fe,         /* mov  lr, pc */      ARM_INSN(0xe59fc000),             /* ldr  ip, [pc, #0] */
2142                          /* bx   r6 */      ARM_INSN(0xe08cf00f),             /* add  pc, ip, pc */
2143      0xe8bd4040,         /* pop  {r6, pc} */      DATA_WORD(0, R_ARM_REL32, -4),     /* dcd  R_ARM_REL32(X) */
     0xe12fff1e,         /* bx   lr */  
     0x00000000,         /* dcd  R_ARM_ABS32(X) */  
2144    };    };
2145    
2146  static const bfd_vma arm_thumb_arm_v4t_short_branch_stub[] =  /* Thumb -> Thumb long branch stub, PIC. Used on M-profile
2147       architectures.  */
2148    static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] =
2149    {    {
2150      0x46c04778,         /* bx   pc */      THUMB16_INSN(0xb401),             /* push {r0} */
2151                          /* nop   */      THUMB16_INSN(0x4802),             /* ldr  r0, [pc, #8] */
2152      0xea000000,         /* b    (X) */      THUMB16_INSN(0x46fc),             /* mov  ip, pc */
2153        THUMB16_INSN(0x4484),             /* add  ip, r0 */
2154        THUMB16_INSN(0xbc01),             /* pop  {r0} */
2155        THUMB16_INSN(0x4760),             /* bx   ip */
2156        DATA_WORD(0, R_ARM_REL32, 4),     /* dcd  R_ARM_REL32(X) */
2157    };    };
2158    
2159  static const bfd_vma arm_pic_long_branch_stub[] =  /* V4T Thumb -> Thumb long branch stub, PIC. Using the stack is not
2160       allowed.  */
2161    static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb_pic[] =
2162    {    {
2163      0xe59fc000,         /* ldr   r12, [pc] */      THUMB16_INSN(0x4778),             /* bx   pc */
2164      0xe08ff00c,         /* add   pc, pc, ip */      THUMB16_INSN(0x46c0),             /* nop */
2165      0x00000000,         /* dcd   R_ARM_REL32(X) */      ARM_INSN(0xe59fc004),             /* ldr  ip, [pc, #4] */
2166        ARM_INSN(0xe08fc00c),             /* add   ip, pc, ip */
2167        ARM_INSN(0xe12fff1c),             /* bx   ip */
2168        DATA_WORD(0, R_ARM_REL32, 0),     /* dcd  R_ARM_REL32(X) */
2169      };
2170    
2171    /* Cortex-A8 erratum-workaround stubs.  */
2172    
2173    /* Stub used for conditional branches (which may be beyond +/-1MB away, so we
2174       can't use a conditional branch to reach this stub).  */
2175    
2176    static const insn_sequence elf32_arm_stub_a8_veneer_b_cond[] =
2177      {
2178        THUMB16_BCOND_INSN(0xd001),         /* b<cond>.n true.  */
2179        THUMB32_B_INSN(0xf000b800, -4),     /* b.w insn_after_original_branch.  */
2180        THUMB32_B_INSN(0xf000b800, -4)      /* true: b.w original_branch_dest.  */
2181      };
2182    
2183    /* Stub used for b.w and bl.w instructions.  */
2184    
2185    static const insn_sequence elf32_arm_stub_a8_veneer_b[] =
2186      {
2187        THUMB32_B_INSN(0xf000b800, -4)      /* b.w original_branch_dest.  */
2188      };
2189    
2190    static const insn_sequence elf32_arm_stub_a8_veneer_bl[] =
2191      {
2192        THUMB32_B_INSN(0xf000b800, -4)      /* b.w original_branch_dest.  */
2193      };
2194    
2195    /* Stub used for Thumb-2 blx.w instructions.  We modified the original blx.w
2196       instruction (which switches to ARM mode) to point to this stub.  Jump to the
2197       real destination using an ARM-mode branch.  */
2198    
2199    static const insn_sequence elf32_arm_stub_a8_veneer_blx[] =
2200      {
2201        ARM_REL_INSN(0xea000000, -8)        /* b original_branch_dest.  */
2202    };    };
2203    
2204  /* Section name for stubs is the associated section name plus this  /* Section name for stubs is the associated section name plus this
2205     string.  */     string.  */
2206  #define STUB_SUFFIX ".stub"  #define STUB_SUFFIX ".stub"
2207    
2208  enum elf32_arm_stub_type  /* One entry per long/short branch stub defined above.  */
2209  {  #define DEF_STUBS \
2210      DEF_STUB(long_branch_any_any) \
2211      DEF_STUB(long_branch_v4t_arm_thumb) \
2212      DEF_STUB(long_branch_thumb_only) \
2213      DEF_STUB(long_branch_v4t_thumb_thumb) \
2214      DEF_STUB(long_branch_v4t_thumb_arm) \
2215      DEF_STUB(short_branch_v4t_thumb_arm) \
2216      DEF_STUB(long_branch_any_arm_pic) \
2217      DEF_STUB(long_branch_any_thumb_pic) \
2218      DEF_STUB(long_branch_v4t_thumb_thumb_pic) \
2219      DEF_STUB(long_branch_v4t_arm_thumb_pic) \
2220      DEF_STUB(long_branch_v4t_thumb_arm_pic) \
2221      DEF_STUB(long_branch_thumb_only_pic) \
2222      DEF_STUB(a8_veneer_b_cond) \
2223      DEF_STUB(a8_veneer_b) \
2224      DEF_STUB(a8_veneer_bl) \
2225      DEF_STUB(a8_veneer_blx)
2226    
2227    #define DEF_STUB(x) arm_stub_##x,
2228    enum elf32_arm_stub_type {
2229    arm_stub_none,    arm_stub_none,
2230    arm_stub_long_branch,    DEF_STUBS
2231    arm_thumb_v4t_stub_long_branch,  };
2232    arm_thumb_thumb_stub_long_branch,  #undef DEF_STUB
2233    arm_thumb_arm_v4t_stub_long_branch,  
2234    arm_thumb_arm_v4t_stub_short_branch,  typedef struct
2235    arm_stub_pic_long_branch,  {
2236      const insn_sequence* template;
2237      int template_size;
2238    } stub_def;
2239    
2240    #define DEF_STUB(x) {elf32_arm_stub_##x, ARRAY_SIZE(elf32_arm_stub_##x)},
2241    static const stub_def stub_definitions[] = {
2242      {NULL, 0},
2243      DEF_STUBS
2244  };  };
2245    
2246  struct elf32_arm_stub_hash_entry  struct elf32_arm_stub_hash_entry
# Line 2090  struct elf32_arm_stub_hash_entry Line 2259  struct elf32_arm_stub_hash_entry
2259    bfd_vma target_value;    bfd_vma target_value;
2260    asection *target_section;    asection *target_section;
2261    
2262      /* Offset to apply to relocation referencing target_value.  */
2263      bfd_vma target_addend;
2264    
2265      /* The instruction which caused this stub to be generated (only valid for
2266         Cortex-A8 erratum workaround stubs at present).  */
2267      unsigned long orig_insn;
2268    
2269      /* The stub type.  */
2270    enum elf32_arm_stub_type stub_type;    enum elf32_arm_stub_type stub_type;
2271      /* Its encoding size in bytes.  */
2272      int stub_size;
2273      /* Its template.  */
2274      const insn_sequence *stub_template;
2275      /* The size of the template (number of entries).  */
2276      int stub_template_size;
2277    
2278    /* The symbol table entry, if any, that this was derived from.  */    /* The symbol table entry, if any, that this was derived from.  */
2279    struct elf32_arm_link_hash_entry *h;    struct elf32_arm_link_hash_entry *h;
# Line 2150  typedef struct elf32_vfp11_erratum_list Line 2333  typedef struct elf32_vfp11_erratum_list
2333  }  }
2334  elf32_vfp11_erratum_list;  elf32_vfp11_erratum_list;
2335    
2336    typedef enum
2337    {
2338      DELETE_EXIDX_ENTRY,
2339      INSERT_EXIDX_CANTUNWIND_AT_END
2340    }
2341    arm_unwind_edit_type;
2342    
2343    /* A (sorted) list of edits to apply to an unwind table.  */
2344    typedef struct arm_unwind_table_edit
2345    {
2346      arm_unwind_edit_type type;
2347      /* Note: we sometimes want to insert an unwind entry corresponding to a
2348         section different from the one we're currently writing out, so record the
2349         (text) section this edit relates to here.  */
2350      asection *linked_section;
2351      unsigned int index;
2352      struct arm_unwind_table_edit *next;
2353    }
2354    arm_unwind_table_edit;
2355    
2356  typedef struct _arm_elf_section_data  typedef struct _arm_elf_section_data
2357  {  {
2358      /* Information about mapping symbols.  */
2359    struct bfd_elf_section_data elf;    struct bfd_elf_section_data elf;
2360    unsigned int mapcount;    unsigned int mapcount;
2361    unsigned int mapsize;    unsigned int mapsize;
2362    elf32_arm_section_map *map;    elf32_arm_section_map *map;
2363      /* Information about CPU errata.  */
2364    unsigned int erratumcount;    unsigned int erratumcount;
2365    elf32_vfp11_erratum_list *erratumlist;    elf32_vfp11_erratum_list *erratumlist;
2366      /* Information about unwind tables.  */
2367      union
2368      {
2369        /* Unwind info attached to a text section.  */
2370        struct
2371        {
2372          asection *arm_exidx_sec;
2373        } text;
2374    
2375        /* Unwind info attached to an .ARM.exidx section.  */
2376        struct
2377        {
2378          arm_unwind_table_edit *unwind_edit_list;
2379          arm_unwind_table_edit *unwind_edit_tail;
2380        } exidx;
2381      } u;
2382  }  }
2383  _arm_elf_section_data;  _arm_elf_section_data;
2384    
2385  #define elf32_arm_section_data(sec) \  #define elf32_arm_section_data(sec) \
2386    ((_arm_elf_section_data *) elf_section_data (sec))    ((_arm_elf_section_data *) elf_section_data (sec))
2387    
2388    /* A fix which might be required for Cortex-A8 Thumb-2 branch/TLB erratum.
2389       These fixes are subject to a relaxation procedure (in elf32_arm_size_stubs),
2390       so may be created multiple times: we use an array of these entries whilst
2391       relaxing which we can refresh easily, then create stubs for each potentially
2392       erratum-triggering instruction once we've settled on a solution.  */
2393    
2394    struct a8_erratum_fix {
2395      bfd *input_bfd;
2396      asection *section;
2397      bfd_vma offset;
2398      bfd_vma addend;
2399      unsigned long orig_insn;
2400      char *stub_name;
2401      enum elf32_arm_stub_type stub_type;
2402    };
2403    
2404    /* A table of relocs applied to branches which might trigger Cortex-A8
2405       erratum.  */
2406    
2407    struct a8_erratum_reloc {
2408      bfd_vma from;
2409      bfd_vma destination;
2410      unsigned int r_type;
2411      unsigned char st_type;
2412      const char *sym_name;
2413      bfd_boolean non_a8_stub;
2414    };
2415    
2416  /* The size of the thread control block.  */  /* The size of the thread control block.  */
2417  #define TCB_SIZE        8  #define TCB_SIZE        8
2418    
# Line 2295  struct elf32_arm_link_hash_table Line 2544  struct elf32_arm_link_hash_table
2544       veneers.  */       veneers.  */
2545    bfd_size_type vfp11_erratum_glue_size;    bfd_size_type vfp11_erratum_glue_size;
2546    
2547      /* A table of fix locations for Cortex-A8 Thumb-2 branch/TLB erratum.  This
2548         holds Cortex-A8 erratum fix locations between elf32_arm_size_stubs() and
2549         elf32_arm_write_section().  */
2550      struct a8_erratum_fix *a8_erratum_fixes;
2551      unsigned int num_a8_erratum_fixes;
2552    
2553    /* An arbitrary input BFD chosen to hold the glue sections.  */    /* An arbitrary input BFD chosen to hold the glue sections.  */
2554    bfd * bfd_of_glue_owner;    bfd * bfd_of_glue_owner;
2555    
# Line 2313  struct elf32_arm_link_hash_table Line 2568  struct elf32_arm_link_hash_table
2568       2 = Generate v4 interworing stubs.  */       2 = Generate v4 interworing stubs.  */
2569    int fix_v4bx;    int fix_v4bx;
2570    
2571      /* Whether we should fix the Cortex-A8 Thumb-2 branch/TLB erratum.  */
2572      int fix_cortex_a8;
2573    
2574    /* Nonzero if the ARM/Thumb BLX instructions are available for use.  */    /* Nonzero if the ARM/Thumb BLX instructions are available for use.  */
2575    int use_blx;    int use_blx;
2576    
# Line 2360  struct elf32_arm_link_hash_table Line 2618  struct elf32_arm_link_hash_table
2618      bfd_vma offset;      bfd_vma offset;
2619    } tls_ldm_got;    } tls_ldm_got;
2620    
2621    /* Small local sym to section mapping cache.  */    /* Small local sym cache.  */
2622    struct sym_sec_cache sym_sec;    struct sym_cache sym_cache;
2623    
2624    /* For convenience in allocate_dynrelocs.  */    /* For convenience in allocate_dynrelocs.  */
2625    bfd * obfd;    bfd * obfd;
# Line 2458  stub_hash_newfunc (struct bfd_hash_entry Line 2716  stub_hash_newfunc (struct bfd_hash_entry
2716        eh->stub_offset = 0;        eh->stub_offset = 0;
2717        eh->target_value = 0;        eh->target_value = 0;
2718        eh->target_section = NULL;        eh->target_section = NULL;
2719          eh->target_addend = 0;
2720          eh->orig_insn = 0;
2721        eh->stub_type = arm_stub_none;        eh->stub_type = arm_stub_none;
2722          eh->stub_size = 0;
2723          eh->stub_template = NULL;
2724          eh->stub_template_size = 0;
2725        eh->h = NULL;        eh->h = NULL;
2726        eh->id_sec = NULL;        eh->id_sec = NULL;
2727      }      }
# Line 2487  create_got_section (bfd *dynobj, struct Line 2750  create_got_section (bfd *dynobj, struct
2750    if (!htab->sgot || !htab->sgotplt)    if (!htab->sgot || !htab->sgotplt)
2751      abort ();      abort ();
2752    
2753    htab->srelgot = bfd_make_section_with_flags (dynobj,    htab->srelgot = bfd_get_section_by_name (dynobj,
2754                                                 RELOC_SECTION (htab, ".got"),                                             RELOC_SECTION (htab, ".got"));
2755                                                 (SEC_ALLOC | SEC_LOAD    if (htab->srelgot == NULL)
                                                 | SEC_HAS_CONTENTS  
                                                 | SEC_IN_MEMORY  
                                                 | SEC_LINKER_CREATED  
                                                 | SEC_READONLY));  
   if (htab->srelgot == NULL  
       || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))  
2756      return FALSE;      return FALSE;
2757    return TRUE;    return TRUE;
2758  }  }
# Line 2649  elf32_arm_link_hash_table_create (bfd *a Line 2906  elf32_arm_link_hash_table_create (bfd *a
2906    ret->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;    ret->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;
2907    ret->vfp11_erratum_glue_size = 0;    ret->vfp11_erratum_glue_size = 0;
2908    ret->num_vfp11_fixes = 0;    ret->num_vfp11_fixes = 0;
2909      ret->fix_cortex_a8 = 0;
2910    ret->bfd_of_glue_owner = NULL;    ret->bfd_of_glue_owner = NULL;
2911    ret->byteswap_code = 0;    ret->byteswap_code = 0;
2912    ret->target1_is_rel = 0;    ret->target1_is_rel = 0;
# Line 2665  elf32_arm_link_hash_table_create (bfd *a Line 2923  elf32_arm_link_hash_table_create (bfd *a
2923    ret->vxworks_p = 0;    ret->vxworks_p = 0;
2924    ret->symbian_p = 0;    ret->symbian_p = 0;
2925    ret->use_rel = 1;    ret->use_rel = 1;
2926    ret->sym_sec.abfd = NULL;    ret->sym_cache.abfd = NULL;
2927    ret->obfd = abfd;    ret->obfd = abfd;
2928    ret->tls_ldm_got.refcount = 0;    ret->tls_ldm_got.refcount = 0;
2929    ret->stub_bfd = NULL;    ret->stub_bfd = NULL;
# Line 2731  arm_stub_is_thumb (enum elf32_arm_stub_t Line 2989  arm_stub_is_thumb (enum elf32_arm_stub_t
2989  {  {
2990    switch (stub_type)    switch (stub_type)
2991      {      {
2992      case arm_thumb_thumb_stub_long_branch:      case arm_stub_long_branch_thumb_only:
2993      case arm_thumb_arm_v4t_stub_long_branch:      case arm_stub_long_branch_v4t_thumb_arm:
2994      case arm_thumb_arm_v4t_stub_short_branch:      case arm_stub_short_branch_v4t_thumb_arm:
2995        case arm_stub_long_branch_v4t_thumb_arm_pic:
2996        case arm_stub_long_branch_thumb_only_pic:
2997        return TRUE;        return TRUE;
2998      case arm_stub_none:      case arm_stub_none:
2999        BFD_FAIL ();        BFD_FAIL ();
# Line 2764  arm_type_of_stub (struct bfd_link_info * Line 3024  arm_type_of_stub (struct bfd_link_info *
3024    int thumb2;    int thumb2;
3025    int thumb_only;    int thumb_only;
3026    enum elf32_arm_stub_type stub_type = arm_stub_none;    enum elf32_arm_stub_type stub_type = arm_stub_none;
3027      int use_plt = 0;
3028    
3029    /* We don't know the actual type of destination in case it is of    /* We don't know the actual type of destination in case it is of
3030       type STT_SECTION: give up.  */       type STT_SECTION: give up.  */
# Line 2785  arm_type_of_stub (struct bfd_link_info * Line 3046  arm_type_of_stub (struct bfd_link_info *
3046    
3047    r_type = ELF32_R_TYPE (rel->r_info);    r_type = ELF32_R_TYPE (rel->r_info);
3048    
3049    /* If the call will go through a PLT entry then we do not need    /* Keep a simpler condition, for the sake of clarity.  */
      glue.  */  
3050    if (globals->splt != NULL && hash != NULL && hash->root.plt.offset != (bfd_vma) -1)    if (globals->splt != NULL && hash != NULL && hash->root.plt.offset != (bfd_vma) -1)
     return stub_type;  
   
   if (r_type == R_ARM_THM_CALL)  
3051      {      {
3052          use_plt = 1;
3053          /* Note when dealing with PLT entries: the main PLT stub is in
3054             ARM mode, so if the branch is in Thumb mode, another
3055             Thumb->ARM stub will be inserted later just before the ARM
3056             PLT stub. We don't take this extra distance into account
3057             here, because if a long branch stub is needed, we'll add a
3058             Thumb->Arm one and branch directly to the ARM PLT entry
3059             because it avoids spreading offset corrections in several
3060             places.  */
3061        }
3062    
3063      if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
3064        {
3065          /* Handle cases where:
3066             - this call goes too far (different Thumb/Thumb2 max
3067               distance)
3068             - it's a Thumb->Arm call and blx is not available, or it's a
3069               Thumb->Arm branch (not bl). A stub is needed in this case,
3070               but only if this call is not through a PLT entry. Indeed,
3071               PLT stubs handle mode switching already.
3072          */
3073        if ((!thumb2        if ((!thumb2
3074              && (branch_offset > THM_MAX_FWD_BRANCH_OFFSET              && (branch_offset > THM_MAX_FWD_BRANCH_OFFSET
3075                  || (branch_offset < THM_MAX_BWD_BRANCH_OFFSET)))                  || (branch_offset < THM_MAX_BWD_BRANCH_OFFSET)))
3076            || (thumb2            || (thumb2
3077                && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET                && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
3078                    || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))                    || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
3079            || ((st_type != STT_ARM_TFUNC) && !globals->use_blx))            || ((st_type != STT_ARM_TFUNC)
3080                  && (((r_type == R_ARM_THM_CALL) && !globals->use_blx)
3081                      || (r_type == R_ARM_THM_JUMP24))
3082                  && !use_plt))
3083          {          {
3084            if (st_type == STT_ARM_TFUNC)            if (st_type == STT_ARM_TFUNC)
3085              {              {
# Line 2806  arm_type_of_stub (struct bfd_link_info * Line 3087  arm_type_of_stub (struct bfd_link_info *
3087                if (!thumb_only)                if (!thumb_only)
3088                  {                  {
3089                    stub_type = (info->shared | globals->pic_veneer)                    stub_type = (info->shared | globals->pic_veneer)
3090                      ? ((globals->use_blx)                      /* PIC stubs.  */
3091                         ? arm_stub_pic_long_branch                      ? ((globals->use_blx
3092                         : arm_stub_none)                          && (r_type ==R_ARM_THM_CALL))
3093                      : (globals->use_blx)                         /* V5T and above. Stub starts with ARM code, so
3094                      ? arm_stub_long_branch                            we must be able to switch mode before
3095                      : arm_stub_none;                            reaching it, which is only possible for 'bl'
3096                              (ie R_ARM_THM_CALL relocation).  */
3097                           ? arm_stub_long_branch_any_thumb_pic
3098                           /* On V4T, use Thumb code only.  */
3099                           : arm_stub_long_branch_v4t_thumb_thumb_pic)
3100    
3101                        /* non-PIC stubs.  */
3102                        : ((globals->use_blx
3103                            && (r_type ==R_ARM_THM_CALL))
3104                           /* V5T and above.  */
3105                           ? arm_stub_long_branch_any_any
3106                           /* V4T.  */
3107                           : arm_stub_long_branch_v4t_thumb_thumb);
3108                  }                  }
3109                else                else
3110                  {                  {
3111                    stub_type = (info->shared | globals->pic_veneer)                    stub_type = (info->shared | globals->pic_veneer)
3112                      ? arm_stub_none                      /* PIC stub.  */
3113                      : (globals->use_blx)                      ? arm_stub_long_branch_thumb_only_pic
3114                      ? arm_thumb_thumb_stub_long_branch                      /* non-PIC stub.  */
3115                      : arm_stub_none;                      : arm_stub_long_branch_thumb_only;
3116                  }                  }
3117              }              }
3118            else            else
# Line 2836  arm_type_of_stub (struct bfd_link_info * Line 3129  arm_type_of_stub (struct bfd_link_info *
3129                  }                  }
3130    
3131                stub_type = (info->shared | globals->pic_veneer)                stub_type = (info->shared | globals->pic_veneer)
3132                  ? ((globals->use_blx)                  /* PIC stubs.  */
3133                     ? arm_stub_pic_long_branch                  ? ((globals->use_blx
3134                     : arm_stub_none)                      && (r_type ==R_ARM_THM_CALL))
3135                  : (globals->use_blx)                     /* V5T and above.  */
3136                  ? arm_stub_long_branch                     ? arm_stub_long_branch_any_arm_pic
3137                  : arm_thumb_arm_v4t_stub_long_branch;                     /* V4T PIC stub.  */
3138                       : arm_stub_long_branch_v4t_thumb_arm_pic)
3139    
3140                    /* non-PIC stubs.  */
3141                    : ((globals->use_blx
3142                        && (r_type ==R_ARM_THM_CALL))
3143                       /* V5T and above.  */
3144                       ? arm_stub_long_branch_any_any
3145                       /* V4T.  */
3146                       : arm_stub_long_branch_v4t_thumb_arm);
3147    
3148                /* Handle v4t short branches.  */                /* Handle v4t short branches.  */
3149                if ((stub_type == arm_thumb_arm_v4t_stub_long_branch)                if ((stub_type == arm_stub_long_branch_v4t_thumb_arm)
3150                    && (branch_offset <= THM_MAX_FWD_BRANCH_OFFSET)                    && (branch_offset <= THM_MAX_FWD_BRANCH_OFFSET)
3151                    && (branch_offset >= THM_MAX_BWD_BRANCH_OFFSET))                    && (branch_offset >= THM_MAX_BWD_BRANCH_OFFSET))
3152                  stub_type = arm_thumb_arm_v4t_stub_short_branch;                  stub_type = arm_stub_short_branch_v4t_thumb_arm;
3153              }              }
3154          }          }
3155      }      }
3156    else if (r_type == R_ARM_CALL)    else if (r_type == R_ARM_CALL || r_type == R_ARM_JUMP24 || r_type == R_ARM_PLT32)
3157      {      {
3158        if (st_type == STT_ARM_TFUNC)        if (st_type == STT_ARM_TFUNC)
3159          {          {
# Line 2863  arm_type_of_stub (struct bfd_link_info * Line 3165  arm_type_of_stub (struct bfd_link_info *
3165              {              {
3166                (*_bfd_error_handler)                (*_bfd_error_handler)
3167                  (_("%B(%s): warning: interworking not enabled.\n"                  (_("%B(%s): warning: interworking not enabled.\n"
3168                     "  first occurrence: %B: Thumb call to ARM"),                     "  first occurrence: %B: ARM call to Thumb"),
3169                   sym_sec->owner, input_bfd, name);                   sym_sec->owner, input_bfd, name);
3170              }              }
3171    
# Line 2871  arm_type_of_stub (struct bfd_link_info * Line 3173  arm_type_of_stub (struct bfd_link_info *
3173               the mode change (bit 24 (H) of BLX encoding).  */               the mode change (bit 24 (H) of BLX encoding).  */
3174            if (branch_offset > (ARM_MAX_FWD_BRANCH_OFFSET + 2)            if (branch_offset > (ARM_MAX_FWD_BRANCH_OFFSET + 2)
3175                || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET)                || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET)
3176                || !globals->use_blx)                || ((r_type == R_ARM_CALL) && !globals->use_blx)
3177                  || (r_type == R_ARM_JUMP24)
3178                  || (r_type == R_ARM_PLT32))
3179              {              {
3180                stub_type = (info->shared | globals->pic_veneer)                stub_type = (info->shared | globals->pic_veneer)
3181                  ? arm_stub_pic_long_branch                  /* PIC stubs.  */
3182                  : (globals->use_blx)                  ? ((globals->use_blx)
3183                  ? arm_stub_long_branch                     /* V5T and above.  */
3184                  : arm_thumb_v4t_stub_long_branch;                     ? arm_stub_long_branch_any_thumb_pic
3185                       /* V4T stub.  */
3186                       : arm_stub_long_branch_v4t_arm_thumb_pic)
3187    
3188                    /* non-PIC stubs.  */
3189                    : ((globals->use_blx)
3190                       /* V5T and above.  */
3191                       ? arm_stub_long_branch_any_any
3192                       /* V4T.  */
3193                       : arm_stub_long_branch_v4t_arm_thumb);
3194              }              }
3195          }          }
3196        else        else
# Line 2887  arm_type_of_stub (struct bfd_link_info * Line 3200  arm_type_of_stub (struct bfd_link_info *
3200                || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))                || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))
3201              {              {
3202                stub_type = (info->shared | globals->pic_veneer)                stub_type = (info->shared | globals->pic_veneer)
3203                  ? arm_stub_pic_long_branch                  /* PIC stubs.  */
3204                  : arm_stub_long_branch;                  ? arm_stub_long_branch_any_arm_pic
3205                    /* non-PIC stubs.  */
3206                    : arm_stub_long_branch_any_any;
3207              }              }
3208          }          }
3209      }      }
# Line 2981  elf32_arm_get_stub_entry (const asection Line 3296  elf32_arm_get_stub_entry (const asection
3296    return stub_entry;    return stub_entry;
3297  }  }
3298    
3299  /* Add a new stub entry to the stub hash.  Not all fields of the new  /* Find or create a stub section.  Returns a pointer to the stub section, and
3300     stub entry are initialised.  */     the section to which the stub section will be attached (in *LINK_SEC_P).
3301       LINK_SEC_P may be NULL.  */
3302    
3303  static struct elf32_arm_stub_hash_entry *  static asection *
3304  elf32_arm_add_stub (const char *stub_name,  elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section,
3305                      asection *section,                                     struct elf32_arm_link_hash_table *htab)
                     struct elf32_arm_link_hash_table *htab)  
3306  {  {
3307    asection *link_sec;    asection *link_sec;
3308    asection *stub_sec;    asection *stub_sec;
   struct elf32_arm_stub_hash_entry *stub_entry;  
3309    
3310    link_sec = htab->stub_group[section->id].link_sec;    link_sec = htab->stub_group[section->id].link_sec;
3311    stub_sec = htab->stub_group[section->id].stub_sec;    stub_sec = htab->stub_group[section->id].stub_sec;
# Line 3019  elf32_arm_add_stub (const char *stub_nam Line 3333  elf32_arm_add_stub (const char *stub_nam
3333          }          }
3334        htab->stub_group[section->id].stub_sec = stub_sec;        htab->stub_group[section->id].stub_sec = stub_sec;
3335      }      }
3336      
3337      if (link_sec_p)
3338        *link_sec_p = link_sec;
3339      
3340      return stub_sec;
3341    }
3342    
3343    /* Add a new stub entry to the stub hash.  Not all fields of the new
3344       stub entry are initialised.  */
3345    
3346    static struct elf32_arm_stub_hash_entry *
3347    elf32_arm_add_stub (const char *stub_name,
3348                        asection *section,
3349                        struct elf32_arm_link_hash_table *htab)
3350    {
3351      asection *link_sec;
3352      asection *stub_sec;
3353      struct elf32_arm_stub_hash_entry *stub_entry;
3354    
3355      stub_sec = elf32_arm_create_or_find_stub_sec (&link_sec, section, htab);
3356      if (stub_sec == NULL)
3357        return NULL;
3358    
3359    /* Enter this entry into the linker stub hash table.  */    /* Enter this entry into the linker stub hash table.  */
3360    stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,    stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,
# Line 3064  put_thumb_insn (struct elf32_arm_link_ha Line 3400  put_thumb_insn (struct elf32_arm_link_ha
3400      bfd_putb16 (val, ptr);      bfd_putb16 (val, ptr);
3401  }  }
3402    
3403    static bfd_reloc_status_type elf32_arm_final_link_relocate
3404      (reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *,
3405       Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *,
3406       const char *, int, struct elf_link_hash_entry *, bfd_boolean *, char **);
3407    
3408  static bfd_boolean  static bfd_boolean
3409  arm_build_one_stub (struct bfd_hash_entry *gen_entry,  arm_build_one_stub (struct bfd_hash_entry *gen_entry,
3410                      void * in_arg)                      void * in_arg)
3411  {  {
3412    #define MAXRELOCS 2
3413    struct elf32_arm_stub_hash_entry *stub_entry;    struct elf32_arm_stub_hash_entry *stub_entry;
3414    struct bfd_link_info *info;    struct bfd_link_info *info;
3415    struct elf32_arm_link_hash_table *htab;    struct elf32_arm_link_hash_table *htab;
# Line 3078  arm_build_one_stub (struct bfd_hash_entr Line 3420  arm_build_one_stub (struct bfd_hash_entr
3420    bfd_vma sym_value;    bfd_vma sym_value;
3421    int template_size;    int template_size;
3422    int size;    int size;
3423    const bfd_vma *template;    const insn_sequence *template;
3424    int i;    int i;
3425    struct elf32_arm_link_hash_table * globals;    struct elf32_arm_link_hash_table * globals;
3426      int stub_reloc_idx[MAXRELOCS] = {-1, -1};
3427      int stub_reloc_offset[MAXRELOCS] = {0, 0};
3428      int nrelocs = 0;
3429    
3430    /* Massage our args to the form they really have.  */    /* Massage our args to the form they really have.  */
3431    stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;    stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
# Line 3106  arm_build_one_stub (struct bfd_hash_entr Line 3451  arm_build_one_stub (struct bfd_hash_entr
3451                 + stub_entry->target_section->output_offset                 + stub_entry->target_section->output_offset
3452                 + stub_entry->target_section->output_section->vma);                 + stub_entry->target_section->output_section->vma);
3453    
3454    switch (stub_entry->stub_type)    template = stub_entry->stub_template;
3455      {    template_size = stub_entry->stub_template_size;
     case arm_stub_long_branch:  
       template = arm_long_branch_stub;  
       template_size = (sizeof (arm_long_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     case arm_thumb_v4t_stub_long_branch:  
       template =  arm_thumb_v4t_long_branch_stub;  
       template_size = (sizeof (arm_thumb_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     case arm_thumb_thumb_stub_long_branch:  
       template =  arm_thumb_thumb_long_branch_stub;  
       template_size = (sizeof (arm_thumb_thumb_long_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     case arm_thumb_arm_v4t_stub_long_branch:  
       template =  arm_thumb_arm_v4t_long_branch_stub;  
       template_size = (sizeof (arm_thumb_arm_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     case arm_thumb_arm_v4t_stub_short_branch:  
       template =  arm_thumb_arm_v4t_short_branch_stub;  
       template_size = (sizeof(arm_thumb_arm_v4t_short_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     case arm_stub_pic_long_branch:  
       template = arm_pic_long_branch_stub;  
       template_size = (sizeof (arm_pic_long_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     default:  
       BFD_FAIL ();  
       return FALSE;  
     }  
3456    
3457    size = 0;    size = 0;
3458    for (i = 0; i < (template_size / 4); i++)    for (i = 0; i < template_size; i++)
3459      {      {
3460        /* A 0 pattern is a placeholder, every other pattern is an        switch (template[i].type)
3461           instruction.  */          {
3462        if (template[i] != 0)          case THUMB16_TYPE:
3463          put_arm_insn (globals, stub_bfd, template[i], loc + size);            {
3464        else              bfd_vma data = template[i].data;
3465          bfd_put_32 (stub_bfd, template[i], loc + size);              if (template[i].reloc_addend != 0)
3466                  {
3467                    /* We've borrowed the reloc_addend field to mean we should
3468                       insert a condition code into this (Thumb-1 branch)
3469                       instruction.  See THUMB16_BCOND_INSN.  */
3470                    BFD_ASSERT ((data & 0xff00) == 0xd000);
3471                    data |= ((stub_entry->orig_insn >> 22) & 0xf) << 8;
3472                  }
3473                put_thumb_insn (globals, stub_bfd, data, loc + size);
3474                size += 2;
3475              }
3476              break;
3477    
3478            case THUMB32_TYPE:
3479              put_thumb_insn (globals, stub_bfd, (template[i].data >> 16) & 0xffff,
3480                              loc + size);
3481              put_thumb_insn (globals, stub_bfd, template[i].data & 0xffff,
3482                              loc + size + 2);
3483              if (template[i].r_type != R_ARM_NONE)
3484                {
3485                  stub_reloc_idx[nrelocs] = i;
3486                  stub_reloc_offset[nrelocs++] = size;
3487                }
3488              size += 4;
3489              break;
3490    
3491            case ARM_TYPE:
3492              put_arm_insn (globals, stub_bfd, template[i].data, loc + size);
3493              /* Handle cases where the target is encoded within the
3494                 instruction.  */
3495              if (template[i].r_type == R_ARM_JUMP24)
3496                {
3497                  stub_reloc_idx[nrelocs] = i;
3498                  stub_reloc_offset[nrelocs++] = size;
3499                }
3500              size += 4;
3501              break;
3502    
3503        size += 4;          case DATA_TYPE:
3504              bfd_put_32 (stub_bfd, template[i].data, loc + size);
3505              stub_reloc_idx[nrelocs] = i;
3506              stub_reloc_offset[nrelocs++] = size;
3507              size += 4;
3508              break;
3509    
3510            default:
3511              BFD_FAIL ();
3512              return FALSE;
3513            }
3514      }      }
3515    
3516    stub_sec->size += size;    stub_sec->size += size;
3517    
3518      /* Stub size has already been computed in arm_size_one_stub. Check
3519         consistency.  */
3520      BFD_ASSERT (size == stub_entry->stub_size);
3521    
3522    /* Destination is Thumb. Force bit 0 to 1 to reflect this.  */    /* Destination is Thumb. Force bit 0 to 1 to reflect this.  */
3523    if (stub_entry->st_type == STT_ARM_TFUNC)    if (stub_entry->st_type == STT_ARM_TFUNC)
3524      sym_value |= 1;      sym_value |= 1;
3525    
3526    switch (stub_entry->stub_type)    /* Assume there is at least one and at most MAXRELOCS entries to relocate
3527      {       in each stub.  */
3528      case arm_stub_long_branch:    BFD_ASSERT (nrelocs != 0 && nrelocs <= MAXRELOCS);
3529        _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),  
3530                                  stub_bfd, stub_sec, stub_sec->contents,    for (i = 0; i < nrelocs; i++)
3531                                  stub_entry->stub_offset + 4, sym_value, 0);      if (template[stub_reloc_idx[i]].r_type == R_ARM_THM_JUMP24
3532        break;          || template[stub_reloc_idx[i]].r_type == R_ARM_THM_JUMP19
3533      case arm_thumb_v4t_stub_long_branch:          || template[stub_reloc_idx[i]].r_type == R_ARM_THM_CALL
3534        _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),          || template[stub_reloc_idx[i]].r_type == R_ARM_THM_XPC22)
3535                                  stub_bfd, stub_sec, stub_sec->contents,        {
3536                                  stub_entry->stub_offset + 8, sym_value, 0);          Elf_Internal_Rela rel;
3537        break;          bfd_boolean unresolved_reloc;
3538      case arm_thumb_thumb_stub_long_branch:          char *error_message;
3539        _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),          int sym_flags
3540                                  stub_bfd, stub_sec, stub_sec->contents,            = (template[stub_reloc_idx[i]].r_type != R_ARM_THM_XPC22)
3541                                  stub_entry->stub_offset + 12, sym_value, 0);              ? STT_ARM_TFUNC : 0;
3542        break;          bfd_vma points_to = sym_value + stub_entry->target_addend;
3543      case arm_thumb_arm_v4t_stub_long_branch:  
3544        _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),          rel.r_offset = stub_entry->stub_offset + stub_reloc_offset[i];
3545                                  stub_bfd, stub_sec, stub_sec->contents,          rel.r_info = ELF32_R_INFO (0, template[stub_reloc_idx[i]].r_type);
3546                                  stub_entry->stub_offset + 16, sym_value, 0);          rel.r_addend = template[stub_reloc_idx[i]].reloc_addend;
3547        break;  
3548      case arm_thumb_arm_v4t_stub_short_branch:          if (stub_entry->stub_type == arm_stub_a8_veneer_b_cond && i == 0)
3549              /* The first relocation in the elf32_arm_stub_a8_veneer_b_cond[]
3550                 template should refer back to the instruction after the original
3551                 branch.  */
3552              points_to = sym_value;
3553    
3554            /* There may be unintended consequences if this is not true.  */
3555            BFD_ASSERT (stub_entry->h == NULL);
3556    
3557            /* Note: _bfd_final_link_relocate doesn't handle these relocations
3558               properly.  We should probably use this function unconditionally,
3559               rather than only for certain relocations listed in the enclosing
3560               conditional, for the sake of consistency.  */
3561            elf32_arm_final_link_relocate (elf32_arm_howto_from_type
3562                (template[stub_reloc_idx[i]].r_type),
3563              stub_bfd, info->output_bfd, stub_sec, stub_sec->contents, &rel,
3564              points_to, info, stub_entry->target_section, "", sym_flags,
3565              (struct elf_link_hash_entry *) stub_entry->h, &unresolved_reloc,
3566              &error_message);
3567          }
3568        else
3569        {        {
3570          long int rel_offset;          _bfd_final_link_relocate (elf32_arm_howto_from_type
3571          static const insn32 t2a3_b_insn = 0xea000000;              (template[stub_reloc_idx[i]].r_type), stub_bfd, stub_sec,
3572              stub_sec->contents, stub_entry->stub_offset + stub_reloc_offset[i],
3573              sym_value + stub_entry->target_addend,
3574              template[stub_reloc_idx[i]].reloc_addend);
3575          }
3576    
3577          rel_offset = sym_value - (stub_addr + 8 + 4);    return TRUE;
3578    #undef MAXRELOCS
3579    }
3580    
3581          put_arm_insn (globals, stub_bfd,  /* Calculate the template, template size and instruction size for a stub.
3582                        (bfd_vma) t2a3_b_insn | ((rel_offset >> 2) & 0x00FFFFFF),     Return value is the instruction size.  */
                       loc + 4);  
       }  
       break;  
3583    
3584      case arm_stub_pic_long_branch:  static unsigned int
3585        /* We want the value relative to the address 8 bytes from the  find_stub_size_and_template (enum elf32_arm_stub_type stub_type,
3586           start of the stub.  */                               const insn_sequence **stub_template,
3587        _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_REL32),                               int *stub_template_size)
3588                                  stub_bfd, stub_sec, stub_sec->contents,  {
3589                                  stub_entry->stub_offset + 8, sym_value, 0);    const insn_sequence *template = NULL;
3590        break;    int template_size = 0, i;
3591      default:    unsigned int size;
3592        break;  
3593      template = stub_definitions[stub_type].template;
3594      template_size = stub_definitions[stub_type].template_size;
3595    
3596      size = 0;
3597      for (i = 0; i < template_size; i++)
3598        {
3599          switch (template[i].type)
3600            {
3601            case THUMB16_TYPE:
3602              size += 2;
3603              break;
3604    
3605            case ARM_TYPE:
3606            case THUMB32_TYPE:
3607            case DATA_TYPE:
3608              size += 4;
3609              break;
3610    
3611            default:
3612              BFD_FAIL ();
3613              return FALSE;
3614            }
3615      }      }
3616    
3617    return TRUE;    if (stub_template)
3618        *stub_template = template;
3619    
3620      if (stub_template_size)
3621        *stub_template_size = template_size;
3622    
3623      return size;
3624  }  }
3625    
3626  /* As above, but don't actually build the stub.  Just bump offset so  /* As above, but don't actually build the stub.  Just bump offset so
# Line 3213  arm_size_one_stub (struct bfd_hash_entry Line 3632  arm_size_one_stub (struct bfd_hash_entry
3632  {  {
3633    struct elf32_arm_stub_hash_entry *stub_entry;    struct elf32_arm_stub_hash_entry *stub_entry;
3634    struct elf32_arm_link_hash_table *htab;    struct elf32_arm_link_hash_table *htab;
3635    const bfd_vma *template;    const insn_sequence *template;
3636    int template_size;    int template_size, size;
   int size;  
   int i;  
3637    
3638    /* Massage our args to the form they really have.  */    /* Massage our args to the form they really have.  */
3639    stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;    stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
3640    htab = (struct elf32_arm_link_hash_table *) in_arg;    htab = (struct elf32_arm_link_hash_table *) in_arg;
3641    
3642    switch (stub_entry->stub_type)    BFD_ASSERT((stub_entry->stub_type > arm_stub_none)
3643      {               && stub_entry->stub_type < ARRAY_SIZE(stub_definitions));
3644      case arm_stub_long_branch:  
3645        template =  arm_long_branch_stub;    size = find_stub_size_and_template (stub_entry->stub_type, &template,
3646        template_size = (sizeof (arm_long_branch_stub) / sizeof (bfd_vma)) * 4;                                        &template_size);
3647        break;  
3648      case arm_thumb_v4t_stub_long_branch:    stub_entry->stub_size = size;
3649        template =  arm_thumb_v4t_long_branch_stub;    stub_entry->stub_template = template;
3650        template_size = (sizeof (arm_thumb_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;    stub_entry->stub_template_size = template_size;
       break;  
     case arm_thumb_thumb_stub_long_branch:  
       template =  arm_thumb_thumb_long_branch_stub;  
       template_size = (sizeof (arm_thumb_thumb_long_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     case arm_thumb_arm_v4t_stub_long_branch:  
       template =  arm_thumb_arm_v4t_long_branch_stub;  
       template_size = (sizeof (arm_thumb_arm_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     case arm_thumb_arm_v4t_stub_short_branch:  
       template =  arm_thumb_arm_v4t_short_branch_stub;  
       template_size = (sizeof(arm_thumb_arm_v4t_short_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     case arm_stub_pic_long_branch:  
       template = arm_pic_long_branch_stub;  
       template_size = (sizeof (arm_pic_long_branch_stub) / sizeof (bfd_vma)) * 4;  
       break;  
     default:  
       BFD_FAIL ();  
       return FALSE;  
       break;  
     }  
3651    
   size = 0;  
   for (i = 0; i < (template_size / 4); i++)  
       size += 4;  
3652    size = (size + 7) & ~7;    size = (size + 7) & ~7;
3653    stub_entry->stub_sec->size += size;    stub_entry->stub_sec->size += size;
3654    
3655    return TRUE;    return TRUE;
3656  }  }
3657    
# Line 3360  elf32_arm_next_input_section (struct bfd Line 3753  elf32_arm_next_input_section (struct bfd
3753            /* Steal the link_sec pointer for our list.  */            /* Steal the link_sec pointer for our list.  */
3754  #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)  #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
3755            /* This happens to make the list in reverse order,            /* This happens to make the list in reverse order,
3756               which is what we want.  */               which we reverse later.  */
3757            PREV_SEC (isec) = *list;            PREV_SEC (isec) = *list;
3758            *list = isec;            *list = isec;
3759          }          }
# Line 3369  elf32_arm_next_input_section (struct bfd Line 3762  elf32_arm_next_input_section (struct bfd
3762    
3763  /* See whether we can group stub sections together.  Grouping stub  /* See whether we can group stub sections together.  Grouping stub
3764     sections may result in fewer stubs.  More importantly, we need to     sections may result in fewer stubs.  More importantly, we need to
3765     put all .init* and .fini* stubs at the beginning of the .init or     put all .init* and .fini* stubs at the end of the .init or
3766     .fini output sections respectively, because glibc splits the     .fini output sections respectively, because glibc splits the
3767     _init and _fini functions into multiple parts.  Putting a stub in     _init and _fini functions into multiple parts.  Putting a stub in
3768     the middle of a function is not a good idea.  */     the middle of a function is not a good idea.  */
# Line 3377  elf32_arm_next_input_section (struct bfd Line 3770  elf32_arm_next_input_section (struct bfd
3770  static void  static void
3771  group_sections (struct elf32_arm_link_hash_table *htab,  group_sections (struct elf32_arm_link_hash_table *htab,
3772                  bfd_size_type stub_group_size,                  bfd_size_type stub_group_size,
3773                  bfd_boolean stubs_always_before_branch)                  bfd_boolean stubs_always_after_branch)
3774  {  {
3775    asection **list = htab->input_list + htab->top_index;    asection **list = htab->input_list;
3776    
3777    do    do
3778      {      {
3779        asection *tail = *list;        asection *tail = *list;
3780          asection *head;
3781    
3782        if (tail == bfd_abs_section_ptr)        if (tail == bfd_abs_section_ptr)
3783          continue;          continue;
3784    
3785          /* Reverse the list: we must avoid placing stubs at the
3786             beginning of the section because the beginning of the text
3787             section may be required for an interrupt vector in bare metal
3788             code.  */
3789    #define NEXT_SEC PREV_SEC
3790          head = NULL;
3791        while (tail != NULL)        while (tail != NULL)
3792            {
3793              /* Pop from tail.  */
3794              asection *item = tail;
3795              tail = PREV_SEC (item);
3796    
3797              /* Push on head.  */
3798              NEXT_SEC (item) = head;
3799              head = item;
3800            }
3801    
3802          while (head != NULL)
3803          {          {
3804            asection *curr;            asection *curr;
3805            asection *prev;            asection *next;
3806            bfd_size_type total;            bfd_vma stub_group_start = head->output_offset;
3807              bfd_vma end_of_next;
3808            curr = tail;  
3809            total = tail->size;            curr = head;
3810            while ((prev = PREV_SEC (curr)) != NULL            while (NEXT_SEC (curr) != NULL)
3811                   && ((total += curr->output_offset - prev->output_offset)              {
3812                       < stub_group_size))                next = NEXT_SEC (curr);
3813              curr = prev;                end_of_next = next->output_offset + next->size;
3814                  if (end_of_next - stub_group_start >= stub_group_size)
3815                    /* End of NEXT is too far from start, so stop.  */
3816                    break;
3817                  /* Add NEXT to the group.  */
3818                  curr = next;
3819                }
3820    
3821            /* OK, the size from the start of CURR to the end is less            /* OK, the size from the start to the start of CURR is less
3822               than stub_group_size and thus can be handled by one stub               than stub_group_size and thus can be handled by one stub
3823               section.  (Or the tail section is itself larger than               section.  (Or the head section is itself larger than
3824               stub_group_size, in which case we may be toast.)               stub_group_size, in which case we may be toast.)
3825               We should really be keeping track of the total size of               We should really be keeping track of the total size of
3826               stubs added here, as stubs contribute to the final output               stubs added here, as stubs contribute to the final output
3827               section size.  */               section size.  */
3828            do            do
3829              {              {
3830                prev = PREV_SEC (tail);                next = NEXT_SEC (head);
3831                /* Set up this stub group.  */                /* Set up this stub group.  */
3832                htab->stub_group[tail->id].link_sec = curr;                htab->stub_group[head->id].link_sec = curr;
3833              }              }
3834            while (tail != curr && (tail = prev) != NULL);            while (head != curr && (head = next) != NULL);
3835    
3836            /* But wait, there's more!  Input sections up to stub_group_size            /* But wait, there's more!  Input sections up to stub_group_size
3837               bytes before the stub section can be handled by it too.  */               bytes after the stub section can be handled by it too.  */
3838            if (!stubs_always_before_branch)            if (!stubs_always_after_branch)
3839              {              {
3840                total = 0;                stub_group_start = curr->output_offset + curr->size;
3841                while (prev != NULL  
3842                       && ((total += tail->output_offset - prev->output_offset)                while (next != NULL)
                          < stub_group_size))  
3843                  {                  {
3844                    tail = prev;                    end_of_next = next->output_offset + next->size;
3845                    prev = PREV_SEC (tail);                    if (end_of_next - stub_group_start >= stub_group_size)
3846                    htab->stub_group[tail->id].link_sec = curr;                      /* End of NEXT is too far from stubs, so stop.  */
3847                        break;
3848                      /* Add NEXT to the stub group.  */
3849                      head = next;
3850                      next = NEXT_SEC (head);
3851                      htab->stub_group[head->id].link_sec = curr;
3852                  }                  }
3853              }              }
3854            tail = prev;            head = next;
3855          }          }
3856      }      }
3857    while (list-- != htab->input_list);    while (list++ != htab->input_list + htab->top_index);
3858    
3859    free (htab->input_list);    free (htab->input_list);
3860  #undef PREV_SEC  #undef PREV_SEC
3861    #undef NEXT_SEC
3862    }
3863    
3864    /* Comparison function for sorting/searching relocations relating to Cortex-A8
3865       erratum fix.  */
3866    
3867    static int
3868    a8_reloc_compare (const void *a, const void *b)
3869    {
3870      const struct a8_erratum_reloc *ra = a, *rb = b;
3871    
3872      if (ra->from < rb->from)
3873        return -1;
3874      else if (ra->from > rb->from)
3875        return 1;
3876      else
3877        return 0;
3878    }
3879    
3880    static struct elf_link_hash_entry *find_thumb_glue (struct bfd_link_info *,
3881                                                        const char *, char **);
3882    
3883    /* Helper function to scan code for sequences which might trigger the Cortex-A8
3884       branch/TLB erratum.  Fill in the table described by A8_FIXES_P,
3885       NUM_A8_FIXES_P, A8_FIX_TABLE_SIZE_P.  Returns true if an error occurs, false
3886       otherwise.  */
3887    
3888    static bfd_boolean
3889    cortex_a8_erratum_scan (bfd *input_bfd,
3890                            struct bfd_link_info *info,
3891                            struct a8_erratum_fix **a8_fixes_p,
3892                            unsigned int *num_a8_fixes_p,
3893                            unsigned int *a8_fix_table_size_p,
3894                            struct a8_erratum_reloc *a8_relocs,
3895                            unsigned int num_a8_relocs)
3896    {
3897      asection *section;
3898      struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
3899      struct a8_erratum_fix *a8_fixes = *a8_fixes_p;
3900      unsigned int num_a8_fixes = *num_a8_fixes_p;
3901      unsigned int a8_fix_table_size = *a8_fix_table_size_p;
3902    
3903      for (section = input_bfd->sections;
3904           section != NULL;
3905           section = section->next)
3906        {
3907          bfd_byte *contents = NULL;
3908          struct _arm_elf_section_data *sec_data;
3909          unsigned int span;
3910          bfd_vma base_vma;
3911    
3912          if (elf_section_type (section) != SHT_PROGBITS
3913              || (elf_section_flags (section) & SHF_EXECINSTR) == 0
3914              || (section->flags & SEC_EXCLUDE) != 0
3915              || (section->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
3916              || (section->output_section == bfd_abs_section_ptr))
3917            continue;
3918    
3919          base_vma = section->output_section->vma + section->output_offset;
3920    
3921          if (elf_section_data (section)->this_hdr.contents != NULL)
3922            contents = elf_section_data (section)->this_hdr.contents;
3923          else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
3924            return TRUE;
3925    
3926          sec_data = elf32_arm_section_data (section);
3927    
3928          for (span = 0; span < sec_data->mapcount; span++)
3929            {
3930              unsigned int span_start = sec_data->map[span].vma;
3931              unsigned int span_end = (span == sec_data->mapcount - 1)
3932                ? section->size : sec_data->map[span + 1].vma;
3933              unsigned int i;
3934              char span_type = sec_data->map[span].type;
3935              bfd_boolean last_was_32bit = FALSE, last_was_branch = FALSE;
3936    
3937              if (span_type != 't')
3938                continue;
3939    
3940              /* Span is entirely within a single 4KB region: skip scanning.  */
3941              if (((base_vma + span_start) & ~0xfff)
3942                  == ((base_vma + span_end) & ~0xfff))
3943                continue;
3944    
3945              /* Scan for 32-bit Thumb-2 branches which span two 4K regions, where:
3946    
3947                   * The opcode is BLX.W, BL.W, B.W, Bcc.W
3948                   * The branch target is in the same 4KB region as the
3949                     first half of the branch.
3950                   * The instruction before the branch is a 32-bit
3951                     length non-branch instruction.  */
3952              for (i = span_start; i < span_end;)
3953                {
3954                  unsigned int insn = bfd_getl16 (&contents[i]);
3955                  bfd_boolean insn_32bit = FALSE, is_blx = FALSE, is_b = FALSE;
3956                  bfd_boolean is_bl = FALSE, is_bcc = FALSE, is_32bit_branch;
3957    
3958                  if ((insn & 0xe000) == 0xe000 && (insn & 0x1800) != 0x0000)
3959                    insn_32bit = TRUE;
3960    
3961                  if (insn_32bit)
3962                    {
3963                      /* Load the rest of the insn (in manual-friendly order).  */
3964                      insn = (insn << 16) | bfd_getl16 (&contents[i + 2]);
3965    
3966                      /* Encoding T4: B<c>.W.  */
3967                      is_b = (insn & 0xf800d000) == 0xf0009000;
3968                      /* Encoding T1: BL<c>.W.  */
3969                      is_bl = (insn & 0xf800d000) == 0xf000d000;
3970                      /* Encoding T2: BLX<c>.W.  */
3971                      is_blx = (insn & 0xf800d000) == 0xf000c000;
3972                      /* Encoding T3: B<c>.W (not permitted in IT block).  */
3973                      is_bcc = (insn & 0xf800d000) == 0xf0008000
3974                               && (insn & 0x07f00000) != 0x03800000;
3975                    }
3976    
3977                  is_32bit_branch = is_b || is_bl || is_blx || is_bcc;
3978                              
3979                  if (((base_vma + i) & 0xfff) == 0xffe
3980                      && insn_32bit
3981                      && is_32bit_branch
3982                      && last_was_32bit
3983                      && ! last_was_branch)
3984                    {
3985                      bfd_signed_vma offset;
3986                      bfd_boolean force_target_arm = FALSE;
3987                      bfd_boolean force_target_thumb = FALSE;
3988                      bfd_vma target;
3989                      enum elf32_arm_stub_type stub_type = arm_stub_none;
3990                      struct a8_erratum_reloc key, *found;
3991    
3992                      key.from = base_vma + i;
3993                      found = bsearch (&key, a8_relocs, num_a8_relocs,
3994                                       sizeof (struct a8_erratum_reloc),
3995                                       &a8_reloc_compare);
3996    
3997                      if (found)
3998                        {
3999                          char *error_message = NULL;
4000                          struct elf_link_hash_entry *entry;
4001    
4002                          /* We don't care about the error returned from this
4003                             function, only if there is glue or not.  */
4004                          entry = find_thumb_glue (info, found->sym_name,
4005                                                   &error_message);
4006    
4007                          if (entry)
4008                            found->non_a8_stub = TRUE;
4009    
4010                          if (found->r_type == R_ARM_THM_CALL
4011                              && found->st_type != STT_ARM_TFUNC)
4012                            force_target_arm = TRUE;
4013                          else if (found->r_type == R_ARM_THM_CALL
4014                                   && found->st_type == STT_ARM_TFUNC)
4015                            force_target_thumb = TRUE;
4016                        }
4017    
4018                      /* Check if we have an offending branch instruction.  */
4019    
4020                      if (found && found->non_a8_stub)
4021                        /* We've already made a stub for this instruction, e.g.
4022                           it's a long branch or a Thumb->ARM stub.  Assume that
4023                           stub will suffice to work around the A8 erratum (see
4024                           setting of always_after_branch above).  */
4025                        ;
4026                      else if (is_bcc)
4027                        {
4028                          offset = (insn & 0x7ff) << 1;
4029                          offset |= (insn & 0x3f0000) >> 4;
4030                          offset |= (insn & 0x2000) ? 0x40000 : 0;
4031                          offset |= (insn & 0x800) ? 0x80000 : 0;
4032                          offset |= (insn & 0x4000000) ? 0x100000 : 0;
4033                          if (offset & 0x100000)
4034                            offset |= ~ ((bfd_signed_vma) 0xfffff);
4035                          stub_type = arm_stub_a8_veneer_b_cond;
4036                        }
4037                      else if (is_b || is_bl || is_blx)
4038                        {
4039                          int s = (insn & 0x4000000) != 0;
4040                          int j1 = (insn & 0x2000) != 0;
4041                          int j2 = (insn & 0x800) != 0;
4042                          int i1 = !(j1 ^ s);
4043                          int i2 = !(j2 ^ s);
4044    
4045                          offset = (insn & 0x7ff) << 1;
4046                          offset |= (insn & 0x3ff0000) >> 4;
4047                          offset |= i2 << 22;
4048                          offset |= i1 << 23;
4049                          offset |= s << 24;
4050                          if (offset & 0x1000000)
4051                            offset |= ~ ((bfd_signed_vma) 0xffffff);
4052    
4053                          if (is_blx)
4054                            offset &= ~ ((bfd_signed_vma) 3);
4055    
4056                          stub_type = is_blx ? arm_stub_a8_veneer_blx :
4057                            is_bl ? arm_stub_a8_veneer_bl : arm_stub_a8_veneer_b;
4058                        }
4059    
4060                      if (stub_type != arm_stub_none)
4061                        {
4062                          bfd_vma pc_for_insn = base_vma + i + 4;
4063    
4064                          /* The original instruction is a BL, but the target is
4065                             an ARM instruction.  If we were not making a stub,
4066                             the BL would have been converted to a BLX.  Use the
4067                             BLX stub instead in that case.  */
4068                          if (htab->use_blx && force_target_arm
4069                              && stub_type == arm_stub_a8_veneer_bl)
4070                            {
4071                              stub_type = arm_stub_a8_veneer_blx;
4072                              is_blx = TRUE;
4073                              is_bl = FALSE;
4074                            }
4075                          /* Conversely, if the original instruction was
4076                             BLX but the target is Thumb mode, use the BL
4077                             stub.  */
4078                          else if (force_target_thumb
4079                                   && stub_type == arm_stub_a8_veneer_blx)
4080                            {
4081                              stub_type = arm_stub_a8_veneer_bl;
4082                              is_blx = FALSE;
4083                              is_bl = TRUE;
4084                            }
4085    
4086                          if (is_blx)
4087                            pc_for_insn &= ~ ((bfd_vma) 3);
4088    
4089                          /* If we found a relocation, use the proper destination,
4090                             not the offset in the (unrelocated) instruction.
4091                             Note this is always done if we switched the stub type
4092                             above.  */
4093                          if (found)
4094                            offset =
4095                              (bfd_signed_vma) (found->destination - pc_for_insn);
4096    
4097                          target = pc_for_insn + offset;
4098    
4099                          /* The BLX stub is ARM-mode code.  Adjust the offset to
4100                             take the different PC value (+8 instead of +4) into
4101                             account.  */
4102                          if (stub_type == arm_stub_a8_veneer_blx)
4103                            offset += 4;
4104    
4105                          if (((base_vma + i) & ~0xfff) == (target & ~0xfff))
4106                            {
4107                              char *stub_name;
4108    
4109                              if (num_a8_fixes == a8_fix_table_size)
4110                                {
4111                                  a8_fix_table_size *= 2;
4112                                  a8_fixes = bfd_realloc (a8_fixes,
4113                                    sizeof (struct a8_erratum_fix)
4114                                    * a8_fix_table_size);
4115                                }
4116    
4117                              stub_name = bfd_malloc (8 + 1 + 8 + 1);
4118                              if (stub_name != NULL)
4119                                sprintf (stub_name, "%x:%x", section->id, i);
4120    
4121                              a8_fixes[num_a8_fixes].input_bfd = input_bfd;
4122                              a8_fixes[num_a8_fixes].section = section;
4123                              a8_fixes[num_a8_fixes].offset = i;
4124                              a8_fixes[num_a8_fixes].addend = offset;
4125                              a8_fixes[num_a8_fixes].orig_insn = insn;
4126                              a8_fixes[num_a8_fixes].stub_name = stub_name;
4127                              a8_fixes[num_a8_fixes].stub_type = stub_type;
4128    
4129                              num_a8_fixes++;
4130                            }
4131                        }
4132                    }
4133    
4134                  i += insn_32bit ? 4 : 2;
4135                  last_was_32bit = insn_32bit;
4136                  last_was_branch = is_32bit_branch;
4137                }
4138            }
4139    
4140          if (elf_section_data (section)->this_hdr.contents == NULL)
4141            free (contents);
4142        }
4143      
4144      *a8_fixes_p = a8_fixes;
4145      *num_a8_fixes_p = num_a8_fixes;
4146      *a8_fix_table_size_p = a8_fix_table_size;
4147      
4148      return FALSE;
4149  }  }
4150    
4151  /* Determine and set the size of the stub section for a final link.  /* Determine and set the size of the stub section for a final link.
# Line 3454  elf32_arm_size_stubs (bfd *output_bfd, Line 4163  elf32_arm_size_stubs (bfd *output_bfd,
4163                        void (*layout_sections_again) (void))                        void (*layout_sections_again) (void))
4164  {  {
4165    bfd_size_type stub_group_size;    bfd_size_type stub_group_size;
4166    bfd_boolean stubs_always_before_branch;    bfd_boolean stubs_always_after_branch;
4167    bfd_boolean stub_changed = 0;    bfd_boolean stub_changed = 0;
4168    struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);    struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
4169      struct a8_erratum_fix *a8_fixes = NULL;
4170      unsigned int num_a8_fixes = 0, prev_num_a8_fixes = 0, a8_fix_table_size = 10;
4171      struct a8_erratum_reloc *a8_relocs = NULL;
4172      unsigned int num_a8_relocs = 0, a8_reloc_table_size = 10, i;
4173    
4174      if (htab->fix_cortex_a8)
4175        {
4176          a8_fixes = bfd_zmalloc (sizeof (struct a8_erratum_fix)
4177                                  * a8_fix_table_size);
4178          a8_relocs = bfd_zmalloc (sizeof (struct a8_erratum_reloc)
4179                                   * a8_reloc_table_size);
4180        }
4181    
4182    /* Propagate mach to stub bfd, because it may not have been    /* Propagate mach to stub bfd, because it may not have been
4183       finalized when we created stub_bfd.  */       finalized when we created stub_bfd.  */
# Line 3467  elf32_arm_size_stubs (bfd *output_bfd, Line 4188  elf32_arm_size_stubs (bfd *output_bfd,
4188    htab->stub_bfd = stub_bfd;    htab->stub_bfd = stub_bfd;
4189    htab->add_stub_section = add_stub_section;    htab->add_stub_section = add_stub_section;
4190    htab->layout_sections_again = layout_sections_again;    htab->layout_sections_again = layout_sections_again;
4191    stubs_always_before_branch = group_size < 0;    stubs_always_after_branch = group_size < 0;
4192    
4193      /* The Cortex-A8 erratum fix depends on stubs not being in the same 4K page
4194         as the first half of a 32-bit branch straddling two 4K pages.  This is a
4195         crude way of enforcing that.  */
4196      if (htab->fix_cortex_a8)
4197        stubs_always_after_branch = 1;
4198    
4199    if (group_size < 0)    if (group_size < 0)
4200      stub_group_size = -group_size;      stub_group_size = -group_size;
4201    else    else
# Line 3487  elf32_arm_size_stubs (bfd *output_bfd, Line 4215  elf32_arm_size_stubs (bfd *output_bfd,
4215        stub_group_size = 4170000;        stub_group_size = 4170000;
4216      }      }
4217    
4218    group_sections (htab, stub_group_size, stubs_always_before_branch);    group_sections (htab, stub_group_size, stubs_always_after_branch);
4219    
4220    while (1)    while (1)
4221      {      {
# Line 3495  elf32_arm_size_stubs (bfd *output_bfd, Line 4223  elf32_arm_size_stubs (bfd *output_bfd,
4223        unsigned int bfd_indx;        unsigned int bfd_indx;
4224        asection *stub_sec;        asection *stub_sec;
4225    
4226          num_a8_fixes = 0;
4227    
4228        for (input_bfd = info->input_bfds, bfd_indx = 0;        for (input_bfd = info->input_bfds, bfd_indx = 0;
4229             input_bfd != NULL;             input_bfd != NULL;
4230             input_bfd = input_bfd->link_next, bfd_indx++)             input_bfd = input_bfd->link_next, bfd_indx++)
# Line 3503  elf32_arm_size_stubs (bfd *output_bfd, Line 4233  elf32_arm_size_stubs (bfd *output_bfd,
4233            asection *section;            asection *section;
4234            Elf_Internal_Sym *local_syms = NULL;            Elf_Internal_Sym *local_syms = NULL;
4235    
4236              num_a8_relocs = 0;
4237    
4238            /* We'll need the symbol table in a second.  */            /* We'll need the symbol table in a second.  */
4239            symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;            symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4240            if (symtab_hdr->sh_info == 0)            if (symtab_hdr->sh_info == 0)
# Line 3551  elf32_arm_size_stubs (bfd *output_bfd, Line 4283  elf32_arm_size_stubs (bfd *output_bfd,
4283                    char *stub_name;                    char *stub_name;
4284                    const asection *id_sec;                    const asection *id_sec;
4285                    unsigned char st_type;                    unsigned char st_type;
4286                      bfd_boolean created_stub = FALSE;
4287    
4288                    r_type = ELF32_R_TYPE (irela->r_info);                    r_type = ELF32_R_TYPE (irela->r_info);
4289                    r_indx = ELF32_R_SYM (irela->r_info);                    r_indx = ELF32_R_SYM (irela->r_info);
# Line 3564  elf32_arm_size_stubs (bfd *output_bfd, Line 4297  elf32_arm_size_stubs (bfd *output_bfd,
4297                        goto error_ret_free_local;                        goto error_ret_free_local;
4298                      }                      }
4299    
4300                    /* Only look for stubs on call instructions.  */                    /* Only look for stubs on branch instructions.  */
4301                    if ((r_type != (unsigned int) R_ARM_CALL)                    if ((r_type != (unsigned int) R_ARM_CALL)
4302                        && (r_type != (unsigned int) R_ARM_THM_CALL))                        && (r_type != (unsigned int) R_ARM_THM_CALL)
4303                          && (r_type != (unsigned int) R_ARM_JUMP24)
4304                          && (r_type != (unsigned int) R_ARM_THM_JUMP19)
4305                          && (r_type != (unsigned int) R_ARM_THM_XPC22)
4306                          && (r_type != (unsigned int) R_ARM_THM_JUMP24)
4307                          && (r_type != (unsigned int) R_ARM_PLT32))
4308                      continue;                      continue;
4309    
4310                    /* Now determine the call target, its name, value,                    /* Now determine the call target, its name, value,
# Line 3628  elf32_arm_size_stubs (bfd *output_bfd, Line 4366  elf32_arm_size_stubs (bfd *output_bfd,
4366                          {                          {
4367                            sym_sec = hash->root.root.u.def.section;                            sym_sec = hash->root.root.u.def.section;
4368                            sym_value = hash->root.root.u.def.value;                            sym_value = hash->root.root.u.def.value;
4369                            if (sym_sec->output_section != NULL)  
4370                              struct elf32_arm_link_hash_table *globals =
4371                                                      elf32_arm_hash_table (info);
4372    
4373                              /* For a destination in a shared library,
4374                                 use the PLT stub as target address to
4375                                 decide whether a branch stub is
4376                                 needed.  */
4377                              if (globals->splt != NULL && hash != NULL
4378                                  && hash->root.plt.offset != (bfd_vma) -1)
4379                                {
4380                                  sym_sec = globals->splt;
4381                                  sym_value = hash->root.plt.offset;
4382                                  if (sym_sec->output_section != NULL)
4383                                    destination = (sym_value
4384                                                   + sym_sec->output_offset
4385                                                   + sym_sec->output_section->vma);
4386                                }
4387                              else if (sym_sec->output_section != NULL)
4388                              destination = (sym_value + irela->r_addend                              destination = (sym_value + irela->r_addend
4389                                             + sym_sec->output_offset                                             + sym_sec->output_offset
4390                                             + sym_sec->output_section->vma);                                             + sym_sec->output_section->vma);
4391                          }                          }
4392                        else if (hash->root.root.type == bfd_link_hash_undefweak                        else if ((hash->root.root.type == bfd_link_hash_undefined)
4393                                 || hash->root.root.type == bfd_link_hash_undefined)                                 || (hash->root.root.type == bfd_link_hash_undefweak))
4394                          /* For a shared library, these will need a PLT stub,                          {
4395                             which is treated separately.                            /* For a shared library, use the PLT stub as
4396                             For absolute code, they cannot be handled.  */                               target address to decide whether a long
4397                          continue;                               branch stub is needed.
4398                                 For absolute code, they cannot be handled.  */
4399                              struct elf32_arm_link_hash_table *globals =
4400                                elf32_arm_hash_table (info);
4401    
4402                              if (globals->splt != NULL && hash != NULL
4403                                  && hash->root.plt.offset != (bfd_vma) -1)
4404                                {
4405                                  sym_sec = globals->splt;
4406                                  sym_value = hash->root.plt.offset;
4407                                  if (sym_sec->output_section != NULL)
4408                                    destination = (sym_value
4409                                                   + sym_sec->output_offset
4410                                                   + sym_sec->output_section->vma);
4411                                }
4412                              else
4413                                continue;
4414                            }
4415                        else                        else
4416                          {                          {
4417                            bfd_set_error (bfd_error_bad_value);                            bfd_set_error (bfd_error_bad_value);
# Line 3648  elf32_arm_size_stubs (bfd *output_bfd, Line 4421  elf32_arm_size_stubs (bfd *output_bfd,
4421                        sym_name = hash->root.root.root.string;                        sym_name = hash->root.root.root.string;
4422                      }                      }
4423    
4424                    /* Determine what (if any) linker stub is needed.  */                    do
                   stub_type = arm_type_of_stub (info, section, irela, st_type,  
                                                 hash, destination, sym_sec,  
                                                 input_bfd, sym_name);  
                   if (stub_type == arm_stub_none)  
                     continue;  
   
                   /* Support for grouping stub sections.  */  
                   id_sec = htab->stub_group[section->id].link_sec;  
   
                   /* Get the name of this stub.  */  
                   stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash, irela);  
                   if (!stub_name)  
                     goto error_ret_free_internal;  
   
                   stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table,  
                                                     stub_name,  
                                                     FALSE, FALSE);  
                   if (stub_entry != NULL)  
4425                      {                      {
4426                        /* The proper stub has already been created.  */                        /* Determine what (if any) linker stub is needed.  */
4427                        free (stub_name);                        stub_type = arm_type_of_stub (info, section, irela,
4428                        continue;                                                      st_type, hash,
4429                      }                                                      destination, sym_sec,
4430                                                        input_bfd, sym_name);
4431                          if (stub_type == arm_stub_none)
4432                            break;
4433    
4434                          /* Support for grouping stub sections.  */
4435                          id_sec = htab->stub_group[section->id].link_sec;
4436    
4437                          /* Get the name of this stub.  */
4438                          stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash,
4439                                                           irela);
4440                          if (!stub_name)
4441                            goto error_ret_free_internal;
4442    
4443                          /* We've either created a stub for this reloc already,
4444                             or we are about to.  */
4445                          created_stub = TRUE;
4446    
4447                          stub_entry = arm_stub_hash_lookup
4448                                         (&htab->stub_hash_table, stub_name,
4449                                          FALSE, FALSE);
4450                          if (stub_entry != NULL)
4451                            {
4452                              /* The proper stub has already been created.  */
4453                              free (stub_name);
4454                              break;
4455                            }
4456    
4457                    stub_entry = elf32_arm_add_stub (stub_name, section, htab);                        stub_entry = elf32_arm_add_stub (stub_name, section,
4458                    if (stub_entry == NULL)                                                         htab);
4459                      {                        if (stub_entry == NULL)
4460                        free (stub_name);                          {
4461                        goto error_ret_free_internal;                            free (stub_name);
4462                      }                            goto error_ret_free_internal;
4463                            }
4464    
4465                    stub_entry->target_value = sym_value;                        stub_entry->target_value = sym_value;
4466                    stub_entry->target_section = sym_sec;                        stub_entry->target_section = sym_sec;
4467                    stub_entry->stub_type = stub_type;                        stub_entry->stub_type = stub_type;
4468                    stub_entry->h = hash;                        stub_entry->h = hash;
4469                    stub_entry->st_type = st_type;                        stub_entry->st_type = st_type;
4470    
4471                    if (sym_name == NULL)                        if (sym_name == NULL)
4472                      sym_name = "unnamed";                          sym_name = "unnamed";
4473                    stub_entry->output_name                        stub_entry->output_name
4474                      = bfd_alloc (htab->stub_bfd,                          = bfd_alloc (htab->stub_bfd,
4475                                   sizeof (THUMB2ARM_GLUE_ENTRY_NAME)                                       sizeof (THUMB2ARM_GLUE_ENTRY_NAME)
4476                                   + strlen (sym_name));                                       + strlen (sym_name));
4477                    if (stub_entry->output_name == NULL)                        if (stub_entry->output_name == NULL)
4478                      {                          {
4479                        free (stub_name);                            free (stub_name);
4480                        goto error_ret_free_internal;                            goto error_ret_free_internal;
4481                      }                          }
4482    
4483                          /* For historical reasons, use the existing names for
4484                             ARM-to-Thumb and Thumb-to-ARM stubs.  */
4485                          if ( ((r_type == (unsigned int) R_ARM_THM_CALL)
4486                                || (r_type == (unsigned int) R_ARM_THM_JUMP24))
4487                               && st_type != STT_ARM_TFUNC)
4488                            sprintf (stub_entry->output_name,
4489                                     THUMB2ARM_GLUE_ENTRY_NAME, sym_name);
4490                          else if ( ((r_type == (unsigned int) R_ARM_CALL)
4491                                     || (r_type == (unsigned int) R_ARM_JUMP24))
4492                                   && st_type == STT_ARM_TFUNC)
4493                            sprintf (stub_entry->output_name,
4494                                     ARM2THUMB_GLUE_ENTRY_NAME, sym_name);
4495                          else
4496                            sprintf (stub_entry->output_name, STUB_ENTRY_NAME,
4497                                     sym_name);
4498    
4499                    /* For historical reasons, use the existing names for                        stub_changed = TRUE;
4500                       ARM-to-Thumb and Thumb-to-ARM stubs.  */                      }
4501                    if (r_type == (unsigned int) R_ARM_THM_CALL                    while (0);
                       && st_type != STT_ARM_TFUNC)  
                     sprintf (stub_entry->output_name, THUMB2ARM_GLUE_ENTRY_NAME,  
                              sym_name);  
                   else if (r_type == (unsigned int) R_ARM_CALL  
                            && st_type == STT_ARM_TFUNC)  
                     sprintf (stub_entry->output_name, ARM2THUMB_GLUE_ENTRY_NAME,  
                              sym_name);  
                   else  
                     sprintf (stub_entry->output_name, STUB_ENTRY_NAME,  
                              sym_name);  
4502    
4503                    stub_changed = TRUE;                    /* Look for relocations which might trigger Cortex-A8
4504                         erratum.  */
4505                      if (htab->fix_cortex_a8
4506                          && (r_type == (unsigned int) R_ARM_THM_JUMP24
4507                              || r_type == (unsigned int) R_ARM_THM_JUMP19
4508                              || r_type == (unsigned int) R_ARM_THM_CALL
4509                              || r_type == (unsigned int) R_ARM_THM_XPC22))
4510                        {
4511                          bfd_vma from = section->output_section->vma
4512                                         + section->output_offset
4513                                         + irela->r_offset;
4514    
4515                          if ((from & 0xfff) == 0xffe)
4516                            {
4517                              /* Found a candidate.  Note we haven't checked the
4518                                 destination is within 4K here: if we do so (and
4519                                 don't create an entry in a8_relocs) we can't tell
4520                                 that a branch should have been relocated when
4521                                 scanning later.  */
4522                              if (num_a8_relocs == a8_reloc_table_size)
4523                                {
4524                                  a8_reloc_table_size *= 2;
4525                                  a8_relocs = bfd_realloc (a8_relocs,
4526                                    sizeof (struct a8_erratum_reloc)
4527                                    * a8_reloc_table_size);
4528                                }
4529    
4530                              a8_relocs[num_a8_relocs].from = from;
4531                              a8_relocs[num_a8_relocs].destination = destination;
4532                              a8_relocs[num_a8_relocs].r_type = r_type;
4533                              a8_relocs[num_a8_relocs].st_type = st_type;
4534                              a8_relocs[num_a8_relocs].sym_name = sym_name;
4535                              a8_relocs[num_a8_relocs].non_a8_stub = created_stub;
4536    
4537                              num_a8_relocs++;
4538                            }
4539                        }
4540                  }                  }
4541    
4542                /* We're done with the internal relocs, free them.  */                /* We're done with the internal relocs, free them.  */
4543                if (elf_section_data (section)->relocs == NULL)                if (elf_section_data (section)->relocs == NULL)
4544                  free (internal_relocs);                  free (internal_relocs);
4545                }
4546    
4547              if (htab->fix_cortex_a8)
4548                {
4549                  /* Sort relocs which might apply to Cortex-A8 erratum.  */
4550                  qsort (a8_relocs, num_a8_relocs, sizeof (struct a8_erratum_reloc),
4551                         &a8_reloc_compare);
4552    
4553                  /* Scan for branches which might trigger Cortex-A8 erratum.  */
4554                  if (cortex_a8_erratum_scan (input_bfd, info, &a8_fixes,
4555                                              &num_a8_fixes, &a8_fix_table_size,
4556                                              a8_relocs, num_a8_relocs) != 0)
4557                    goto error_ret_free_local;
4558              }              }
4559          }          }
4560    
4561          if (htab->fix_cortex_a8 && num_a8_fixes != prev_num_a8_fixes)
4562            stub_changed = TRUE;
4563    
4564        if (!stub_changed)        if (!stub_changed)
4565          break;          break;
4566    
# Line 3729  elf32_arm_size_stubs (bfd *output_bfd, Line 4569  elf32_arm_size_stubs (bfd *output_bfd,
4569        for (stub_sec = htab->stub_bfd->sections;        for (stub_sec = htab->stub_bfd->sections;
4570             stub_sec != NULL;             stub_sec != NULL;
4571             stub_sec = stub_sec->next)             stub_sec = stub_sec->next)
4572          stub_sec->size = 0;          {
4573              /* Ignore non-stub sections.  */
4574              if (!strstr (stub_sec->name, STUB_SUFFIX))
4575                continue;
4576    
4577              stub_sec->size = 0;
4578            }
4579    
4580        bfd_hash_traverse (&htab->stub_hash_table, arm_size_one_stub, htab);        bfd_hash_traverse (&htab->stub_hash_table, arm_size_one_stub, htab);
4581    
4582          /* Add Cortex-A8 erratum veneers to stub section sizes too.  */
4583          if (htab->fix_cortex_a8)
4584            for (i = 0; i < num_a8_fixes; i++)
4585              {
4586                stub_sec = elf32_arm_create_or_find_stub_sec (NULL,
4587                             a8_fixes[i].section, htab);
4588    
4589                if (stub_sec == NULL)
4590                  goto error_ret_free_local;
4591    
4592                stub_sec->size
4593                  += find_stub_size_and_template (a8_fixes[i].stub_type, NULL,
4594                                                  NULL);
4595              }
4596    
4597    
4598        /* Ask the linker to do its stuff.  */        /* Ask the linker to do its stuff.  */
4599        (*htab->layout_sections_again) ();        (*htab->layout_sections_again) ();
4600        stub_changed = FALSE;        stub_changed = FALSE;
4601          prev_num_a8_fixes = num_a8_fixes;
4602      }      }
4603    
4604      /* Add stubs for Cortex-A8 erratum fixes now.  */
4605      if (htab->fix_cortex_a8)
4606        {
4607          for (i = 0; i < num_a8_fixes; i++)
4608            {
4609              struct elf32_arm_stub_hash_entry *stub_entry;
4610              char *stub_name = a8_fixes[i].stub_name;
4611              asection *section = a8_fixes[i].section;
4612              unsigned int section_id = a8_fixes[i].section->id;
4613              asection *link_sec = htab->stub_group[section_id].link_sec;
4614              asection *stub_sec = htab->stub_group[section_id].stub_sec;
4615              const insn_sequence *template;
4616              int template_size, size = 0;
4617    
4618              stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,
4619                                                 TRUE, FALSE);
4620              if (stub_entry == NULL)
4621                {
4622                  (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
4623                                         section->owner,
4624                                         stub_name);
4625                  return FALSE;
4626                }
4627    
4628              stub_entry->stub_sec = stub_sec;
4629              stub_entry->stub_offset = 0;
4630              stub_entry->id_sec = link_sec;
4631              stub_entry->stub_type = a8_fixes[i].stub_type;
4632              stub_entry->target_section = a8_fixes[i].section;
4633              stub_entry->target_value = a8_fixes[i].offset;
4634              stub_entry->target_addend = a8_fixes[i].addend;
4635              stub_entry->orig_insn = a8_fixes[i].orig_insn;
4636              stub_entry->st_type = STT_ARM_TFUNC;
4637    
4638              size = find_stub_size_and_template (a8_fixes[i].stub_type, &template,
4639                                                  &template_size);
4640    
4641              stub_entry->stub_size = size;
4642              stub_entry->stub_template = template;
4643              stub_entry->stub_template_size = template_size;
4644            }
4645    
4646          /* Stash the Cortex-A8 erratum fix array for use later in
4647             elf32_arm_write_section().  */
4648          htab->a8_erratum_fixes = a8_fixes;
4649          htab->num_a8_erratum_fixes = num_a8_fixes;
4650        }
4651      else
4652        {
4653          htab->a8_erratum_fixes = NULL;
4654          htab->num_a8_erratum_fixes = 0;
4655        }
4656    return TRUE;    return TRUE;
4657    
4658   error_ret_free_local:   error_ret_free_local:
# Line 3927  arm_allocate_glue_section_space (bfd * a Line 4842  arm_allocate_glue_section_space (bfd * a
4842    bfd_byte * contents;    bfd_byte * contents;
4843    
4844    if (size == 0)    if (size == 0)
4845      return;      {
4846          /* Do not include empty glue sections in the output.  */
4847          if (abfd != NULL)
4848            {
4849              s = bfd_get_section_by_name (abfd, name);
4850              if (s != NULL)
4851                s->flags |= SEC_EXCLUDE;
4852            }
4853          return;
4854        }
4855    
4856    BFD_ASSERT (abfd != NULL);    BFD_ASSERT (abfd != NULL);
4857    
# Line 4039  record_arm_to_thumb_glue (struct bfd_lin Line 4963  record_arm_to_thumb_glue (struct bfd_lin
4963    return myh;    return myh;
4964  }  }
4965    
 static void  
 record_thumb_to_arm_glue (struct bfd_link_info *link_info,  
                           struct elf_link_hash_entry *h)  
 {  
   const char *name = h->root.root.string;  
   asection *s;  
   char *tmp_name;  
   struct elf_link_hash_entry *myh;  
   struct bfd_link_hash_entry *bh;  
   struct elf32_arm_link_hash_table *hash_table;  
   bfd_vma val;  
   
   hash_table = elf32_arm_hash_table (link_info);  
   
   BFD_ASSERT (hash_table != NULL);  
   BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);  
   
   s = bfd_get_section_by_name  
     (hash_table->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);  
   
   BFD_ASSERT (s != NULL);  
   
   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)  
                          + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);  
   
   BFD_ASSERT (tmp_name);  
   
   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);  
   
   myh = elf_link_hash_lookup  
     (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);  
   
   if (myh != NULL)  
     {  
       /* We've already seen this guy.  */  
       free (tmp_name);  
       return;  
     }  
   
   /* The only trick here is using hash_table->thumb_glue_size as the value.  
      Even though the section isn't allocated yet, this is where we will be  
      putting it.  The +1 on the value marks that the stub has not been  
      output yet - not that it is a Thumb function.  */  
   bh = NULL;  
   val = hash_table->thumb_glue_size + 1;  
   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,  
                                     tmp_name, BSF_GLOBAL, s, val,  
                                     NULL, TRUE, FALSE, &bh);  
   
   /* If we mark it 'Thumb', the disassembler will do a better job.  */  
   myh = (struct elf_link_hash_entry *) bh;  
   myh->type = ELF_ST_INFO (STB_LOCAL, STT_ARM_TFUNC);  
   myh->forced_local = 1;  
   
   free (tmp_name);  
   
 #define CHANGE_TO_ARM "__%s_change_to_arm"  
 #define BACK_FROM_ARM "__%s_back_from_arm"  
   
   /* Allocate another symbol to mark where we switch to Arm mode.  */  
   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)  
                          + strlen (CHANGE_TO_ARM) + 1);  
   
   BFD_ASSERT (tmp_name);  
   
   sprintf (tmp_name, CHANGE_TO_ARM, name);  
   
   bh = NULL;  
   val = hash_table->thumb_glue_size + 4,  
   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,  
                                     tmp_name, BSF_LOCAL, s, val,  
                                     NULL, TRUE, FALSE, &bh);  
   
   free (tmp_name);  
   
   s->size += THUMB2ARM_GLUE_SIZE;  
   hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;  
 }  
   
   
4966  /* Allocate space for ARMv4 BX veneers.  */  /* Allocate space for ARMv4 BX veneers.  */
4967    
4968  static void  static void
# Line 4329  record_vfp11_erratum_veneer (struct bfd_ Line 5173  record_vfp11_erratum_veneer (struct bfd_
5173    return val;    return val;
5174  }  }
5175    
 /* Note: we do not include the flag SEC_LINKER_CREATED, as that  
    would prevent elf_link_input_bfd() from processing the contents  
    of the section.  */  
5176  #define ARM_GLUE_SECTION_FLAGS \  #define ARM_GLUE_SECTION_FLAGS \
5177    (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY)    (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE \
5178       | SEC_READONLY | SEC_LINKER_CREATED)
5179    
5180  /* Create a fake section for use by the ARM backend of the linker.  */  /* Create a fake section for use by the ARM backend of the linker.  */
5181    
# Line 4372  bfd_elf32_arm_add_glue_sections_to_bfd ( Line 5214  bfd_elf32_arm_add_glue_sections_to_bfd (
5214    if (info->relocatable)    if (info->relocatable)
5215      return TRUE;      return TRUE;
5216    
   /* Linker stubs don't need glue.  */  
   if (!strcmp (abfd->filename, "linker stubs"))  
     return TRUE;  
   
5217    return arm_make_glue_section (abfd, ARM2THUMB_GLUE_SECTION_NAME)    return arm_make_glue_section (abfd, ARM2THUMB_GLUE_SECTION_NAME)
5218      && arm_make_glue_section (abfd, THUMB2ARM_GLUE_SECTION_NAME)      && arm_make_glue_section (abfd, THUMB2ARM_GLUE_SECTION_NAME)
5219      && arm_make_glue_section (abfd, VFP11_ERRATUM_VENEER_SECTION_NAME)      && arm_make_glue_section (abfd, VFP11_ERRATUM_VENEER_SECTION_NAME)
# Line 4494  bfd_elf32_arm_process_before_allocation Line 5332  bfd_elf32_arm_process_before_allocation
5332    
5333            /* These are the only relocation types we care about.  */            /* These are the only relocation types we care about.  */
5334            if (   r_type != R_ARM_PC24            if (   r_type != R_ARM_PC24
               && r_type != R_ARM_PLT32  
               && r_type != R_ARM_JUMP24  
               && r_type != R_ARM_THM_JUMP24  
5335                && (r_type != R_ARM_V4BX || globals->fix_v4bx < 2))                && (r_type != R_ARM_V4BX || globals->fix_v4bx < 2))
5336              continue;              continue;
5337    
# Line 4548  bfd_elf32_arm_process_before_allocation Line 5383  bfd_elf32_arm_process_before_allocation
5383            switch (r_type)            switch (r_type)
5384              {              {
5385              case R_ARM_PC24:              case R_ARM_PC24:
             case R_ARM_PLT32:  
             case R_ARM_JUMP24:  
5386                /* This one is a call from arm code.  We need to look up                /* This one is a call from arm code.  We need to look up
5387                   the target of the call.  If it is a thumb target, we                   the target of the call.  If it is a thumb target, we
5388                   insert glue.  */                   insert glue.  */
5389                if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC                if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC)
                   && !(r_type == R_ARM_CALL && globals->use_blx))  
5390                  record_arm_to_thumb_glue (link_info, h);                  record_arm_to_thumb_glue (link_info, h);
5391                break;                break;
5392    
             case R_ARM_THM_JUMP24:  
               /* This one is a call from thumb code.  We look  
                  up the target of the call.  If it is not a thumb  
                  target, we insert glue.  */  
               if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC  
                   && !(globals->use_blx && r_type == R_ARM_THM_CALL)  
                   && h->root.type != bfd_link_hash_undefweak)  
                 record_thumb_to_arm_glue (link_info, h);  
               break;  
   
5393              default:              default:
5394                abort ();                abort ();
5395              }              }
# Line 4648  bfd_elf32_arm_init_maps (bfd *abfd) Line 5470  bfd_elf32_arm_init_maps (bfd *abfd)
5470  }  }
5471    
5472    
5473    /* Auto-select enabling of Cortex-A8 erratum fix if the user didn't explicitly
5474       say what they wanted.  */
5475    
5476    void
5477    bfd_elf32_arm_set_cortex_a8_fix (bfd *obfd, struct bfd_link_info *link_info)
5478    {
5479      struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
5480      obj_attribute *out_attr = elf_known_obj_attributes_proc (obfd);
5481    
5482      if (globals->fix_cortex_a8 == -1)
5483        {
5484          /* Turn on Cortex-A8 erratum workaround for ARMv7-A.  */
5485          if (out_attr[Tag_CPU_arch].i == TAG_CPU_ARCH_V7
5486              && (out_attr[Tag_CPU_arch_profile].i == 'A'
5487                  || out_attr[Tag_CPU_arch_profile].i == 0))
5488            globals->fix_cortex_a8 = 1;
5489          else
5490            globals->fix_cortex_a8 = 0;
5491        }
5492    }
5493    
5494    
5495  void  void
5496  bfd_elf32_arm_set_vfp11_fix (bfd *obfd, struct bfd_link_info *link_info)  bfd_elf32_arm_set_vfp11_fix (bfd *obfd, struct bfd_link_info *link_info)
5497  {  {
# Line 4998  bfd_elf32_arm_vfp11_erratum_scan (bfd *a Line 5842  bfd_elf32_arm_vfp11_erratum_scan (bfd *a
5842    if (globals->vfp11_fix == BFD_ARM_VFP11_FIX_NONE)    if (globals->vfp11_fix == BFD_ARM_VFP11_FIX_NONE)
5843      return TRUE;      return TRUE;
5844    
5845      /* Skip this BFD if it corresponds to an executable or dynamic object.  */
5846      if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
5847        return TRUE;
5848    
5849    for (sec = abfd->sections; sec != NULL; sec = sec->next)    for (sec = abfd->sections; sec != NULL; sec = sec->next)
5850      {      {
5851        unsigned int i, span, first_fmac = 0, veneer_of_insn = 0;        unsigned int i, span, first_fmac = 0, veneer_of_insn = 0;
# Line 5008  bfd_elf32_arm_vfp11_erratum_scan (bfd *a Line 5856  bfd_elf32_arm_vfp11_erratum_scan (bfd *a
5856        if (elf_section_type (sec) != SHT_PROGBITS        if (elf_section_type (sec) != SHT_PROGBITS
5857            || (elf_section_flags (sec) & SHF_EXECINSTR) == 0            || (elf_section_flags (sec) & SHF_EXECINSTR) == 0
5858            || (sec->flags & SEC_EXCLUDE) != 0            || (sec->flags & SEC_EXCLUDE) != 0
5859              || sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS
5860              || sec->output_section == bfd_abs_section_ptr
5861            || strcmp (sec->name, VFP11_ERRATUM_VENEER_SECTION_NAME) == 0)            || strcmp (sec->name, VFP11_ERRATUM_VENEER_SECTION_NAME) == 0)
5862          continue;          continue;
5863    
# Line 5251  bfd_elf32_arm_set_target_relocs (struct Line 6101  bfd_elf32_arm_set_target_relocs (struct
6101                                   int use_blx,                                   int use_blx,
6102                                   bfd_arm_vfp11_fix vfp11_fix,                                   bfd_arm_vfp11_fix vfp11_fix,
6103                                   int no_enum_warn, int no_wchar_warn,                                   int no_enum_warn, int no_wchar_warn,
6104                                   int pic_veneer)                                   int pic_veneer, int fix_cortex_a8)
6105  {  {
6106    struct elf32_arm_link_hash_table *globals;    struct elf32_arm_link_hash_table *globals;
6107    
# Line 5273  bfd_elf32_arm_set_target_relocs (struct Line 6123  bfd_elf32_arm_set_target_relocs (struct
6123    globals->use_blx |= use_blx;    globals->use_blx |= use_blx;
6124    globals->vfp11_fix = vfp11_fix;    globals->vfp11_fix = vfp11_fix;
6125    globals->pic_veneer = pic_veneer;    globals->pic_veneer = pic_veneer;
6126      globals->fix_cortex_a8 = fix_cortex_a8;
6127    
6128    BFD_ASSERT (is_arm_elf (output_bfd));    BFD_ASSERT (is_arm_elf (output_bfd));
6129    elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;    elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
# Line 5903  elf32_arm_final_link_relocate (reloc_how Line 6754  elf32_arm_final_link_relocate (reloc_how
6754        /* Handle relocations which should use the PLT entry.  ABS32/REL32        /* Handle relocations which should use the PLT entry.  ABS32/REL32
6755           will use the symbol's value, which may point to a PLT entry, but we           will use the symbol's value, which may point to a PLT entry, but we
6756           don't need to handle that here.  If we created a PLT entry, all           don't need to handle that here.  If we created a PLT entry, all
6757           branches in this object should go to it.  */           branches in this object should go to it, except if the PLT is too
6758             far away, in which case a long branch stub should be inserted.  */
6759        if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32        if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32
6760             && r_type != R_ARM_ABS32_NOI && r_type != R_ARM_REL32_NOI)             && r_type != R_ARM_ABS32_NOI && r_type != R_ARM_REL32_NOI
6761               && r_type != R_ARM_CALL
6762               && r_type != R_ARM_JUMP24
6763               && r_type != R_ARM_PLT32)
6764            && h != NULL            && h != NULL
6765            && splt != NULL            && splt != NULL
6766            && h->plt.offset != (bfd_vma) -1)            && h->plt.offset != (bfd_vma) -1)
# Line 6062  elf32_arm_final_link_relocate (reloc_how Line 6917  elf32_arm_final_link_relocate (reloc_how
6917            bfd_signed_vma branch_offset;            bfd_signed_vma branch_offset;
6918            struct elf32_arm_stub_hash_entry *stub_entry = NULL;            struct elf32_arm_stub_hash_entry *stub_entry = NULL;
6919    
           from = (input_section->output_section->vma  
                   + input_section->output_offset  
                   + rel->r_offset);  
           branch_offset = (bfd_signed_vma)(value - from);  
   
6920            if (r_type == R_ARM_XPC25)            if (r_type == R_ARM_XPC25)
6921              {              {
6922                /* Check for Arm calling Arm function.  */                /* Check for Arm calling Arm function.  */
# Line 6078  elf32_arm_final_link_relocate (reloc_how Line 6928  elf32_arm_final_link_relocate (reloc_how
6928                     input_bfd,                     input_bfd,
6929                     h ? h->root.root.string : "(local)");                     h ? h->root.root.string : "(local)");
6930              }              }
6931            else if (r_type != R_ARM_CALL)            else if (r_type == R_ARM_PC24)
6932              {              {
6933                /* Check for Arm calling Thumb function.  */                /* Check for Arm calling Thumb function.  */
6934                if (sym_flags == STT_ARM_TFUNC)                if (sym_flags == STT_ARM_TFUNC)
# Line 6096  elf32_arm_final_link_relocate (reloc_how Line 6946  elf32_arm_final_link_relocate (reloc_how
6946    
6947            /* Check if a stub has to be inserted because the            /* Check if a stub has to be inserted because the
6948               destination is too far or we are changing mode.  */               destination is too far or we are changing mode.  */
6949            if (r_type == R_ARM_CALL)            if (   r_type == R_ARM_CALL
6950              {                || r_type == R_ARM_JUMP24
6951                  || r_type == R_ARM_PLT32)
6952                {
6953                  /* If the call goes through a PLT entry, make sure to
6954                     check distance to the right destination address.  */
6955                  if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
6956                    {
6957                      value = (splt->output_section->vma
6958                               + splt->output_offset
6959                               + h->plt.offset);
6960                      *unresolved_reloc_p = FALSE;
6961                    }
6962    
6963                  from = (input_section->output_section->vma
6964                          + input_section->output_offset
6965                          + rel->r_offset);
6966                  branch_offset = (bfd_signed_vma)(value - from);
6967    
6968                if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET                if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
6969                    || branch_offset < ARM_MAX_BWD_BRANCH_OFFSET                    || branch_offset < ARM_MAX_BWD_BRANCH_OFFSET
6970                    || sym_flags == STT_ARM_TFUNC)                    || ((sym_flags == STT_ARM_TFUNC)
6971                          && (((r_type == R_ARM_CALL) && !globals->use_blx)
6972                              || (r_type == R_ARM_JUMP24)
6973                              || (r_type == R_ARM_PLT32) ))
6974                      )
6975                  {                  {
6976                    /* The target is out of reach, so redirect the                    /* The target is out of reach, so redirect the
6977                       branch to the local stub for this function.  */                       branch to the local stub for this function.  */
# Line 6147  elf32_arm_final_link_relocate (reloc_how Line 7018  elf32_arm_final_link_relocate (reloc_how
7018            signed_addend >>= howto->rightshift;            signed_addend >>= howto->rightshift;
7019    
7020            /* A branch to an undefined weak symbol is turned into a jump to            /* A branch to an undefined weak symbol is turned into a jump to
7021               the next instruction.  */               the next instruction unless a PLT entry will be created.  */
7022            if (h && h->root.type == bfd_link_hash_undefweak)            if (h && h->root.type == bfd_link_hash_undefweak
7023                  && !(splt != NULL && h->plt.offset != (bfd_vma) -1))
7024              {              {
7025                value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000)                value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000)
7026                        | 0x0affffff;                        | 0x0affffff;
# Line 6165  elf32_arm_final_link_relocate (reloc_how Line 7037  elf32_arm_final_link_relocate (reloc_how
7037                value = (signed_addend & howto->dst_mask)                value = (signed_addend & howto->dst_mask)
7038                  | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));                  | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
7039    
               /* Set the H bit in the BLX instruction.  */  
               if (sym_flags == STT_ARM_TFUNC)  
                 {  
                   if (addend)  
                     value |= (1 << 24);  
                   else  
                     value &= ~(bfd_vma)(1 << 24);  
                 }  
7040                if (r_type == R_ARM_CALL)                if (r_type == R_ARM_CALL)
7041                  {                  {
7042                      /* Set the H bit in the BLX instruction.  */
7043                      if (sym_flags == STT_ARM_TFUNC)
7044                        {
7045                          if (addend)
7046                            value |= (1 << 24);
7047                          else
7048                            value &= ~(bfd_vma)(1 << 24);
7049                        }
7050    
7051                    /* Select the correct instruction (BL or BLX).  */                    /* Select the correct instruction (BL or BLX).  */
7052                    /* Only if we are not handling a BL to a stub. In this                    /* Only if we are not handling a BL to a stub. In this
7053                       case, mode switching is performed by the stub.  */                       case, mode switching is performed by the stub.  */
# Line 6310  elf32_arm_final_link_relocate (reloc_how Line 7183  elf32_arm_final_link_relocate (reloc_how
7183          return bfd_reloc_ok;          return bfd_reloc_ok;
7184        }        }
7185    
7186        case R_ARM_THM_PC8:
7187          /* PR 10073:  This reloc is not generated by the GNU toolchain,
7188             but it is supported for compatibility with third party libraries
7189             generated by other compilers, specifically the ARM/IAR.  */
7190          {
7191            bfd_vma insn;
7192            bfd_signed_vma relocation;
7193    
7194            insn = bfd_get_16 (input_bfd, hit_data);
7195    
7196            if (globals->use_rel)
7197              addend = (insn & 0x00ff) << 2;
7198    
7199            relocation = value + addend;
7200            relocation -= (input_section->output_section->vma
7201                           + input_section->output_offset
7202                           + rel->r_offset);
7203    
7204            value = abs (relocation);
7205    
7206            /* We do not check for overflow of this reloc.  Although strictly
7207               speaking this is incorrect, it appears to be necessary in order
7208               to work with IAR generated relocs.  Since GCC and GAS do not
7209               generate R_ARM_THM_PC8 relocs, the lack of a check should not be
7210               a problem for them.  */
7211            value &= 0x3fc;
7212    
7213            insn = (insn & 0xff00) | (value >> 2);
7214    
7215            bfd_put_16 (input_bfd, insn, hit_data);
7216    
7217            return bfd_reloc_ok;
7218          }
7219    
7220      case R_ARM_THM_PC12:      case R_ARM_THM_PC12:
7221        /* Corresponds to: ldr.w reg, [pc, #offset].  */        /* Corresponds to: ldr.w reg, [pc, #offset].  */
7222        {        {
# Line 6418  elf32_arm_final_link_relocate (reloc_how Line 7325  elf32_arm_final_link_relocate (reloc_how
7325                      /* Convert BL to BLX.  */                      /* Convert BL to BLX.  */
7326                      lower_insn = (lower_insn & ~0x1000) | 0x0800;                      lower_insn = (lower_insn & ~0x1000) | 0x0800;
7327                    }                    }
7328                  else if (r_type != R_ARM_THM_CALL)                  else if ((   r_type != R_ARM_THM_CALL)
7329                             && (r_type != R_ARM_THM_JUMP24))
7330                    {                    {
7331                      if (elf32_thumb_to_arm_stub                      if (elf32_thumb_to_arm_stub
7332                          (info, sym_name, input_bfd, output_bfd, input_section,                          (info, sym_name, input_bfd, output_bfd, input_section,
# Line 6455  elf32_arm_final_link_relocate (reloc_how Line 7363  elf32_arm_final_link_relocate (reloc_how
7363              *unresolved_reloc_p = FALSE;              *unresolved_reloc_p = FALSE;
7364            }            }
7365    
7366          if (r_type == R_ARM_THM_CALL)          if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
7367            {            {
7368              /* Check if a stub has to be inserted because the destination              /* Check if a stub has to be inserted because the destination
7369                 is too far.  */                 is too far.  */
# Line 6475  elf32_arm_final_link_relocate (reloc_how Line 7383  elf32_arm_final_link_relocate (reloc_how
7383                  (thumb2                  (thumb2
7384                   && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET                   && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
7385                       || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))                       || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
7386                  || ((sym_flags != STT_ARM_TFUNC) && !globals->use_blx))                  || ((sym_flags != STT_ARM_TFUNC)
7387                        && (((r_type == R_ARM_THM_CALL) && !globals->use_blx)
7388                            || r_type == R_ARM_THM_JUMP24)))
7389                {                {
7390                  /* The target is out of reach or we are changing modes, so                  /* The target is out of reach or we are changing modes, so
7391                     redirect the branch to the local stub for this                     redirect the branch to the local stub for this
# Line 6489  elf32_arm_final_link_relocate (reloc_how Line 7399  elf32_arm_final_link_relocate (reloc_how
7399                             + stub_entry->stub_sec->output_section->vma);                             + stub_entry->stub_sec->output_section->vma);
7400    
7401                  /* If this call becomes a call to Arm, force BLX.  */                  /* If this call becomes a call to Arm, force BLX.  */
7402                  if (globals->use_blx)                  if (globals->use_blx && (r_type == R_ARM_THM_CALL))
7403                    {                    {
7404                      if ((stub_entry                      if ((stub_entry
7405                           && !arm_stub_is_thumb (stub_entry->stub_type))                           && !arm_stub_is_thumb (stub_entry->stub_type))
# Line 7998  elf32_arm_relocate_section (bfd * Line 8908  elf32_arm_relocate_section (bfd *
8908    return TRUE;    return TRUE;
8909  }  }
8910    
8911    /* Add a new unwind edit to the list described by HEAD, TAIL.  If INDEX is zero,
8912       adds the edit to the start of the list.  (The list must be built in order of
8913       ascending INDEX: the function's callers are primarily responsible for
8914       maintaining that condition).  */
8915    
8916    static void
8917    add_unwind_table_edit (arm_unwind_table_edit **head,
8918                           arm_unwind_table_edit **tail,
8919                           arm_unwind_edit_type type,
8920                           asection *linked_section,
8921                           unsigned int index)
8922    {
8923      arm_unwind_table_edit *new_edit = xmalloc (sizeof (arm_unwind_table_edit));
8924      
8925      new_edit->type = type;
8926      new_edit->linked_section = linked_section;
8927      new_edit->index = index;
8928      
8929      if (index > 0)
8930        {
8931          new_edit->next = NULL;
8932    
8933          if (*tail)
8934            (*tail)->next = new_edit;
8935    
8936          (*tail) = new_edit;
8937    
8938          if (!*head)
8939            (*head) = new_edit;
8940        }
8941      else
8942        {
8943          new_edit->next = *head;
8944    
8945          if (!*tail)
8946            *tail = new_edit;
8947    
8948          *head = new_edit;
8949        }
8950    }
8951    
8952    static _arm_elf_section_data *get_arm_elf_section_data (asection *);
8953    
8954    /* Increase the size of EXIDX_SEC by ADJUST bytes.  ADJUST mau be negative.  */
8955    static void
8956    adjust_exidx_size(asection *exidx_sec, int adjust)
8957    {
8958      asection *out_sec;
8959    
8960      if (!exidx_sec->rawsize)
8961        exidx_sec->rawsize = exidx_sec->size;
8962    
8963      bfd_set_section_size (exidx_sec->owner, exidx_sec, exidx_sec->size + adjust);
8964      out_sec = exidx_sec->output_section;
8965      /* Adjust size of output section.  */
8966      bfd_set_section_size (out_sec->owner, out_sec, out_sec->size +adjust);
8967    }
8968    
8969    /* Insert an EXIDX_CANTUNWIND marker at the end of a section.  */
8970    static void
8971    insert_cantunwind_after(asection *text_sec, asection *exidx_sec)
8972    {
8973      struct _arm_elf_section_data *exidx_arm_data;
8974    
8975      exidx_arm_data = get_arm_elf_section_data (exidx_sec);
8976      add_unwind_table_edit (
8977        &exidx_arm_data->u.exidx.unwind_edit_list,
8978        &exidx_arm_data->u.exidx.unwind_edit_tail,
8979        INSERT_EXIDX_CANTUNWIND_AT_END, text_sec, UINT_MAX);
8980    
8981      adjust_exidx_size(exidx_sec, 8);
8982    }
8983    
8984    /* Scan .ARM.exidx tables, and create a list describing edits which should be
8985       made to those tables, such that:
8986      
8987         1. Regions without unwind data are marked with EXIDX_CANTUNWIND entries.
8988         2. Duplicate entries are merged together (EXIDX_CANTUNWIND, or unwind
8989            codes which have been inlined into the index).
8990    
8991       The edits are applied when the tables are written
8992       (in elf32_arm_write_section).
8993    */
8994    
8995    bfd_boolean
8996    elf32_arm_fix_exidx_coverage (asection **text_section_order,
8997                                  unsigned int num_text_sections,
8998                                  struct bfd_link_info *info)
8999    {
9000      bfd *inp;
9001      unsigned int last_second_word = 0, i;
9002      asection *last_exidx_sec = NULL;
9003      asection *last_text_sec = NULL;
9004      int last_unwind_type = -1;
9005    
9006      /* Walk over all EXIDX sections, and create backlinks from the corrsponding
9007         text sections.  */
9008      for (inp = info->input_bfds; inp != NULL; inp = inp->link_next)
9009        {
9010          asection *sec;
9011          
9012          for (sec = inp->sections; sec != NULL; sec = sec->next)
9013            {
9014              struct bfd_elf_section_data *elf_sec = elf_section_data (sec);
9015              Elf_Internal_Shdr *hdr = &elf_sec->this_hdr;
9016              
9017              if (!hdr || hdr->sh_type != SHT_ARM_EXIDX)
9018                continue;
9019              
9020              if (elf_sec->linked_to)
9021                {
9022                  Elf_Internal_Shdr *linked_hdr
9023                    = &elf_section_data (elf_sec->linked_to)->this_hdr;
9024                  struct _arm_elf_section_data *linked_sec_arm_data
9025                    = get_arm_elf_section_data (linked_hdr->bfd_section);
9026    
9027                  if (linked_sec_arm_data == NULL)
9028                    continue;
9029    
9030                  /* Link this .ARM.exidx section back from the text section it
9031                     describes.  */
9032                  linked_sec_arm_data->u.text.arm_exidx_sec = sec;
9033                }
9034            }
9035        }
9036    
9037      /* Walk all text sections in order of increasing VMA.  Eilminate duplicate
9038         index table entries (EXIDX_CANTUNWIND and inlined unwind opcodes),
9039         and add EXIDX_CANTUNWIND entries for sections with no unwind table data.
9040       */
9041    
9042      for (i = 0; i < num_text_sections; i++)
9043        {
9044          asection *sec = text_section_order[i];
9045          asection *exidx_sec;
9046          struct _arm_elf_section_data *arm_data = get_arm_elf_section_data (sec);
9047          struct _arm_elf_section_data *exidx_arm_data;
9048          bfd_byte *contents = NULL;
9049          int deleted_exidx_bytes = 0;
9050          bfd_vma j;
9051          arm_unwind_table_edit *unwind_edit_head = NULL;
9052          arm_unwind_table_edit *unwind_edit_tail = NULL;
9053          Elf_Internal_Shdr *hdr;
9054          bfd *ibfd;
9055    
9056          if (arm_data == NULL)
9057            continue;
9058    
9059          exidx_sec = arm_data->u.text.arm_exidx_sec;
9060          if (exidx_sec == NULL)
9061            {
9062              /* Section has no unwind data.  */
9063              if (last_unwind_type == 0 || !last_exidx_sec)
9064                continue;
9065    
9066              /* Ignore zero sized sections.  */
9067              if (sec->size == 0)
9068                continue;
9069    
9070              insert_cantunwind_after(last_text_sec, last_exidx_sec);
9071              last_unwind_type = 0;
9072              continue;
9073            }
9074    
9075          /* Skip /DISCARD/ sections.  */
9076          if (bfd_is_abs_section (exidx_sec->output_section))
9077            continue;
9078    
9079          hdr = &elf_section_data (exidx_sec)->this_hdr;
9080          if (hdr->sh_type != SHT_ARM_EXIDX)
9081            continue;
9082          
9083          exidx_arm_data = get_arm_elf_section_data (exidx_sec);
9084          if (exidx_arm_data == NULL)
9085            continue;
9086          
9087          ibfd = exidx_sec->owner;
9088              
9089          if (hdr->contents != NULL)
9090            contents = hdr->contents;
9091          else if (! bfd_malloc_and_get_section (ibfd, exidx_sec, &contents))
9092            /* An error?  */
9093            continue;
9094    
9095          for (j = 0; j < hdr->sh_size; j += 8)
9096            {
9097              unsigned int second_word = bfd_get_32 (ibfd, contents + j + 4);
9098              int unwind_type;
9099              int elide = 0;
9100    
9101              /* An EXIDX_CANTUNWIND entry.  */
9102              if (second_word == 1)
9103                {
9104                  if (last_unwind_type == 0)
9105                    elide = 1;
9106                  unwind_type = 0;
9107                }
9108              /* Inlined unwinding data.  Merge if equal to previous.  */
9109              else if ((second_word & 0x80000000) != 0)
9110                {
9111                  if (last_second_word == second_word && last_unwind_type == 1)
9112                    elide = 1;
9113                  unwind_type = 1;
9114                  last_second_word = second_word;
9115                }
9116              /* Normal table entry.  In theory we could merge these too,
9117                 but duplicate entries are likely to be much less common.  */
9118              else
9119                unwind_type = 2;
9120    
9121              if (elide)
9122                {
9123                  add_unwind_table_edit (&unwind_edit_head, &unwind_edit_tail,
9124                                         DELETE_EXIDX_ENTRY, NULL, j / 8);
9125    
9126                  deleted_exidx_bytes += 8;
9127                }
9128    
9129              last_unwind_type = unwind_type;
9130            }
9131    
9132          /* Free contents if we allocated it ourselves.  */
9133          if (contents != hdr->contents)
9134            free (contents);
9135    
9136          /* Record edits to be applied later (in elf32_arm_write_section).  */
9137          exidx_arm_data->u.exidx.unwind_edit_list = unwind_edit_head;
9138          exidx_arm_data->u.exidx.unwind_edit_tail = unwind_edit_tail;
9139              
9140          if (deleted_exidx_bytes > 0)
9141            adjust_exidx_size(exidx_sec, -deleted_exidx_bytes);
9142    
9143          last_exidx_sec = exidx_sec;
9144          last_text_sec = sec;
9145        }
9146    
9147      /* Add terminating CANTUNWIND entry.  */
9148      if (last_exidx_sec && last_unwind_type != 0)
9149        insert_cantunwind_after(last_text_sec, last_exidx_sec);
9150    
9151      return TRUE;
9152    }
9153    
9154    static bfd_boolean
9155    elf32_arm_output_glue_section (struct bfd_link_info *info, bfd *obfd,
9156                                   bfd *ibfd, const char *name)
9157    {
9158      asection *sec, *osec;
9159    
9160      sec = bfd_get_section_by_name (ibfd, name);
9161      if (sec == NULL || (sec->flags & SEC_EXCLUDE) != 0)
9162        return TRUE;
9163    
9164      osec = sec->output_section;
9165      if (elf32_arm_write_section (obfd, info, sec, sec->contents))
9166        return TRUE;
9167    
9168      if (! bfd_set_section_contents (obfd, osec, sec->contents,
9169                                      sec->output_offset, sec->size))
9170        return FALSE;
9171    
9172      return TRUE;
9173    }
9174    
9175    static bfd_boolean
9176    elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
9177    {
9178      struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info);
9179    
9180      /* Invoke the regular ELF backend linker to do all the work.  */
9181      if (!bfd_elf_final_link (abfd, info))
9182        return FALSE;
9183    
9184      /* Write out any glue sections now that we have created all the
9185         stubs.  */
9186      if (globals->bfd_of_glue_owner != NULL)
9187        {
9188          if (! elf32_arm_output_glue_section (info, abfd,
9189                                               globals->bfd_of_glue_owner,
9190                                               ARM2THUMB_GLUE_SECTION_NAME))
9191            return FALSE;
9192    
9193          if (! elf32_arm_output_glue_section (info, abfd,
9194                                               globals->bfd_of_glue_owner,
9195                                               THUMB2ARM_GLUE_SECTION_NAME))
9196            return FALSE;
9197    
9198          if (! elf32_arm_output_glue_section (info, abfd,
9199                                               globals->bfd_of_glue_owner,
9200                                               VFP11_ERRATUM_VENEER_SECTION_NAME))
9201            return FALSE;
9202    
9203          if (! elf32_arm_output_glue_section (info, abfd,
9204                                               globals->bfd_of_glue_owner,
9205                                               ARM_BX_GLUE_SECTION_NAME))
9206            return FALSE;
9207        }
9208    
9209      return TRUE;
9210    }
9211    
9212  /* Set the right machine number.  */  /* Set the right machine number.  */
9213    
9214  static bfd_boolean  static bfd_boolean
# Line 8138  static int Line 9349  static int
9349  elf32_arm_obj_attrs_arg_type (int tag)  elf32_arm_obj_attrs_arg_type (int tag)
9350  {  {
9351    if (tag == Tag_compatibility)    if (tag == Tag_compatibility)
9352      return 3;      return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
9353    else if (tag == 4 || tag == 5)    else if (tag == Tag_nodefaults)
9354      return 2;      return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_NO_DEFAULT;
9355      else if (tag == Tag_CPU_raw_name || tag == Tag_CPU_name)
9356        return ATTR_TYPE_FLAG_STR_VAL;
9357    else if (tag < 32)    else if (tag < 32)
9358      return 1;      return ATTR_TYPE_FLAG_INT_VAL;
9359    else    else
9360      return (tag & 1) != 0 ? 2 : 1;      return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
9361    }
9362    
9363    /* The ABI defines that Tag_conformance should be emitted first, and that
9364       Tag_nodefaults should be second (if either is defined).  This sets those
9365       two positions, and bumps up the position of all the remaining tags to
9366       compensate.  */
9367    static int
9368    elf32_arm_obj_attrs_order (int num)
9369    {
9370      if (num == 4)
9371        return Tag_conformance;
9372      if (num == 5)
9373        return Tag_nodefaults;
9374      if ((num - 2) < Tag_nodefaults)
9375        return num - 2;
9376      if ((num - 1) < Tag_conformance)
9377        return num - 1;
9378      return num;
9379    }
9380    
9381    /* Read the architecture from the Tag_also_compatible_with attribute, if any.
9382       Returns -1 if no architecture could be read.  */
9383    
9384    static int
9385    get_secondary_compatible_arch (bfd *abfd)
9386    {
9387      obj_attribute *attr =
9388        &elf_known_obj_attributes_proc (abfd)[Tag_also_compatible_with];
9389    
9390      /* Note: the tag and its argument below are uleb128 values, though
9391         currently-defined values fit in one byte for each.  */
9392      if (attr->s
9393          && attr->s[0] == Tag_CPU_arch
9394          && (attr->s[1] & 128) != 128
9395          && attr->s[2] == 0)
9396       return attr->s[1];
9397    
9398      /* This tag is "safely ignorable", so don't complain if it looks funny.  */
9399      return -1;
9400  }  }
9401    
9402    /* Set, or unset, the architecture of the Tag_also_compatible_with attribute.
9403       The tag is removed if ARCH is -1.  */
9404    
9405  static void  static void
9406  elf32_arm_copy_one_eabi_other_attribute (bfd *ibfd, bfd *obfd, obj_attribute_list *in_list)  set_secondary_compatible_arch (bfd *abfd, int arch)
9407  {  {
9408    switch (in_list->tag)    obj_attribute *attr =
9409      {      &elf_known_obj_attributes_proc (abfd)[Tag_also_compatible_with];
     case Tag_VFP_HP_extension:  
     case Tag_ABI_FP_16bit_format:  
       bfd_elf_add_obj_attr_int (obfd, OBJ_ATTR_PROC, in_list->tag, in_list->attr.i);  
       break;  
9410    
9411      default:    if (arch == -1)
9412        if ((in_list->tag & 127) < 64)      {
9413          {        attr->s = NULL;
9414            _bfd_error_handler        return;
               (_("Warning: %B: Unknown EABI object attribute %d"), ibfd, in_list->tag);  
           break;  
         }  
9415      }      }
9416    
9417      /* Note: the tag and its argument below are uleb128 values, though
9418         currently-defined values fit in one byte for each.  */
9419      if (!attr->s)
9420        attr->s = bfd_alloc (abfd, 3);
9421      attr->s[0] = Tag_CPU_arch;
9422      attr->s[1] = arch;
9423      attr->s[2] = '\0';
9424  }  }
9425    
9426  static void  /* Combine two values for Tag_CPU_arch, taking secondary compatibility tags
9427  elf32_arm_copy_eabi_other_attribute_list (bfd *ibfd, bfd *obfd, obj_attribute_list *in_list)     into account.  */
9428    
9429    static int
9430    tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
9431                          int newtag, int secondary_compat)
9432  {  {
9433    for (; in_list; in_list = in_list->next )  #define T(X) TAG_CPU_ARCH_##X
9434      elf32_arm_copy_one_eabi_other_attribute (ibfd, obfd, in_list);    int tagl, tagh, result;
9435      const int v6t2[] =
9436        {
9437          T(V6T2),   /* PRE_V4.  */
9438          T(V6T2),   /* V4.  */
9439          T(V6T2),   /* V4T.  */
9440          T(V6T2),   /* V5T.  */
9441          T(V6T2),   /* V5TE.  */
9442          T(V6T2),   /* V5TEJ.  */
9443          T(V6T2),   /* V6.  */
9444          T(V7),     /* V6KZ.  */
9445          T(V6T2)    /* V6T2.  */
9446        };
9447      const int v6k[] =
9448        {
9449          T(V6K),    /* PRE_V4.  */
9450          T(V6K),    /* V4.  */
9451          T(V6K),    /* V4T.  */
9452          T(V6K),    /* V5T.  */
9453          T(V6K),    /* V5TE.  */
9454          T(V6K),    /* V5TEJ.  */
9455          T(V6K),    /* V6.  */
9456          T(V6KZ),   /* V6KZ.  */
9457          T(V7),     /* V6T2.  */
9458          T(V6K)     /* V6K.  */
9459        };
9460      const int v7[] =
9461        {
9462          T(V7),     /* PRE_V4.  */
9463          T(V7),     /* V4.  */
9464          T(V7),     /* V4T.  */
9465          T(V7),     /* V5T.  */
9466          T(V7),     /* V5TE.  */
9467          T(V7),     /* V5TEJ.  */
9468          T(V7),     /* V6.  */
9469          T(V7),     /* V6KZ.  */
9470          T(V7),     /* V6T2.  */
9471          T(V7),     /* V6K.  */
9472          T(V7)      /* V7.  */
9473        };
9474      const int v6_m[] =
9475        {
9476          -1,        /* PRE_V4.  */
9477          -1,        /* V4.  */
9478          T(V6K),    /* V4T.  */
9479          T(V6K),    /* V5T.  */
9480          T(V6K),    /* V5TE.  */
9481          T(V6K),    /* V5TEJ.  */
9482          T(V6K),    /* V6.  */
9483          T(V6KZ),   /* V6KZ.  */
9484          T(V7),     /* V6T2.  */
9485          T(V6K),    /* V6K.  */
9486          T(V7),     /* V7.  */
9487          T(V6_M)    /* V6_M.  */
9488        };
9489      const int v6s_m[] =
9490        {
9491          -1,        /* PRE_V4.  */
9492          -1,        /* V4.  */
9493          T(V6K),    /* V4T.  */
9494          T(V6K),    /* V5T.  */
9495          T(V6K),    /* V5TE.  */
9496          T(V6K),    /* V5TEJ.  */
9497          T(V6K),    /* V6.  */
9498          T(V6KZ),   /* V6KZ.  */
9499          T(V7),     /* V6T2.  */
9500          T(V6K),    /* V6K.  */
9501          T(V7),     /* V7.  */
9502          T(V6S_M),  /* V6_M.  */
9503          T(V6S_M)   /* V6S_M.  */
9504        };
9505      const int v4t_plus_v6_m[] =
9506        {
9507          -1,               /* PRE_V4.  */
9508          -1,               /* V4.  */
9509          T(V4T),           /* V4T.  */
9510          T(V5T),           /* V5T.  */
9511          T(V5TE),          /* V5TE.  */
9512          T(V5TEJ),         /* V5TEJ.  */
9513          T(V6),            /* V6.  */
9514          T(V6KZ),          /* V6KZ.  */
9515          T(V6T2),          /* V6T2.  */
9516          T(V6K),           /* V6K.  */
9517          T(V7),            /* V7.  */
9518          T(V6_M),          /* V6_M.  */
9519          T(V6S_M),         /* V6S_M.  */
9520          T(V4T_PLUS_V6_M)  /* V4T plus V6_M.  */
9521        };
9522      const int *comb[] =
9523        {
9524          v6t2,
9525          v6k,
9526          v7,
9527          v6_m,
9528          v6s_m,
9529          /* Pseudo-architecture.  */
9530          v4t_plus_v6_m
9531        };
9532    
9533      /* Check we've not got a higher architecture than we know about.  */
9534    
9535      if (oldtag >= MAX_TAG_CPU_ARCH || newtag >= MAX_TAG_CPU_ARCH)
9536        {
9537          _bfd_error_handler (_("error: %B: Unknown CPU architecture"), ibfd);
9538          return -1;
9539        }
9540    
9541      /* Override old tag if we have a Tag_also_compatible_with on the output.  */
9542    
9543      if ((oldtag == T(V6_M) && *secondary_compat_out == T(V4T))
9544          || (oldtag == T(V4T) && *secondary_compat_out == T(V6_M)))
9545        oldtag = T(V4T_PLUS_V6_M);
9546    
9547      /* And override the new tag if we have a Tag_also_compatible_with on the
9548         input.  */
9549    
9550      if ((newtag == T(V6_M) && secondary_compat == T(V4T))
9551          || (newtag == T(V4T) && secondary_compat == T(V6_M)))
9552        newtag = T(V4T_PLUS_V6_M);
9553    
9554      tagl = (oldtag < newtag) ? oldtag : newtag;
9555      result = tagh = (oldtag > newtag) ? oldtag : newtag;
9556    
9557      /* Architectures before V6KZ add features monotonically.  */
9558      if (tagh <= TAG_CPU_ARCH_V6KZ)
9559        return result;
9560    
9561      result = comb[tagh - T(V6T2)][tagl];
9562    
9563      /* Use Tag_CPU_arch == V4T and Tag_also_compatible_with (Tag_CPU_arch V6_M)
9564         as the canonical version.  */
9565      if (result == T(V4T_PLUS_V6_M))
9566        {
9567          result = T(V4T);
9568          *secondary_compat_out = T(V6_M);
9569        }
9570      else
9571        *secondary_compat_out = -1;
9572    
9573      if (result == -1)
9574        {
9575          _bfd_error_handler (_("error: %B: Conflicting CPU architectures %d/%d"),
9576                              ibfd, oldtag, newtag);
9577          return -1;
9578        }
9579    
9580      return result;
9581    #undef T
9582  }  }
9583    
9584  /* Merge EABI object attributes from IBFD into OBFD.  Raise an error if there  /* Merge EABI object attributes from IBFD into OBFD.  Raise an error if there
# Line 8184  elf32_arm_merge_eabi_attributes (bfd *ib Line 9591  elf32_arm_merge_eabi_attributes (bfd *ib
9591    obj_attribute *out_attr;    obj_attribute *out_attr;
9592    obj_attribute_list *in_list;    obj_attribute_list *in_list;
9593    obj_attribute_list *out_list;    obj_attribute_list *out_list;
9594      obj_attribute_list **out_listp;
9595    /* Some tags have 0 = don't care, 1 = strong requirement,    /* Some tags have 0 = don't care, 1 = strong requirement,
9596       2 = weak requirement.  */       2 = weak requirement.  */
9597    static const int order_312[3] = {3, 1, 2};    static const int order_021[3] = {0, 2, 1};
9598    /* For use with Tag_VFP_arch.  */    /* For use with Tag_VFP_arch.  */
9599    static const int order_01243[5] = {0, 1, 2, 4, 3};    static const int order_01243[5] = {0, 1, 2, 4, 3};
9600    int i;    int i;
9601      bfd_boolean result = TRUE;
9602    
9603      /* Skip the linker stubs file.  This preserves previous behavior
9604         of accepting unknown attributes in the first input file - but
9605         is that a bug?  */
9606      if (ibfd->flags & BFD_LINKER_CREATED)
9607        return TRUE;
9608    
9609    if (!elf_known_obj_attributes_proc (obfd)[0].i)    if (!elf_known_obj_attributes_proc (obfd)[0].i)
9610      {      {
# Line 8214  elf32_arm_merge_eabi_attributes (bfd *ib Line 9629  elf32_arm_merge_eabi_attributes (bfd *ib
9629        else if (in_attr[Tag_ABI_FP_number_model].i != 0)        else if (in_attr[Tag_ABI_FP_number_model].i != 0)
9630          {          {
9631            _bfd_error_handler            _bfd_error_handler
9632              (_("ERROR: %B uses VFP register arguments, %B does not"),              (_("error: %B uses VFP register arguments, %B does not"),
9633               ibfd, obfd);               ibfd, obfd);
9634            return FALSE;            result = FALSE;
9635          }          }
9636      }      }
9637    
# Line 8227  elf32_arm_merge_eabi_attributes (bfd *ib Line 9642  elf32_arm_merge_eabi_attributes (bfd *ib
9642          {          {
9643          case Tag_CPU_raw_name:          case Tag_CPU_raw_name:
9644          case Tag_CPU_name:          case Tag_CPU_name:
9645            /* Use whichever has the greatest architecture requirements.  We            /* These are merged after Tag_CPU_arch. */
              won't necessarily have both the above tags, so make sure input  
              name is non-NULL.  */  
           if (in_attr[Tag_CPU_arch].i > out_attr[Tag_CPU_arch].i  
               && in_attr[i].s)  
             out_attr[i].s = _bfd_elf_attr_strdup (obfd, in_attr[i].s);  
9646            break;            break;
9647    
9648          case Tag_ABI_optimization_goals:          case Tag_ABI_optimization_goals:
# Line 8241  elf32_arm_merge_eabi_attributes (bfd *ib Line 9651  elf32_arm_merge_eabi_attributes (bfd *ib
9651            break;            break;
9652    
9653          case Tag_CPU_arch:          case Tag_CPU_arch:
9654              {
9655                int secondary_compat = -1, secondary_compat_out = -1;
9656                unsigned int saved_out_attr = out_attr[i].i;
9657                static const char *name_table[] = {
9658                    /* These aren't real CPU names, but we can't guess
9659                       that from the architecture version alone.  */
9660                    "Pre v4",
9661                    "ARM v4",
9662                    "ARM v4T",
9663                    "ARM v5T",
9664                    "ARM v5TE",
9665                    "ARM v5TEJ",
9666                    "ARM v6",
9667                    "ARM v6KZ",
9668                    "ARM v6T2",
9669                    "ARM v6K",
9670                    "ARM v7",
9671                    "ARM v6-M",
9672                    "ARM v6S-M"
9673                };
9674    
9675                /* Merge Tag_CPU_arch and Tag_also_compatible_with.  */
9676                secondary_compat = get_secondary_compatible_arch (ibfd);
9677                secondary_compat_out = get_secondary_compatible_arch (obfd);
9678                out_attr[i].i = tag_cpu_arch_combine (ibfd, out_attr[i].i,
9679                                                      &secondary_compat_out,
9680                                                      in_attr[i].i,
9681                                                      secondary_compat);
9682                set_secondary_compatible_arch (obfd, secondary_compat_out);
9683    
9684                /* Merge Tag_CPU_name and Tag_CPU_raw_name.  */
9685                if (out_attr[i].i == saved_out_attr)
9686                  ; /* Leave the names alone.  */
9687                else if (out_attr[i].i == in_attr[i].i)
9688                  {
9689                    /* The output architecture has been changed to match the
9690                       input architecture.  Use the input names.  */
9691                    out_attr[Tag_CPU_name].s = in_attr[Tag_CPU_name].s
9692                      ? _bfd_elf_attr_strdup (obfd, in_attr[Tag_CPU_name].s)
9693                      : NULL;
9694                    out_attr[Tag_CPU_raw_name].s = in_attr[Tag_CPU_raw_name].s
9695                      ? _bfd_elf_attr_strdup (obfd, in_attr[Tag_CPU_raw_name].s)
9696                      : NULL;
9697                  }
9698                else
9699                  {
9700                    out_attr[Tag_CPU_name].s = NULL;
9701                    out_attr[Tag_CPU_raw_name].s = NULL;
9702                  }
9703    
9704                /* If we still don't have a value for Tag_CPU_name,
9705                   make one up now.  Tag_CPU_raw_name remains blank.  */
9706                if (out_attr[Tag_CPU_name].s == NULL
9707                    && out_attr[i].i < ARRAY_SIZE (name_table))
9708                  out_attr[Tag_CPU_name].s =
9709                    _bfd_elf_attr_strdup (obfd, name_table[out_attr[i].i]);
9710              }
9711              break;
9712    
9713          case Tag_ARM_ISA_use:          case Tag_ARM_ISA_use:
9714          case Tag_THUMB_ISA_use:          case Tag_THUMB_ISA_use:
9715          case Tag_WMMX_arch:          case Tag_WMMX_arch:
9716          case Tag_NEON_arch:          case Tag_Advanced_SIMD_arch:
9717            /* ??? Do NEON and WMMX conflict?  */            /* ??? Do Advanced_SIMD (NEON) and WMMX conflict?  */
9718          case Tag_ABI_FP_rounding:          case Tag_ABI_FP_rounding:
         case Tag_ABI_FP_denormal:  
9719          case Tag_ABI_FP_exceptions:          case Tag_ABI_FP_exceptions:
9720          case Tag_ABI_FP_user_exceptions:          case Tag_ABI_FP_user_exceptions:
9721          case Tag_ABI_FP_number_model:          case Tag_ABI_FP_number_model:
9722          case Tag_ABI_align8_preserved:          case Tag_VFP_HP_extension:
9723          case Tag_ABI_HardFP_use:          case Tag_CPU_unaligned_access:
9724            case Tag_T2EE_use:
9725            case Tag_Virtualization_use:
9726            case Tag_MPextension_use:
9727            /* Use the largest value specified.  */            /* Use the largest value specified.  */
9728            if (in_attr[i].i > out_attr[i].i)            if (in_attr[i].i > out_attr[i].i)
9729              out_attr[i].i = in_attr[i].i;              out_attr[i].i = in_attr[i].i;
9730            break;            break;
9731    
9732          case Tag_CPU_arch_profile:          case Tag_ABI_align8_preserved:
9733            /* Warn if conflicting architecture profiles used.  */          case Tag_ABI_PCS_RO_data:
9734            if (out_attr[i].i && in_attr[i].i && in_attr[i].i != out_attr[i].i)            /* Use the smallest value specified.  */
9735              {            if (in_attr[i].i < out_attr[i].i)
9736                out_attr[i].i = in_attr[i].i;
9737              break;
9738    
9739            case Tag_ABI_align8_needed:
9740              if ((in_attr[i].i > 0 || out_attr[i].i > 0)
9741                  && (in_attr[Tag_ABI_align8_preserved].i == 0
9742                      || out_attr[Tag_ABI_align8_preserved].i == 0))
9743                {
9744                  /* This error message should be enabled once all non-conformant
9745                     binaries in the toolchain have had the attributes set
9746                     properly.
9747                _bfd_error_handler                _bfd_error_handler
9748                  (_("ERROR: %B: Conflicting architecture profiles %c/%c"),                  (_("error: %B: 8-byte data alignment conflicts with %B"),
9749                   ibfd, in_attr[i].i, out_attr[i].i);                   obfd, ibfd);
9750                return FALSE;                result = FALSE; */
9751              }              }
9752            if (in_attr[i].i)            /* Fall through.  */
9753            case Tag_ABI_FP_denormal:
9754            case Tag_ABI_PCS_GOT_use:
9755              /* Use the "greatest" from the sequence 0, 2, 1, or the largest
9756                 value if greater than 2 (for future-proofing).  */
9757              if ((in_attr[i].i > 2 && in_attr[i].i > out_attr[i].i)
9758                  || (in_attr[i].i <= 2 && out_attr[i].i <= 2
9759                      && order_021[in_attr[i].i] > order_021[out_attr[i].i]))
9760              out_attr[i].i = in_attr[i].i;              out_attr[i].i = in_attr[i].i;
9761            break;            break;
9762    
9763    
9764            case Tag_CPU_arch_profile:
9765              if (out_attr[i].i != in_attr[i].i)
9766                {
9767                  /* 0 will merge with anything.
9768                     'A' and 'S' merge to 'A'.
9769                     'R' and 'S' merge to 'R'.
9770                     'M' and 'A|R|S' is an error.  */
9771                  if (out_attr[i].i == 0
9772                      || (out_attr[i].i == 'S'
9773                          && (in_attr[i].i == 'A' || in_attr[i].i == 'R')))
9774                    out_attr[i].i = in_attr[i].i;
9775                  else if (in_attr[i].i == 0
9776                           || (in_attr[i].i == 'S'
9777                               && (out_attr[i].i == 'A' || out_attr[i].i == 'R')))
9778                    ; /* Do nothing. */
9779                  else
9780                    {
9781                      _bfd_error_handler
9782                        (_("error: %B: Conflicting architecture profiles %c/%c"),
9783                         ibfd,
9784                         in_attr[i].i ? in_attr[i].i : '0',
9785                         out_attr[i].i ? out_attr[i].i : '0');
9786                      result = FALSE;
9787                    }
9788                }
9789              break;
9790          case Tag_VFP_arch:          case Tag_VFP_arch:
9791            if (in_attr[i].i > 4 || out_attr[i].i > 4            /* Use the "greatest" from the sequence 0, 1, 2, 4, 3, or the
9792                || order_01243[in_attr[i].i] > order_01243[out_attr[i].i])               largest value if greater than 4 (for future-proofing).  */
9793              if ((in_attr[i].i > 4 && in_attr[i].i > out_attr[i].i)
9794                  || (in_attr[i].i <= 4 && out_attr[i].i <= 4
9795                      && order_01243[in_attr[i].i] > order_01243[out_attr[i].i]))
9796              out_attr[i].i = in_attr[i].i;              out_attr[i].i = in_attr[i].i;
9797            break;            break;
9798          case Tag_PCS_config:          case Tag_PCS_config:
# Line 8292  elf32_arm_merge_eabi_attributes (bfd *ib Line 9812  elf32_arm_merge_eabi_attributes (bfd *ib
9812                && in_attr[i].i != AEABI_R9_unused)                && in_attr[i].i != AEABI_R9_unused)
9813              {              {
9814                _bfd_error_handler                _bfd_error_handler
9815                  (_("ERROR: %B: Conflicting use of R9"), ibfd);                  (_("error: %B: Conflicting use of R9"), ibfd);
9816                return FALSE;                result = FALSE;
9817              }              }
9818            if (out_attr[i].i == AEABI_R9_unused)            if (out_attr[i].i == AEABI_R9_unused)
9819              out_attr[i].i = in_attr[i].i;              out_attr[i].i = in_attr[i].i;
# Line 8304  elf32_arm_merge_eabi_attributes (bfd *ib Line 9824  elf32_arm_merge_eabi_attributes (bfd *ib
9824                && out_attr[Tag_ABI_PCS_R9_use].i != AEABI_R9_unused)                && out_attr[Tag_ABI_PCS_R9_use].i != AEABI_R9_unused)
9825              {              {
9826                _bfd_error_handler                _bfd_error_handler
9827                  (_("ERROR: %B: SB relative addressing conflicts with use of R9"),                  (_("error: %B: SB relative addressing conflicts with use of R9"),
9828                   ibfd);                   ibfd);
9829                return FALSE;                result = FALSE;
9830              }              }
9831            /* Use the smallest value specified.  */            /* Use the smallest value specified.  */
9832            if (in_attr[i].i < out_attr[i].i)            if (in_attr[i].i < out_attr[i].i)
9833              out_attr[i].i = in_attr[i].i;              out_attr[i].i = in_attr[i].i;
9834            break;            break;
         case Tag_ABI_PCS_RO_data:  
           /* Use the smallest value specified.  */  
           if (in_attr[i].i < out_attr[i].i)  
             out_attr[i].i = in_attr[i].i;  
           break;  
         case Tag_ABI_PCS_GOT_use:  
           if (in_attr[i].i > 2 || out_attr[i].i > 2  
               || order_312[in_attr[i].i] < order_312[out_attr[i].i])  
             out_attr[i].i = in_attr[i].i;  
           break;  
9835          case Tag_ABI_PCS_wchar_t:          case Tag_ABI_PCS_wchar_t:
9836            if (out_attr[i].i && in_attr[i].i && out_attr[i].i != in_attr[i].i            if (out_attr[i].i && in_attr[i].i && out_attr[i].i != in_attr[i].i
9837                && !elf_arm_tdata (obfd)->no_wchar_size_warning)                && !elf_arm_tdata (obfd)->no_wchar_size_warning)
# Line 8333  elf32_arm_merge_eabi_attributes (bfd *ib Line 9843  elf32_arm_merge_eabi_attributes (bfd *ib
9843            else if (in_attr[i].i && !out_attr[i].i)            else if (in_attr[i].i && !out_attr[i].i)
9844              out_attr[i].i = in_attr[i].i;              out_attr[i].i = in_attr[i].i;
9845            break;            break;
         case Tag_ABI_align8_needed:  
           /* ??? Check against Tag_ABI_align8_preserved.  */  
           if (in_attr[i].i > 2 || out_attr[i].i > 2  
               || order_312[in_attr[i].i] < order_312[out_attr[i].i])  
             out_attr[i].i = in_attr[i].i;  
           break;  
9846          case Tag_ABI_enum_size:          case Tag_ABI_enum_size:
9847            if (in_attr[i].i != AEABI_enum_unused)            if (in_attr[i].i != AEABI_enum_unused)
9848              {              {
# Line 8353  elf32_arm_merge_eabi_attributes (bfd *ib Line 9857  elf32_arm_merge_eabi_attributes (bfd *ib
9857                         && out_attr[i].i != in_attr[i].i                         && out_attr[i].i != in_attr[i].i
9858                         && !elf_arm_tdata (obfd)->no_enum_size_warning)                         && !elf_arm_tdata (obfd)->no_enum_size_warning)
9859                  {                  {
9860                    const char *aeabi_enum_names[] =                    static const char *aeabi_enum_names[] =
9861                      { "", "variable-size", "32-bit", "" };                      { "", "variable-size", "32-bit", "" };
9862                      const char *in_name =
9863                        in_attr[i].i < ARRAY_SIZE(aeabi_enum_names)
9864                        ? aeabi_enum_names[in_attr[i].i]
9865                        : "<unknown>";
9866                      const char *out_name =
9867                        out_attr[i].i < ARRAY_SIZE(aeabi_enum_names)
9868                        ? aeabi_enum_names[out_attr[i].i]
9869                        : "<unknown>";
9870                    _bfd_error_handler                    _bfd_error_handler
9871                      (_("warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"),                      (_("warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"),
9872                       ibfd, aeabi_enum_names[in_attr[i].i],                       ibfd, in_name, out_name);
                      aeabi_enum_names[out_attr[i].i]);  
9873                  }                  }
9874              }              }
9875            break;            break;
# Line 8369  elf32_arm_merge_eabi_attributes (bfd *ib Line 9880  elf32_arm_merge_eabi_attributes (bfd *ib
9880            if (in_attr[i].i != out_attr[i].i)            if (in_attr[i].i != out_attr[i].i)
9881              {              {
9882                _bfd_error_handler                _bfd_error_handler
9883                  (_("ERROR: %B uses iWMMXt register arguments, %B does not"),                  (_("error: %B uses iWMMXt register arguments, %B does not"),
9884                   ibfd, obfd);                   ibfd, obfd);
9885                return FALSE;                result = FALSE;
9886              }              }
9887            break;            break;
9888            case Tag_compatibility:
9889              /* Merged in target-independent code.  */
9890              break;
9891            case Tag_ABI_HardFP_use:
9892              /* 1 (SP) and 2 (DP) conflict, so combine to 3 (SP & DP).  */
9893              if ((in_attr[i].i == 1 && out_attr[i].i == 2)
9894                  || (in_attr[i].i == 2 && out_attr[i].i == 1))
9895                out_attr[i].i = 3;
9896              else if (in_attr[i].i > out_attr[i].i)
9897                out_attr[i].i = in_attr[i].i;
9898              break;
9899            case Tag_ABI_FP_16bit_format:
9900              if (in_attr[i].i != 0 && out_attr[i].i != 0)
9901                {
9902                  if (in_attr[i].i != out_attr[i].i)
9903                    {
9904                      _bfd_error_handler
9905                        (_("error: fp16 format mismatch between %B and %B"),
9906                         ibfd, obfd);
9907                      result = FALSE;
9908                    }
9909                }
9910              if (in_attr[i].i != 0)
9911                out_attr[i].i = in_attr[i].i;
9912              break;
9913    
9914          default: /* All known attributes should be explicitly covered.   */          case Tag_nodefaults:
9915            abort ();            /* This tag is set if it exists, but the value is unused (and is
9916          }               typically zero).  We don't actually need to do anything here -
9917                 the merge happens automatically when the type flags are merged
9918                 below.  */
9919              break;
9920            case Tag_also_compatible_with:
9921              /* Already done in Tag_CPU_arch.  */
9922              break;
9923            case Tag_conformance:
9924              /* Keep the attribute if it matches.  Throw it away otherwise.
9925                 No attribute means no claim to conform.  */
9926              if (!in_attr[i].s || !out_attr[i].s
9927                  || strcmp (in_attr[i].s, out_attr[i].s) != 0)
9928                out_attr[i].s = NULL;
9929              break;
9930    
9931        if (in_attr[i].type && !out_attr[i].type)          default:
         switch (in_attr[i].type)  
9932            {            {
9933            case 1:              bfd *err_bfd = NULL;
             if (out_attr[i].i)  
               out_attr[i].type = 1;  
             break;  
9934    
9935            case 2:              /* The "known_obj_attributes" table does contain some undefined
9936              if (out_attr[i].s)                 attributes.  Ensure that there are unused.  */
9937                out_attr[i].type = 2;              if (out_attr[i].i != 0 || out_attr[i].s != NULL)
9938              break;                err_bfd = obfd;