summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-11-13 11:14:44 -0800
committerGitHub <noreply@github.com>2020-11-13 11:14:44 -0800
commit0f49b56029f93c1b54736ed2473d23f457d46894 (patch)
tree50e6e57a475971827137a0f4aacd27ae257e9489 /src
parent262bd62777fcde6b930d520e61457699dbb9901e (diff)
downloadbinaryen-0f49b56029f93c1b54736ed2473d23f457d46894.tar.gz
binaryen-0f49b56029f93c1b54736ed2473d23f457d46894.tar.bz2
binaryen-0f49b56029f93c1b54736ed2473d23f457d46894.zip
Fix a hashing regression from #3332 (#3349)
We used to check if a load's sign matters before hashing it. If the load does not extend, then the sign doesn't matter, and we ignored the value there. It turns out that value could be garbage, as we didn't assign it in the binary reader, if it wasn't relevant. In the rewrite this was missed, and actually it's not really possible to do, since we have just a macro for the field, but not the object it is on - which there may be more than one. To fix this, just always assign the field. This is simpler anyhow, and avoids confusion not just here but probably when debugging. The testcase here is reduced from the fuzzer, and is not a 100% guarantee to catch a read of uninitialized memory, but it can't hurt, and with ASan it may be pretty consistent.
Diffstat (limited to 'src')
-rw-r--r--src/wasm/wasm-binary.cpp34
1 files changed, 6 insertions, 28 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 18ae724f0..813810016 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -3160,86 +3160,72 @@ void WasmBinaryBuilder::readMemoryAccess(Address& alignment, Address& offset) {
bool WasmBinaryBuilder::maybeVisitLoad(Expression*& out,
uint8_t code,
bool isAtomic) {
- Load* curr;
+ auto* curr = allocator.alloc<Load>();
+ // The signed field does not matter in some cases (where the size of the load
+ // is equal to the size of the type, in which case we do not extend), but give
+ // it a default value nonetheless, to make hashing and other code simpler, so
+ // that they do not need to consider whether the sign matters or not.
+ curr->signed_ = false;
if (!isAtomic) {
switch (code) {
case BinaryConsts::I32LoadMem8S:
- curr = allocator.alloc<Load>();
curr->bytes = 1;
curr->type = Type::i32;
curr->signed_ = true;
break;
case BinaryConsts::I32LoadMem8U:
- curr = allocator.alloc<Load>();
curr->bytes = 1;
curr->type = Type::i32;
- curr->signed_ = false;
break;
case BinaryConsts::I32LoadMem16S:
- curr = allocator.alloc<Load>();
curr->bytes = 2;
curr->type = Type::i32;
curr->signed_ = true;
break;
case BinaryConsts::I32LoadMem16U:
- curr = allocator.alloc<Load>();
curr->bytes = 2;
curr->type = Type::i32;
- curr->signed_ = false;
break;
case BinaryConsts::I32LoadMem:
- curr = allocator.alloc<Load>();
curr->bytes = 4;
curr->type = Type::i32;
break;
case BinaryConsts::I64LoadMem8S:
- curr = allocator.alloc<Load>();
curr->bytes = 1;
curr->type = Type::i64;
curr->signed_ = true;
break;
case BinaryConsts::I64LoadMem8U:
- curr = allocator.alloc<Load>();
curr->bytes = 1;
curr->type = Type::i64;
- curr->signed_ = false;
break;
case BinaryConsts::I64LoadMem16S:
- curr = allocator.alloc<Load>();
curr->bytes = 2;
curr->type = Type::i64;
curr->signed_ = true;
break;
case BinaryConsts::I64LoadMem16U:
- curr = allocator.alloc<Load>();
curr->bytes = 2;
curr->type = Type::i64;
- curr->signed_ = false;
break;
case BinaryConsts::I64LoadMem32S:
- curr = allocator.alloc<Load>();
curr->bytes = 4;
curr->type = Type::i64;
curr->signed_ = true;
break;
case BinaryConsts::I64LoadMem32U:
- curr = allocator.alloc<Load>();
curr->bytes = 4;
curr->type = Type::i64;
- curr->signed_ = false;
break;
case BinaryConsts::I64LoadMem:
- curr = allocator.alloc<Load>();
curr->bytes = 8;
curr->type = Type::i64;
break;
case BinaryConsts::F32LoadMem:
- curr = allocator.alloc<Load>();
curr->bytes = 4;
curr->type = Type::f32;
break;
case BinaryConsts::F64LoadMem:
- curr = allocator.alloc<Load>();
curr->bytes = 8;
curr->type = Type::f64;
break;
@@ -3250,44 +3236,36 @@ bool WasmBinaryBuilder::maybeVisitLoad(Expression*& out,
} else {
switch (code) {
case BinaryConsts::I32AtomicLoad8U:
- curr = allocator.alloc<Load>();
curr->bytes = 1;
curr->type = Type::i32;
break;
case BinaryConsts::I32AtomicLoad16U:
- curr = allocator.alloc<Load>();
curr->bytes = 2;
curr->type = Type::i32;
break;
case BinaryConsts::I32AtomicLoad:
- curr = allocator.alloc<Load>();
curr->bytes = 4;
curr->type = Type::i32;
break;
case BinaryConsts::I64AtomicLoad8U:
- curr = allocator.alloc<Load>();
curr->bytes = 1;
curr->type = Type::i64;
break;
case BinaryConsts::I64AtomicLoad16U:
- curr = allocator.alloc<Load>();
curr->bytes = 2;
curr->type = Type::i64;
break;
case BinaryConsts::I64AtomicLoad32U:
- curr = allocator.alloc<Load>();
curr->bytes = 4;
curr->type = Type::i64;
break;
case BinaryConsts::I64AtomicLoad:
- curr = allocator.alloc<Load>();
curr->bytes = 8;
curr->type = Type::i64;
break;
default:
return false;
}
- curr->signed_ = false;
BYN_TRACE("zz node: AtomicLoad\n");
}