[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 39/39] target-arm: Avoid buffer overrun on UNPREDICTA
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 39/39] target-arm: Avoid buffer overrun on UNPREDICTABLE ldrd/strd |
Date: |
Fri, 29 May 2015 14:10:45 +0100 |
A LDRD or STRD where rd is not an even number is UNPREDICTABLE.
We were letting this fall through, which is OK unless rd is 15,
in which case we would attempt to do a load_reg or store_reg
to a nonexistent r16 for the second half of the double-word.
Catch the odd-numbered-rd cases and UNDEF them instead.
To do this we rearrange the structure of the code a little
so we can put the UNDEF catches at the top before we've
allocated TCG temporaries.
Cc: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
Message-id: address@hidden
---
target-arm/translate.c | 56 ++++++++++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 24 deletions(-)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6493b9a..39692d7 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -8430,34 +8430,30 @@ static void disas_arm_insn(DisasContext *s, unsigned
int insn)
}
} else {
int address_offset;
- int load;
+ bool load = insn & (1 << 20);
+ bool doubleword = false;
/* Misc load/store */
rn = (insn >> 16) & 0xf;
rd = (insn >> 12) & 0xf;
+
+ if (!load && (sh & 2)) {
+ /* doubleword */
+ ARCH(5TE);
+ if (rd & 1) {
+ /* UNPREDICTABLE; we choose to UNDEF */
+ goto illegal_op;
+ }
+ load = (sh & 1) == 0;
+ doubleword = true;
+ }
+
addr = load_reg(s, rn);
if (insn & (1 << 24))
gen_add_datah_offset(s, insn, 0, addr);
address_offset = 0;
- if (insn & (1 << 20)) {
- /* load */
- tmp = tcg_temp_new_i32();
- switch(sh) {
- case 1:
- gen_aa32_ld16u(tmp, addr, get_mem_index(s));
- break;
- case 2:
- gen_aa32_ld8s(tmp, addr, get_mem_index(s));
- break;
- default:
- case 3:
- gen_aa32_ld16s(tmp, addr, get_mem_index(s));
- break;
- }
- load = 1;
- } else if (sh & 2) {
- ARCH(5TE);
- /* doubleword */
- if (sh & 1) {
+
+ if (doubleword) {
+ if (!load) {
/* store */
tmp = load_reg(s, rd);
gen_aa32_st32(tmp, addr, get_mem_index(s));
@@ -8466,7 +8462,6 @@ static void disas_arm_insn(DisasContext *s, unsigned int
insn)
tmp = load_reg(s, rd + 1);
gen_aa32_st32(tmp, addr, get_mem_index(s));
tcg_temp_free_i32(tmp);
- load = 0;
} else {
/* load */
tmp = tcg_temp_new_i32();
@@ -8476,15 +8471,28 @@ static void disas_arm_insn(DisasContext *s, unsigned
int insn)
tmp = tcg_temp_new_i32();
gen_aa32_ld32u(tmp, addr, get_mem_index(s));
rd++;
- load = 1;
}
address_offset = -4;
+ } else if (load) {
+ /* load */
+ tmp = tcg_temp_new_i32();
+ switch (sh) {
+ case 1:
+ gen_aa32_ld16u(tmp, addr, get_mem_index(s));
+ break;
+ case 2:
+ gen_aa32_ld8s(tmp, addr, get_mem_index(s));
+ break;
+ default:
+ case 3:
+ gen_aa32_ld16s(tmp, addr, get_mem_index(s));
+ break;
+ }
} else {
/* store */
tmp = load_reg(s, rd);
gen_aa32_st16(tmp, addr, get_mem_index(s));
tcg_temp_free_i32(tmp);
- load = 0;
}
/* Perform base writeback before the loaded value to
ensure correct behavior with overlapping index registers.
--
1.9.1
- [Qemu-devel] [PULL 00/39] target-arm queue, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 35/39] hw/acpi/aml-build: Add Unicode macro, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 30/39] hw/acpi/aml-build: Add aml_or() term, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 37/39] ACPI: split CONFIG_ACPI into 4 pieces, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 34/39] hw/acpi/aml-build: Add aml_dword_io() term, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 28/39] hw/acpi/aml-build: Make aml_buffer() definition consistent with the spec, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 31/39] hw/acpi/aml-build: Add aml_lnot() term, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 36/39] hw/arm/virt-acpi-build: Add PCIe controller in ACPI DSDT table, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 26/39] hw/arm/virt-acpi-build: Generate RSDP table, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 25/39] hw/arm/virt-acpi-build: Generate RSDT table, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 39/39] target-arm: Avoid buffer overrun on UNPREDICTABLE ldrd/strd,
Peter Maydell <=
- [Qemu-devel] [PULL 33/39] hw/acpi/aml-build: Add aml_create_dword_field() term, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 23/39] hw/arm/virt-acpi-build: Generate MADT table, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 32/39] hw/acpi/aml-build: Add aml_else() term, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 20/39] hw/acpi/aml-build: Add aml_interrupt() term, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 27/39] hw/arm/virt-acpi-build: Generate MCFG table, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 38/39] hw/arm/virt: Enable dynamic generation of ACPI v5.1 tables, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 21/39] hw/arm/virt-acpi-build: Generation of DSDT table for virt devices, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 17/39] hw/arm/virt: Record PCIe ranges in MemMapEntry array, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 01/39] target-arm: Add exception target el infrastructure, Peter Maydell, 2015/05/29
- [Qemu-devel] [PULL 22/39] hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers, Peter Maydell, 2015/05/29