cpu-aarch64.c revision 1.10 1 1.1 christos /* BFD support for AArch64.
2 1.10 christos Copyright (C) 2009-2022 Free Software Foundation, Inc.
3 1.1 christos Contributed by ARM Ltd.
4 1.1 christos
5 1.1 christos This file is part of BFD, the Binary File Descriptor library.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; see the file COPYING3. If not,
19 1.1 christos see <http://www.gnu.org/licenses/>. */
20 1.1 christos
21 1.1 christos #include "sysdep.h"
22 1.1 christos #include "bfd.h"
23 1.1 christos #include "libbfd.h"
24 1.1 christos #include "libiberty.h"
25 1.9 christos #include "cpu-aarch64.h"
26 1.1 christos
27 1.1 christos /* This routine is provided two arch_infos and works out which Aarch64
28 1.1 christos machine which would be compatible with both and returns a pointer
29 1.1 christos to its info structure. */
30 1.1 christos
31 1.1 christos static const bfd_arch_info_type *
32 1.1 christos compatible (const bfd_arch_info_type * a, const bfd_arch_info_type * b)
33 1.1 christos {
34 1.1 christos /* If a & b are for different architecture we can do nothing. */
35 1.1 christos if (a->arch != b->arch)
36 1.1 christos return NULL;
37 1.1 christos
38 1.1 christos /* If a & b are for the same machine then all is well. */
39 1.1 christos if (a->mach == b->mach)
40 1.1 christos return a;
41 1.1 christos
42 1.10 christos /* Don't allow mixing data models. */
43 1.10 christos if ((a->mach ^ b->mach) & (bfd_mach_aarch64_ilp32 | bfd_mach_aarch64_llp64))
44 1.1 christos return NULL;
45 1.1 christos
46 1.1 christos /* Otherwise if either a or b is the 'default' machine
47 1.1 christos then it can be polymorphed into the other. */
48 1.1 christos if (a->the_default)
49 1.1 christos return b;
50 1.1 christos
51 1.1 christos if (b->the_default)
52 1.1 christos return a;
53 1.1 christos
54 1.1 christos /* So far all newer cores are
55 1.1 christos supersets of previous cores. */
56 1.1 christos if (a->mach < b->mach)
57 1.1 christos return b;
58 1.1 christos else if (a->mach > b->mach)
59 1.1 christos return a;
60 1.1 christos
61 1.1 christos /* Never reached! */
62 1.1 christos return NULL;
63 1.1 christos }
64 1.1 christos
65 1.1 christos static struct
66 1.1 christos {
67 1.1 christos unsigned int mach;
68 1.1 christos char *name;
69 1.1 christos }
70 1.1 christos processors[] =
71 1.1 christos {
72 1.9 christos { bfd_mach_aarch64, "cortex-a34" },
73 1.9 christos { bfd_mach_aarch64, "cortex-a65" },
74 1.9 christos { bfd_mach_aarch64, "cortex-a65ae" },
75 1.9 christos { bfd_mach_aarch64, "cortex-a76ae" },
76 1.9 christos { bfd_mach_aarch64, "cortex-a77" }
77 1.1 christos };
78 1.1 christos
79 1.10 christos static bool
80 1.1 christos scan (const struct bfd_arch_info *info, const char *string)
81 1.1 christos {
82 1.1 christos int i;
83 1.1 christos
84 1.1 christos /* First test for an exact match. */
85 1.1 christos if (strcasecmp (string, info->printable_name) == 0)
86 1.10 christos return true;
87 1.10 christos
88 1.10 christos /* If there is a prefix of "aarch64:" then skip it. */
89 1.10 christos const char * colon;
90 1.10 christos if ((colon = strchr (string, ':')) != NULL)
91 1.10 christos {
92 1.10 christos if (strncasecmp (string, "aarch64", colon - string) != 0)
93 1.10 christos return false;
94 1.10 christos string = colon + 1;
95 1.10 christos }
96 1.1 christos
97 1.1 christos /* Next check for a processor name instead of an Architecture name. */
98 1.1 christos for (i = sizeof (processors) / sizeof (processors[0]); i--;)
99 1.1 christos {
100 1.1 christos if (strcasecmp (string, processors[i].name) == 0)
101 1.1 christos break;
102 1.1 christos }
103 1.1 christos
104 1.1 christos if (i != -1 && info->mach == processors[i].mach)
105 1.10 christos return true;
106 1.1 christos
107 1.1 christos /* Finally check for the default architecture. */
108 1.1 christos if (strcasecmp (string, "aarch64") == 0)
109 1.1 christos return info->the_default;
110 1.1 christos
111 1.10 christos return false;
112 1.1 christos }
113 1.1 christos
114 1.10 christos /* Figure out if llp64 is default */
115 1.10 christos #if DEFAULT_VECTOR == aarch64_pe_le_vec
116 1.10 christos #define LLP64_DEFAULT true
117 1.10 christos #define AARCH64_DEFAULT false
118 1.10 christos #else
119 1.10 christos #define LLP64_DEFAULT false
120 1.10 christos #define AARCH64_DEFAULT true
121 1.10 christos #endif
122 1.10 christos
123 1.10 christos #define N(NUMBER, PRINT, WORDSIZE, ADDRSIZE, DEFAULT, NEXT) \
124 1.10 christos { WORDSIZE, ADDRSIZE, 8, bfd_arch_aarch64, NUMBER, \
125 1.10 christos "aarch64", PRINT, 4, DEFAULT, compatible, scan, \
126 1.10 christos bfd_arch_default_fill, NEXT, 0 }
127 1.9 christos
128 1.10 christos static const bfd_arch_info_type bfd_aarch64_arch_v8_r =
129 1.10 christos N (bfd_mach_aarch64_8R, "aarch64:armv8-r", 64, 64, false, NULL);
130 1.1 christos
131 1.1 christos static const bfd_arch_info_type bfd_aarch64_arch_ilp32 =
132 1.10 christos N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", 32, 32, false,
133 1.9 christos &bfd_aarch64_arch_v8_r);
134 1.1 christos
135 1.10 christos static const bfd_arch_info_type bfd_aarch64_arch_llp64 =
136 1.10 christos N (bfd_mach_aarch64_llp64, "aarch64:llp64", 32, 64, LLP64_DEFAULT,
137 1.10 christos &bfd_aarch64_arch_ilp32);
138 1.10 christos
139 1.10 christos const bfd_arch_info_type bfd_aarch64_arch =
140 1.10 christos N (0, "aarch64", 64, 64, AARCH64_DEFAULT, &bfd_aarch64_arch_llp64);
141 1.1 christos
142 1.10 christos bool
143 1.1 christos bfd_is_aarch64_special_symbol_name (const char *name, int type)
144 1.1 christos {
145 1.1 christos if (!name || name[0] != '$')
146 1.10 christos return false;
147 1.1 christos if (name[1] == 'x' || name[1] == 'd')
148 1.1 christos type &= BFD_AARCH64_SPECIAL_SYM_TYPE_MAP;
149 1.1 christos else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
150 1.1 christos type &= BFD_AARCH64_SPECIAL_SYM_TYPE_TAG;
151 1.1 christos else
152 1.10 christos return false;
153 1.1 christos
154 1.1 christos return (type != 0 && (name[2] == 0 || name[2] == '.'));
155 1.1 christos }
156