Commit ff134a19 authored by ishell@chromium.org's avatar ishell@chromium.org

Stack overflow checkers are now compatible with ASAN's detect_stack_use_after_return mode.

BUG=chromium:376287
BUG=chromium:376262
BUG=chromium:369962
LOG=N
R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/368053002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22183 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7b941432
...@@ -1848,19 +1848,10 @@ v8::TryCatch::TryCatch() ...@@ -1848,19 +1848,10 @@ v8::TryCatch::TryCatch()
rethrow_(false), rethrow_(false),
has_terminated_(false) { has_terminated_(false) {
Reset(); Reset();
js_stack_comparable_address_ = this;
#ifdef V8_USE_ADDRESS_SANITIZER
void* asan_fake_stack_handle = __asan_get_current_fake_stack();
if (asan_fake_stack_handle != NULL) {
js_stack_comparable_address_ = __asan_addr_is_in_fake_stack(
asan_fake_stack_handle, js_stack_comparable_address_, NULL, NULL);
CHECK(js_stack_comparable_address_ != NULL);
}
#endif
// Special handling for simulators which have a separate JS stack. // Special handling for simulators which have a separate JS stack.
js_stack_comparable_address_ = reinterpret_cast<void*>( js_stack_comparable_address_ =
v8::internal::SimulatorStack::RegisterCTryCatch( reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
reinterpret_cast<uintptr_t>(js_stack_comparable_address_))); GetCurrentStackPosition()));
isolate_->RegisterTryCatchHandler(this); isolate_->RegisterTryCatchHandler(this);
} }
......
...@@ -246,4 +246,14 @@ inline uint32_t RoundDownToPowerOf2(uint32_t x) { ...@@ -246,4 +246,14 @@ inline uint32_t RoundDownToPowerOf2(uint32_t x) {
return rounded_up; return rounded_up;
} }
// Returns current value of top of the stack. Works correctly with ASAN.
DISABLE_ASAN
inline uintptr_t GetCurrentStackPosition() {
// Takes the address of the limit variable in order to find out where
// the top of stack is right now.
uintptr_t limit = reinterpret_cast<uintptr_t>(&limit);
return limit;
}
#endif // V8_BASE_MACROS_H_ #endif // V8_BASE_MACROS_H_
...@@ -443,11 +443,9 @@ void StackGuard::ThreadLocal::Clear() { ...@@ -443,11 +443,9 @@ void StackGuard::ThreadLocal::Clear() {
bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) { bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
bool should_set_stack_limits = false; bool should_set_stack_limits = false;
if (real_climit_ == kIllegalLimit) { if (real_climit_ == kIllegalLimit) {
// Takes the address of the limit variable in order to find out where
// the top of stack is right now.
const uintptr_t kLimitSize = FLAG_stack_size * KB; const uintptr_t kLimitSize = FLAG_stack_size * KB;
uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; ASSERT(GetCurrentStackPosition() > kLimitSize);
ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); uintptr_t limit = GetCurrentStackPosition() - kLimitSize;
real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
real_climit_ = limit; real_climit_ = limit;
......
...@@ -261,11 +261,6 @@ class StackGuard V8_FINAL { ...@@ -261,11 +261,6 @@ class StackGuard V8_FINAL {
int interrupt_flags_; int interrupt_flags_;
}; };
class StackPointer {
public:
inline uintptr_t address() { return reinterpret_cast<uintptr_t>(this); }
};
// TODO(isolates): Technically this could be calculated directly from a // TODO(isolates): Technically this could be calculated directly from a
// pointer to StackGuard. // pointer to StackGuard.
Isolate* isolate_; Isolate* isolate_;
......
...@@ -2354,7 +2354,7 @@ bool StackLimitCheck::JsHasOverflowed() const { ...@@ -2354,7 +2354,7 @@ bool StackLimitCheck::JsHasOverflowed() const {
uintptr_t jssp = reinterpret_cast<uintptr_t>(jssp_address); uintptr_t jssp = reinterpret_cast<uintptr_t>(jssp_address);
if (jssp < stack_guard->real_jslimit()) return true; if (jssp < stack_guard->real_jslimit()) return true;
#endif // USE_SIMULATOR #endif // USE_SIMULATOR
return reinterpret_cast<uintptr_t>(this) < stack_guard->real_climit(); return GetCurrentStackPosition() < stack_guard->real_climit();
} }
......
...@@ -1417,7 +1417,7 @@ class StackLimitCheck BASE_EMBEDDED { ...@@ -1417,7 +1417,7 @@ class StackLimitCheck BASE_EMBEDDED {
// Use this to check for stack-overflows in C++ code. // Use this to check for stack-overflows in C++ code.
inline bool HasOverflowed() const { inline bool HasOverflowed() const {
StackGuard* stack_guard = isolate_->stack_guard(); StackGuard* stack_guard = isolate_->stack_guard();
return reinterpret_cast<uintptr_t>(this) < stack_guard->real_climit(); return GetCurrentStackPosition() < stack_guard->real_climit();
} }
// Use this to check for stack-overflow when entering runtime from JS code. // Use this to check for stack-overflow when entering runtime from JS code.
......
...@@ -246,8 +246,7 @@ class ParserBase : public Traits { ...@@ -246,8 +246,7 @@ class ParserBase : public Traits {
INLINE(Token::Value Next()) { INLINE(Token::Value Next()) {
if (stack_overflow_) return Token::ILLEGAL; if (stack_overflow_) return Token::ILLEGAL;
{ {
int marker; if (GetCurrentStackPosition() < stack_limit_) {
if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
// Any further calls to Next or peek will return the illegal token. // Any further calls to Next or peek will return the illegal token.
// The current call must return the next token, which might already // The current call must return the next token, which might already
// have been peek'ed. // have been peek'ed.
......
...@@ -143,9 +143,8 @@ TEST(ScanHTMLEndComments) { ...@@ -143,9 +143,8 @@ TEST(ScanHTMLEndComments) {
}; };
// Parser/Scanner needs a stack limit. // Parser/Scanner needs a stack limit.
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
for (int i = 0; tests[i]; i++) { for (int i = 0; tests[i]; i++) {
const i::byte* source = const i::byte* source =
...@@ -199,9 +198,8 @@ TEST(UsingCachedData) { ...@@ -199,9 +198,8 @@ TEST(UsingCachedData) {
v8::HandleScope handles(isolate); v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate); v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
// Source containing functions that might be lazily compiled and all types // Source containing functions that might be lazily compiled and all types
// of symbols (string, propertyName, regexp). // of symbols (string, propertyName, regexp).
...@@ -247,9 +245,8 @@ TEST(PreparseFunctionDataIsUsed) { ...@@ -247,9 +245,8 @@ TEST(PreparseFunctionDataIsUsed) {
v8::HandleScope handles(isolate); v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate); v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
const char* good_code = const char* good_code =
"function this_is_lazy() { var a; } function foo() { return 25; } foo();"; "function this_is_lazy() { var a; } function foo() { return 25; } foo();";
...@@ -282,9 +279,8 @@ TEST(PreparseFunctionDataIsUsed) { ...@@ -282,9 +279,8 @@ TEST(PreparseFunctionDataIsUsed) {
TEST(StandAlonePreParser) { TEST(StandAlonePreParser) {
v8::V8::Initialize(); v8::V8::Initialize();
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
const char* programs[] = { const char* programs[] = {
"{label: 42}", "{label: 42}",
...@@ -319,9 +315,8 @@ TEST(StandAlonePreParser) { ...@@ -319,9 +315,8 @@ TEST(StandAlonePreParser) {
TEST(StandAlonePreParserNoNatives) { TEST(StandAlonePreParserNoNatives) {
v8::V8::Initialize(); v8::V8::Initialize();
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
const char* programs[] = { const char* programs[] = {
"%ArgleBargle(glop);", "%ArgleBargle(glop);",
...@@ -358,9 +353,8 @@ TEST(PreparsingObjectLiterals) { ...@@ -358,9 +353,8 @@ TEST(PreparsingObjectLiterals) {
v8::HandleScope handles(isolate); v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate); v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
{ {
const char* source = "var myo = {if: \"foo\"}; myo.if;"; const char* source = "var myo = {if: \"foo\"}; myo.if;";
...@@ -392,9 +386,7 @@ TEST(RegressChromium62639) { ...@@ -392,9 +386,7 @@ TEST(RegressChromium62639) {
v8::V8::Initialize(); v8::V8::Initialize();
i::Isolate* isolate = CcTest::i_isolate(); i::Isolate* isolate = CcTest::i_isolate();
int marker; isolate->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 128 * 1024);
isolate->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
const char* program = "var x = 'something';\n" const char* program = "var x = 'something';\n"
"escape: function() {}"; "escape: function() {}";
...@@ -429,9 +421,7 @@ TEST(Regress928) { ...@@ -429,9 +421,7 @@ TEST(Regress928) {
// as with-content, which made it assume that a function inside // as with-content, which made it assume that a function inside
// the block could be lazily compiled, and an extra, unexpected, // the block could be lazily compiled, and an extra, unexpected,
// entry was added to the data. // entry was added to the data.
int marker; isolate->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 128 * 1024);
isolate->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
const char* program = const char* program =
"try { } catch (e) { var foo = function () { /* first */ } }" "try { } catch (e) { var foo = function () { /* first */ } }"
...@@ -473,9 +463,8 @@ TEST(Regress928) { ...@@ -473,9 +463,8 @@ TEST(Regress928) {
TEST(PreParseOverflow) { TEST(PreParseOverflow) {
v8::V8::Initialize(); v8::V8::Initialize();
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
size_t kProgramSize = 1024 * 1024; size_t kProgramSize = 1024 * 1024;
i::SmartArrayPointer<char> program(i::NewArray<char>(kProgramSize + 1)); i::SmartArrayPointer<char> program(i::NewArray<char>(kProgramSize + 1));
...@@ -1097,9 +1086,7 @@ TEST(ScopePositions) { ...@@ -1097,9 +1086,7 @@ TEST(ScopePositions) {
v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
int marker; isolate->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 128 * 1024);
isolate->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
for (int i = 0; source_data[i].outer_prefix; i++) { for (int i = 0; source_data[i].outer_prefix; i++) {
int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix); int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
...@@ -1400,9 +1387,8 @@ TEST(ParserSync) { ...@@ -1400,9 +1387,8 @@ TEST(ParserSync) {
v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
static const ParserFlag flags1[] = { static const ParserFlag flags1[] = {
kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators, kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
...@@ -1478,9 +1464,8 @@ void RunParserSyncTest(const char* context_data[][2], ...@@ -1478,9 +1464,8 @@ void RunParserSyncTest(const char* context_data[][2],
v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
static const ParserFlag default_flags[] = { static const ParserFlag default_flags[] = {
kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators, kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
...@@ -2153,9 +2138,8 @@ TEST(DontRegressPreParserDataSizes) { ...@@ -2153,9 +2138,8 @@ TEST(DontRegressPreParserDataSizes) {
v8::Isolate* isolate = CcTest::isolate(); v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate); v8::HandleScope handles(isolate);
int marker; CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
CcTest::i_isolate()->stack_guard()->SetStackLimit( 128 * 1024);
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
struct TestCase { struct TestCase {
const char* program; const char* program;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment