Automatic date update in version.in
[binutils-gdb.git] / bfd / cpu-arm.c
blob9298c1ddb7c7d518994d756e8bf123120c413a8f
1 /* BFD support for the ARM processor
2 Copyright (C) 1994-2024 Free Software Foundation, Inc.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libbfd.h"
25 #include "libiberty.h"
26 #include "cpu-arm.h"
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. */
32 static const bfd_arch_info_type *
33 compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
35 /* If a & b are for different architecture we can do nothing. */
36 if (a->arch != b->arch)
37 return NULL;
39 /* If a & b are for the same machine then all is well. */
40 if (a->mach == b->mach)
41 return a;
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;
48 if (b->the_default)
49 return a;
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;
58 /* Never reached! */
59 return NULL;
62 static struct
64 unsigned int mach;
65 char * name;
67 processors[] =
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_8, "cortex-x1c" },
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" },
197 { bfd_mach_arm_9, "cortex-a710" },
198 { bfd_mach_arm_iWMMXt, "iwmmxt" },
199 { bfd_mach_arm_iWMMXt2, "iwmmxt2" },
200 { bfd_mach_arm_unknown, "arm_any" }
203 static bool
204 scan (const struct bfd_arch_info *info, const char *string)
206 int i;
208 /* First test for an exact match. */
209 if (strcasecmp (string, info->printable_name) == 0)
210 return true;
212 /* If there is a prefix of "arm:" then skip it. */
213 const char * colon;
214 if ((colon = strchr (string, ':')) != NULL)
216 if (strncasecmp (string, "arm", colon - string) != 0)
217 return false;
218 string = colon + 1;
221 /* Next check for a processor name instead of an Architecture name. */
222 for (i = sizeof (processors) / sizeof (processors[0]); i--;)
224 if (strcasecmp (string, processors [i].name) == 0)
225 break;
228 if (i != -1 && info->mach == processors [i].mach)
229 return true;
231 /* Finally check for the default architecture. */
232 if (strcasecmp (string, "arm") == 0)
233 return info->the_default;
235 return false;
238 #define N(number, print, default, next) \
239 { 32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, \
240 scan, bfd_arch_default_fill, next, 0 }
242 static const bfd_arch_info_type arch_info_struct[] =
244 N (bfd_mach_arm_2, "armv2", false, & arch_info_struct[1]),
245 N (bfd_mach_arm_2a, "armv2a", false, & arch_info_struct[2]),
246 N (bfd_mach_arm_3, "armv3", false, & arch_info_struct[3]),
247 N (bfd_mach_arm_3M, "armv3m", false, & arch_info_struct[4]),
248 N (bfd_mach_arm_4, "armv4", false, & arch_info_struct[5]),
249 N (bfd_mach_arm_4T, "armv4t", false, & arch_info_struct[6]),
250 N (bfd_mach_arm_5, "armv5", false, & arch_info_struct[7]),
251 N (bfd_mach_arm_5T, "armv5t", false, & arch_info_struct[8]),
252 N (bfd_mach_arm_5TE, "armv5te", false, & arch_info_struct[9]),
253 N (bfd_mach_arm_XScale, "xscale", false, & arch_info_struct[10]),
254 N (bfd_mach_arm_iWMMXt, "iwmmxt", false, & arch_info_struct[11]),
255 N (bfd_mach_arm_iWMMXt2, "iwmmxt2", false, & arch_info_struct[12]),
256 N (bfd_mach_arm_5TEJ, "armv5tej", false, & arch_info_struct[13]),
257 N (bfd_mach_arm_6, "armv6", false, & arch_info_struct[14]),
258 N (bfd_mach_arm_6KZ, "armv6kz", false, & arch_info_struct[15]),
259 N (bfd_mach_arm_6T2, "armv6t2", false, & arch_info_struct[16]),
260 N (bfd_mach_arm_6K, "armv6k", false, & arch_info_struct[17]),
261 N (bfd_mach_arm_7, "armv7", false, & arch_info_struct[18]),
262 N (bfd_mach_arm_6M, "armv6-m", false, & arch_info_struct[19]),
263 N (bfd_mach_arm_6SM, "armv6s-m", false, & arch_info_struct[20]),
264 N (bfd_mach_arm_7EM, "armv7e-m", false, & arch_info_struct[21]),
265 N (bfd_mach_arm_8, "armv8-a", false, & arch_info_struct[22]),
266 N (bfd_mach_arm_8R, "armv8-r", false, & arch_info_struct[23]),
267 N (bfd_mach_arm_8M_BASE, "armv8-m.base", false, & arch_info_struct[24]),
268 N (bfd_mach_arm_8M_MAIN, "armv8-m.main", false, & arch_info_struct[25]),
269 N (bfd_mach_arm_8_1M_MAIN, "armv8.1-m.main", false, & arch_info_struct[26]),
270 N (bfd_mach_arm_9, "armv9-a", false, & arch_info_struct[27]),
271 N (bfd_mach_arm_unknown, "arm_any", false, NULL)
274 const bfd_arch_info_type bfd_arm_arch =
275 N (0, "arm", true, & arch_info_struct[0]);
277 /* Support functions used by both the COFF and ELF versions of the ARM port. */
279 /* Handle the merging of the 'machine' settings of input file IBFD
280 and an output file OBFD. These values actually represent the
281 different possible ARM architecture variants.
282 Returns TRUE if they were merged successfully or FALSE otherwise. */
284 bool
285 bfd_arm_merge_machines (bfd *ibfd, bfd *obfd)
287 unsigned int in = bfd_get_mach (ibfd);
288 unsigned int out = bfd_get_mach (obfd);
290 /* If the output architecture is unknown, we now have a value to set. */
291 if (out == bfd_mach_arm_unknown)
292 bfd_set_arch_mach (obfd, bfd_arch_arm, in);
294 /* If the input architecture is unknown,
295 then so must be the output architecture. */
296 else if (in == bfd_mach_arm_unknown)
297 /* FIXME: We ought to have some way to
298 override this on the command line. */
299 bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);
301 /* If they are the same then nothing needs to be done. */
302 else if (out == in)
305 /* Otherwise the general principle that a earlier architecture can be
306 linked with a later architecture to produce a binary that will execute
307 on the later architecture. */
308 else if (in > out)
309 bfd_set_arch_mach (obfd, bfd_arch_arm, in);
310 /* else
311 Nothing to do. */
313 return true;
316 typedef struct
318 unsigned char namesz[4]; /* Size of entry's owner string. */
319 unsigned char descsz[4]; /* Size of the note descriptor. */
320 unsigned char type[4]; /* Interpretation of the descriptor. */
321 char name[1]; /* Start of the name+desc data. */
322 } arm_Note;
324 static bool
325 arm_check_note (bfd *abfd,
326 bfd_byte *buffer,
327 bfd_size_type buffer_size,
328 const char *expected_name,
329 char **description_return)
331 unsigned long namesz;
332 unsigned long descsz;
333 unsigned long type;
334 char * descr;
336 if (buffer_size < offsetof (arm_Note, name))
337 return false;
339 /* We have to extract the values this way to allow for a
340 host whose endian-ness is different from the target. */
341 namesz = bfd_get_32 (abfd, buffer);
342 descsz = bfd_get_32 (abfd, buffer + offsetof (arm_Note, descsz));
343 type = bfd_get_32 (abfd, buffer + offsetof (arm_Note, type));
344 descr = (char *) buffer + offsetof (arm_Note, name);
346 /* Check for buffer overflow. */
347 if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
348 return false;
350 if (expected_name == NULL)
352 if (namesz != 0)
353 return false;
355 else
357 if (namesz != ((strlen (expected_name) + 1 + 3) & ~3))
358 return false;
360 if (strcmp (descr, expected_name) != 0)
361 return false;
363 descr += (namesz + 3) & ~3;
366 /* FIXME: We should probably check the type as well. */
367 (void) type;
369 if (description_return != NULL)
370 * description_return = descr;
372 return true;
375 #define NOTE_ARCH_STRING "arch: "
377 bool
378 bfd_arm_update_notes (bfd *abfd, const char *note_section)
380 asection * arm_arch_section;
381 bfd_size_type buffer_size;
382 bfd_byte * buffer;
383 char * arch_string;
384 char * expected;
386 /* Look for a note section. If one is present check the architecture
387 string encoded in it, and set it to the current architecture if it is
388 different. */
389 arm_arch_section = bfd_get_section_by_name (abfd, note_section);
391 if (arm_arch_section == NULL
392 || (arm_arch_section->flags & SEC_HAS_CONTENTS) == 0)
393 return true;
395 buffer_size = arm_arch_section->size;
396 if (buffer_size == 0)
397 return false;
399 if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
400 goto FAIL;
402 /* Parse the note. */
403 if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
404 goto FAIL;
406 /* Check the architecture in the note against the architecture of the bfd.
407 Newer architectures versions should not be added here as build attribute
408 are a better mechanism to convey ISA used. */
409 switch (bfd_get_mach (abfd))
411 default:
412 case bfd_mach_arm_unknown: expected = "unknown"; break;
413 case bfd_mach_arm_2: expected = "armv2"; break;
414 case bfd_mach_arm_2a: expected = "armv2a"; break;
415 case bfd_mach_arm_3: expected = "armv3"; break;
416 case bfd_mach_arm_3M: expected = "armv3M"; break;
417 case bfd_mach_arm_4: expected = "armv4"; break;
418 case bfd_mach_arm_4T: expected = "armv4t"; break;
419 case bfd_mach_arm_5: expected = "armv5"; break;
420 case bfd_mach_arm_5T: expected = "armv5t"; break;
421 case bfd_mach_arm_5TE: expected = "armv5te"; break;
422 case bfd_mach_arm_XScale: expected = "XScale"; break;
423 case bfd_mach_arm_iWMMXt: expected = "iWMMXt"; break;
424 case bfd_mach_arm_iWMMXt2: expected = "iWMMXt2"; break;
427 if (strcmp (arch_string, expected) != 0)
429 strcpy ((char *) buffer + (offsetof (arm_Note, name)
430 + ((strlen (NOTE_ARCH_STRING) + 3) & ~3)),
431 expected);
433 if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
434 (file_ptr) 0, buffer_size))
436 _bfd_error_handler
437 /* xgettext: c-format */
438 (_("warning: unable to update contents of %s section in %pB"),
439 note_section, abfd);
440 goto FAIL;
444 free (buffer);
445 return true;
447 FAIL:
448 free (buffer);
449 return false;
453 static struct
455 const char * string;
456 unsigned int mach;
459 /* Newer architectures versions should not be added here as build attribute are
460 a better mechanism to convey ISA used. */
461 architectures[] =
463 { "armv2", bfd_mach_arm_2 },
464 { "armv2a", bfd_mach_arm_2a },
465 { "armv3", bfd_mach_arm_3 },
466 { "armv3M", bfd_mach_arm_3M },
467 { "armv4", bfd_mach_arm_4 },
468 { "armv4t", bfd_mach_arm_4T },
469 { "armv5", bfd_mach_arm_5 },
470 { "armv5t", bfd_mach_arm_5T },
471 { "armv5te", bfd_mach_arm_5TE },
472 { "XScale", bfd_mach_arm_XScale },
473 /* Maverick extensions have been dropped, so treat this as Armv4T. */
474 { "ep9312", bfd_mach_arm_4T },
475 { "iWMMXt", bfd_mach_arm_iWMMXt },
476 { "iWMMXt2", bfd_mach_arm_iWMMXt2 },
477 { "arm_any", bfd_mach_arm_unknown }
480 /* Extract the machine number stored in a note section. */
481 unsigned int
482 bfd_arm_get_mach_from_notes (bfd *abfd, const char *note_section)
484 asection * arm_arch_section;
485 bfd_size_type buffer_size;
486 bfd_byte * buffer;
487 char * arch_string;
488 int i;
490 /* Look for a note section. If one is present check the architecture
491 string encoded in it, and set it to the current architecture if it is
492 different. */
493 arm_arch_section = bfd_get_section_by_name (abfd, note_section);
495 if (arm_arch_section == NULL
496 || (arm_arch_section->flags & SEC_HAS_CONTENTS) == 0)
497 return bfd_mach_arm_unknown;
499 buffer_size = arm_arch_section->size;
500 if (buffer_size == 0)
501 return bfd_mach_arm_unknown;
503 if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
504 goto FAIL;
506 /* Parse the note. */
507 if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
508 goto FAIL;
510 /* Interpret the architecture string. */
511 for (i = ARRAY_SIZE (architectures); i--;)
512 if (strcmp (arch_string, architectures[i].string) == 0)
514 free (buffer);
515 return architectures[i].mach;
518 FAIL:
519 free (buffer);
520 return bfd_mach_arm_unknown;
523 bool
524 bfd_is_arm_special_symbol_name (const char * name, int type)
526 /* The ARM compiler outputs several obsolete forms. Recognize them
527 in addition to the standard $a, $t and $d. We are somewhat loose
528 in what we accept here, since the full set is not documented. */
529 if (!name || name[0] != '$')
530 return false;
531 if (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
532 type &= BFD_ARM_SPECIAL_SYM_TYPE_MAP;
533 else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
534 type &= BFD_ARM_SPECIAL_SYM_TYPE_TAG;
535 else if (name[1] >= 'a' && name[1] <= 'z')
536 type &= BFD_ARM_SPECIAL_SYM_TYPE_OTHER;
537 else
538 return false;
540 return (type != 0 && (name[2] == 0 || name[2] == '.'));