1 |
|
2 |
gas/config/tc-i386.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------- |
3 |
1 file changed, 117 insertions(+), 69 deletions(-) |
4 |
|
5 |
diff -Nurp binutils-2.37.orig/gas/config/tc-i386.c binutils-2.37/gas/config/tc-i386.c |
6 |
--- binutils-2.37.orig/gas/config/tc-i386.c 2021-07-08 14:37:19.000000000 +0300 |
7 |
+++ binutils-2.37/gas/config/tc-i386.c 2021-07-20 11:44:12.027260112 +0300 |
8 |
@@ -50,6 +50,13 @@ |
9 |
#endif |
10 |
#endif |
11 |
|
12 |
+#if defined(__linux__) && defined(__x86_64__) |
13 |
+#include <sys/syscall.h> |
14 |
+#include <sys/personality.h> |
15 |
+ |
16 |
+#define is_linux32() ((syscall(SYS_personality, 0xffffffff) & PER_MASK) == PER_LINUX32) |
17 |
+#endif |
18 |
+ |
19 |
/* Prefixes will be emitted in the order defined below. |
20 |
WAIT_PREFIX must be the first prefix since FWAIT is really is an |
21 |
instruction, and so must come before any prefixes. |
22 |
@@ -198,7 +205,18 @@ static unsigned int x86_feature_2_used; |
23 |
static unsigned int x86_used_note = DEFAULT_X86_USED_NOTE; |
24 |
#endif |
25 |
|
26 |
-static const char *default_arch = DEFAULT_ARCH; |
27 |
+enum x86_arch |
28 |
+ { |
29 |
+ ARCH_default, |
30 |
+ ARCH_i386, |
31 |
+ ARCH_x86_64, |
32 |
+ ARCH_x64_32, |
33 |
+ }; |
34 |
+ |
35 |
+static enum x86_arch g_default_arch = ARCH_default; |
36 |
+static enum x86_arch get_default_arch (void); |
37 |
+static INLINE void set_default_arch (enum x86_arch arch); |
38 |
+static INLINE const char *get_default_arch_str (void); |
39 |
|
40 |
/* parse_register() returns this when a register alias cannot be used. */ |
41 |
static const reg_entry bad_reg = { "<bad>", OPERAND_TYPE_NONE, 0, 0, |
42 |
@@ -2681,7 +2699,7 @@ update_code_flag (int value, int check) |
43 |
else |
44 |
as_error = as_bad; |
45 |
(*as_error) (_("64bit mode not supported on `%s'."), |
46 |
- cpu_arch_name ? cpu_arch_name : default_arch); |
47 |
+ cpu_arch_name ? cpu_arch_name : get_default_arch_str()); |
48 |
} |
49 |
if (value == CODE_32BIT && !cpu_arch_flags.bitfield.cpui386) |
50 |
{ |
51 |
@@ -2690,7 +2708,7 @@ update_code_flag (int value, int check) |
52 |
else |
53 |
as_error = as_bad; |
54 |
(*as_error) (_("32bit mode not supported on `%s'."), |
55 |
- cpu_arch_name ? cpu_arch_name : default_arch); |
56 |
+ cpu_arch_name ? cpu_arch_name : get_default_arch_str()); |
57 |
} |
58 |
stackop_size = '\0'; |
59 |
} |
60 |
@@ -2818,7 +2836,7 @@ check_cpu_arch_compatible (const char *n |
61 |
use default_arch. */ |
62 |
arch = cpu_arch_name; |
63 |
if (!arch) |
64 |
- arch = default_arch; |
65 |
+ arch = get_default_arch_str(); |
66 |
} |
67 |
|
68 |
/* If we are targeting Intel MCU, we must enable it. */ |
69 |
@@ -3000,44 +3018,87 @@ i386_arch (void) |
70 |
return bfd_arch_i386; |
71 |
} |
72 |
|
73 |
+static enum x86_arch |
74 |
+get_default_arch () |
75 |
+{ |
76 |
+ const char *default_arch_str = DEFAULT_ARCH; |
77 |
+ |
78 |
+ if (g_default_arch != ARCH_default) |
79 |
+ return g_default_arch; |
80 |
+ |
81 |
+#ifdef is_linux32 |
82 |
+ if (is_linux32 ()) |
83 |
+ default_arch_str = "i386"; |
84 |
+#endif |
85 |
+ |
86 |
+ if (!strcmp (default_arch_str, "x86_64")) |
87 |
+ g_default_arch = ARCH_x86_64; |
88 |
+ else if (!strcmp (default_arch_str, "x86_64:32")) |
89 |
+ g_default_arch = ARCH_x64_32; |
90 |
+ else if (!strcmp (default_arch_str, "i386")) |
91 |
+ g_default_arch = ARCH_i386; |
92 |
+ |
93 |
+ return g_default_arch; |
94 |
+} |
95 |
+ |
96 |
+static INLINE const char |
97 |
+*get_default_arch_str () |
98 |
+{ |
99 |
+ switch (g_default_arch) |
100 |
+ { |
101 |
+ case ARCH_default: |
102 |
+ return DEFAULT_ARCH; |
103 |
+ case ARCH_x86_64: |
104 |
+ return "x86_64"; |
105 |
+ case ARCH_x64_32: |
106 |
+ return "x86_64:32"; |
107 |
+ case ARCH_i386: |
108 |
+ return "i386"; |
109 |
+ default: |
110 |
+ return "noarch"; |
111 |
+ } |
112 |
+} |
113 |
+ |
114 |
+static INLINE void |
115 |
+set_default_arch (arch) |
116 |
+ enum x86_arch arch; |
117 |
+{ |
118 |
+ g_default_arch = arch; |
119 |
+} |
120 |
+ |
121 |
unsigned long |
122 |
i386_mach (void) |
123 |
{ |
124 |
- if (startswith (default_arch, "x86_64")) |
125 |
+ switch (get_default_arch ()) |
126 |
{ |
127 |
- if (cpu_arch_isa == PROCESSOR_L1OM) |
128 |
- { |
129 |
- if (OUTPUT_FLAVOR != bfd_target_elf_flavour |
130 |
- || default_arch[6] != '\0') |
131 |
+ case ARCH_x86_64: |
132 |
+ if (cpu_arch_isa == PROCESSOR_L1OM) |
133 |
+ { |
134 |
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour) |
135 |
+ as_fatal (_("Intel L1OM is 64bit ELF only")); |
136 |
+ return bfd_mach_l1om; |
137 |
+ } |
138 |
+ else if (cpu_arch_isa == PROCESSOR_K1OM) |
139 |
+ { |
140 |
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour) |
141 |
+ as_fatal (_("Intel K1OM is 64bit ELF only")); |
142 |
+ return bfd_mach_k1om; |
143 |
+ } |
144 |
+ return bfd_mach_x86_64; |
145 |
+ |
146 |
+ case ARCH_x64_32: |
147 |
+ if (cpu_arch_isa == PROCESSOR_L1OM) |
148 |
as_fatal (_("Intel L1OM is 64bit ELF only")); |
149 |
- return bfd_mach_l1om; |
150 |
- } |
151 |
- else if (cpu_arch_isa == PROCESSOR_K1OM) |
152 |
- { |
153 |
- if (OUTPUT_FLAVOR != bfd_target_elf_flavour |
154 |
- || default_arch[6] != '\0') |
155 |
+ if (cpu_arch_isa == PROCESSOR_K1OM) |
156 |
as_fatal (_("Intel K1OM is 64bit ELF only")); |
157 |
- return bfd_mach_k1om; |
158 |
- } |
159 |
- else if (default_arch[6] == '\0') |
160 |
- return bfd_mach_x86_64; |
161 |
- else |
162 |
return bfd_mach_x64_32; |
163 |
- } |
164 |
- else if (!strcmp (default_arch, "i386") |
165 |
- || !strcmp (default_arch, "iamcu")) |
166 |
- { |
167 |
- if (cpu_arch_isa == PROCESSOR_IAMCU) |
168 |
- { |
169 |
- if (OUTPUT_FLAVOR != bfd_target_elf_flavour) |
170 |
- as_fatal (_("Intel MCU is 32bit ELF only")); |
171 |
- return bfd_mach_i386_iamcu; |
172 |
- } |
173 |
- else |
174 |
+ |
175 |
+ case ARCH_i386: |
176 |
return bfd_mach_i386_i386; |
177 |
+ |
178 |
+ default: |
179 |
+ as_fatal (_("unknown architecture")); |
180 |
} |
181 |
- else |
182 |
- as_fatal (_("unknown architecture")); |
183 |
} |
184 |
|
185 |
void |
186 |
@@ -3183,7 +3244,7 @@ md_begin (void) |
187 |
{ |
188 |
#if defined (OBJ_COFF) && defined (TE_PE) |
189 |
x86_dwarf2_return_column = (OUTPUT_FLAVOR == bfd_target_coff_flavour |
190 |
- ? 32 : 16); |
191 |
+ x86_64:3232 : 16); |
192 |
#else |
193 |
x86_dwarf2_return_column = 16; |
194 |
#endif |
195 |
@@ -5509,7 +5570,7 @@ parse_insn (char *line, char *mnemonic) |
196 |
else |
197 |
as_bad (_("`%s' is not supported on `%s%s'"), |
198 |
current_templates->start->name, |
199 |
- cpu_arch_name ? cpu_arch_name : default_arch, |
200 |
+ cpu_arch_name ? cpu_arch_name : get_default_arch_str(), |
201 |
cpu_sub_arch_name ? cpu_sub_arch_name : ""); |
202 |
|
203 |
return NULL; |
204 |
@@ -13128,7 +13189,7 @@ md_parse_option (int c, const char *arg) |
205 |
|| strcmp (*l, "pei-x86-64") == 0 |
206 |
|| strcmp (*l, "mach-o-x86-64") == 0) |
207 |
{ |
208 |
- default_arch = "x86_64"; |
209 |
+ set_default_arch (ARCH_x86_64); |
210 |
break; |
211 |
} |
212 |
if (*l == NULL) |
213 |
@@ -13148,7 +13209,7 @@ md_parse_option (int c, const char *arg) |
214 |
for (l = list; *l != NULL; l++) |
215 |
if (startswith (*l, "elf32-x86-64")) |
216 |
{ |
217 |
- default_arch = "x86_64:32"; |
218 |
+ set_default_arch (ARCH_x64_32); |
219 |
break; |
220 |
} |
221 |
if (*l == NULL) |
222 |
@@ -13161,7 +13222,7 @@ md_parse_option (int c, const char *arg) |
223 |
#endif |
224 |
|
225 |
case OPTION_32: |
226 |
- default_arch = "i386"; |
227 |
+ set_default_arch (ARCH_i386); |
228 |
break; |
229 |
|
230 |
case OPTION_DIVIDE: |
231 |
@@ -13859,39 +13920,26 @@ md_show_usage (FILE *stream) |
232 |
const char * |
233 |
i386_target_format (void) |
234 |
{ |
235 |
- if (startswith (default_arch, "x86_64")) |
236 |
+ switch (get_default_arch ()) |
237 |
{ |
238 |
- update_code_flag (CODE_64BIT, 1); |
239 |
- if (default_arch[6] == '\0') |
240 |
- x86_elf_abi = X86_64_ABI; |
241 |
- else |
242 |
- x86_elf_abi = X86_64_X32_ABI; |
243 |
- } |
244 |
- else if (!strcmp (default_arch, "i386")) |
245 |
- update_code_flag (CODE_32BIT, 1); |
246 |
- else if (!strcmp (default_arch, "iamcu")) |
247 |
- { |
248 |
- update_code_flag (CODE_32BIT, 1); |
249 |
- if (cpu_arch_isa == PROCESSOR_UNKNOWN) |
250 |
- { |
251 |
- static const i386_cpu_flags iamcu_flags = CPU_IAMCU_FLAGS; |
252 |
- cpu_arch_name = "iamcu"; |
253 |
- cpu_sub_arch_name = NULL; |
254 |
- cpu_arch_flags = iamcu_flags; |
255 |
- cpu_arch_isa = PROCESSOR_IAMCU; |
256 |
- cpu_arch_isa_flags = iamcu_flags; |
257 |
- if (!cpu_arch_tune_set) |
258 |
- { |
259 |
- cpu_arch_tune = cpu_arch_isa; |
260 |
- cpu_arch_tune_flags = cpu_arch_isa_flags; |
261 |
- } |
262 |
- } |
263 |
- else if (cpu_arch_isa != PROCESSOR_IAMCU) |
264 |
- as_fatal (_("Intel MCU doesn't support `%s' architecture"), |
265 |
- cpu_arch_name); |
266 |
+ case ARCH_x86_64: |
267 |
+ update_code_flag (CODE_64BIT, 1); |
268 |
+ x86_elf_abi = X86_64_ABI; |
269 |
+ break; |
270 |
+ |
271 |
+ case ARCH_x64_32: |
272 |
+ update_code_flag (CODE_64BIT, 1); |
273 |
+ x86_elf_abi = X86_64_X32_ABI; |
274 |
+ break; |
275 |
+ |
276 |
+ case ARCH_i386: |
277 |
+ update_code_flag (CODE_32BIT, 1); |
278 |
+ break; |
279 |
+ |
280 |
+ default: |
281 |
+ as_fatal (_("Unknown architecture")); |
282 |
+ break; |
283 |
} |
284 |
- else |
285 |
- as_fatal (_("unknown architecture")); |
286 |
|
287 |
if (cpu_flags_all_zero (&cpu_arch_isa_flags)) |
288 |
cpu_arch_isa_flags = cpu_arch[flag_code == CODE_64BIT].flags; |