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