diff options
author | Mark Hatle <mark.hatle@amd.com> | 2024-05-27 14:58:33 -0500 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-05-30 09:04:14 +0100 |
commit | 293cb9b25b49d8c0fc60b0be8a810ad761aa9ca8 (patch) | |
tree | de9b48842caaae11170d0e1e186c5e4803747b7e /meta/recipes-devtools/binutils | |
parent | b33dcf1123425c667d09204456102719b35e1a89 (diff) | |
download | poky-293cb9b25b49d8c0fc60b0be8a810ad761aa9ca8.tar.gz |
binutils: Fix aarch64 disassembly abort
Code backported from binutils development tree.
aarch64: Remove asserts from operand qualifier decoders [PR31595]
Given that the disassembler should never abort when decoding
(potentially random) data, assertion statements in the
`get_*reg_qualifier_from_value' function family prove problematic.
...
(From OE-Core rev: 00f3d8495a1d8fe44336b53c5a9d9a5f8a8d5664)
Signed-off-by: Mark Hatle <mark.hatle@amd.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/binutils')
-rw-r--r-- | meta/recipes-devtools/binutils/binutils-2.42.inc | 1 | ||||
-rw-r--r-- | meta/recipes-devtools/binutils/binutils/0016-aarch64-Remove-asserts-from-operand-qualifier-decode.patch | 382 |
2 files changed, 383 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.42.inc b/meta/recipes-devtools/binutils/binutils-2.42.inc index b4d273c9c3..d4e94d0162 100644 --- a/meta/recipes-devtools/binutils/binutils-2.42.inc +++ b/meta/recipes-devtools/binutils/binutils-2.42.inc | |||
@@ -36,5 +36,6 @@ SRC_URI = "\ | |||
36 | file://0013-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch \ | 36 | file://0013-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch \ |
37 | file://0014-Remove-duplicate-pe-dll.o-entry-deom-targ_extra_ofil.patch \ | 37 | file://0014-Remove-duplicate-pe-dll.o-entry-deom-targ_extra_ofil.patch \ |
38 | file://0015-gprofng-change-use-of-bignum-to-bigint.patch \ | 38 | file://0015-gprofng-change-use-of-bignum-to-bigint.patch \ |
39 | file://0016-aarch64-Remove-asserts-from-operand-qualifier-decode.patch \ | ||
39 | " | 40 | " |
40 | S = "${WORKDIR}/git" | 41 | S = "${WORKDIR}/git" |
diff --git a/meta/recipes-devtools/binutils/binutils/0016-aarch64-Remove-asserts-from-operand-qualifier-decode.patch b/meta/recipes-devtools/binutils/binutils/0016-aarch64-Remove-asserts-from-operand-qualifier-decode.patch new file mode 100644 index 0000000000..7b52425a38 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0016-aarch64-Remove-asserts-from-operand-qualifier-decode.patch | |||
@@ -0,0 +1,382 @@ | |||
1 | From 5b1c70bfe0d8f84dc28237d6150b7b9d57c791a8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Victor Do Nascimento <victor.donascimento@arm.com> | ||
3 | Date: Tue, 16 Apr 2024 11:49:15 +0100 | ||
4 | Subject: [PATCH] aarch64: Remove asserts from operand qualifier decoders | ||
5 | [PR31595] | ||
6 | |||
7 | Given that the disassembler should never abort when decoding | ||
8 | (potentially random) data, assertion statements in the | ||
9 | `get_*reg_qualifier_from_value' function family prove problematic. | ||
10 | |||
11 | Consider the random 32-bit word W, encoded in a data segment and | ||
12 | encountered on execution of `objdump -D <obj_name>'. | ||
13 | |||
14 | If: | ||
15 | |||
16 | (W & ~opcode_mask) == valid instruction | ||
17 | |||
18 | Then before `print_insn_aarch64_word' has a chance to report the | ||
19 | instruction as potentially undefined, an attempt will be made to have | ||
20 | the qualifiers for the instruction's register operands (if any) | ||
21 | decoded. If the relevant bits do not map onto a valid qualifier for | ||
22 | the matched instruction-like word, an abort will be triggered and the | ||
23 | execution of objdump aborted. | ||
24 | |||
25 | As this scenario is perfectly feasible and, in light of the fact that | ||
26 | objdump must successfully decode all sections of a given object file, | ||
27 | it is not appropriate to assert in this family of functions. | ||
28 | |||
29 | Therefore, we add a new pseudo-qualifier `AARCH64_OPND_QLF_ERR' for | ||
30 | handling invalid qualifier-associated values and re-purpose the | ||
31 | assertion conditions in qualifier-retrieving functions to be the | ||
32 | predicate guarding the returning of the calculated qualifier type. | ||
33 | If the predicate fails, we return this new qualifier and allow the | ||
34 | caller to handle the error as appropriate. | ||
35 | |||
36 | As these functions are called either from within | ||
37 | `aarch64_extract_operand' or `do_special_decoding', both of which are | ||
38 | expected to return non-zero values, it suffices that callers return | ||
39 | zero upon encountering `AARCH64_OPND_QLF_ERR'. | ||
40 | |||
41 | Ar present the error presented in the hypothetical scenario has been | ||
42 | encountered in `get_sreg_qualifier_from_value', but the change is made | ||
43 | to the whole family to keep the interface consistent. | ||
44 | |||
45 | Bug: https://sourceware.org/PR31595 | ||
46 | |||
47 | Upstream-Status: Backport [commit 2601b201e95ea0edab89342ee7137c74e88a8a79] | ||
48 | |||
49 | Signed-off-by: Mark Hatle <mark.hatle@amd.com> | ||
50 | --- | ||
51 | .../testsuite/binutils-all/aarch64/illegal.d | 1 + | ||
52 | .../testsuite/binutils-all/aarch64/illegal.s | 3 + | ||
53 | include/opcode/aarch64.h | 3 + | ||
54 | opcodes/aarch64-dis.c | 98 +++++++++++++++---- | ||
55 | 4 files changed, 87 insertions(+), 18 deletions(-) | ||
56 | |||
57 | diff --git a/binutils/testsuite/binutils-all/aarch64/illegal.d b/binutils/testsuite/binutils-all/aarch64/illegal.d | ||
58 | index 4b90a1d9f39..b69318aec85 100644 | ||
59 | --- a/binutils/testsuite/binutils-all/aarch64/illegal.d | ||
60 | +++ b/binutils/testsuite/binutils-all/aarch64/illegal.d | ||
61 | @@ -8,5 +8,6 @@ Disassembly of section \.text: | ||
62 | |||
63 | 0+000 <.*>: | ||
64 | [ ]+0:[ ]+68ea18cc[ ]+.inst[ ]+0x68ea18cc ; undefined | ||
65 | +[ ]+4:[ ]+9dc39839[ ]+.inst[ ]+0x9dc39839 ; undefined | ||
66 | #pass | ||
67 | |||
68 | diff --git a/binutils/testsuite/binutils-all/aarch64/illegal.s b/binutils/testsuite/binutils-all/aarch64/illegal.s | ||
69 | index 216cbe6f265..43668c6db55 100644 | ||
70 | --- a/binutils/testsuite/binutils-all/aarch64/illegal.s | ||
71 | +++ b/binutils/testsuite/binutils-all/aarch64/illegal.s | ||
72 | @@ -4,4 +4,7 @@ | ||
73 | # ldpsw x12, x6, [x6],#-8 ; illegal because one of the dest regs is also the address reg | ||
74 | .inst 0x68ea18cc | ||
75 | |||
76 | + # illegal, resembles the opcode `ldapur' with invalid qualifier bits | ||
77 | + .inst 0x9dc39839 | ||
78 | + | ||
79 | # FIXME: Add more illegal instructions here. | ||
80 | diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h | ||
81 | index 2fca9528c20..e8fe93ef127 100644 | ||
82 | --- a/include/opcode/aarch64.h | ||
83 | +++ b/include/opcode/aarch64.h | ||
84 | @@ -894,6 +894,9 @@ enum aarch64_opnd_qualifier | ||
85 | /* Special qualifier helping retrieve qualifier information during the | ||
86 | decoding time (currently not in use). */ | ||
87 | AARCH64_OPND_QLF_RETRIEVE, | ||
88 | + | ||
89 | + /* Special qualifier used for indicating error in qualifier retrieval. */ | ||
90 | + AARCH64_OPND_QLF_ERR, | ||
91 | }; | ||
92 | |||
93 | /* Instruction class. */ | ||
94 | diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c | ||
95 | index 96f42ae862a..b70e6da9eb7 100644 | ||
96 | --- a/opcodes/aarch64-dis.c | ||
97 | +++ b/opcodes/aarch64-dis.c | ||
98 | @@ -219,9 +219,10 @@ static inline enum aarch64_opnd_qualifier | ||
99 | get_greg_qualifier_from_value (aarch64_insn value) | ||
100 | { | ||
101 | enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_W + value; | ||
102 | - assert (value <= 0x1 | ||
103 | - && aarch64_get_qualifier_standard_value (qualifier) == value); | ||
104 | - return qualifier; | ||
105 | + if (value <= 0x1 | ||
106 | + && aarch64_get_qualifier_standard_value (qualifier) == value) | ||
107 | + return qualifier; | ||
108 | + return AARCH64_OPND_QLF_ERR; | ||
109 | } | ||
110 | |||
111 | /* Given VALUE, return qualifier for a vector register. This does not support | ||
112 | @@ -237,9 +238,10 @@ get_vreg_qualifier_from_value (aarch64_insn value) | ||
113 | if (qualifier >= AARCH64_OPND_QLF_V_2H) | ||
114 | qualifier += 1; | ||
115 | |||
116 | - assert (value <= 0x8 | ||
117 | - && aarch64_get_qualifier_standard_value (qualifier) == value); | ||
118 | - return qualifier; | ||
119 | + if (value <= 0x8 | ||
120 | + && aarch64_get_qualifier_standard_value (qualifier) == value) | ||
121 | + return qualifier; | ||
122 | + return AARCH64_OPND_QLF_ERR; | ||
123 | } | ||
124 | |||
125 | /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register. */ | ||
126 | @@ -248,9 +250,10 @@ get_sreg_qualifier_from_value (aarch64_insn value) | ||
127 | { | ||
128 | enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_S_B + value; | ||
129 | |||
130 | - assert (value <= 0x4 | ||
131 | - && aarch64_get_qualifier_standard_value (qualifier) == value); | ||
132 | - return qualifier; | ||
133 | + if (value <= 0x4 | ||
134 | + && aarch64_get_qualifier_standard_value (qualifier) == value) | ||
135 | + return qualifier; | ||
136 | + return AARCH64_OPND_QLF_ERR; | ||
137 | } | ||
138 | |||
139 | /* Given the instruction in *INST which is probably half way through the | ||
140 | @@ -263,13 +266,17 @@ get_expected_qualifier (const aarch64_inst *inst, int i) | ||
141 | { | ||
142 | aarch64_opnd_qualifier_seq_t qualifiers; | ||
143 | /* Should not be called if the qualifier is known. */ | ||
144 | - assert (inst->operands[i].qualifier == AARCH64_OPND_QLF_NIL); | ||
145 | - int invalid_count; | ||
146 | - if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list, | ||
147 | - i, qualifiers, &invalid_count)) | ||
148 | - return qualifiers[i]; | ||
149 | + if (inst->operands[i].qualifier == AARCH64_OPND_QLF_NIL) | ||
150 | + { | ||
151 | + int invalid_count; | ||
152 | + if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list, | ||
153 | + i, qualifiers, &invalid_count)) | ||
154 | + return qualifiers[i]; | ||
155 | + else | ||
156 | + return AARCH64_OPND_QLF_NIL; | ||
157 | + } | ||
158 | else | ||
159 | - return AARCH64_OPND_QLF_NIL; | ||
160 | + return AARCH64_OPND_QLF_ERR; | ||
161 | } | ||
162 | |||
163 | /* Operand extractors. */ | ||
164 | @@ -355,6 +362,8 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info, | ||
165 | aarch64_insn value = extract_field (FLD_imm4_11, code, 0); | ||
166 | /* Depend on AARCH64_OPND_Ed to determine the qualifier. */ | ||
167 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
168 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
169 | + return 0; | ||
170 | shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier)); | ||
171 | info->reglane.index = value >> shift; | ||
172 | } | ||
173 | @@ -374,6 +383,8 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info, | ||
174 | if (pos > 3) | ||
175 | return false; | ||
176 | info->qualifier = get_sreg_qualifier_from_value (pos); | ||
177 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
178 | + return 0; | ||
179 | info->reglane.index = (unsigned) (value >> 1); | ||
180 | } | ||
181 | } | ||
182 | @@ -381,6 +392,8 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info, | ||
183 | { | ||
184 | /* Need information in other operand(s) to help decoding. */ | ||
185 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
186 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
187 | + return 0; | ||
188 | switch (info->qualifier) | ||
189 | { | ||
190 | case AARCH64_OPND_QLF_S_4B: | ||
191 | @@ -405,6 +418,8 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info, | ||
192 | |||
193 | /* Need information in other operand(s) to help decoding. */ | ||
194 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
195 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
196 | + return 0; | ||
197 | switch (info->qualifier) | ||
198 | { | ||
199 | case AARCH64_OPND_QLF_S_H: | ||
200 | @@ -644,9 +659,15 @@ aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED, | ||
201 | 1xxx 1 2D */ | ||
202 | info->qualifier = | ||
203 | get_vreg_qualifier_from_value ((pos << 1) | (int) Q); | ||
204 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
205 | + return false; | ||
206 | } | ||
207 | else | ||
208 | - info->qualifier = get_sreg_qualifier_from_value (pos); | ||
209 | + { | ||
210 | + info->qualifier = get_sreg_qualifier_from_value (pos); | ||
211 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
212 | + return 0; | ||
213 | + } | ||
214 | |||
215 | if (info->type == AARCH64_OPND_IMM_VLSR) | ||
216 | /* immh <shift> | ||
217 | @@ -773,6 +794,8 @@ aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED, | ||
218 | |||
219 | /* cmode */ | ||
220 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
221 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
222 | + return 0; | ||
223 | switch (info->qualifier) | ||
224 | { | ||
225 | case AARCH64_OPND_QLF_NIL: | ||
226 | @@ -1014,6 +1037,8 @@ aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED, | ||
227 | if (value > 0x4) | ||
228 | return false; | ||
229 | info->qualifier = get_sreg_qualifier_from_value (value); | ||
230 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
231 | + return 0; | ||
232 | } | ||
233 | |||
234 | return true; | ||
235 | @@ -1086,6 +1111,8 @@ aarch64_ext_rcpc3_addr_offset (const aarch64_operand *self ATTRIBUTE_UNUSED, | ||
236 | aarch64_operand_error *errors ATTRIBUTE_UNUSED) | ||
237 | { | ||
238 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
239 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
240 | + return 0; | ||
241 | |||
242 | /* Rn */ | ||
243 | info->addr.base_regno = extract_field (self->fields[0], code, 0); | ||
244 | @@ -1105,6 +1132,8 @@ aarch64_ext_addr_offset (const aarch64_operand *self ATTRIBUTE_UNUSED, | ||
245 | aarch64_operand_error *errors ATTRIBUTE_UNUSED) | ||
246 | { | ||
247 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
248 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
249 | + return 0; | ||
250 | |||
251 | /* Rn */ | ||
252 | info->addr.base_regno = extract_field (self->fields[0], code, 0); | ||
253 | @@ -1154,6 +1183,8 @@ aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED, | ||
254 | /* Need information in other operand(s) to help achieve the decoding | ||
255 | from 'S' field. */ | ||
256 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
257 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
258 | + return 0; | ||
259 | /* Get the size of the data element that is accessed, which may be | ||
260 | different from that of the source register size, e.g. in strb/ldrb. */ | ||
261 | size = aarch64_get_qualifier_esize (info->qualifier); | ||
262 | @@ -1172,6 +1203,8 @@ aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info, | ||
263 | { | ||
264 | aarch64_insn imm; | ||
265 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
266 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
267 | + return 0; | ||
268 | |||
269 | /* Rn */ | ||
270 | info->addr.base_regno = extract_field (FLD_Rn, code, 0); | ||
271 | @@ -1210,6 +1243,8 @@ aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info, | ||
272 | { | ||
273 | int shift; | ||
274 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
275 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
276 | + return 0; | ||
277 | shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier)); | ||
278 | /* Rn */ | ||
279 | info->addr.base_regno = extract_field (self->fields[0], code, 0); | ||
280 | @@ -1228,6 +1263,8 @@ aarch64_ext_addr_simm10 (const aarch64_operand *self, aarch64_opnd_info *info, | ||
281 | aarch64_insn imm; | ||
282 | |||
283 | info->qualifier = get_expected_qualifier (inst, info->idx); | ||
284 | + if (info->qualifier == AARCH64_OPND_QLF_ERR) | ||
285 | + return 0; | ||
286 | /* Rn */ | ||
287 | info->addr.base_regno = extract_field (self->fields[0], code, 0); | ||
288 | /* simm10 */ | ||
289 | @@ -2467,6 +2504,8 @@ decode_sizeq (aarch64_inst *inst) | ||
290 | if (mask == 0x7) | ||
291 | { | ||
292 | inst->operands[idx].qualifier = get_vreg_qualifier_from_value (value); | ||
293 | + if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR) | ||
294 | + return 0; | ||
295 | return 1; | ||
296 | } | ||
297 | |||
298 | @@ -2649,6 +2688,8 @@ do_special_decoding (aarch64_inst *inst) | ||
299 | idx = select_operand_for_sf_field_coding (inst->opcode); | ||
300 | value = extract_field (FLD_sf, inst->value, 0); | ||
301 | inst->operands[idx].qualifier = get_greg_qualifier_from_value (value); | ||
302 | + if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR) | ||
303 | + return 0; | ||
304 | if ((inst->opcode->flags & F_N) | ||
305 | && extract_field (FLD_N, inst->value, 0) != value) | ||
306 | return 0; | ||
307 | @@ -2659,6 +2700,8 @@ do_special_decoding (aarch64_inst *inst) | ||
308 | idx = select_operand_for_sf_field_coding (inst->opcode); | ||
309 | value = extract_field (FLD_lse_sz, inst->value, 0); | ||
310 | inst->operands[idx].qualifier = get_greg_qualifier_from_value (value); | ||
311 | + if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR) | ||
312 | + return 0; | ||
313 | } | ||
314 | /* rcpc3 'size' field. */ | ||
315 | if (inst->opcode->flags & F_RCPC3_SIZE) | ||
316 | @@ -2670,12 +2713,18 @@ do_special_decoding (aarch64_inst *inst) | ||
317 | { | ||
318 | if (aarch64_operands[inst->operands[i].type].op_class | ||
319 | == AARCH64_OPND_CLASS_INT_REG) | ||
320 | - inst->operands[i].qualifier = get_greg_qualifier_from_value (value & 1); | ||
321 | + { | ||
322 | + inst->operands[i].qualifier = get_greg_qualifier_from_value (value & 1); | ||
323 | + if (inst->operands[i].qualifier == AARCH64_OPND_QLF_ERR) | ||
324 | + return 0; | ||
325 | + } | ||
326 | else if (aarch64_operands[inst->operands[i].type].op_class | ||
327 | == AARCH64_OPND_CLASS_FP_REG) | ||
328 | { | ||
329 | value += (extract_field (FLD_opc1, inst->value, 0) << 2); | ||
330 | inst->operands[i].qualifier = get_sreg_qualifier_from_value (value); | ||
331 | + if (inst->operands[i].qualifier == AARCH64_OPND_QLF_ERR) | ||
332 | + return 0; | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | @@ -2709,7 +2758,11 @@ do_special_decoding (aarch64_inst *inst) | ||
337 | /* For most related instruciton, the 'size' field is fully available for | ||
338 | operand encoding. */ | ||
339 | if (mask == 0x3) | ||
340 | - inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value); | ||
341 | + { | ||
342 | + inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value); | ||
343 | + if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR) | ||
344 | + return 0; | ||
345 | + } | ||
346 | else | ||
347 | { | ||
348 | get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list, | ||
349 | @@ -2744,6 +2797,9 @@ do_special_decoding (aarch64_inst *inst) | ||
350 | Q = (unsigned) extract_field (FLD_Q, inst->value, inst->opcode->mask); | ||
351 | inst->operands[0].qualifier = | ||
352 | get_vreg_qualifier_from_value ((num << 1) | Q); | ||
353 | + if (inst->operands[0].qualifier == AARCH64_OPND_QLF_ERR) | ||
354 | + return 0; | ||
355 | + | ||
356 | } | ||
357 | |||
358 | if ((inst->opcode->flags & F_OPD_SIZE) && inst->opcode->iclass == sve2_urqvs) | ||
359 | @@ -2753,7 +2809,11 @@ do_special_decoding (aarch64_inst *inst) | ||
360 | inst->opcode->mask); | ||
361 | inst->operands[0].qualifier | ||
362 | = get_vreg_qualifier_from_value (1 + (size << 1)); | ||
363 | + if (inst->operands[0].qualifier == AARCH64_OPND_QLF_ERR) | ||
364 | + return 0; | ||
365 | inst->operands[2].qualifier = get_sreg_qualifier_from_value (size); | ||
366 | + if (inst->operands[2].qualifier == AARCH64_OPND_QLF_ERR) | ||
367 | + return 0; | ||
368 | } | ||
369 | |||
370 | if (inst->opcode->flags & F_GPRSIZE_IN_Q) | ||
371 | @@ -2772,6 +2832,8 @@ do_special_decoding (aarch64_inst *inst) | ||
372 | assert (idx == 0 || idx == 1); | ||
373 | value = extract_field (FLD_Q, inst->value, 0); | ||
374 | inst->operands[idx].qualifier = get_greg_qualifier_from_value (value); | ||
375 | + if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR) | ||
376 | + return 0; | ||
377 | } | ||
378 | |||
379 | if (inst->opcode->flags & F_LDS_SIZE) | ||
380 | -- | ||
381 | 2.34.1 | ||
382 | |||