@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -797,7 +797,26 @@ static bool decode_parsebits_is_loopend(uint32_t encoding32)
return bits == 0x2;
}
-static void
+static bool has_valid_slot_assignment(Packet *pkt)
+{
+ int used_slots = 0;
+ for (int i = 0; i < pkt->num_insns; i++) {
+ int slot_mask;
+ Insn *insn = &pkt->insn[i];
+ if (decode_opcode_ends_loop(insn->opcode)) {
+ /* We overload slot 0 for endloop. */
+ continue;
+ }
+ slot_mask = 1 << insn->slot;
+ if (used_slots & slot_mask) {
+ return false;
+ }
+ used_slots |= slot_mask;
+ }
+ return true;
+}
+
+static bool
decode_set_slot_number(Packet *pkt)
{
int slot;
@@ -886,6 +905,8 @@ decode_set_slot_number(Packet *pkt)
/* Then push it to slot0 */
pkt->insn[slot1_iidx].slot = 0;
}
+
+ return has_valid_slot_assignment(pkt);
}
/*
@@ -962,7 +983,10 @@ int decode_packet(int max_words, const uint32_t *words, Packet *pkt,
if (!disas_only) {
decode_remove_extenders(pkt);
}
- decode_set_slot_number(pkt);
+ if (!decode_set_slot_number(pkt)) {
+ /* Invalid packet */
+ return 0;
+ }
decode_fill_newvalue_regno(pkt);
if (pkt->pkt_has_hvx) {
new file mode 100644
@@ -0,0 +1,29 @@
+/*
+ * Copyright(c) 2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+char mem[8] __attribute__((aligned(8)));
+
+int main()
+{
+ asm volatile(
+ "r0 = #mem\n"
+ /* Invalid packet (2 instructions at slot 0): */
+ ".word 0xa1804100\n" /* { memw(r0) = r1; */
+ ".word 0x28032804\n" /* r3 = #0; r4 = #0 } */
+ : : : "r0", "r3", "r4", "memory");
+ return 0;
+}
@@ -49,6 +49,17 @@ HEX_TESTS += vector_add_int
HEX_TESTS += scatter_gather
HEX_TESTS += hvx_misc
HEX_TESTS += hvx_histogram
+HEX_TESTS += invalid-slots
+
+run-and-check-exception = $(call run-test,$2,$3 2>$2.stderr; \
+ test $$? -eq 1 && grep -q "exception $(strip $1)" $2.stderr)
+
+run-invalid-slots: invalid-slots
+ $(call run-and-check-exception, 0x15, $@, $(QEMU) $(QEMU_OPTS) $<)
+
+run-plugin-invalid-slots-with-%: invalid-slots
+ $(call run-and-check-exception, 0x15, $@, $(QEMU) $(QEMU_OPTS) \
+ -plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) $(call strip-plugin,$<))
HEX_TESTS += test_abs
HEX_TESTS += test_bitcnt