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