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