cpu-aarch64.c revision 1.9 1 1.1 christos /* BFD support for AArch64.
2 1.9 christos Copyright (C) 2009-2020 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.1 christos /* Don't allow mixing ilp32 with lp64. */
43 1.1 christos if ((a->mach & bfd_mach_aarch64_ilp32) != (b->mach & bfd_mach_aarch64_ilp32))
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.1 christos static bfd_boolean
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.1 christos return TRUE;
87 1.1 christos
88 1.1 christos /* Next check for a processor name instead of an Architecture name. */
89 1.1 christos for (i = sizeof (processors) / sizeof (processors[0]); i--;)
90 1.1 christos {
91 1.1 christos if (strcasecmp (string, processors[i].name) == 0)
92 1.1 christos break;
93 1.1 christos }
94 1.1 christos
95 1.1 christos if (i != -1 && info->mach == processors[i].mach)
96 1.1 christos return TRUE;
97 1.1 christos
98 1.1 christos /* Finally check for the default architecture. */
99 1.1 christos if (strcasecmp (string, "aarch64") == 0)
100 1.1 christos return info->the_default;
101 1.1 christos
102 1.1 christos return FALSE;
103 1.1 christos }
104 1.1 christos
105 1.7 christos #define N(NUMBER, PRINT, WORDSIZE, DEFAULT, NEXT) \
106 1.7 christos { WORDSIZE, WORDSIZE, 8, bfd_arch_aarch64, NUMBER, \
107 1.1 christos "aarch64", PRINT, 4, DEFAULT, compatible, scan, \
108 1.9 christos bfd_arch_default_fill, NEXT, 0 }
109 1.9 christos
110 1.9 christos static const bfd_arch_info_type bfd_aarch64_arch_v8_r =
111 1.9 christos N (bfd_mach_aarch64_8R, "aarch64:armv8-r", 64, FALSE, NULL);
112 1.1 christos
113 1.1 christos static const bfd_arch_info_type bfd_aarch64_arch_ilp32 =
114 1.9 christos N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", 32, FALSE,
115 1.9 christos &bfd_aarch64_arch_v8_r);
116 1.1 christos
117 1.1 christos const bfd_arch_info_type bfd_aarch64_arch =
118 1.7 christos N (0, "aarch64", 64, TRUE, &bfd_aarch64_arch_ilp32);
119 1.1 christos
120 1.1 christos bfd_boolean
121 1.1 christos bfd_is_aarch64_special_symbol_name (const char *name, int type)
122 1.1 christos {
123 1.1 christos if (!name || name[0] != '$')
124 1.1 christos return FALSE;
125 1.1 christos if (name[1] == 'x' || name[1] == 'd')
126 1.1 christos type &= BFD_AARCH64_SPECIAL_SYM_TYPE_MAP;
127 1.1 christos else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
128 1.1 christos type &= BFD_AARCH64_SPECIAL_SYM_TYPE_TAG;
129 1.1 christos else
130 1.1 christos return FALSE;
131 1.1 christos
132 1.1 christos return (type != 0 && (name[2] == 0 || name[2] == '.'));
133 1.1 christos }
134