blob: ea9fb09afdb7b497ed0ed5680a77c1c9d528b91c [file] [log] [blame]
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "test/fuzzer/fuzzer-support.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/libplatform/libplatform.h"
#include "src/flags.h"
namespace v8_fuzzer {
namespace {
FuzzerSupport* g_fuzzer_support = nullptr;
void DeleteFuzzerSupport() {
if (g_fuzzer_support) {
delete g_fuzzer_support;
g_fuzzer_support = nullptr;
}
}
} // namespace
class FuzzerSupport::ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public:
virtual void* Allocate(size_t length) {
void* data = AllocateUninitialized(length);
return data == NULL ? data : memset(data, 0, length);
}
virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
virtual void Free(void* data, size_t) { free(data); }
};
FuzzerSupport::FuzzerSupport(int* argc, char*** argv) {
v8::internal::FLAG_expose_gc = true;
v8::V8::SetFlagsFromCommandLine(argc, *argv, true);
v8::V8::InitializeICUDefaultLocation((*argv)[0]);
v8::V8::InitializeExternalStartupData((*argv)[0]);
platform_ = v8::platform::CreateDefaultPlatform();
v8::V8::InitializePlatform(platform_);
v8::V8::Initialize();
allocator_ = new ArrayBufferAllocator;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = allocator_;
isolate_ = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate_);
v8::HandleScope handle_scope(isolate_);
context_.Reset(isolate_, v8::Context::New(isolate_));
}
}
FuzzerSupport::~FuzzerSupport() {
{
v8::Isolate::Scope isolate_scope(isolate_);
while (v8::platform::PumpMessageLoop(platform_, isolate_)) /* empty */
;
v8::HandleScope handle_scope(isolate_);
context_.Reset();
}
isolate_->LowMemoryNotification();
isolate_->Dispose();
isolate_ = nullptr;
delete allocator_;
allocator_ = nullptr;
v8::V8::Dispose();
v8::V8::ShutdownPlatform();
delete platform_;
platform_ = nullptr;
}
// static
FuzzerSupport* FuzzerSupport::Get() { return g_fuzzer_support; }
v8::Isolate* FuzzerSupport::GetIsolate() { return isolate_; }
v8::Local<v8::Context> FuzzerSupport::GetContext() {
v8::Isolate::Scope isolate_scope(isolate_);
v8::EscapableHandleScope handle_scope(isolate_);
v8::Local<v8::Context> context =
v8::Local<v8::Context>::New(isolate_, context_);
return handle_scope.Escape(context);
}
} // namespace v8_fuzzer
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
v8_fuzzer::g_fuzzer_support = new v8_fuzzer::FuzzerSupport(argc, argv);
atexit(&v8_fuzzer::DeleteFuzzerSupport);
return 0;
}