Home | History | Annotate | Line # | Download | only in bfd
      1   1.1  christos /* BFD support for the ARM processor
      2  1.11  christos    Copyright (C) 1994-2024 Free Software Foundation, Inc.
      3   1.1  christos    Contributed by Richard Earnshaw (rwe (at) pegasus.esprit.ec.org)
      4   1.1  christos 
      5   1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      6   1.1  christos 
      7   1.1  christos    This program is free software; you can redistribute it and/or modify
      8   1.1  christos    it under the terms of the GNU General Public License as published by
      9   1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10   1.1  christos    (at your option) any later version.
     11   1.1  christos 
     12   1.1  christos    This program is distributed in the hope that it will be useful,
     13   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15   1.1  christos    GNU General Public License for more details.
     16   1.1  christos 
     17   1.1  christos    You should have received a copy of the GNU General Public License
     18   1.1  christos    along with this program; if not, write to the Free Software
     19   1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20   1.1  christos    MA 02110-1301, USA.  */
     21   1.1  christos 
     22   1.1  christos #include "sysdep.h"
     23   1.1  christos #include "bfd.h"
     24   1.1  christos #include "libbfd.h"
     25   1.1  christos #include "libiberty.h"
     26   1.9  christos #include "cpu-arm.h"
     27   1.1  christos 
     28   1.1  christos /* This routine is provided two arch_infos and works out which ARM
     29   1.1  christos    machine which would be compatible with both and returns a pointer
     30   1.1  christos    to its info structure.  */
     31   1.1  christos 
     32   1.1  christos static const bfd_arch_info_type *
     33   1.1  christos compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
     34   1.1  christos {
     35   1.1  christos   /* If a & b are for different architecture we can do nothing.  */
     36   1.1  christos   if (a->arch != b->arch)
     37   1.1  christos       return NULL;
     38   1.1  christos 
     39   1.1  christos   /* If a & b are for the same machine then all is well.  */
     40   1.1  christos   if (a->mach == b->mach)
     41   1.1  christos     return a;
     42   1.1  christos 
     43   1.1  christos   /* Otherwise if either a or b is the 'default' machine
     44   1.1  christos      then it can be polymorphed into the other.  */
     45   1.1  christos   if (a->the_default)
     46   1.1  christos     return b;
     47   1.1  christos 
     48   1.1  christos   if (b->the_default)
     49   1.1  christos     return a;
     50   1.1  christos 
     51   1.1  christos   /* So far all newer ARM architecture cores are
     52   1.1  christos      supersets of previous cores.  */
     53   1.1  christos   if (a->mach < b->mach)
     54   1.1  christos     return b;
     55   1.1  christos   else if (a->mach > b->mach)
     56   1.1  christos     return a;
     57   1.1  christos 
     58   1.1  christos   /* Never reached!  */
     59   1.1  christos   return NULL;
     60   1.1  christos }
     61   1.1  christos 
     62   1.1  christos static struct
     63   1.1  christos {
     64   1.1  christos   unsigned int mach;
     65   1.1  christos   char *       name;
     66   1.1  christos }
     67   1.1  christos processors[] =
     68   1.1  christos {
     69   1.8  christos   { bfd_mach_arm_2,	  "arm2"	    },
     70   1.8  christos   { bfd_mach_arm_2a,	  "arm250"	    },
     71   1.8  christos   { bfd_mach_arm_2a,	  "arm3"	    },
     72   1.8  christos   { bfd_mach_arm_3,	  "arm6"	    },
     73   1.8  christos   { bfd_mach_arm_3,	  "arm60"	    },
     74   1.8  christos   { bfd_mach_arm_3,	  "arm600"	    },
     75   1.8  christos   { bfd_mach_arm_3,	  "arm610"	    },
     76   1.8  christos   { bfd_mach_arm_3,	  "arm620"	    },
     77   1.8  christos   { bfd_mach_arm_3,	  "arm7"	    },
     78   1.8  christos   { bfd_mach_arm_3,	  "arm70"	    },
     79   1.8  christos   { bfd_mach_arm_3,	  "arm700"	    },
     80   1.8  christos   { bfd_mach_arm_3,	  "arm700i"	    },
     81   1.8  christos   { bfd_mach_arm_3,	  "arm710"	    },
     82   1.8  christos   { bfd_mach_arm_3,	  "arm7100"	    },
     83   1.8  christos   { bfd_mach_arm_3,	  "arm710c"	    },
     84   1.8  christos   { bfd_mach_arm_4T,	  "arm710t"	    },
     85   1.8  christos   { bfd_mach_arm_3,	  "arm720"	    },
     86   1.8  christos   { bfd_mach_arm_4T,	  "arm720t"	    },
     87   1.8  christos   { bfd_mach_arm_4T,	  "arm740t"	    },
     88   1.8  christos   { bfd_mach_arm_3,	  "arm7500"	    },
     89   1.8  christos   { bfd_mach_arm_3,	  "arm7500fe"	    },
     90   1.8  christos   { bfd_mach_arm_3,	  "arm7d"	    },
     91   1.8  christos   { bfd_mach_arm_3,	  "arm7di"	    },
     92   1.8  christos   { bfd_mach_arm_3M,	  "arm7dm"	    },
     93   1.8  christos   { bfd_mach_arm_3M,	  "arm7dmi"	    },
     94   1.8  christos   { bfd_mach_arm_4T,	  "arm7t"	    },
     95   1.8  christos   { bfd_mach_arm_4T,	  "arm7tdmi"	    },
     96   1.8  christos   { bfd_mach_arm_4T,	  "arm7tdmi-s"	    },
     97   1.8  christos   { bfd_mach_arm_3M,	  "arm7m"	    },
     98   1.8  christos   { bfd_mach_arm_4,	  "arm8"	    },
     99   1.8  christos   { bfd_mach_arm_4,	  "arm810"	    },
    100   1.8  christos   { bfd_mach_arm_4,	  "arm9"	    },
    101   1.8  christos   { bfd_mach_arm_4T,	  "arm920"	    },
    102   1.8  christos   { bfd_mach_arm_4T,	  "arm920t"	    },
    103   1.8  christos   { bfd_mach_arm_4T,	  "arm922t"	    },
    104   1.8  christos   { bfd_mach_arm_5TEJ,	  "arm926ej"	    },
    105   1.8  christos   { bfd_mach_arm_5TEJ,	  "arm926ejs"	    },
    106   1.8  christos   { bfd_mach_arm_5TEJ,	  "arm926ej-s"	    },
    107   1.8  christos   { bfd_mach_arm_4T,	  "arm940t"	    },
    108   1.8  christos   { bfd_mach_arm_5TE,	  "arm946e"	    },
    109   1.8  christos   { bfd_mach_arm_5TE,	  "arm946e-r0"	    },
    110   1.8  christos   { bfd_mach_arm_5TE,	  "arm946e-s"	    },
    111   1.8  christos   { bfd_mach_arm_5TE,	  "arm966e"	    },
    112   1.8  christos   { bfd_mach_arm_5TE,	  "arm966e-r0"	    },
    113   1.8  christos   { bfd_mach_arm_5TE,	  "arm966e-s"	    },
    114   1.8  christos   { bfd_mach_arm_5TE,	  "arm968e-s"	    },
    115   1.8  christos   { bfd_mach_arm_5TE,	  "arm9e"	    },
    116   1.8  christos   { bfd_mach_arm_5TE,	  "arm9e-r0"	    },
    117   1.8  christos   { bfd_mach_arm_4T,	  "arm9tdmi"	    },
    118   1.8  christos   { bfd_mach_arm_5TE,	  "arm1020"	    },
    119   1.8  christos   { bfd_mach_arm_5T,	  "arm1020t"	    },
    120   1.8  christos   { bfd_mach_arm_5TE,	  "arm1020e"	    },
    121   1.8  christos   { bfd_mach_arm_5TE,	  "arm1022e"	    },
    122   1.8  christos   { bfd_mach_arm_5TEJ,	  "arm1026ejs"	    },
    123   1.8  christos   { bfd_mach_arm_5TEJ,	  "arm1026ej-s"	    },
    124   1.8  christos   { bfd_mach_arm_5TE,	  "arm10e"	    },
    125   1.8  christos   { bfd_mach_arm_5T,	  "arm10t"	    },
    126   1.8  christos   { bfd_mach_arm_5T,	  "arm10tdmi"	    },
    127   1.8  christos   { bfd_mach_arm_6,	  "arm1136j-s"	    },
    128   1.8  christos   { bfd_mach_arm_6,	  "arm1136js"	    },
    129   1.8  christos   { bfd_mach_arm_6,	  "arm1136jf-s"	    },
    130   1.8  christos   { bfd_mach_arm_6,	  "arm1136jfs"	    },
    131   1.8  christos   { bfd_mach_arm_6KZ,	  "arm1176jz-s"	    },
    132   1.8  christos   { bfd_mach_arm_6KZ,	  "arm1176jzf-s"    },
    133   1.8  christos   { bfd_mach_arm_6T2,	  "arm1156t2-s"	    },
    134   1.8  christos   { bfd_mach_arm_6T2,	  "arm1156t2f-s"    },
    135   1.8  christos   { bfd_mach_arm_7,	  "cortex-a5"	    },
    136   1.8  christos   { bfd_mach_arm_7,	  "cortex-a7"	    },
    137   1.8  christos   { bfd_mach_arm_7,	  "cortex-a8"	    },
    138   1.8  christos   { bfd_mach_arm_7,	  "cortex-a9"	    },
    139   1.8  christos   { bfd_mach_arm_7,	  "cortex-a12"	    },
    140   1.8  christos   { bfd_mach_arm_7,	  "cortex-a15"	    },
    141   1.8  christos   { bfd_mach_arm_7,	  "cortex-a17"	    },
    142   1.8  christos   { bfd_mach_arm_8,	  "cortex-a32"	    },
    143   1.8  christos   { bfd_mach_arm_8,	  "cortex-a35"	    },
    144   1.8  christos   { bfd_mach_arm_8,	  "cortex-a53"	    },
    145   1.8  christos   { bfd_mach_arm_8,	  "cortex-a55"	    },
    146   1.8  christos   { bfd_mach_arm_8,	  "cortex-a57"	    },
    147   1.8  christos   { bfd_mach_arm_8,	  "cortex-a72"	    },
    148   1.8  christos   { bfd_mach_arm_8,	  "cortex-a73"	    },
    149   1.8  christos   { bfd_mach_arm_8,	  "cortex-a75"	    },
    150   1.8  christos   { bfd_mach_arm_8,	  "cortex-a76"	    },
    151   1.9  christos   { bfd_mach_arm_8,	  "cortex-a76ae"    },
    152   1.9  christos   { bfd_mach_arm_8,	  "cortex-a77"	    },
    153  1.10  christos   { bfd_mach_arm_8,	  "cortex-a78"	    },
    154  1.10  christos   { bfd_mach_arm_8,	  "cortex-a78ae"    },
    155  1.10  christos   { bfd_mach_arm_8,	  "cortex-a78c"     },
    156   1.8  christos   { bfd_mach_arm_6SM,	  "cortex-m0"	    },
    157   1.8  christos   { bfd_mach_arm_6SM,	  "cortex-m0plus"   },
    158   1.8  christos   { bfd_mach_arm_6SM,	  "cortex-m1"	    },
    159   1.8  christos   { bfd_mach_arm_8M_BASE, "cortex-m23"	    },
    160   1.8  christos   { bfd_mach_arm_7,	  "cortex-m3"	    },
    161   1.8  christos   { bfd_mach_arm_8M_MAIN, "cortex-m33"	    },
    162   1.9  christos   { bfd_mach_arm_8M_MAIN, "cortex-m35p"	    },
    163   1.8  christos   { bfd_mach_arm_7EM,	  "cortex-m4"	    },
    164   1.8  christos   { bfd_mach_arm_7EM,	  "cortex-m7"	    },
    165   1.8  christos   { bfd_mach_arm_7,	  "cortex-r4"	    },
    166   1.8  christos   { bfd_mach_arm_7,	  "cortex-r4f"	    },
    167   1.8  christos   { bfd_mach_arm_7,	  "cortex-r5"	    },
    168   1.8  christos   { bfd_mach_arm_8R,	  "cortex-r52"	    },
    169  1.10  christos   { bfd_mach_arm_8R,	  "cortex-r52plus"	    },
    170   1.8  christos   { bfd_mach_arm_7,	  "cortex-r7"	    },
    171   1.8  christos   { bfd_mach_arm_7,	  "cortex-r8"	    },
    172  1.10  christos   { bfd_mach_arm_8,	  "cortex-x1"	    },
    173  1.10  christos   { bfd_mach_arm_8,	  "cortex-x1c"	    },
    174   1.8  christos   { bfd_mach_arm_4T,	  "ep9312"	    },
    175   1.8  christos   { bfd_mach_arm_8,	  "exynos-m1"	    },
    176   1.8  christos   { bfd_mach_arm_4,	  "fa526"	    },
    177   1.8  christos   { bfd_mach_arm_5TE,	  "fa606te"	    },
    178   1.8  christos   { bfd_mach_arm_5TE,	  "fa616te"	    },
    179   1.8  christos   { bfd_mach_arm_4,	  "fa626"	    },
    180   1.8  christos   { bfd_mach_arm_5TE,	  "fa626te"	    },
    181   1.8  christos   { bfd_mach_arm_5TE,	  "fa726te"	    },
    182   1.8  christos   { bfd_mach_arm_5TE,	  "fmp626"	    },
    183   1.8  christos   { bfd_mach_arm_XScale,  "i80200"	    },
    184   1.8  christos   { bfd_mach_arm_7,	  "marvell-pj4"	    },
    185   1.8  christos   { bfd_mach_arm_7,	  "marvell-whitney" },
    186   1.8  christos   { bfd_mach_arm_6K,	  "mpcore"	    },
    187   1.8  christos   { bfd_mach_arm_6K,	  "mpcorenovfp"	    },
    188   1.8  christos   { bfd_mach_arm_4,	  "sa1"		    },
    189   1.8  christos   { bfd_mach_arm_4,	  "strongarm"	    },
    190   1.8  christos   { bfd_mach_arm_4,	  "strongarm1"	    },
    191   1.8  christos   { bfd_mach_arm_4,	  "strongarm110"    },
    192   1.8  christos   { bfd_mach_arm_4,	  "strongarm1100"   },
    193   1.8  christos   { bfd_mach_arm_4,	  "strongarm1110"   },
    194   1.8  christos   { bfd_mach_arm_XScale,  "xscale"	    },
    195   1.8  christos   { bfd_mach_arm_8,	  "xgene1"	    },
    196   1.8  christos   { bfd_mach_arm_8,	  "xgene2"	    },
    197  1.10  christos   { bfd_mach_arm_9,	  "cortex-a710"	    },
    198   1.8  christos   { bfd_mach_arm_iWMMXt,  "iwmmxt"	    },
    199   1.8  christos   { bfd_mach_arm_iWMMXt2, "iwmmxt2"	    },
    200   1.8  christos   { bfd_mach_arm_unknown, "arm_any"	    }
    201   1.1  christos };
    202   1.1  christos 
    203  1.10  christos static bool
    204   1.1  christos scan (const struct bfd_arch_info *info, const char *string)
    205   1.1  christos {
    206   1.1  christos   int  i;
    207   1.1  christos 
    208   1.1  christos   /* First test for an exact match.  */
    209   1.1  christos   if (strcasecmp (string, info->printable_name) == 0)
    210  1.10  christos     return true;
    211  1.10  christos 
    212  1.10  christos   /* If there is a prefix of "arm:" then skip it.  */
    213  1.10  christos   const char * colon;
    214  1.10  christos   if ((colon = strchr (string, ':')) != NULL)
    215  1.10  christos     {
    216  1.10  christos       if (strncasecmp (string, "arm", colon - string) != 0)
    217  1.10  christos 	return false;
    218  1.10  christos       string = colon + 1;
    219  1.10  christos     }
    220   1.1  christos 
    221   1.1  christos   /* Next check for a processor name instead of an Architecture name.  */
    222   1.1  christos   for (i = sizeof (processors) / sizeof (processors[0]); i--;)
    223   1.1  christos     {
    224   1.1  christos       if (strcasecmp (string, processors [i].name) == 0)
    225   1.1  christos 	break;
    226   1.1  christos     }
    227   1.1  christos 
    228   1.1  christos   if (i != -1 && info->mach == processors [i].mach)
    229  1.10  christos     return true;
    230   1.1  christos 
    231   1.1  christos   /* Finally check for the default architecture.  */
    232   1.1  christos   if (strcasecmp (string, "arm") == 0)
    233   1.1  christos     return info->the_default;
    234   1.1  christos 
    235  1.10  christos   return false;
    236   1.1  christos }
    237   1.1  christos 
    238   1.1  christos #define N(number, print, default, next)  \
    239   1.1  christos {  32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, \
    240   1.9  christos     scan, bfd_arch_default_fill, next, 0 }
    241   1.1  christos 
    242   1.1  christos static const bfd_arch_info_type arch_info_struct[] =
    243   1.1  christos {
    244  1.10  christos   N (bfd_mach_arm_2,         "armv2",          false, & arch_info_struct[1]),
    245  1.10  christos   N (bfd_mach_arm_2a,        "armv2a",         false, & arch_info_struct[2]),
    246  1.10  christos   N (bfd_mach_arm_3,         "armv3",          false, & arch_info_struct[3]),
    247  1.10  christos   N (bfd_mach_arm_3M,        "armv3m",         false, & arch_info_struct[4]),
    248  1.10  christos   N (bfd_mach_arm_4,         "armv4",          false, & arch_info_struct[5]),
    249  1.10  christos   N (bfd_mach_arm_4T,        "armv4t",         false, & arch_info_struct[6]),
    250  1.10  christos   N (bfd_mach_arm_5,         "armv5",          false, & arch_info_struct[7]),
    251  1.10  christos   N (bfd_mach_arm_5T,        "armv5t",         false, & arch_info_struct[8]),
    252  1.10  christos   N (bfd_mach_arm_5TE,       "armv5te",        false, & arch_info_struct[9]),
    253  1.10  christos   N (bfd_mach_arm_XScale,    "xscale",         false, & arch_info_struct[10]),
    254  1.11  christos   N (bfd_mach_arm_iWMMXt,    "iwmmxt",         false, & arch_info_struct[11]),
    255  1.11  christos   N (bfd_mach_arm_iWMMXt2,   "iwmmxt2",        false, & arch_info_struct[12]),
    256  1.11  christos   N (bfd_mach_arm_5TEJ,      "armv5tej",       false, & arch_info_struct[13]),
    257  1.11  christos   N (bfd_mach_arm_6,         "armv6",          false, & arch_info_struct[14]),
    258  1.11  christos   N (bfd_mach_arm_6KZ,       "armv6kz",        false, & arch_info_struct[15]),
    259  1.11  christos   N (bfd_mach_arm_6T2,       "armv6t2",        false, & arch_info_struct[16]),
    260  1.11  christos   N (bfd_mach_arm_6K,        "armv6k",         false, & arch_info_struct[17]),
    261  1.11  christos   N (bfd_mach_arm_7,         "armv7",          false, & arch_info_struct[18]),
    262  1.11  christos   N (bfd_mach_arm_6M,        "armv6-m",        false, & arch_info_struct[19]),
    263  1.11  christos   N (bfd_mach_arm_6SM,       "armv6s-m",       false, & arch_info_struct[20]),
    264  1.11  christos   N (bfd_mach_arm_7EM,       "armv7e-m",       false, & arch_info_struct[21]),
    265  1.11  christos   N (bfd_mach_arm_8,         "armv8-a",        false, & arch_info_struct[22]),
    266  1.11  christos   N (bfd_mach_arm_8R,        "armv8-r",        false, & arch_info_struct[23]),
    267  1.11  christos   N (bfd_mach_arm_8M_BASE,   "armv8-m.base",   false, & arch_info_struct[24]),
    268  1.11  christos   N (bfd_mach_arm_8M_MAIN,   "armv8-m.main",   false, & arch_info_struct[25]),
    269  1.11  christos   N (bfd_mach_arm_8_1M_MAIN, "armv8.1-m.main", false, & arch_info_struct[26]),
    270  1.11  christos   N (bfd_mach_arm_9,         "armv9-a",        false, & arch_info_struct[27]),
    271  1.10  christos   N (bfd_mach_arm_unknown,   "arm_any",        false, NULL)
    272   1.1  christos };
    273   1.1  christos 
    274   1.1  christos const bfd_arch_info_type bfd_arm_arch =
    275  1.10  christos   N (0, "arm", true, & arch_info_struct[0]);
    276   1.1  christos 
    277   1.1  christos /* Support functions used by both the COFF and ELF versions of the ARM port.  */
    278   1.1  christos 
    279   1.1  christos /* Handle the merging of the 'machine' settings of input file IBFD
    280   1.1  christos    and an output file OBFD.  These values actually represent the
    281   1.1  christos    different possible ARM architecture variants.
    282   1.1  christos    Returns TRUE if they were merged successfully or FALSE otherwise.  */
    283   1.1  christos 
    284  1.10  christos bool
    285   1.1  christos bfd_arm_merge_machines (bfd *ibfd, bfd *obfd)
    286   1.1  christos {
    287   1.1  christos   unsigned int in  = bfd_get_mach (ibfd);
    288   1.1  christos   unsigned int out = bfd_get_mach (obfd);
    289   1.1  christos 
    290   1.1  christos   /* If the output architecture is unknown, we now have a value to set.  */
    291   1.1  christos   if (out == bfd_mach_arm_unknown)
    292   1.1  christos     bfd_set_arch_mach (obfd, bfd_arch_arm, in);
    293   1.1  christos 
    294   1.1  christos   /* If the input architecture is unknown,
    295   1.1  christos      then so must be the output architecture.  */
    296   1.1  christos   else if (in == bfd_mach_arm_unknown)
    297   1.1  christos     /* FIXME: We ought to have some way to
    298   1.1  christos        override this on the command line.  */
    299   1.1  christos     bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);
    300   1.1  christos 
    301   1.1  christos   /* If they are the same then nothing needs to be done.  */
    302   1.1  christos   else if (out == in)
    303   1.1  christos     ;
    304   1.1  christos 
    305   1.1  christos   /* Otherwise the general principle that a earlier architecture can be
    306   1.1  christos      linked with a later architecture to produce a binary that will execute
    307  1.11  christos      on the later architecture.  */
    308   1.1  christos   else if (in > out)
    309   1.1  christos     bfd_set_arch_mach (obfd, bfd_arch_arm, in);
    310   1.1  christos   /* else
    311   1.1  christos      Nothing to do.  */
    312   1.1  christos 
    313  1.10  christos   return true;
    314   1.1  christos }
    315   1.1  christos 
    316   1.1  christos typedef struct
    317   1.1  christos {
    318   1.1  christos   unsigned char	namesz[4];	/* Size of entry's owner string.  */
    319   1.1  christos   unsigned char	descsz[4];	/* Size of the note descriptor.  */
    320   1.1  christos   unsigned char	type[4];	/* Interpretation of the descriptor.  */
    321   1.1  christos   char		name[1];	/* Start of the name+desc data.  */
    322   1.1  christos } arm_Note;
    323   1.1  christos 
    324  1.10  christos static bool
    325   1.1  christos arm_check_note (bfd *abfd,
    326   1.1  christos 		bfd_byte *buffer,
    327   1.1  christos 		bfd_size_type buffer_size,
    328   1.1  christos 		const char *expected_name,
    329   1.1  christos 		char **description_return)
    330   1.1  christos {
    331   1.1  christos   unsigned long namesz;
    332   1.1  christos   unsigned long descsz;
    333   1.1  christos   unsigned long type;
    334   1.8  christos   char *	descr;
    335   1.1  christos 
    336   1.1  christos   if (buffer_size < offsetof (arm_Note, name))
    337  1.10  christos     return false;
    338   1.1  christos 
    339   1.1  christos   /* We have to extract the values this way to allow for a
    340   1.1  christos      host whose endian-ness is different from the target.  */
    341   1.1  christos   namesz = bfd_get_32 (abfd, buffer);
    342   1.1  christos   descsz = bfd_get_32 (abfd, buffer + offsetof (arm_Note, descsz));
    343   1.1  christos   type   = bfd_get_32 (abfd, buffer + offsetof (arm_Note, type));
    344   1.1  christos   descr  = (char *) buffer + offsetof (arm_Note, name);
    345   1.1  christos 
    346   1.1  christos   /* Check for buffer overflow.  */
    347   1.1  christos   if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
    348  1.10  christos     return false;
    349   1.1  christos 
    350   1.1  christos   if (expected_name == NULL)
    351   1.1  christos     {
    352   1.1  christos       if (namesz != 0)
    353  1.10  christos 	return false;
    354   1.1  christos     }
    355   1.1  christos   else
    356   1.1  christos     {
    357   1.1  christos       if (namesz != ((strlen (expected_name) + 1 + 3) & ~3))
    358  1.10  christos 	return false;
    359   1.1  christos 
    360   1.1  christos       if (strcmp (descr, expected_name) != 0)
    361  1.10  christos 	return false;
    362   1.1  christos 
    363   1.1  christos       descr += (namesz + 3) & ~3;
    364   1.1  christos     }
    365   1.1  christos 
    366   1.1  christos   /* FIXME: We should probably check the type as well.  */
    367   1.1  christos   (void) type;
    368   1.1  christos 
    369   1.1  christos   if (description_return != NULL)
    370   1.1  christos     * description_return = descr;
    371   1.1  christos 
    372  1.10  christos   return true;
    373   1.1  christos }
    374   1.1  christos 
    375   1.8  christos #define NOTE_ARCH_STRING	"arch: "
    376   1.1  christos 
    377  1.10  christos bool
    378   1.1  christos bfd_arm_update_notes (bfd *abfd, const char *note_section)
    379   1.1  christos {
    380   1.8  christos   asection *	 arm_arch_section;
    381   1.8  christos   bfd_size_type	 buffer_size;
    382   1.8  christos   bfd_byte *	 buffer;
    383   1.8  christos   char *	 arch_string;
    384   1.8  christos   char *	 expected;
    385   1.1  christos 
    386   1.1  christos   /* Look for a note section.  If one is present check the architecture
    387   1.1  christos      string encoded in it, and set it to the current architecture if it is
    388   1.1  christos      different.  */
    389   1.1  christos   arm_arch_section = bfd_get_section_by_name (abfd, note_section);
    390   1.1  christos 
    391  1.11  christos   if (arm_arch_section == NULL
    392  1.11  christos       || (arm_arch_section->flags & SEC_HAS_CONTENTS) == 0)
    393  1.10  christos     return true;
    394   1.1  christos 
    395   1.1  christos   buffer_size = arm_arch_section->size;
    396   1.1  christos   if (buffer_size == 0)
    397  1.10  christos     return false;
    398   1.1  christos 
    399   1.1  christos   if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
    400   1.1  christos     goto FAIL;
    401   1.1  christos 
    402   1.1  christos   /* Parse the note.  */
    403   1.1  christos   if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
    404   1.1  christos     goto FAIL;
    405   1.1  christos 
    406   1.8  christos   /* Check the architecture in the note against the architecture of the bfd.
    407   1.8  christos      Newer architectures versions should not be added here as build attribute
    408   1.8  christos      are a better mechanism to convey ISA used.  */
    409   1.1  christos   switch (bfd_get_mach (abfd))
    410   1.1  christos     {
    411   1.1  christos     default:
    412   1.1  christos     case bfd_mach_arm_unknown: expected = "unknown"; break;
    413   1.1  christos     case bfd_mach_arm_2:       expected = "armv2"; break;
    414   1.1  christos     case bfd_mach_arm_2a:      expected = "armv2a"; break;
    415   1.1  christos     case bfd_mach_arm_3:       expected = "armv3"; break;
    416   1.1  christos     case bfd_mach_arm_3M:      expected = "armv3M"; break;
    417   1.1  christos     case bfd_mach_arm_4:       expected = "armv4"; break;
    418   1.1  christos     case bfd_mach_arm_4T:      expected = "armv4t"; break;
    419   1.1  christos     case bfd_mach_arm_5:       expected = "armv5"; break;
    420   1.1  christos     case bfd_mach_arm_5T:      expected = "armv5t"; break;
    421   1.1  christos     case bfd_mach_arm_5TE:     expected = "armv5te"; break;
    422   1.1  christos     case bfd_mach_arm_XScale:  expected = "XScale"; break;
    423   1.1  christos     case bfd_mach_arm_iWMMXt:  expected = "iWMMXt"; break;
    424   1.1  christos     case bfd_mach_arm_iWMMXt2: expected = "iWMMXt2"; break;
    425   1.1  christos     }
    426   1.1  christos 
    427   1.1  christos   if (strcmp (arch_string, expected) != 0)
    428   1.1  christos     {
    429   1.1  christos       strcpy ((char *) buffer + (offsetof (arm_Note, name)
    430   1.1  christos 				 + ((strlen (NOTE_ARCH_STRING) + 3) & ~3)),
    431   1.1  christos 	      expected);
    432   1.1  christos 
    433   1.1  christos       if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
    434   1.1  christos 				      (file_ptr) 0, buffer_size))
    435   1.1  christos 	{
    436   1.7  christos 	  _bfd_error_handler
    437   1.7  christos 	    /* xgettext: c-format */
    438   1.8  christos 	    (_("warning: unable to update contents of %s section in %pB"),
    439   1.7  christos 	     note_section, abfd);
    440   1.1  christos 	  goto FAIL;
    441   1.1  christos 	}
    442   1.1  christos     }
    443   1.1  christos 
    444   1.1  christos   free (buffer);
    445  1.10  christos   return true;
    446   1.1  christos 
    447   1.1  christos  FAIL:
    448   1.9  christos   free (buffer);
    449  1.10  christos   return false;
    450   1.1  christos }
    451   1.1  christos 
    452   1.1  christos 
    453   1.1  christos static struct
    454   1.1  christos {
    455   1.1  christos   const char * string;
    456   1.1  christos   unsigned int mach;
    457   1.1  christos }
    458   1.8  christos 
    459   1.8  christos /* Newer architectures versions should not be added here as build attribute are
    460   1.8  christos    a better mechanism to convey ISA used.  */
    461   1.1  christos architectures[] =
    462   1.1  christos {
    463   1.1  christos   { "armv2",   bfd_mach_arm_2 },
    464   1.1  christos   { "armv2a",  bfd_mach_arm_2a },
    465   1.1  christos   { "armv3",   bfd_mach_arm_3 },
    466   1.1  christos   { "armv3M",  bfd_mach_arm_3M },
    467   1.1  christos   { "armv4",   bfd_mach_arm_4 },
    468   1.1  christos   { "armv4t",  bfd_mach_arm_4T },
    469   1.1  christos   { "armv5",   bfd_mach_arm_5 },
    470   1.1  christos   { "armv5t",  bfd_mach_arm_5T },
    471   1.1  christos   { "armv5te", bfd_mach_arm_5TE },
    472   1.1  christos   { "XScale",  bfd_mach_arm_XScale },
    473  1.11  christos   /* Maverick extensions have been dropped, so treat this as Armv4T.  */
    474  1.11  christos   { "ep9312",  bfd_mach_arm_4T },
    475   1.1  christos   { "iWMMXt",  bfd_mach_arm_iWMMXt },
    476   1.6  christos   { "iWMMXt2", bfd_mach_arm_iWMMXt2 },
    477   1.6  christos   { "arm_any", bfd_mach_arm_unknown }
    478   1.1  christos };
    479   1.1  christos 
    480   1.1  christos /* Extract the machine number stored in a note section.  */
    481   1.1  christos unsigned int
    482   1.1  christos bfd_arm_get_mach_from_notes (bfd *abfd, const char *note_section)
    483   1.1  christos {
    484   1.8  christos   asection *	 arm_arch_section;
    485   1.8  christos   bfd_size_type	 buffer_size;
    486   1.8  christos   bfd_byte *	 buffer;
    487   1.8  christos   char *	 arch_string;
    488   1.8  christos   int		 i;
    489   1.1  christos 
    490   1.1  christos   /* Look for a note section.  If one is present check the architecture
    491   1.1  christos      string encoded in it, and set it to the current architecture if it is
    492   1.1  christos      different.  */
    493   1.1  christos   arm_arch_section = bfd_get_section_by_name (abfd, note_section);
    494   1.1  christos 
    495  1.11  christos   if (arm_arch_section == NULL
    496  1.11  christos       || (arm_arch_section->flags & SEC_HAS_CONTENTS) == 0)
    497   1.1  christos     return bfd_mach_arm_unknown;
    498   1.1  christos 
    499   1.1  christos   buffer_size = arm_arch_section->size;
    500   1.1  christos   if (buffer_size == 0)
    501   1.1  christos     return bfd_mach_arm_unknown;
    502   1.1  christos 
    503   1.1  christos   if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
    504   1.1  christos     goto FAIL;
    505   1.1  christos 
    506   1.1  christos   /* Parse the note.  */
    507   1.1  christos   if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
    508   1.1  christos     goto FAIL;
    509   1.1  christos 
    510   1.1  christos   /* Interpret the architecture string.  */
    511   1.1  christos   for (i = ARRAY_SIZE (architectures); i--;)
    512   1.1  christos     if (strcmp (arch_string, architectures[i].string) == 0)
    513   1.1  christos       {
    514   1.1  christos 	free (buffer);
    515   1.1  christos 	return architectures[i].mach;
    516   1.1  christos       }
    517   1.1  christos 
    518   1.1  christos  FAIL:
    519   1.9  christos   free (buffer);
    520   1.1  christos   return bfd_mach_arm_unknown;
    521   1.1  christos }
    522   1.1  christos 
    523  1.10  christos bool
    524   1.1  christos bfd_is_arm_special_symbol_name (const char * name, int type)
    525   1.1  christos {
    526   1.1  christos   /* The ARM compiler outputs several obsolete forms.  Recognize them
    527   1.1  christos      in addition to the standard $a, $t and $d.  We are somewhat loose
    528   1.1  christos      in what we accept here, since the full set is not documented.  */
    529   1.1  christos   if (!name || name[0] != '$')
    530  1.10  christos     return false;
    531   1.1  christos   if (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
    532   1.1  christos     type &= BFD_ARM_SPECIAL_SYM_TYPE_MAP;
    533   1.1  christos   else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
    534   1.1  christos     type &= BFD_ARM_SPECIAL_SYM_TYPE_TAG;
    535   1.1  christos   else if (name[1] >= 'a' && name[1] <= 'z')
    536   1.1  christos     type &= BFD_ARM_SPECIAL_SYM_TYPE_OTHER;
    537   1.1  christos   else
    538  1.10  christos     return false;
    539   1.1  christos 
    540   1.1  christos   return (type != 0 && (name[2] == 0 || name[2] == '.'));
    541   1.1  christos }
    542   1.1  christos 
    543