1 /* BFD support for the ARM processor 2 Copyright (C) 1994-2026 Free Software Foundation, Inc. 3 Contributed by Richard Earnshaw (rwe (at) 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 #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_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" } 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 /* If there is a prefix of "arm:" then skip it. */ 213 const char * colon; 214 if ((colon = strchr (string, ':')) != NULL) 215 { 216 if (strncasecmp (string, "arm", colon - string) != 0) 217 return false; 218 string = colon + 1; 219 } 220 221 /* Next check for a processor name instead of an Architecture name. */ 222 for (i = sizeof (processors) / sizeof (processors[0]); i--;) 223 { 224 if (strcasecmp (string, processors [i].name) == 0) 225 break; 226 } 227 228 if (i != -1 && info->mach == processors [i].mach) 229 return true; 230 231 /* Finally check for the default architecture. */ 232 if (strcasecmp (string, "arm") == 0) 233 return info->the_default; 234 235 return false; 236 } 237 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 } 241 242 static const bfd_arch_info_type arch_info_struct[] = 243 { 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) 272 }; 273 274 const bfd_arch_info_type bfd_arm_arch = 275 N (0, "arm", true, & arch_info_struct[0]); 276 277 /* Support functions used by both the COFF and ELF versions of the ARM port. */ 278 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. */ 283 284 bool 285 bfd_arm_merge_machines (bfd *ibfd, bfd *obfd) 286 { 287 unsigned int in = bfd_get_mach (ibfd); 288 unsigned int out = bfd_get_mach (obfd); 289 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); 293 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); 300 301 /* If they are the same then nothing needs to be done. */ 302 else if (out == in) 303 ; 304 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. */ 312 313 return true; 314 } 315 316 typedef struct 317 { 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; 323 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) 330 { 331 unsigned long namesz; 332 unsigned long descsz; 333 unsigned long type; 334 char * descr; 335 336 if (buffer_size < offsetof (arm_Note, name)) 337 return false; 338 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); 345 346 /* Check for buffer overflow. */ 347 if (namesz + descsz + offsetof (arm_Note, name) > buffer_size) 348 return false; 349 350 if (expected_name == NULL) 351 { 352 if (namesz != 0) 353 return false; 354 } 355 else 356 { 357 if (namesz != ((strlen (expected_name) + 1 + 3) & ~3)) 358 return false; 359 360 if (strcmp (descr, expected_name) != 0) 361 return false; 362 363 descr += (namesz + 3) & ~3; 364 } 365 366 /* FIXME: We should probably check the type as well. */ 367 (void) type; 368 369 if (description_return != NULL) 370 * description_return = descr; 371 372 return true; 373 } 374 375 #define NOTE_ARCH_STRING "arch: " 376 377 bool 378 bfd_arm_update_notes (bfd *abfd, const char *note_section) 379 { 380 asection * arm_arch_section; 381 bfd_size_type buffer_size; 382 bfd_byte * buffer; 383 char * arch_string; 384 char * expected; 385 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); 390 391 if (arm_arch_section == NULL 392 || (arm_arch_section->flags & SEC_HAS_CONTENTS) == 0) 393 return true; 394 395 buffer_size = arm_arch_section->size; 396 if (buffer_size == 0) 397 return false; 398 399 if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer)) 400 goto FAIL; 401 402 /* Parse the note. */ 403 if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string)) 404 goto FAIL; 405 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)) 410 { 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; 425 } 426 427 if (strcmp (arch_string, expected) != 0) 428 { 429 strcpy ((char *) buffer + (offsetof (arm_Note, name) 430 + ((strlen (NOTE_ARCH_STRING) + 3) & ~3)), 431 expected); 432 433 if (! bfd_set_section_contents (abfd, arm_arch_section, buffer, 434 (file_ptr) 0, buffer_size)) 435 { 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; 441 } 442 } 443 444 free (buffer); 445 return true; 446 447 FAIL: 448 free (buffer); 449 return false; 450 } 451 452 453 static struct 454 { 455 const char * string; 456 unsigned int mach; 457 } 458 459 /* Newer architectures versions should not be added here as build attribute are 460 a better mechanism to convey ISA used. */ 461 architectures[] = 462 { 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 } 478 }; 479 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) 483 { 484 asection * arm_arch_section; 485 bfd_size_type buffer_size; 486 bfd_byte * buffer; 487 char * arch_string; 488 int i; 489 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); 494 495 if (arm_arch_section == NULL 496 || (arm_arch_section->flags & SEC_HAS_CONTENTS) == 0) 497 return bfd_mach_arm_unknown; 498 499 buffer_size = arm_arch_section->size; 500 if (buffer_size == 0) 501 return bfd_mach_arm_unknown; 502 503 if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer)) 504 goto FAIL; 505 506 /* Parse the note. */ 507 if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string)) 508 goto FAIL; 509 510 /* Interpret the architecture string. */ 511 for (i = ARRAY_SIZE (architectures); i--;) 512 if (strcmp (arch_string, architectures[i].string) == 0) 513 { 514 free (buffer); 515 return architectures[i].mach; 516 } 517 518 FAIL: 519 free (buffer); 520 return bfd_mach_arm_unknown; 521 } 522 523 bool 524 bfd_is_arm_special_symbol_name (const char * name, int type) 525 { 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; 539 540 return (type != 0 && (name[2] == 0 || name[2] == '.')); 541 } 542 543