]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/cpu-arm.c
Indent labels
[thirdparty/binutils-gdb.git] / bfd / cpu-arm.c
CommitLineData
252b5132 1/* BFD support for the ARM processor
b3adc24a 2 Copyright (C) 1994-2020 Free Software Foundation, Inc.
252b5132
RH
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4
e2fd756b 5 This file is part of BFD, the Binary File Descriptor library.
252b5132 6
e2fd756b
NC
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
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
e2fd756b 10 (at your option) any later version.
252b5132 11
e2fd756b
NC
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.
252b5132 16
e2fd756b
NC
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
cd123cb7
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
252b5132 21
252b5132 22#include "sysdep.h"
3db64b00 23#include "bfd.h"
252b5132 24#include "libbfd.h"
5a6c6817 25#include "libiberty.h"
f37164d7 26#include "cpu-arm.h"
252b5132 27
252b5132
RH
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
e2fd756b 30 to its info structure. */
252b5132
RH
31
32static const bfd_arch_info_type *
f075ee0c 33compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
252b5132 34{
e2fd756b 35 /* If a & b are for different architecture we can do nothing. */
252b5132
RH
36 if (a->arch != b->arch)
37 return NULL;
38
e2fd756b 39 /* If a & b are for the same machine then all is well. */
252b5132
RH
40 if (a->mach == b->mach)
41 return a;
42
e2fd756b
NC
43 /* Otherwise if either a or b is the 'default' machine
44 then it can be polymorphed into the other. */
252b5132
RH
45 if (a->the_default)
46 return b;
71f6b586 47
252b5132
RH
48 if (b->the_default)
49 return a;
50
e2fd756b
NC
51 /* So far all newer ARM architecture cores are
52 supersets of previous cores. */
252b5132
RH
53 if (a->mach < b->mach)
54 return b;
55 else if (a->mach > b->mach)
56 return a;
57
e2fd756b 58 /* Never reached! */
252b5132
RH
59 return NULL;
60}
61
62static struct
63{
e2fd756b
NC
64 unsigned int mach;
65 char * name;
252b5132
RH
66}
67processors[] =
68{
b5ab3163
TP
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" },
0535e5d7
DZ
151 { bfd_mach_arm_8, "cortex-a76ae" },
152 { bfd_mach_arm_8, "cortex-a77" },
b5ab3163
TP
153 { bfd_mach_arm_6SM, "cortex-m0" },
154 { bfd_mach_arm_6SM, "cortex-m0plus" },
155 { bfd_mach_arm_6SM, "cortex-m1" },
156 { bfd_mach_arm_8M_BASE, "cortex-m23" },
157 { bfd_mach_arm_7, "cortex-m3" },
158 { bfd_mach_arm_8M_MAIN, "cortex-m33" },
0535e5d7 159 { bfd_mach_arm_8M_MAIN, "cortex-m35p" },
b5ab3163
TP
160 { bfd_mach_arm_7EM, "cortex-m4" },
161 { bfd_mach_arm_7EM, "cortex-m7" },
162 { bfd_mach_arm_7, "cortex-r4" },
163 { bfd_mach_arm_7, "cortex-r4f" },
164 { bfd_mach_arm_7, "cortex-r5" },
165 { bfd_mach_arm_8R, "cortex-r52" },
166 { bfd_mach_arm_7, "cortex-r7" },
167 { bfd_mach_arm_7, "cortex-r8" },
168 { bfd_mach_arm_4T, "ep9312" },
169 { bfd_mach_arm_8, "exynos-m1" },
170 { bfd_mach_arm_4, "fa526" },
171 { bfd_mach_arm_5TE, "fa606te" },
172 { bfd_mach_arm_5TE, "fa616te" },
173 { bfd_mach_arm_4, "fa626" },
174 { bfd_mach_arm_5TE, "fa626te" },
175 { bfd_mach_arm_5TE, "fa726te" },
176 { bfd_mach_arm_5TE, "fmp626" },
177 { bfd_mach_arm_XScale, "i80200" },
178 { bfd_mach_arm_7, "marvell-pj4" },
179 { bfd_mach_arm_7, "marvell-whitney" },
180 { bfd_mach_arm_6K, "mpcore" },
181 { bfd_mach_arm_6K, "mpcorenovfp" },
182 { bfd_mach_arm_4, "sa1" },
183 { bfd_mach_arm_4, "strongarm" },
184 { bfd_mach_arm_4, "strongarm1" },
185 { bfd_mach_arm_4, "strongarm110" },
186 { bfd_mach_arm_4, "strongarm1100" },
187 { bfd_mach_arm_4, "strongarm1110" },
188 { bfd_mach_arm_XScale, "xscale" },
189 { bfd_mach_arm_8, "xgene1" },
190 { bfd_mach_arm_8, "xgene2" },
191 { bfd_mach_arm_ep9312, "ep9312" },
192 { bfd_mach_arm_iWMMXt, "iwmmxt" },
193 { bfd_mach_arm_iWMMXt2, "iwmmxt2" },
194 { bfd_mach_arm_unknown, "arm_any" }
252b5132
RH
195};
196
b34976b6 197static bfd_boolean
f075ee0c 198scan (const struct bfd_arch_info *info, const char *string)
252b5132
RH
199{
200 int i;
201
e2fd756b 202 /* First test for an exact match. */
252b5132 203 if (strcasecmp (string, info->printable_name) == 0)
b34976b6 204 return TRUE;
252b5132 205
e2fd756b 206 /* Next check for a processor name instead of an Architecture name. */
252b5132
RH
207 for (i = sizeof (processors) / sizeof (processors[0]); i--;)
208 {
e2fd756b 209 if (strcasecmp (string, processors [i].name) == 0)
252b5132
RH
210 break;
211 }
212
e2fd756b 213 if (i != -1 && info->mach == processors [i].mach)
b34976b6 214 return TRUE;
252b5132 215
e2fd756b 216 /* Finally check for the default architecture. */
252b5132
RH
217 if (strcasecmp (string, "arm") == 0)
218 return info->the_default;
71f6b586 219
b34976b6 220 return FALSE;
252b5132
RH
221}
222
252b5132 223#define N(number, print, default, next) \
b7761f11 224{ 32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, \
aebcfb76 225 scan, bfd_arch_default_fill, next, 0 }
252b5132
RH
226
227static const bfd_arch_info_type arch_info_struct[] =
71f6b586 228{
c0c468d5
TP
229 N (bfd_mach_arm_2, "armv2", FALSE, & arch_info_struct[1]),
230 N (bfd_mach_arm_2a, "armv2a", FALSE, & arch_info_struct[2]),
231 N (bfd_mach_arm_3, "armv3", FALSE, & arch_info_struct[3]),
232 N (bfd_mach_arm_3M, "armv3m", FALSE, & arch_info_struct[4]),
233 N (bfd_mach_arm_4, "armv4", FALSE, & arch_info_struct[5]),
234 N (bfd_mach_arm_4T, "armv4t", FALSE, & arch_info_struct[6]),
235 N (bfd_mach_arm_5, "armv5", FALSE, & arch_info_struct[7]),
236 N (bfd_mach_arm_5T, "armv5t", FALSE, & arch_info_struct[8]),
237 N (bfd_mach_arm_5TE, "armv5te", FALSE, & arch_info_struct[9]),
238 N (bfd_mach_arm_XScale, "xscale", FALSE, & arch_info_struct[10]),
239 N (bfd_mach_arm_ep9312, "ep9312", FALSE, & arch_info_struct[11]),
240 N (bfd_mach_arm_iWMMXt, "iwmmxt", FALSE, & arch_info_struct[12]),
241 N (bfd_mach_arm_iWMMXt2, "iwmmxt2", FALSE, & arch_info_struct[13]),
242 N (bfd_mach_arm_5TEJ, "armv5tej", FALSE, & arch_info_struct[14]),
243 N (bfd_mach_arm_6, "armv6", FALSE, & arch_info_struct[15]),
244 N (bfd_mach_arm_6KZ, "armv6kz", FALSE, & arch_info_struct[16]),
245 N (bfd_mach_arm_6T2, "armv6t2", FALSE, & arch_info_struct[17]),
246 N (bfd_mach_arm_6K, "armv6k", FALSE, & arch_info_struct[18]),
247 N (bfd_mach_arm_7, "armv7", FALSE, & arch_info_struct[19]),
248 N (bfd_mach_arm_6M, "armv6-m", FALSE, & arch_info_struct[20]),
249 N (bfd_mach_arm_6SM, "armv6s-m", FALSE, & arch_info_struct[21]),
250 N (bfd_mach_arm_7EM, "armv7e-m", FALSE, & arch_info_struct[22]),
251 N (bfd_mach_arm_8, "armv8-a", FALSE, & arch_info_struct[23]),
252 N (bfd_mach_arm_8R, "armv8-r", FALSE, & arch_info_struct[24]),
253 N (bfd_mach_arm_8M_BASE, "armv8-m.base", FALSE, & arch_info_struct[25]),
254 N (bfd_mach_arm_8M_MAIN, "armv8-m.main", FALSE, & arch_info_struct[26]),
031254f2 255 N (bfd_mach_arm_8_1M_MAIN, "armv8.1-m.main", FALSE, & arch_info_struct[27]),
c0c468d5 256 N (bfd_mach_arm_unknown, "arm_any", FALSE, NULL)
252b5132
RH
257};
258
259const bfd_arch_info_type bfd_arm_arch =
b34976b6 260 N (0, "arm", TRUE, & arch_info_struct[0]);
5a6c6817
NC
261
262/* Support functions used by both the COFF and ELF versions of the ARM port. */
263
5c4491d3 264/* Handle the merging of the 'machine' settings of input file IBFD
5a6c6817
NC
265 and an output file OBFD. These values actually represent the
266 different possible ARM architecture variants.
267 Returns TRUE if they were merged successfully or FALSE otherwise. */
268
269bfd_boolean
f075ee0c 270bfd_arm_merge_machines (bfd *ibfd, bfd *obfd)
5a6c6817
NC
271{
272 unsigned int in = bfd_get_mach (ibfd);
273 unsigned int out = bfd_get_mach (obfd);
274
275 /* If the output architecture is unknown, we now have a value to set. */
276 if (out == bfd_mach_arm_unknown)
277 bfd_set_arch_mach (obfd, bfd_arch_arm, in);
278
5c4491d3 279 /* If the input architecture is unknown,
5a6c6817
NC
280 then so must be the output architecture. */
281 else if (in == bfd_mach_arm_unknown)
282 /* FIXME: We ought to have some way to
283 override this on the command line. */
284 bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);
285
286 /* If they are the same then nothing needs to be done. */
287 else if (out == in)
288 ;
289
290 /* Otherwise the general principle that a earlier architecture can be
5c4491d3 291 linked with a later architecture to produce a binary that will execute
5a6c6817
NC
292 on the later architecture.
293
294 We fail however if we attempt to link a Cirrus EP9312 binary with an
295 Intel XScale binary, since these architecture have co-processors which
296 will not both be present on the same physical hardware. */
297 else if (in == bfd_mach_arm_ep9312
2d447fca
JM
298 && (out == bfd_mach_arm_XScale
299 || out == bfd_mach_arm_iWMMXt
300 || out == bfd_mach_arm_iWMMXt2))
5a6c6817 301 {
695344c0 302 /* xgettext: c-format */
dc1e8a47
AM
303 _bfd_error_handler (_("error: %pB is compiled for the EP9312, "
304 "whereas %pB is compiled for XScale"),
d003868e 305 ibfd, obfd);
5a6c6817
NC
306 bfd_set_error (bfd_error_wrong_format);
307 return FALSE;
308 }
309 else if (out == bfd_mach_arm_ep9312
2d447fca
JM
310 && (in == bfd_mach_arm_XScale
311 || in == bfd_mach_arm_iWMMXt
312 || in == bfd_mach_arm_iWMMXt2))
5a6c6817 313 {
695344c0 314 /* xgettext: c-format */
dc1e8a47
AM
315 _bfd_error_handler (_("error: %pB is compiled for the EP9312, "
316 "whereas %pB is compiled for XScale"),
d003868e 317 obfd, ibfd);
5a6c6817
NC
318 bfd_set_error (bfd_error_wrong_format);
319 return FALSE;
320 }
321 else if (in > out)
322 bfd_set_arch_mach (obfd, bfd_arch_arm, in);
323 /* else
324 Nothing to do. */
325
326 return TRUE;
327}
328
329typedef struct
330{
331 unsigned char namesz[4]; /* Size of entry's owner string. */
332 unsigned char descsz[4]; /* Size of the note descriptor. */
333 unsigned char type[4]; /* Interpretation of the descriptor. */
334 char name[1]; /* Start of the name+desc data. */
335} arm_Note;
336
337static bfd_boolean
f075ee0c
AM
338arm_check_note (bfd *abfd,
339 bfd_byte *buffer,
340 bfd_size_type buffer_size,
341 const char *expected_name,
342 char **description_return)
5a6c6817
NC
343{
344 unsigned long namesz;
345 unsigned long descsz;
346 unsigned long type;
07d6d2b8 347 char * descr;
5a6c6817
NC
348
349 if (buffer_size < offsetof (arm_Note, name))
350 return FALSE;
351
352 /* We have to extract the values this way to allow for a
353 host whose endian-ness is different from the target. */
354 namesz = bfd_get_32 (abfd, buffer);
355 descsz = bfd_get_32 (abfd, buffer + offsetof (arm_Note, descsz));
356 type = bfd_get_32 (abfd, buffer + offsetof (arm_Note, type));
f075ee0c 357 descr = (char *) buffer + offsetof (arm_Note, name);
5a6c6817
NC
358
359 /* Check for buffer overflow. */
360 if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
361 return FALSE;
362
363 if (expected_name == NULL)
364 {
365 if (namesz != 0)
366 return FALSE;
367 }
368 else
68ffbac6 369 {
60d8b524 370 if (namesz != ((strlen (expected_name) + 1 + 3) & ~3))
5a6c6817 371 return FALSE;
68ffbac6 372
5a6c6817
NC
373 if (strcmp (descr, expected_name) != 0)
374 return FALSE;
375
376 descr += (namesz + 3) & ~3;
377 }
378
379 /* FIXME: We should probably check the type as well. */
c7e2358a 380 (void) type;
5a6c6817
NC
381
382 if (description_return != NULL)
383 * description_return = descr;
384
385 return TRUE;
386}
387
07d6d2b8 388#define NOTE_ARCH_STRING "arch: "
5a6c6817
NC
389
390bfd_boolean
f075ee0c 391bfd_arm_update_notes (bfd *abfd, const char *note_section)
5a6c6817 392{
07d6d2b8
AM
393 asection * arm_arch_section;
394 bfd_size_type buffer_size;
395 bfd_byte * buffer;
396 char * arch_string;
397 char * expected;
5a6c6817
NC
398
399 /* Look for a note section. If one is present check the architecture
400 string encoded in it, and set it to the current architecture if it is
401 different. */
402 arm_arch_section = bfd_get_section_by_name (abfd, note_section);
403
404 if (arm_arch_section == NULL)
405 return TRUE;
406
eea6121a 407 buffer_size = arm_arch_section->size;
5a6c6817
NC
408 if (buffer_size == 0)
409 return FALSE;
410
eea6121a 411 if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
5a6c6817
NC
412 goto FAIL;
413
414 /* Parse the note. */
415 if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
416 goto FAIL;
417
b5ab3163
TP
418 /* Check the architecture in the note against the architecture of the bfd.
419 Newer architectures versions should not be added here as build attribute
420 are a better mechanism to convey ISA used. */
5a6c6817
NC
421 switch (bfd_get_mach (abfd))
422 {
423 default:
424 case bfd_mach_arm_unknown: expected = "unknown"; break;
425 case bfd_mach_arm_2: expected = "armv2"; break;
426 case bfd_mach_arm_2a: expected = "armv2a"; break;
427 case bfd_mach_arm_3: expected = "armv3"; break;
428 case bfd_mach_arm_3M: expected = "armv3M"; break;
429 case bfd_mach_arm_4: expected = "armv4"; break;
430 case bfd_mach_arm_4T: expected = "armv4t"; break;
431 case bfd_mach_arm_5: expected = "armv5"; break;
432 case bfd_mach_arm_5T: expected = "armv5t"; break;
433 case bfd_mach_arm_5TE: expected = "armv5te"; break;
434 case bfd_mach_arm_XScale: expected = "XScale"; break;
435 case bfd_mach_arm_ep9312: expected = "ep9312"; break;
436 case bfd_mach_arm_iWMMXt: expected = "iWMMXt"; break;
2d447fca 437 case bfd_mach_arm_iWMMXt2: expected = "iWMMXt2"; break;
5a6c6817
NC
438 }
439
440 if (strcmp (arch_string, expected) != 0)
441 {
f075ee0c
AM
442 strcpy ((char *) buffer + (offsetof (arm_Note, name)
443 + ((strlen (NOTE_ARCH_STRING) + 3) & ~3)),
444 expected);
5a6c6817
NC
445
446 if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
447 (file_ptr) 0, buffer_size))
448 {
4eca0228 449 _bfd_error_handler
695344c0 450 /* xgettext: c-format */
871b3ab2 451 (_("warning: unable to update contents of %s section in %pB"),
dae82561 452 note_section, abfd);
5a6c6817
NC
453 goto FAIL;
454 }
455 }
456
457 free (buffer);
458 return TRUE;
459
460 FAIL:
eea6121a
AM
461 if (buffer != NULL)
462 free (buffer);
5a6c6817
NC
463 return FALSE;
464}
465
466
467static struct
468{
469 const char * string;
470 unsigned int mach;
471}
b5ab3163
TP
472
473/* Newer architectures versions should not be added here as build attribute are
474 a better mechanism to convey ISA used. */
5a6c6817
NC
475architectures[] =
476{
477 { "armv2", bfd_mach_arm_2 },
478 { "armv2a", bfd_mach_arm_2a },
479 { "armv3", bfd_mach_arm_3 },
480 { "armv3M", bfd_mach_arm_3M },
481 { "armv4", bfd_mach_arm_4 },
482 { "armv4t", bfd_mach_arm_4T },
483 { "armv5", bfd_mach_arm_5 },
484 { "armv5t", bfd_mach_arm_5T },
485 { "armv5te", bfd_mach_arm_5TE },
486 { "XScale", bfd_mach_arm_XScale },
487 { "ep9312", bfd_mach_arm_ep9312 },
2d447fca 488 { "iWMMXt", bfd_mach_arm_iWMMXt },
99914dfd
NC
489 { "iWMMXt2", bfd_mach_arm_iWMMXt2 },
490 { "arm_any", bfd_mach_arm_unknown }
5a6c6817
NC
491};
492
493/* Extract the machine number stored in a note section. */
494unsigned int
f075ee0c 495bfd_arm_get_mach_from_notes (bfd *abfd, const char *note_section)
5a6c6817 496{
07d6d2b8
AM
497 asection * arm_arch_section;
498 bfd_size_type buffer_size;
499 bfd_byte * buffer;
500 char * arch_string;
501 int i;
5a6c6817
NC
502
503 /* Look for a note section. If one is present check the architecture
504 string encoded in it, and set it to the current architecture if it is
505 different. */
506 arm_arch_section = bfd_get_section_by_name (abfd, note_section);
507
508 if (arm_arch_section == NULL)
509 return bfd_mach_arm_unknown;
510
eea6121a 511 buffer_size = arm_arch_section->size;
5a6c6817
NC
512 if (buffer_size == 0)
513 return bfd_mach_arm_unknown;
514
eea6121a 515 if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
5a6c6817
NC
516 goto FAIL;
517
518 /* Parse the note. */
519 if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
520 goto FAIL;
521
522 /* Interpret the architecture string. */
523 for (i = ARRAY_SIZE (architectures); i--;)
524 if (strcmp (arch_string, architectures[i].string) == 0)
525 {
526 free (buffer);
527 return architectures[i].mach;
528 }
529
530 FAIL:
eea6121a
AM
531 if (buffer != NULL)
532 free (buffer);
5a6c6817
NC
533 return bfd_mach_arm_unknown;
534}
9d2da7ca
JB
535
536bfd_boolean
b0796911 537bfd_is_arm_special_symbol_name (const char * name, int type)
9d2da7ca 538{
38406048 539 /* The ARM compiler outputs several obsolete forms. Recognize them
efacb0fb
DJ
540 in addition to the standard $a, $t and $d. We are somewhat loose
541 in what we accept here, since the full set is not documented. */
b0796911
PB
542 if (!name || name[0] != '$')
543 return FALSE;
544 if (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
545 type &= BFD_ARM_SPECIAL_SYM_TYPE_MAP;
546 else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
547 type &= BFD_ARM_SPECIAL_SYM_TYPE_TAG;
548 else if (name[1] >= 'a' && name[1] <= 'z')
549 type &= BFD_ARM_SPECIAL_SYM_TYPE_OTHER;
550 else
551 return FALSE;
552
553 return (type != 0 && (name[2] == 0 || name[2] == '.'));
9d2da7ca
JB
554}
555