summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/binutils
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/binutils')
-rw-r--r--meta/recipes-devtools/binutils/binutils-2.42.inc3
-rw-r--r--meta/recipes-devtools/binutils/binutils/0016-aarch64-Remove-asserts-from-operand-qualifier-decode.patch382
2 files changed, 384 insertions, 1 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.42.inc b/meta/recipes-devtools/binutils/binutils-2.42.inc
index 3b6f47d4ce..d4e94d0162 100644
--- a/meta/recipes-devtools/binutils/binutils-2.42.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.42.inc
@@ -20,7 +20,7 @@ UPSTREAM_CHECK_GITTAGREGEX = "binutils-(?P<pver>\d+_(\d_?)*)"
20 20
21CVE_STATUS[CVE-2023-25584] = "cpe-incorrect: Applies only for version 2.40 and earlier" 21CVE_STATUS[CVE-2023-25584] = "cpe-incorrect: Applies only for version 2.40 and earlier"
22 22
23SRCREV ?= "553c7f61b74badf91df484450944675efd9cd485" 23SRCREV ?= "73b22b4481e85635eb978585f405c4433bcc0174"
24BINUTILS_GIT_URI ?= "git://sourceware.org/git/binutils-gdb.git;branch=${SRCBRANCH};protocol=https" 24BINUTILS_GIT_URI ?= "git://sourceware.org/git/binutils-gdb.git;branch=${SRCBRANCH};protocol=https"
25SRC_URI = "\ 25SRC_URI = "\
26 ${BINUTILS_GIT_URI} \ 26 ${BINUTILS_GIT_URI} \
@@ -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"
40S = "${WORKDIR}/git" 41S = "${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 @@
1From 5b1c70bfe0d8f84dc28237d6150b7b9d57c791a8 Mon Sep 17 00:00:00 2001
2From: Victor Do Nascimento <victor.donascimento@arm.com>
3Date: Tue, 16 Apr 2024 11:49:15 +0100
4Subject: [PATCH] aarch64: Remove asserts from operand qualifier decoders
5 [PR31595]
6
7Given 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
11Consider the random 32-bit word W, encoded in a data segment and
12encountered on execution of `objdump -D <obj_name>'.
13
14If:
15
16 (W & ~opcode_mask) == valid instruction
17
18Then before `print_insn_aarch64_word' has a chance to report the
19instruction as potentially undefined, an attempt will be made to have
20the qualifiers for the instruction's register operands (if any)
21decoded. If the relevant bits do not map onto a valid qualifier for
22the matched instruction-like word, an abort will be triggered and the
23execution of objdump aborted.
24
25As this scenario is perfectly feasible and, in light of the fact that
26objdump must successfully decode all sections of a given object file,
27it is not appropriate to assert in this family of functions.
28
29Therefore, we add a new pseudo-qualifier `AARCH64_OPND_QLF_ERR' for
30handling invalid qualifier-associated values and re-purpose the
31assertion conditions in qualifier-retrieving functions to be the
32predicate guarding the returning of the calculated qualifier type.
33If the predicate fails, we return this new qualifier and allow the
34caller to handle the error as appropriate.
35
36As these functions are called either from within
37`aarch64_extract_operand' or `do_special_decoding', both of which are
38expected to return non-zero values, it suffices that callers return
39zero upon encountering `AARCH64_OPND_QLF_ERR'.
40
41Ar present the error presented in the hypothetical scenario has been
42encountered in `get_sreg_qualifier_from_value', but the change is made
43to the whole family to keep the interface consistent.
44
45Bug: https://sourceware.org/PR31595
46
47Upstream-Status: Backport [commit 2601b201e95ea0edab89342ee7137c74e88a8a79]
48
49Signed-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
57diff --git a/binutils/testsuite/binutils-all/aarch64/illegal.d b/binutils/testsuite/binutils-all/aarch64/illegal.d
58index 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
68diff --git a/binutils/testsuite/binutils-all/aarch64/illegal.s b/binutils/testsuite/binutils-all/aarch64/illegal.s
69index 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.
80diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
81index 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. */
94diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
95index 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--
3812.34.1
382