Home | History | Annotate | Line # | Download | only in bfd
cpu-arm.c revision 1.1
      1  1.1  christos /* BFD support for the ARM processor
      2  1.1  christos    Copyright 1994, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
      3  1.1  christos    2009, 2010 Free Software Foundation, Inc.
      4  1.1  christos    Contributed by Richard Earnshaw (rwe (at) pegasus.esprit.ec.org)
      5  1.1  christos 
      6  1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      7  1.1  christos 
      8  1.1  christos    This program is free software; you can redistribute it and/or modify
      9  1.1  christos    it under the terms of the GNU General Public License as published by
     10  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     11  1.1  christos    (at your option) any later version.
     12  1.1  christos 
     13  1.1  christos    This program is distributed in the hope that it will be useful,
     14  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  christos    GNU General Public License for more details.
     17  1.1  christos 
     18  1.1  christos    You should have received a copy of the GNU General Public License
     19  1.1  christos    along with this program; if not, write to the Free Software
     20  1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21  1.1  christos    MA 02110-1301, USA.  */
     22  1.1  christos 
     23  1.1  christos #include "sysdep.h"
     24  1.1  christos #include "bfd.h"
     25  1.1  christos #include "libbfd.h"
     26  1.1  christos #include "libiberty.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.1  christos   { bfd_mach_arm_2,  "arm2"     },
     70  1.1  christos   { bfd_mach_arm_2a, "arm250"   },
     71  1.1  christos   { bfd_mach_arm_2a, "arm3"     },
     72  1.1  christos   { bfd_mach_arm_3,  "arm6"     },
     73  1.1  christos   { bfd_mach_arm_3,  "arm60"    },
     74  1.1  christos   { bfd_mach_arm_3,  "arm600"   },
     75  1.1  christos   { bfd_mach_arm_3,  "arm610"   },
     76  1.1  christos   { bfd_mach_arm_3,  "arm7"     },
     77  1.1  christos   { bfd_mach_arm_3,  "arm710"   },
     78  1.1  christos   { bfd_mach_arm_3,  "arm7500"  },
     79  1.1  christos   { bfd_mach_arm_3,  "arm7d"    },
     80  1.1  christos   { bfd_mach_arm_3,  "arm7di"   },
     81  1.1  christos   { bfd_mach_arm_3M, "arm7dm"   },
     82  1.1  christos   { bfd_mach_arm_3M, "arm7dmi"  },
     83  1.1  christos   { bfd_mach_arm_4T, "arm7tdmi" },
     84  1.1  christos   { bfd_mach_arm_4,  "arm8"     },
     85  1.1  christos   { bfd_mach_arm_4,  "arm810"   },
     86  1.1  christos   { bfd_mach_arm_4,  "arm9"     },
     87  1.1  christos   { bfd_mach_arm_4,  "arm920"   },
     88  1.1  christos   { bfd_mach_arm_4T, "arm920t"  },
     89  1.1  christos   { bfd_mach_arm_4T, "arm9tdmi" },
     90  1.1  christos   { bfd_mach_arm_4,  "sa1"      },
     91  1.1  christos   { bfd_mach_arm_4,  "strongarm"},
     92  1.1  christos   { bfd_mach_arm_4,  "strongarm110" },
     93  1.1  christos   { bfd_mach_arm_4,  "strongarm1100" },
     94  1.1  christos   { bfd_mach_arm_XScale, "xscale" },
     95  1.1  christos   { bfd_mach_arm_ep9312, "ep9312" },
     96  1.1  christos   { bfd_mach_arm_iWMMXt, "iwmmxt" },
     97  1.1  christos   { bfd_mach_arm_iWMMXt2, "iwmmxt2" }
     98  1.1  christos };
     99  1.1  christos 
    100  1.1  christos static bfd_boolean
    101  1.1  christos scan (const struct bfd_arch_info *info, const char *string)
    102  1.1  christos {
    103  1.1  christos   int  i;
    104  1.1  christos 
    105  1.1  christos   /* First test for an exact match.  */
    106  1.1  christos   if (strcasecmp (string, info->printable_name) == 0)
    107  1.1  christos     return TRUE;
    108  1.1  christos 
    109  1.1  christos   /* Next check for a processor name instead of an Architecture name.  */
    110  1.1  christos   for (i = sizeof (processors) / sizeof (processors[0]); i--;)
    111  1.1  christos     {
    112  1.1  christos       if (strcasecmp (string, processors [i].name) == 0)
    113  1.1  christos 	break;
    114  1.1  christos     }
    115  1.1  christos 
    116  1.1  christos   if (i != -1 && info->mach == processors [i].mach)
    117  1.1  christos     return TRUE;
    118  1.1  christos 
    119  1.1  christos   /* Finally check for the default architecture.  */
    120  1.1  christos   if (strcasecmp (string, "arm") == 0)
    121  1.1  christos     return info->the_default;
    122  1.1  christos 
    123  1.1  christos   return FALSE;
    124  1.1  christos }
    125  1.1  christos 
    126  1.1  christos #define N(number, print, default, next)  \
    127  1.1  christos {  32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, \
    128  1.1  christos    scan, bfd_arch_default_fill, next }
    129  1.1  christos 
    130  1.1  christos static const bfd_arch_info_type arch_info_struct[] =
    131  1.1  christos {
    132  1.1  christos   N (bfd_mach_arm_2,      "armv2",   FALSE, & arch_info_struct[1]),
    133  1.1  christos   N (bfd_mach_arm_2a,     "armv2a",  FALSE, & arch_info_struct[2]),
    134  1.1  christos   N (bfd_mach_arm_3,      "armv3",   FALSE, & arch_info_struct[3]),
    135  1.1  christos   N (bfd_mach_arm_3M,     "armv3m",  FALSE, & arch_info_struct[4]),
    136  1.1  christos   N (bfd_mach_arm_4,      "armv4",   FALSE, & arch_info_struct[5]),
    137  1.1  christos   N (bfd_mach_arm_4T,     "armv4t",  FALSE, & arch_info_struct[6]),
    138  1.1  christos   N (bfd_mach_arm_5,      "armv5",   FALSE, & arch_info_struct[7]),
    139  1.1  christos   N (bfd_mach_arm_5T,     "armv5t",  FALSE, & arch_info_struct[8]),
    140  1.1  christos   N (bfd_mach_arm_5TE,    "armv5te", FALSE, & arch_info_struct[9]),
    141  1.1  christos   N (bfd_mach_arm_XScale, "xscale",  FALSE, & arch_info_struct[10]),
    142  1.1  christos   N (bfd_mach_arm_ep9312, "ep9312",  FALSE, & arch_info_struct[11]),
    143  1.1  christos   N (bfd_mach_arm_iWMMXt, "iwmmxt",  FALSE, & arch_info_struct[12]),
    144  1.1  christos   N (bfd_mach_arm_iWMMXt2, "iwmmxt2", FALSE, NULL)
    145  1.1  christos };
    146  1.1  christos 
    147  1.1  christos const bfd_arch_info_type bfd_arm_arch =
    148  1.1  christos   N (0, "arm", TRUE, & arch_info_struct[0]);
    149  1.1  christos 
    150  1.1  christos /* Support functions used by both the COFF and ELF versions of the ARM port.  */
    151  1.1  christos 
    152  1.1  christos /* Handle the merging of the 'machine' settings of input file IBFD
    153  1.1  christos    and an output file OBFD.  These values actually represent the
    154  1.1  christos    different possible ARM architecture variants.
    155  1.1  christos    Returns TRUE if they were merged successfully or FALSE otherwise.  */
    156  1.1  christos 
    157  1.1  christos bfd_boolean
    158  1.1  christos bfd_arm_merge_machines (bfd *ibfd, bfd *obfd)
    159  1.1  christos {
    160  1.1  christos   unsigned int in  = bfd_get_mach (ibfd);
    161  1.1  christos   unsigned int out = bfd_get_mach (obfd);
    162  1.1  christos 
    163  1.1  christos   /* If the output architecture is unknown, we now have a value to set.  */
    164  1.1  christos   if (out == bfd_mach_arm_unknown)
    165  1.1  christos     bfd_set_arch_mach (obfd, bfd_arch_arm, in);
    166  1.1  christos 
    167  1.1  christos   /* If the input architecture is unknown,
    168  1.1  christos      then so must be the output architecture.  */
    169  1.1  christos   else if (in == bfd_mach_arm_unknown)
    170  1.1  christos     /* FIXME: We ought to have some way to
    171  1.1  christos        override this on the command line.  */
    172  1.1  christos     bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);
    173  1.1  christos 
    174  1.1  christos   /* If they are the same then nothing needs to be done.  */
    175  1.1  christos   else if (out == in)
    176  1.1  christos     ;
    177  1.1  christos 
    178  1.1  christos   /* Otherwise the general principle that a earlier architecture can be
    179  1.1  christos      linked with a later architecture to produce a binary that will execute
    180  1.1  christos      on the later architecture.
    181  1.1  christos 
    182  1.1  christos      We fail however if we attempt to link a Cirrus EP9312 binary with an
    183  1.1  christos      Intel XScale binary, since these architecture have co-processors which
    184  1.1  christos      will not both be present on the same physical hardware.  */
    185  1.1  christos   else if (in == bfd_mach_arm_ep9312
    186  1.1  christos 	   && (out == bfd_mach_arm_XScale
    187  1.1  christos 	       || out == bfd_mach_arm_iWMMXt
    188  1.1  christos 	       || out == bfd_mach_arm_iWMMXt2))
    189  1.1  christos     {
    190  1.1  christos       _bfd_error_handler (_("\
    191  1.1  christos error: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
    192  1.1  christos 			  ibfd, obfd);
    193  1.1  christos       bfd_set_error (bfd_error_wrong_format);
    194  1.1  christos       return FALSE;
    195  1.1  christos     }
    196  1.1  christos   else if (out == bfd_mach_arm_ep9312
    197  1.1  christos 	   && (in == bfd_mach_arm_XScale
    198  1.1  christos 	       || in == bfd_mach_arm_iWMMXt
    199  1.1  christos 	       || in == bfd_mach_arm_iWMMXt2))
    200  1.1  christos     {
    201  1.1  christos       _bfd_error_handler (_("\
    202  1.1  christos error: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
    203  1.1  christos 			  obfd, ibfd);
    204  1.1  christos       bfd_set_error (bfd_error_wrong_format);
    205  1.1  christos       return FALSE;
    206  1.1  christos     }
    207  1.1  christos   else if (in > out)
    208  1.1  christos     bfd_set_arch_mach (obfd, bfd_arch_arm, in);
    209  1.1  christos   /* else
    210  1.1  christos      Nothing to do.  */
    211  1.1  christos 
    212  1.1  christos   return TRUE;
    213  1.1  christos }
    214  1.1  christos 
    215  1.1  christos typedef struct
    216  1.1  christos {
    217  1.1  christos   unsigned char	namesz[4];	/* Size of entry's owner string.  */
    218  1.1  christos   unsigned char	descsz[4];	/* Size of the note descriptor.  */
    219  1.1  christos   unsigned char	type[4];	/* Interpretation of the descriptor.  */
    220  1.1  christos   char		name[1];	/* Start of the name+desc data.  */
    221  1.1  christos } arm_Note;
    222  1.1  christos 
    223  1.1  christos static bfd_boolean
    224  1.1  christos arm_check_note (bfd *abfd,
    225  1.1  christos 		bfd_byte *buffer,
    226  1.1  christos 		bfd_size_type buffer_size,
    227  1.1  christos 		const char *expected_name,
    228  1.1  christos 		char **description_return)
    229  1.1  christos {
    230  1.1  christos   unsigned long namesz;
    231  1.1  christos   unsigned long descsz;
    232  1.1  christos   unsigned long type;
    233  1.1  christos   char *        descr;
    234  1.1  christos 
    235  1.1  christos   if (buffer_size < offsetof (arm_Note, name))
    236  1.1  christos     return FALSE;
    237  1.1  christos 
    238  1.1  christos   /* We have to extract the values this way to allow for a
    239  1.1  christos      host whose endian-ness is different from the target.  */
    240  1.1  christos   namesz = bfd_get_32 (abfd, buffer);
    241  1.1  christos   descsz = bfd_get_32 (abfd, buffer + offsetof (arm_Note, descsz));
    242  1.1  christos   type   = bfd_get_32 (abfd, buffer + offsetof (arm_Note, type));
    243  1.1  christos   descr  = (char *) buffer + offsetof (arm_Note, name);
    244  1.1  christos 
    245  1.1  christos   /* Check for buffer overflow.  */
    246  1.1  christos   if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
    247  1.1  christos     return FALSE;
    248  1.1  christos 
    249  1.1  christos   if (expected_name == NULL)
    250  1.1  christos     {
    251  1.1  christos       if (namesz != 0)
    252  1.1  christos 	return FALSE;
    253  1.1  christos     }
    254  1.1  christos   else
    255  1.1  christos     {
    256  1.1  christos       if (namesz != ((strlen (expected_name) + 1 + 3) & ~3))
    257  1.1  christos 	return FALSE;
    258  1.1  christos 
    259  1.1  christos       if (strcmp (descr, expected_name) != 0)
    260  1.1  christos 	return FALSE;
    261  1.1  christos 
    262  1.1  christos       descr += (namesz + 3) & ~3;
    263  1.1  christos     }
    264  1.1  christos 
    265  1.1  christos   /* FIXME: We should probably check the type as well.  */
    266  1.1  christos   (void) type;
    267  1.1  christos 
    268  1.1  christos   if (description_return != NULL)
    269  1.1  christos     * description_return = descr;
    270  1.1  christos 
    271  1.1  christos   return TRUE;
    272  1.1  christos }
    273  1.1  christos 
    274  1.1  christos #define NOTE_ARCH_STRING 	"arch: "
    275  1.1  christos 
    276  1.1  christos bfd_boolean
    277  1.1  christos bfd_arm_update_notes (bfd *abfd, const char *note_section)
    278  1.1  christos {
    279  1.1  christos   asection *     arm_arch_section;
    280  1.1  christos   bfd_size_type  buffer_size;
    281  1.1  christos   bfd_byte *     buffer;
    282  1.1  christos   char *         arch_string;
    283  1.1  christos   char *         expected;
    284  1.1  christos 
    285  1.1  christos   /* Look for a note section.  If one is present check the architecture
    286  1.1  christos      string encoded in it, and set it to the current architecture if it is
    287  1.1  christos      different.  */
    288  1.1  christos   arm_arch_section = bfd_get_section_by_name (abfd, note_section);
    289  1.1  christos 
    290  1.1  christos   if (arm_arch_section == NULL)
    291  1.1  christos     return TRUE;
    292  1.1  christos 
    293  1.1  christos   buffer_size = arm_arch_section->size;
    294  1.1  christos   if (buffer_size == 0)
    295  1.1  christos     return FALSE;
    296  1.1  christos 
    297  1.1  christos   if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
    298  1.1  christos     goto FAIL;
    299  1.1  christos 
    300  1.1  christos   /* Parse the note.  */
    301  1.1  christos   if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
    302  1.1  christos     goto FAIL;
    303  1.1  christos 
    304  1.1  christos   /* Check the architecture in the note against the architecture of the bfd.  */
    305  1.1  christos   switch (bfd_get_mach (abfd))
    306  1.1  christos     {
    307  1.1  christos     default:
    308  1.1  christos     case bfd_mach_arm_unknown: expected = "unknown"; break;
    309  1.1  christos     case bfd_mach_arm_2:       expected = "armv2"; break;
    310  1.1  christos     case bfd_mach_arm_2a:      expected = "armv2a"; break;
    311  1.1  christos     case bfd_mach_arm_3:       expected = "armv3"; break;
    312  1.1  christos     case bfd_mach_arm_3M:      expected = "armv3M"; break;
    313  1.1  christos     case bfd_mach_arm_4:       expected = "armv4"; break;
    314  1.1  christos     case bfd_mach_arm_4T:      expected = "armv4t"; break;
    315  1.1  christos     case bfd_mach_arm_5:       expected = "armv5"; break;
    316  1.1  christos     case bfd_mach_arm_5T:      expected = "armv5t"; break;
    317  1.1  christos     case bfd_mach_arm_5TE:     expected = "armv5te"; break;
    318  1.1  christos     case bfd_mach_arm_XScale:  expected = "XScale"; break;
    319  1.1  christos     case bfd_mach_arm_ep9312:  expected = "ep9312"; break;
    320  1.1  christos     case bfd_mach_arm_iWMMXt:  expected = "iWMMXt"; break;
    321  1.1  christos     case bfd_mach_arm_iWMMXt2: expected = "iWMMXt2"; break;
    322  1.1  christos     }
    323  1.1  christos 
    324  1.1  christos   if (strcmp (arch_string, expected) != 0)
    325  1.1  christos     {
    326  1.1  christos       strcpy ((char *) buffer + (offsetof (arm_Note, name)
    327  1.1  christos 				 + ((strlen (NOTE_ARCH_STRING) + 3) & ~3)),
    328  1.1  christos 	      expected);
    329  1.1  christos 
    330  1.1  christos       if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
    331  1.1  christos 				      (file_ptr) 0, buffer_size))
    332  1.1  christos 	{
    333  1.1  christos 	  (*_bfd_error_handler)
    334  1.1  christos 	    (_("warning: unable to update contents of %s section in %s"),
    335  1.1  christos 	     note_section, bfd_get_filename (abfd));
    336  1.1  christos 	  goto FAIL;
    337  1.1  christos 	}
    338  1.1  christos     }
    339  1.1  christos 
    340  1.1  christos   free (buffer);
    341  1.1  christos   return TRUE;
    342  1.1  christos 
    343  1.1  christos  FAIL:
    344  1.1  christos   if (buffer != NULL)
    345  1.1  christos     free (buffer);
    346  1.1  christos   return FALSE;
    347  1.1  christos }
    348  1.1  christos 
    349  1.1  christos 
    350  1.1  christos static struct
    351  1.1  christos {
    352  1.1  christos   const char * string;
    353  1.1  christos   unsigned int mach;
    354  1.1  christos }
    355  1.1  christos architectures[] =
    356  1.1  christos {
    357  1.1  christos   { "armv2",   bfd_mach_arm_2 },
    358  1.1  christos   { "armv2a",  bfd_mach_arm_2a },
    359  1.1  christos   { "armv3",   bfd_mach_arm_3 },
    360  1.1  christos   { "armv3M",  bfd_mach_arm_3M },
    361  1.1  christos   { "armv4",   bfd_mach_arm_4 },
    362  1.1  christos   { "armv4t",  bfd_mach_arm_4T },
    363  1.1  christos   { "armv5",   bfd_mach_arm_5 },
    364  1.1  christos   { "armv5t",  bfd_mach_arm_5T },
    365  1.1  christos   { "armv5te", bfd_mach_arm_5TE },
    366  1.1  christos   { "XScale",  bfd_mach_arm_XScale },
    367  1.1  christos   { "ep9312",  bfd_mach_arm_ep9312 },
    368  1.1  christos   { "iWMMXt",  bfd_mach_arm_iWMMXt },
    369  1.1  christos   { "iWMMXt2", bfd_mach_arm_iWMMXt2 }
    370  1.1  christos };
    371  1.1  christos 
    372  1.1  christos /* Extract the machine number stored in a note section.  */
    373  1.1  christos unsigned int
    374  1.1  christos bfd_arm_get_mach_from_notes (bfd *abfd, const char *note_section)
    375  1.1  christos {
    376  1.1  christos   asection *     arm_arch_section;
    377  1.1  christos   bfd_size_type  buffer_size;
    378  1.1  christos   bfd_byte *     buffer;
    379  1.1  christos   char *         arch_string;
    380  1.1  christos   int            i;
    381  1.1  christos 
    382  1.1  christos   /* Look for a note section.  If one is present check the architecture
    383  1.1  christos      string encoded in it, and set it to the current architecture if it is
    384  1.1  christos      different.  */
    385  1.1  christos   arm_arch_section = bfd_get_section_by_name (abfd, note_section);
    386  1.1  christos 
    387  1.1  christos   if (arm_arch_section == NULL)
    388  1.1  christos     return bfd_mach_arm_unknown;
    389  1.1  christos 
    390  1.1  christos   buffer_size = arm_arch_section->size;
    391  1.1  christos   if (buffer_size == 0)
    392  1.1  christos     return bfd_mach_arm_unknown;
    393  1.1  christos 
    394  1.1  christos   if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
    395  1.1  christos     goto FAIL;
    396  1.1  christos 
    397  1.1  christos   /* Parse the note.  */
    398  1.1  christos   if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
    399  1.1  christos     goto FAIL;
    400  1.1  christos 
    401  1.1  christos   /* Interpret the architecture string.  */
    402  1.1  christos   for (i = ARRAY_SIZE (architectures); i--;)
    403  1.1  christos     if (strcmp (arch_string, architectures[i].string) == 0)
    404  1.1  christos       {
    405  1.1  christos 	free (buffer);
    406  1.1  christos 	return architectures[i].mach;
    407  1.1  christos       }
    408  1.1  christos 
    409  1.1  christos  FAIL:
    410  1.1  christos   if (buffer != NULL)
    411  1.1  christos     free (buffer);
    412  1.1  christos   return bfd_mach_arm_unknown;
    413  1.1  christos }
    414  1.1  christos 
    415  1.1  christos bfd_boolean
    416  1.1  christos bfd_is_arm_special_symbol_name (const char * name, int type)
    417  1.1  christos {
    418  1.1  christos   /* The ARM compiler outputs several obsolete forms.  Recognize them
    419  1.1  christos      in addition to the standard $a, $t and $d.  We are somewhat loose
    420  1.1  christos      in what we accept here, since the full set is not documented.  */
    421  1.1  christos   if (!name || name[0] != '$')
    422  1.1  christos     return FALSE;
    423  1.1  christos   if (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
    424  1.1  christos     type &= BFD_ARM_SPECIAL_SYM_TYPE_MAP;
    425  1.1  christos   else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
    426  1.1  christos     type &= BFD_ARM_SPECIAL_SYM_TYPE_TAG;
    427  1.1  christos   else if (name[1] >= 'a' && name[1] <= 'z')
    428  1.1  christos     type &= BFD_ARM_SPECIAL_SYM_TYPE_OTHER;
    429  1.1  christos   else
    430  1.1  christos     return FALSE;
    431  1.1  christos 
    432  1.1  christos   return (type != 0 && (name[2] == 0 || name[2] == '.'));
    433  1.1  christos }
    434  1.1  christos 
    435