]> Git Repo - binutils.git/blob - bfd/cpu-arm.c
Automatic date update in version.in
[binutils.git] / bfd / cpu-arm.c
1 /* BFD support for the ARM processor
2    Copyright (C) 1994-2022 Free Software Foundation, Inc.
3    Contributed by Richard Earnshaw ([email protected])
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_4T,      "ep9312"          },
174   { bfd_mach_arm_8,       "exynos-m1"       },
175   { bfd_mach_arm_4,       "fa526"           },
176   { bfd_mach_arm_5TE,     "fa606te"         },
177   { bfd_mach_arm_5TE,     "fa616te"         },
178   { bfd_mach_arm_4,       "fa626"           },
179   { bfd_mach_arm_5TE,     "fa626te"         },
180   { bfd_mach_arm_5TE,     "fa726te"         },
181   { bfd_mach_arm_5TE,     "fmp626"          },
182   { bfd_mach_arm_XScale,  "i80200"          },
183   { bfd_mach_arm_7,       "marvell-pj4"     },
184   { bfd_mach_arm_7,       "marvell-whitney" },
185   { bfd_mach_arm_6K,      "mpcore"          },
186   { bfd_mach_arm_6K,      "mpcorenovfp"     },
187   { bfd_mach_arm_4,       "sa1"             },
188   { bfd_mach_arm_4,       "strongarm"       },
189   { bfd_mach_arm_4,       "strongarm1"      },
190   { bfd_mach_arm_4,       "strongarm110"    },
191   { bfd_mach_arm_4,       "strongarm1100"   },
192   { bfd_mach_arm_4,       "strongarm1110"   },
193   { bfd_mach_arm_XScale,  "xscale"          },
194   { bfd_mach_arm_8,       "xgene1"          },
195   { bfd_mach_arm_8,       "xgene2"          },
196   { bfd_mach_arm_9,       "cortex-a710"     },
197   { bfd_mach_arm_ep9312,  "ep9312"          },
198   { bfd_mach_arm_iWMMXt,  "iwmmxt"          },
199   { bfd_mach_arm_iWMMXt2, "iwmmxt2"         },
200   { bfd_mach_arm_unknown, "arm_any"         }
201 };
202
203 static bool
204 scan (const struct bfd_arch_info *info, const char *string)
205 {
206   int  i;
207
208   /* First test for an exact match.  */
209   if (strcasecmp (string, info->printable_name) == 0)
210     return true;
211
212   /* Next check for a processor name instead of an Architecture name.  */
213   for (i = sizeof (processors) / sizeof (processors[0]); i--;)
214     {
215       if (strcasecmp (string, processors [i].name) == 0)
216         break;
217     }
218
219   if (i != -1 && info->mach == processors [i].mach)
220     return true;
221
222   /* Finally check for the default architecture.  */
223   if (strcasecmp (string, "arm") == 0)
224     return info->the_default;
225
226   return false;
227 }
228
229 #define N(number, print, default, next)  \
230 {  32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, \
231     scan, bfd_arch_default_fill, next, 0 }
232
233 static const bfd_arch_info_type arch_info_struct[] =
234 {
235   N (bfd_mach_arm_2,         "armv2",          false, & arch_info_struct[1]),
236   N (bfd_mach_arm_2a,        "armv2a",         false, & arch_info_struct[2]),
237   N (bfd_mach_arm_3,         "armv3",          false, & arch_info_struct[3]),
238   N (bfd_mach_arm_3M,        "armv3m",         false, & arch_info_struct[4]),
239   N (bfd_mach_arm_4,         "armv4",          false, & arch_info_struct[5]),
240   N (bfd_mach_arm_4T,        "armv4t",         false, & arch_info_struct[6]),
241   N (bfd_mach_arm_5,         "armv5",          false, & arch_info_struct[7]),
242   N (bfd_mach_arm_5T,        "armv5t",         false, & arch_info_struct[8]),
243   N (bfd_mach_arm_5TE,       "armv5te",        false, & arch_info_struct[9]),
244   N (bfd_mach_arm_XScale,    "xscale",         false, & arch_info_struct[10]),
245   N (bfd_mach_arm_ep9312,    "ep9312",         false, & arch_info_struct[11]),
246   N (bfd_mach_arm_iWMMXt,    "iwmmxt",         false, & arch_info_struct[12]),
247   N (bfd_mach_arm_iWMMXt2,   "iwmmxt2",        false, & arch_info_struct[13]),
248   N (bfd_mach_arm_5TEJ,      "armv5tej",       false, & arch_info_struct[14]),
249   N (bfd_mach_arm_6,         "armv6",          false, & arch_info_struct[15]),
250   N (bfd_mach_arm_6KZ,       "armv6kz",        false, & arch_info_struct[16]),
251   N (bfd_mach_arm_6T2,       "armv6t2",        false, & arch_info_struct[17]),
252   N (bfd_mach_arm_6K,        "armv6k",         false, & arch_info_struct[18]),
253   N (bfd_mach_arm_7,         "armv7",          false, & arch_info_struct[19]),
254   N (bfd_mach_arm_6M,        "armv6-m",        false, & arch_info_struct[20]),
255   N (bfd_mach_arm_6SM,       "armv6s-m",       false, & arch_info_struct[21]),
256   N (bfd_mach_arm_7EM,       "armv7e-m",       false, & arch_info_struct[22]),
257   N (bfd_mach_arm_8,         "armv8-a",        false, & arch_info_struct[23]),
258   N (bfd_mach_arm_8R,        "armv8-r",        false, & arch_info_struct[24]),
259   N (bfd_mach_arm_8M_BASE,   "armv8-m.base",   false, & arch_info_struct[25]),
260   N (bfd_mach_arm_8M_MAIN,   "armv8-m.main",   false, & arch_info_struct[26]),
261   N (bfd_mach_arm_8_1M_MAIN, "armv8.1-m.main", false, & arch_info_struct[27]),
262   N (bfd_mach_arm_9,         "armv9-a",        false, & arch_info_struct[28]),
263   N (bfd_mach_arm_unknown,   "arm_any",        false, NULL)
264 };
265
266 const bfd_arch_info_type bfd_arm_arch =
267   N (0, "arm", true, & arch_info_struct[0]);
268
269 /* Support functions used by both the COFF and ELF versions of the ARM port.  */
270
271 /* Handle the merging of the 'machine' settings of input file IBFD
272    and an output file OBFD.  These values actually represent the
273    different possible ARM architecture variants.
274    Returns TRUE if they were merged successfully or FALSE otherwise.  */
275
276 bool
277 bfd_arm_merge_machines (bfd *ibfd, bfd *obfd)
278 {
279   unsigned int in  = bfd_get_mach (ibfd);
280   unsigned int out = bfd_get_mach (obfd);
281
282   /* If the output architecture is unknown, we now have a value to set.  */
283   if (out == bfd_mach_arm_unknown)
284     bfd_set_arch_mach (obfd, bfd_arch_arm, in);
285
286   /* If the input architecture is unknown,
287      then so must be the output architecture.  */
288   else if (in == bfd_mach_arm_unknown)
289     /* FIXME: We ought to have some way to
290        override this on the command line.  */
291     bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);
292
293   /* If they are the same then nothing needs to be done.  */
294   else if (out == in)
295     ;
296
297   /* Otherwise the general principle that a earlier architecture can be
298      linked with a later architecture to produce a binary that will execute
299      on the later architecture.
300
301      We fail however if we attempt to link a Cirrus EP9312 binary with an
302      Intel XScale binary, since these architecture have co-processors which
303      will not both be present on the same physical hardware.  */
304   else if (in == bfd_mach_arm_ep9312
305            && (out == bfd_mach_arm_XScale
306                || out == bfd_mach_arm_iWMMXt
307                || out == bfd_mach_arm_iWMMXt2))
308     {
309       /* xgettext: c-format */
310       _bfd_error_handler (_("error: %pB is compiled for the EP9312, "
311                             "whereas %pB is compiled for XScale"),
312                           ibfd, obfd);
313       bfd_set_error (bfd_error_wrong_format);
314       return false;
315     }
316   else if (out == bfd_mach_arm_ep9312
317            && (in == bfd_mach_arm_XScale
318                || in == bfd_mach_arm_iWMMXt
319                || in == bfd_mach_arm_iWMMXt2))
320     {
321       /* xgettext: c-format */
322       _bfd_error_handler (_("error: %pB is compiled for the EP9312, "
323                             "whereas %pB is compiled for XScale"),
324                           obfd, ibfd);
325       bfd_set_error (bfd_error_wrong_format);
326       return false;
327     }
328   else if (in > out)
329     bfd_set_arch_mach (obfd, bfd_arch_arm, in);
330   /* else
331      Nothing to do.  */
332
333   return true;
334 }
335
336 typedef struct
337 {
338   unsigned char namesz[4];      /* Size of entry's owner string.  */
339   unsigned char descsz[4];      /* Size of the note descriptor.  */
340   unsigned char type[4];        /* Interpretation of the descriptor.  */
341   char          name[1];        /* Start of the name+desc data.  */
342 } arm_Note;
343
344 static bool
345 arm_check_note (bfd *abfd,
346                 bfd_byte *buffer,
347                 bfd_size_type buffer_size,
348                 const char *expected_name,
349                 char **description_return)
350 {
351   unsigned long namesz;
352   unsigned long descsz;
353   unsigned long type;
354   char *        descr;
355
356   if (buffer_size < offsetof (arm_Note, name))
357     return false;
358
359   /* We have to extract the values this way to allow for a
360      host whose endian-ness is different from the target.  */
361   namesz = bfd_get_32 (abfd, buffer);
362   descsz = bfd_get_32 (abfd, buffer + offsetof (arm_Note, descsz));
363   type   = bfd_get_32 (abfd, buffer + offsetof (arm_Note, type));
364   descr  = (char *) buffer + offsetof (arm_Note, name);
365
366   /* Check for buffer overflow.  */
367   if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
368     return false;
369
370   if (expected_name == NULL)
371     {
372       if (namesz != 0)
373         return false;
374     }
375   else
376     {
377       if (namesz != ((strlen (expected_name) + 1 + 3) & ~3))
378         return false;
379
380       if (strcmp (descr, expected_name) != 0)
381         return false;
382
383       descr += (namesz + 3) & ~3;
384     }
385
386   /* FIXME: We should probably check the type as well.  */
387   (void) type;
388
389   if (description_return != NULL)
390     * description_return = descr;
391
392   return true;
393 }
394
395 #define NOTE_ARCH_STRING        "arch: "
396
397 bool
398 bfd_arm_update_notes (bfd *abfd, const char *note_section)
399 {
400   asection *     arm_arch_section;
401   bfd_size_type  buffer_size;
402   bfd_byte *     buffer;
403   char *         arch_string;
404   char *         expected;
405
406   /* Look for a note section.  If one is present check the architecture
407      string encoded in it, and set it to the current architecture if it is
408      different.  */
409   arm_arch_section = bfd_get_section_by_name (abfd, note_section);
410
411   if (arm_arch_section == NULL)
412     return true;
413
414   buffer_size = arm_arch_section->size;
415   if (buffer_size == 0)
416     return false;
417
418   if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
419     goto FAIL;
420
421   /* Parse the note.  */
422   if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
423     goto FAIL;
424
425   /* Check the architecture in the note against the architecture of the bfd.
426      Newer architectures versions should not be added here as build attribute
427      are a better mechanism to convey ISA used.  */
428   switch (bfd_get_mach (abfd))
429     {
430     default:
431     case bfd_mach_arm_unknown: expected = "unknown"; break;
432     case bfd_mach_arm_2:       expected = "armv2"; break;
433     case bfd_mach_arm_2a:      expected = "armv2a"; break;
434     case bfd_mach_arm_3:       expected = "armv3"; break;
435     case bfd_mach_arm_3M:      expected = "armv3M"; break;
436     case bfd_mach_arm_4:       expected = "armv4"; break;
437     case bfd_mach_arm_4T:      expected = "armv4t"; break;
438     case bfd_mach_arm_5:       expected = "armv5"; break;
439     case bfd_mach_arm_5T:      expected = "armv5t"; break;
440     case bfd_mach_arm_5TE:     expected = "armv5te"; break;
441     case bfd_mach_arm_XScale:  expected = "XScale"; break;
442     case bfd_mach_arm_ep9312:  expected = "ep9312"; break;
443     case bfd_mach_arm_iWMMXt:  expected = "iWMMXt"; break;
444     case bfd_mach_arm_iWMMXt2: expected = "iWMMXt2"; break;
445     }
446
447   if (strcmp (arch_string, expected) != 0)
448     {
449       strcpy ((char *) buffer + (offsetof (arm_Note, name)
450                                  + ((strlen (NOTE_ARCH_STRING) + 3) & ~3)),
451               expected);
452
453       if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
454                                       (file_ptr) 0, buffer_size))
455         {
456           _bfd_error_handler
457             /* xgettext: c-format */
458             (_("warning: unable to update contents of %s section in %pB"),
459              note_section, abfd);
460           goto FAIL;
461         }
462     }
463
464   free (buffer);
465   return true;
466
467  FAIL:
468   free (buffer);
469   return false;
470 }
471
472
473 static struct
474 {
475   const char * string;
476   unsigned int mach;
477 }
478
479 /* Newer architectures versions should not be added here as build attribute are
480    a better mechanism to convey ISA used.  */
481 architectures[] =
482 {
483   { "armv2",   bfd_mach_arm_2 },
484   { "armv2a",  bfd_mach_arm_2a },
485   { "armv3",   bfd_mach_arm_3 },
486   { "armv3M",  bfd_mach_arm_3M },
487   { "armv4",   bfd_mach_arm_4 },
488   { "armv4t",  bfd_mach_arm_4T },
489   { "armv5",   bfd_mach_arm_5 },
490   { "armv5t",  bfd_mach_arm_5T },
491   { "armv5te", bfd_mach_arm_5TE },
492   { "XScale",  bfd_mach_arm_XScale },
493   { "ep9312",  bfd_mach_arm_ep9312 },
494   { "iWMMXt",  bfd_mach_arm_iWMMXt },
495   { "iWMMXt2", bfd_mach_arm_iWMMXt2 },
496   { "arm_any", bfd_mach_arm_unknown }
497 };
498
499 /* Extract the machine number stored in a note section.  */
500 unsigned int
501 bfd_arm_get_mach_from_notes (bfd *abfd, const char *note_section)
502 {
503   asection *     arm_arch_section;
504   bfd_size_type  buffer_size;
505   bfd_byte *     buffer;
506   char *         arch_string;
507   int            i;
508
509   /* Look for a note section.  If one is present check the architecture
510      string encoded in it, and set it to the current architecture if it is
511      different.  */
512   arm_arch_section = bfd_get_section_by_name (abfd, note_section);
513
514   if (arm_arch_section == NULL)
515     return bfd_mach_arm_unknown;
516
517   buffer_size = arm_arch_section->size;
518   if (buffer_size == 0)
519     return bfd_mach_arm_unknown;
520
521   if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
522     goto FAIL;
523
524   /* Parse the note.  */
525   if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
526     goto FAIL;
527
528   /* Interpret the architecture string.  */
529   for (i = ARRAY_SIZE (architectures); i--;)
530     if (strcmp (arch_string, architectures[i].string) == 0)
531       {
532         free (buffer);
533         return architectures[i].mach;
534       }
535
536  FAIL:
537   free (buffer);
538   return bfd_mach_arm_unknown;
539 }
540
541 bool
542 bfd_is_arm_special_symbol_name (const char * name, int type)
543 {
544   /* The ARM compiler outputs several obsolete forms.  Recognize them
545      in addition to the standard $a, $t and $d.  We are somewhat loose
546      in what we accept here, since the full set is not documented.  */
547   if (!name || name[0] != '$')
548     return false;
549   if (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
550     type &= BFD_ARM_SPECIAL_SYM_TYPE_MAP;
551   else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
552     type &= BFD_ARM_SPECIAL_SYM_TYPE_TAG;
553   else if (name[1] >= 'a' && name[1] <= 'z')
554     type &= BFD_ARM_SPECIAL_SYM_TYPE_OTHER;
555   else
556     return false;
557
558   return (type != 0 && (name[2] == 0 || name[2] == '.'));
559 }
560
This page took 0.060561 seconds and 4 git commands to generate.