Commit a27871d5 authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

PPC/s390: Reland "[turboassembler] Introduce hard-abort mode"

Port d324382e

and

Port bd3f0a68

Original Commit Message:

    This is a reland of a462a785

    Original change's description:
    > [turboassembler] Introduce hard-abort mode
    >
    > For checks and assertions (mostly for debug code, like stack alignment
    > or zero extension), we had two modes: Emit a call to the {Abort}
    > runtime function (the default), and emit a debug break (used for
    > testing, enabled via --trap-on-abort).
    > In wasm, where we cannot just call a runtime function because code must
    > be isolate independent, we always used the trap-on-abort behaviour.
    > This causes problems for our fuzzers, which do not catch SIGTRAP, and
    > hence do not detect debug code failures.
    >
    > This CL introduces a third mode ("hard abort"), which calls a C
    > function via {ExternalReference}. The C function still outputs the
    > abort reason, but does not print the stack trace. It then aborts via
    > "OS::Abort", just like the runtime function.
    > This will allow fuzzers to detect the crash and even find a nice error
    > message.
    >
    > Even though this looks like a lot of code churn, it is actually not.
    > Most added lines are new tests, and other changes are minimal.
    >
    > R=mstarzinger@chromium.org
    >
    > Bug: chromium:863799
    > Change-Id: I77c58ff72db552d49014614436259ccfb49ba87b
    > Reviewed-on: https://chromium-review.googlesource.com/1142163
    > Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
    > Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
    > Cr-Commit-Position: refs/heads/master@{#54592}

R=clemensh@chromium.org, joransiu@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N

Change-Id: I60023470fa07576fd313f628ade06e279d5f4927
Reviewed-on: https://chromium-review.googlesource.com/1165822
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54980}
parent 872b733f
......@@ -1760,13 +1760,23 @@ void TurboAssembler::Abort(AbortReason reason) {
#endif
// Avoid emitting call to builtin if requested.
if (trap_on_abort() || should_abort_hard()) {
// TODO(ppc): Call {ExternalReference::abort_with_reason} if
// {should_abort_hard} is set.
if (trap_on_abort()) {
stop(msg);
return;
}
if (should_abort_hard()) {
// We don't care if we constructed a frame. Just pretend we did.
FrameScope assume_frame(this, StackFrame::NONE);
mov(r3, Operand(static_cast<int>(reason)));
PrepareCallCFunction(1, 0, r4);
Move(r4, ExternalReference::abort_with_reason());
// Use Call directly to avoid any unneeded overhead. The function won't
// return anyway.
Call(r4);
return;
}
LoadSmiLiteral(r4, Smi::FromInt(static_cast<int>(reason)));
// Disable stub call restrictions to always allow calls to abort.
......
......@@ -91,7 +91,7 @@ Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2 = no_reg,
#define Div divw
#endif
class TurboAssembler : public TurboAssemblerBase {
class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
public:
TurboAssembler(Isolate* isolate, const AssemblerOptions& options,
void* buffer, int buffer_size,
......
......@@ -472,7 +472,7 @@ class DeferredRelocInfo {
intptr_t data_;
};
class Assembler : public AssemblerBase {
class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
public:
// Create an assembler. Instructions and relocation information are emitted
// into a buffer, with the instructions starting from the beginning and the
......
......@@ -1691,13 +1691,23 @@ void TurboAssembler::Abort(AbortReason reason) {
#endif
// Avoid emitting call to builtin if requested.
if (trap_on_abort() || should_abort_hard()) {
// TODO(s390): Call {ExternalReference::abort_with_reason} if
// {should_abort_hard} is set.
if (trap_on_abort()) {
stop(msg);
return;
}
if (should_abort_hard()) {
// We don't care if we constructed a frame. Just pretend we did.
FrameScope assume_frame(this, StackFrame::NONE);
lgfi(r2, Operand(static_cast<int>(reason)));
PrepareCallCFunction(1, 0, r3);
Move(r3, ExternalReference::abort_with_reason());
// Use Call directly to avoid any unneeded overhead. The function won't
// return anyway.
Call(r3);
return;
}
LoadSmiLiteral(r3, Smi::FromInt(static_cast<int>(reason)));
// Disable stub call restrictions to always allow calls to abort.
......@@ -1860,7 +1870,7 @@ void TurboAssembler::PrepareCallCFunction(int num_reg_arguments,
} else {
stack_space += stack_passed_arguments;
}
lay(sp, MemOperand(sp, -(stack_space)*kPointerSize));
lay(sp, MemOperand(sp, (-stack_space) * kPointerSize));
}
void TurboAssembler::PrepareCallCFunction(int num_reg_arguments,
......
......@@ -151,7 +151,7 @@ Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2 = no_reg,
#endif
class TurboAssembler : public TurboAssemblerBase {
class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
public:
TurboAssembler(Isolate* isolate, const AssemblerOptions& options,
void* buffer, int buffer_size,
......
......@@ -254,9 +254,15 @@ v8_source_set("unittests_sources") {
"compiler/x64/instruction-selector-x64-unittest.cc",
]
} else if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") {
sources += [ "compiler/ppc/instruction-selector-ppc-unittest.cc" ]
sources += [
"assembler/turbo-assembler-ppc-unittest.cc",
"compiler/ppc/instruction-selector-ppc-unittest.cc",
]
} else if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") {
sources += [ "compiler/s390/instruction-selector-s390-unittest.cc" ]
sources += [
"assembler/turbo-assembler-s390-unittest.cc",
"compiler/s390/instruction-selector-s390-unittest.cc",
]
}
configs = [
......
// Copyright 2018 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 "src/macro-assembler.h"
#include "src/ppc/assembler-ppc-inl.h"
#include "src/simulator.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ tasm.
// Test the ppc assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
size_t allocated;
byte* buffer = AllocateAssemblerBuffer(&allocated);
TurboAssembler tasm(nullptr, AssemblerOptions{}, buffer,
static_cast<int>(allocated), CodeObjectRequired::kNo);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
tasm.GetCode(nullptr, &desc);
MakeAssemblerBufferExecutable(buffer, allocated);
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer);
ASSERT_DEATH_IF_SUPPORTED({ f.Call(); }, "abort: no reason");
}
TEST_F(TurboAssemblerTest, TestCheck) {
size_t allocated;
byte* buffer = AllocateAssemblerBuffer(&allocated);
TurboAssembler tasm(nullptr, AssemblerOptions{}, buffer,
static_cast<int>(allocated), CodeObjectRequired::kNo);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
__ mov(r4, Operand(17));
__ cmp(r3, r4); // 1st parameter is in {r3}.
__ Check(Condition::ne, AbortReason::kNoReason);
__ Ret();
CodeDesc desc;
tasm.GetCode(nullptr, &desc);
MakeAssemblerBufferExecutable(buffer, allocated);
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer);
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED({ f.Call(17); }, "abort: no reason");
}
#undef __
} // namespace internal
} // namespace v8
// Copyright 2018 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 "src/macro-assembler.h"
#include "src/s390/assembler-s390-inl.h"
#include "src/simulator.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ tasm.
// Test the s390 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
size_t allocated;
byte* buffer = AllocateAssemblerBuffer(&allocated);
TurboAssembler tasm(nullptr, AssemblerOptions{}, buffer,
static_cast<int>(allocated), CodeObjectRequired::kNo);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
tasm.GetCode(nullptr, &desc);
MakeAssemblerBufferExecutable(buffer, allocated);
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer);
ASSERT_DEATH_IF_SUPPORTED({ f.Call(); }, "abort: no reason");
}
TEST_F(TurboAssemblerTest, TestCheck) {
size_t allocated;
byte* buffer = AllocateAssemblerBuffer(&allocated);
TurboAssembler tasm(nullptr, AssemblerOptions{}, buffer,
static_cast<int>(allocated), CodeObjectRequired::kNo);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
__ lgfi(r3, Operand(17));
__ CmpP(r2, r3); // 1st parameter is in {r2}.
__ Check(Condition::ne, AbortReason::kNoReason);
__ Ret();
CodeDesc desc;
tasm.GetCode(nullptr, &desc);
MakeAssemblerBufferExecutable(buffer, allocated);
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer);
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED({ f.Call(17); }, "abort: no reason");
}
#undef __
} // namespace internal
} // namespace v8
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