aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Jones <70633990+chris-jones-arm@users.noreply.github.com>2024-04-16 16:21:03 +0100
committerGitHub <noreply@github.com>2024-04-16 16:21:03 +0100
commit89dfbc009318786cffc22a902f2ea0930d937612 (patch)
tree2a5940fe9e3925105972c67a46b9fd18c129bc07
parent5a2144d133754452f7777ce71011412ad63eb6e0 (diff)
Check ld* functions for failure (#92)HEADmain
All memory read functions (e.g: ld1, ld2, etc...) return a value (either std::nullopt or false) to signal that the memory read failed. Some of these memory read functions were not being checked for failure; fix this by checking these functions for failure.
-rw-r--r--src/aarch64/simulator-aarch64.cc22
-rw-r--r--test/aarch64/test-simulator-aarch64.cc23
2 files changed, 32 insertions, 13 deletions
diff --git a/src/aarch64/simulator-aarch64.cc b/src/aarch64/simulator-aarch64.cc
index 17f0916c..5d77548f 100644
--- a/src/aarch64/simulator-aarch64.cc
+++ b/src/aarch64/simulator-aarch64.cc
@@ -8430,7 +8430,9 @@ void Simulator::NEONLoadStoreMultiStructHelper(const Instruction* instr,
break;
case NEON_LD2_post:
case NEON_LD2:
- ld2(vf, ReadVRegister(reg[0]), ReadVRegister(reg[1]), addr[0]);
+ if (!ld2(vf, ReadVRegister(reg[0]), ReadVRegister(reg[1]), addr[0])) {
+ return;
+ }
struct_parts = 2;
reg_count = 2;
break;
@@ -8443,11 +8445,13 @@ void Simulator::NEONLoadStoreMultiStructHelper(const Instruction* instr,
break;
case NEON_LD3_post:
case NEON_LD3:
- ld3(vf,
- ReadVRegister(reg[0]),
- ReadVRegister(reg[1]),
- ReadVRegister(reg[2]),
- addr[0]);
+ if (!ld3(vf,
+ ReadVRegister(reg[0]),
+ ReadVRegister(reg[1]),
+ ReadVRegister(reg[2]),
+ addr[0])) {
+ return;
+ }
struct_parts = 3;
reg_count = 3;
break;
@@ -12222,7 +12226,7 @@ void Simulator::VisitSVELoadAndBroadcastElement(const Instruction* instr) {
VectorFormat unpack_vform =
SVEFormatFromLaneSizeInBytesLog2(msize_in_bytes_log2);
SimVRegister temp;
- ld1r(vform, unpack_vform, temp, base, is_signed);
+ if (!ld1r(vform, unpack_vform, temp, base, is_signed)) return;
mov_zeroing(vform,
ReadVRegister(instr->GetRt()),
ReadPRegister(instr->GetPgLow8()),
@@ -12648,7 +12652,7 @@ void Simulator::VisitSVELoadAndBroadcastQOWord_ScalarPlusImm(
VectorFormat vform = SVEFormatFromLaneSizeInBytesLog2(msz);
for (unsigned i = 0; i < dwords; i++) {
- ld1(kFormatVnD, zt, i, addr + offset + (i * kDRegSizeInBytes));
+ if (!ld1(kFormatVnD, zt, i, addr + offset + (i * kDRegSizeInBytes))) return;
}
mov_zeroing(vform, zt, pg, zt);
dup_element(vform_dst, zt, zt, 0);
@@ -12675,7 +12679,7 @@ void Simulator::VisitSVELoadAndBroadcastQOWord_ScalarPlusScalar(
VectorFormat vform = SVEFormatFromLaneSizeInBytesLog2(msz);
offset <<= msz;
for (unsigned i = 0; i < bytes; i++) {
- ld1(kFormatVnB, zt, i, addr + offset + i);
+ if (!ld1(kFormatVnB, zt, i, addr + offset + i)) return;
}
mov_zeroing(vform, zt, pg, zt);
dup_element(vform_dst, zt, zt, 0);
diff --git a/test/aarch64/test-simulator-aarch64.cc b/test/aarch64/test-simulator-aarch64.cc
index 5318f65b..7ea41031 100644
--- a/test/aarch64/test-simulator-aarch64.cc
+++ b/test/aarch64/test-simulator-aarch64.cc
@@ -5147,18 +5147,28 @@ TEST(RunFrom) {
// Generate a function that creates a segfault by loading from an invalid
// address.
-Instruction* GenerateSegFault(MacroAssembler* masm) {
+Instruction* GenerateSegFault(MacroAssembler* masm, Label* start, Label* end) {
masm->Reset();
// Reset the counter.
__ Mov(x1, 0);
// Perform a series of invalid memory reads.
+ __ Bind(start);
__ Ldrb(w0, MemOperand());
__ Ldrh(w0, MemOperand());
__ Ldr(w0, MemOperand());
__ Ldr(x0, MemOperand());
__ Ldr(q0, MemOperand());
+ __ Ld1(v0.D(), MemOperand());
+ __ Ld2(v0.D(), v1.D(), MemOperand());
+ __ Ld3(v0.D(), v1.D(), v2.D(), MemOperand());
+ __ Ld4(v0.D(), v1.D(), v2.D(), v3.D(), MemOperand());
+ __ Ld1r(v0.D(), MemOperand());
+ __ Ld2r(v0.D(), v1.D(), MemOperand());
+ __ Ld3r(v0.D(), v1.D(), v2.D(), MemOperand());
+ __ Ld4r(v0.D(), v1.D(), v2.D(), v3.D(), MemOperand());
+ __ Bind(end);
// Return the counter.
__ Mov(x0, x1);
@@ -5200,9 +5210,14 @@ TEST(ImplicitCheck) {
sa.sa_sigaction = HandleSegFault;
sigaction(SIGSEGV, &sa, NULL);
- // Check that 5 segfaults were raised and dealt with.
- int64_t result = simulator.RunFrom<int64_t>(GenerateSegFault(&masm));
- VIXL_CHECK(result == 5);
+ // Check that each load/store instruction generated a segfault that was
+ // raised and dealt with.
+ Label start, end;
+ size_t result =
+ simulator.RunFrom<int64_t>(GenerateSegFault(&masm, &start, &end));
+ size_t num_of_faulting_instr = masm.GetSizeOfCodeGeneratedSince(&start) -
+ masm.GetSizeOfCodeGeneratedSince(&end);
+ VIXL_CHECK((result * kInstructionSize) == num_of_faulting_instr);
}
#endif // __x86_64__
#endif