1 /* BFD support for AArch64. 2 Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc. 3 Contributed by ARM Ltd. 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; see the file COPYING3. If not, 19 see <http://www.gnu.org/licenses/>. */ 20 21 #include "sysdep.h" 22 #include "bfd.h" 23 #include "libbfd.h" 24 #include "libiberty.h" 25 26 /* This routine is provided two arch_infos and works out which Aarch64 27 machine which would be compatible with both and returns a pointer 28 to its info structure. */ 29 30 static const bfd_arch_info_type * 31 compatible (const bfd_arch_info_type * a, const bfd_arch_info_type * b) 32 { 33 /* If a & b are for different architecture we can do nothing. */ 34 if (a->arch != b->arch) 35 return NULL; 36 37 /* If a & b are for the same machine then all is well. */ 38 if (a->mach == b->mach) 39 return a; 40 41 /* Otherwise if either a or b is the 'default' machine 42 then it can be polymorphed into the other. */ 43 if (a->the_default) 44 return b; 45 46 if (b->the_default) 47 return a; 48 49 /* So far all newer cores are 50 supersets of previous cores. */ 51 if (a->mach < b->mach) 52 return b; 53 else if (a->mach > b->mach) 54 return a; 55 56 /* Never reached! */ 57 return NULL; 58 } 59 60 static struct 61 { 62 unsigned int mach; 63 char *name; 64 } 65 processors[] = 66 { 67 /* These two are example CPUs supported in GCC, once we have real 68 CPUs they will be removed. */ 69 { bfd_mach_aarch64, "example-1" }, 70 { bfd_mach_aarch64, "example-2" } 71 }; 72 73 static bfd_boolean 74 scan (const struct bfd_arch_info *info, const char *string) 75 { 76 int i; 77 78 /* First test for an exact match. */ 79 if (strcasecmp (string, info->printable_name) == 0) 80 return TRUE; 81 82 /* Next check for a processor name instead of an Architecture name. */ 83 for (i = sizeof (processors) / sizeof (processors[0]); i--;) 84 { 85 if (strcasecmp (string, processors[i].name) == 0) 86 break; 87 } 88 89 if (i != -1 && info->mach == processors[i].mach) 90 return TRUE; 91 92 /* Finally check for the default architecture. */ 93 if (strcasecmp (string, "aarch64") == 0) 94 return info->the_default; 95 96 return FALSE; 97 } 98 99 #define N(NUMBER, PRINT, DEFAULT, NEXT) \ 100 { 64, 64, 8, bfd_arch_aarch64, NUMBER, \ 101 "aarch64", PRINT, 4, DEFAULT, compatible, scan, \ 102 bfd_arch_default_fill, NEXT } 103 104 const bfd_arch_info_type bfd_aarch64_arch = 105 N (0, "aarch64", TRUE, NULL); 106 107 108 bfd_boolean 109 bfd_is_aarch64_special_symbol_name (const char *name, int type) 110 { 111 if (!name || name[0] != '$') 112 return FALSE; 113 if (name[1] == 'x' || name[1] == 'd') 114 type &= BFD_AARCH64_SPECIAL_SYM_TYPE_MAP; 115 else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p') 116 type &= BFD_AARCH64_SPECIAL_SYM_TYPE_TAG; 117 else 118 return FALSE; 119 120 return (type != 0 && (name[2] == 0 || name[2] == '.')); 121 } 122