[wasm] "Vectorize" fuzzer
Instead of passing {uint8_t*, size_t} pairs as arguments, pass {Vector<uint8_t>}. This is less error prone and {Vector} provides some helpful methods. R=ahaas@chromium.org Bug: v8:7754 Change-Id: I7469054774618e0bd5c9d38501759b1b2c51d104 Reviewed-on: https://chromium-review.googlesource.com/1134773 Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#54406}
This commit is contained in:
parent
035581301d
commit
dad67377c3
@ -123,11 +123,18 @@ class Vector {
|
||||
length_ = 0;
|
||||
}
|
||||
|
||||
inline Vector<T> operator+(size_t offset) {
|
||||
Vector<T> operator+(size_t offset) {
|
||||
DCHECK_LE(offset, length_);
|
||||
return Vector<T>(start_ + offset, length_ - offset);
|
||||
}
|
||||
|
||||
Vector<T> operator+=(size_t offset) {
|
||||
DCHECK_LE(offset, length_);
|
||||
start_ += offset;
|
||||
length_ -= offset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Implicit conversion from Vector<T> to Vector<const T>.
|
||||
inline operator Vector<const T>() { return Vector<const T>::cast(*this); }
|
||||
|
||||
|
@ -20,14 +20,14 @@ namespace fuzzer {
|
||||
|
||||
class WasmCodeFuzzer : public WasmExecutionFuzzer {
|
||||
bool GenerateModule(
|
||||
Isolate* isolate, Zone* zone, const uint8_t* data, size_t size,
|
||||
Isolate* isolate, Zone* zone, Vector<const uint8_t> data,
|
||||
ZoneBuffer& buffer, int32_t& num_args,
|
||||
std::unique_ptr<WasmValue[]>& interpreter_args,
|
||||
std::unique_ptr<Handle<Object>[]>& compiler_args) override {
|
||||
TestSignatures sigs;
|
||||
WasmModuleBuilder builder(zone);
|
||||
WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
|
||||
f->EmitCode(data, static_cast<uint32_t>(size));
|
||||
f->EmitCode(data.start(), static_cast<uint32_t>(data.size()));
|
||||
uint8_t end_opcode = kExprEnd;
|
||||
f->EmitCode(&end_opcode, 1);
|
||||
builder.AddExport(CStrVector("main"), f);
|
||||
@ -46,7 +46,7 @@ class WasmCodeFuzzer : public WasmExecutionFuzzer {
|
||||
};
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
return WasmCodeFuzzer().FuzzWasmModule(data, size);
|
||||
return WasmCodeFuzzer().FuzzWasmModule({data, size});
|
||||
}
|
||||
|
||||
} // namespace fuzzer
|
||||
|
@ -34,35 +34,28 @@ constexpr int kMaxFunctions = 4;
|
||||
constexpr int kMaxGlobals = 64;
|
||||
|
||||
class DataRange {
|
||||
const uint8_t* data_;
|
||||
size_t size_;
|
||||
Vector<const uint8_t> data_;
|
||||
|
||||
public:
|
||||
DataRange(const uint8_t* data, size_t size) : data_(data), size_(size) {}
|
||||
explicit DataRange(Vector<const uint8_t> data) : data_(data) {}
|
||||
|
||||
// Don't accidentally pass DataRange by value. This will reuse bytes and might
|
||||
// lead to OOM because the end might not be reached.
|
||||
// Define move constructor and move assignment, disallow copy constructor and
|
||||
// copy assignment (below).
|
||||
DataRange(DataRange&& other) : DataRange(other.data_, other.size_) {
|
||||
other.data_ = nullptr;
|
||||
other.size_ = 0;
|
||||
}
|
||||
DataRange(DataRange&& other) : DataRange(other.data_) { other.data_ = {}; }
|
||||
DataRange& operator=(DataRange&& other) {
|
||||
data_ = other.data_;
|
||||
size_ = other.size_;
|
||||
other.data_ = nullptr;
|
||||
other.size_ = 0;
|
||||
other.data_ = {};
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t size() const { return size_; }
|
||||
size_t size() const { return data_.size(); }
|
||||
|
||||
DataRange split() {
|
||||
uint16_t num_bytes = get<uint16_t>() % std::max(size_t{1}, size_);
|
||||
DataRange split(data_, num_bytes);
|
||||
uint16_t num_bytes = get<uint16_t>() % std::max(size_t{1}, data_.size());
|
||||
DataRange split(data_.SubVector(0, num_bytes));
|
||||
data_ += num_bytes;
|
||||
size_ -= num_bytes;
|
||||
return split;
|
||||
}
|
||||
|
||||
@ -73,11 +66,10 @@ class DataRange {
|
||||
// okay if we don't have a full four bytes available, we'll just use what
|
||||
// we have. We aren't concerned about endianness because we are generating
|
||||
// arbitrary expressions.
|
||||
const size_t num_bytes = std::min(sizeof(T), size_);
|
||||
const size_t num_bytes = std::min(sizeof(T), data_.size());
|
||||
T result = T();
|
||||
memcpy(&result, data_, num_bytes);
|
||||
memcpy(&result, data_.start(), num_bytes);
|
||||
data_ += num_bytes;
|
||||
size_ -= num_bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -751,7 +743,7 @@ FunctionSig* GenerateSig(Zone* zone, DataRange& data) {
|
||||
|
||||
class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
bool GenerateModule(
|
||||
Isolate* isolate, Zone* zone, const uint8_t* data, size_t size,
|
||||
Isolate* isolate, Zone* zone, Vector<const uint8_t> data,
|
||||
ZoneBuffer& buffer, int32_t& num_args,
|
||||
std::unique_ptr<WasmValue[]>& interpreter_args,
|
||||
std::unique_ptr<Handle<Object>[]>& compiler_args) override {
|
||||
@ -759,7 +751,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
|
||||
WasmModuleBuilder builder(zone);
|
||||
|
||||
DataRange range(data, static_cast<uint32_t>(size));
|
||||
DataRange range(data);
|
||||
std::vector<FunctionSig*> function_signatures;
|
||||
function_signatures.push_back(sigs.i_iii());
|
||||
|
||||
@ -819,7 +811,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
constexpr bool require_valid = true;
|
||||
return WasmCompileFuzzer().FuzzWasmModule(data, size, require_valid);
|
||||
return WasmCompileFuzzer().FuzzWasmModule({data, size}, require_valid);
|
||||
}
|
||||
|
||||
} // namespace fuzzer
|
||||
|
@ -247,7 +247,7 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
|
||||
os << "})();\n";
|
||||
}
|
||||
|
||||
int WasmExecutionFuzzer::FuzzWasmModule(const uint8_t* data, size_t size,
|
||||
int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data,
|
||||
bool require_valid) {
|
||||
v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get();
|
||||
v8::Isolate* isolate = support->GetIsolate();
|
||||
@ -269,7 +269,7 @@ int WasmExecutionFuzzer::FuzzWasmModule(const uint8_t* data, size_t size,
|
||||
int32_t num_args = 0;
|
||||
std::unique_ptr<WasmValue[]> interpreter_args;
|
||||
std::unique_ptr<Handle<Object>[]> compiler_args;
|
||||
if (!GenerateModule(i_isolate, &zone, data, size, buffer, num_args,
|
||||
if (!GenerateModule(i_isolate, &zone, data, buffer, num_args,
|
||||
interpreter_args, compiler_args)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -32,12 +32,11 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
|
||||
class WasmExecutionFuzzer {
|
||||
public:
|
||||
virtual ~WasmExecutionFuzzer() {}
|
||||
int FuzzWasmModule(const uint8_t* data, size_t size,
|
||||
bool require_valid = false);
|
||||
int FuzzWasmModule(Vector<const uint8_t> data, bool require_valid = false);
|
||||
|
||||
protected:
|
||||
virtual bool GenerateModule(
|
||||
Isolate* isolate, Zone* zone, const uint8_t* data, size_t size,
|
||||
Isolate* isolate, Zone* zone, Vector<const uint8_t> data,
|
||||
ZoneBuffer& buffer, int32_t& num_args,
|
||||
std::unique_ptr<WasmValue[]>& interpreter_args,
|
||||
std::unique_ptr<Handle<Object>[]>& compiler_args) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user