Commit 9c5f1abc authored by jgruber's avatar jgruber Committed by Commit Bot

[builtins] Pad embedded builtins with int3

This fills the padding between builtins in the embedded blob with a
sequence of int3 instructions (ia32,x64).

Drive-by: Unify code zapping. We can add better support for other
architectures later.

Bug: v8:6666
Change-Id: Ibcb120ec18a8062d7527e0c6fe5ca86869c0dad8
Reviewed-on: https://chromium-review.googlesource.com/1167050
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54976}
parent e2fb86f8
...@@ -3915,7 +3915,7 @@ void MinorMarkCompactCollector::MakeIterable( ...@@ -3915,7 +3915,7 @@ void MinorMarkCompactCollector::MakeIterable(
p->AddressToMarkbitIndex(free_start), p->AddressToMarkbitIndex(free_start),
p->AddressToMarkbitIndex(free_end)); p->AddressToMarkbitIndex(free_end));
if (free_space_mode == ZAP_FREE_SPACE) { if (free_space_mode == ZAP_FREE_SPACE) {
memset(reinterpret_cast<void*>(free_start), 0xCC, size); ZapCode(free_start, size);
} }
p->heap()->CreateFillerObjectAt(free_start, static_cast<int>(size), p->heap()->CreateFillerObjectAt(free_start, static_cast<int>(size),
ClearRecordedSlots::kNo); ClearRecordedSlots::kNo);
...@@ -3932,7 +3932,7 @@ void MinorMarkCompactCollector::MakeIterable( ...@@ -3932,7 +3932,7 @@ void MinorMarkCompactCollector::MakeIterable(
p->AddressToMarkbitIndex(free_start), p->AddressToMarkbitIndex(free_start),
p->AddressToMarkbitIndex(p->area_end())); p->AddressToMarkbitIndex(p->area_end()));
if (free_space_mode == ZAP_FREE_SPACE) { if (free_space_mode == ZAP_FREE_SPACE) {
memset(reinterpret_cast<void*>(free_start), 0xCC, size); ZapCode(free_start, size);
} }
p->heap()->CreateFillerObjectAt(free_start, static_cast<int>(size), p->heap()->CreateFillerObjectAt(free_start, static_cast<int>(size),
ClearRecordedSlots::kNo); ClearRecordedSlots::kNo);
......
...@@ -279,7 +279,7 @@ int Sweeper::RawSweep(Page* p, FreeListRebuildingMode free_list_mode, ...@@ -279,7 +279,7 @@ int Sweeper::RawSweep(Page* p, FreeListRebuildingMode free_list_mode,
CHECK_GT(free_end, free_start); CHECK_GT(free_end, free_start);
size_t size = static_cast<size_t>(free_end - free_start); size_t size = static_cast<size_t>(free_end - free_start);
if (free_space_mode == ZAP_FREE_SPACE) { if (free_space_mode == ZAP_FREE_SPACE) {
memset(reinterpret_cast<void*>(free_start), 0xCC, size); ZapCode(free_start, size);
} }
if (free_list_mode == REBUILD_FREE_LIST) { if (free_list_mode == REBUILD_FREE_LIST) {
freed_bytes = reinterpret_cast<PagedSpace*>(space)->Free( freed_bytes = reinterpret_cast<PagedSpace*>(space)->Free(
...@@ -319,7 +319,7 @@ int Sweeper::RawSweep(Page* p, FreeListRebuildingMode free_list_mode, ...@@ -319,7 +319,7 @@ int Sweeper::RawSweep(Page* p, FreeListRebuildingMode free_list_mode,
CHECK_GT(p->area_end(), free_start); CHECK_GT(p->area_end(), free_start);
size_t size = static_cast<size_t>(p->area_end() - free_start); size_t size = static_cast<size_t>(p->area_end() - free_start);
if (free_space_mode == ZAP_FREE_SPACE) { if (free_space_mode == ZAP_FREE_SPACE) {
memset(reinterpret_cast<void*>(free_start), 0xCC, size); ZapCode(free_start, size);
} }
if (free_list_mode == REBUILD_FREE_LIST) { if (free_list_mode == REBUILD_FREE_LIST) {
freed_bytes = reinterpret_cast<PagedSpace*>(space)->Free( freed_bytes = reinterpret_cast<PagedSpace*>(space)->Free(
......
...@@ -330,9 +330,7 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer, ...@@ -330,9 +330,7 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer,
// caller in which case we can't be sure it's okay to overwrite // caller in which case we can't be sure it's okay to overwrite
// existing code in it. // existing code in it.
#ifdef DEBUG #ifdef DEBUG
if (own_buffer_) { if (own_buffer_) ZapCode(reinterpret_cast<Address>(buffer_), buffer_size_);
memset(buffer_, 0xCC, buffer_size_); // int3
}
#endif #endif
reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
...@@ -3194,7 +3192,7 @@ void Assembler::GrowBuffer() { ...@@ -3194,7 +3192,7 @@ void Assembler::GrowBuffer() {
// Clear the buffer in debug mode. Use 'int3' instructions to make // Clear the buffer in debug mode. Use 'int3' instructions to make
// sure to get into problems if we ever run uninitialized code. // sure to get into problems if we ever run uninitialized code.
#ifdef DEBUG #ifdef DEBUG
memset(desc.buffer, 0xCC, desc.buffer_size); ZapCode(reinterpret_cast<Address>(desc.buffer), desc.buffer_size);
#endif #endif
// Copy the data. // Copy the data.
......
...@@ -406,7 +406,7 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) { ...@@ -406,7 +406,7 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
metadata[i].instructions_length = length; metadata[i].instructions_length = length;
// Align the start of each instruction stream. // Align the start of each instruction stream.
raw_data_size += RoundUp<kCodeAlignment>(length); raw_data_size += PadAndAlign(length);
} else { } else {
metadata[i].instructions_offset = raw_data_size; metadata[i].instructions_offset = raw_data_size;
} }
...@@ -418,8 +418,12 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) { ...@@ -418,8 +418,12 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
"If in doubt, ask jgruber@"); "If in doubt, ask jgruber@");
const uint32_t blob_size = RawDataOffset() + raw_data_size; const uint32_t blob_size = RawDataOffset() + raw_data_size;
uint8_t* blob = new uint8_t[blob_size]; uint8_t* const blob = new uint8_t[blob_size];
std::memset(blob, 0, blob_size); uint8_t* const raw_data_start = blob + RawDataOffset();
// Initially zap the entire blob, effectively padding the alignment area
// between two builtins with int3's (on x64/ia32).
ZapCode(reinterpret_cast<Address>(blob), blob_size);
// Write the metadata tables. // Write the metadata tables.
DCHECK_EQ(MetadataSize(), sizeof(metadata[0]) * metadata.size()); DCHECK_EQ(MetadataSize(), sizeof(metadata[0]) * metadata.size());
...@@ -430,7 +434,7 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) { ...@@ -430,7 +434,7 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
if (!Builtins::IsIsolateIndependent(i)) continue; if (!Builtins::IsIsolateIndependent(i)) continue;
Code* code = builtins->builtin(i); Code* code = builtins->builtin(i);
uint32_t offset = metadata[i].instructions_offset; uint32_t offset = metadata[i].instructions_offset;
uint8_t* dst = blob + RawDataOffset() + offset; uint8_t* dst = raw_data_start + offset;
DCHECK_LE(RawDataOffset() + offset + code->raw_instruction_size(), DCHECK_LE(RawDataOffset() + offset + code->raw_instruction_size(),
blob_size); blob_size);
std::memcpy(dst, reinterpret_cast<uint8_t*>(code->raw_instruction_start()), std::memcpy(dst, reinterpret_cast<uint8_t*>(code->raw_instruction_start()),
......
...@@ -96,7 +96,7 @@ class EmbeddedData final { ...@@ -96,7 +96,7 @@ class EmbeddedData final {
// Padded with kCodeAlignment. // Padded with kCodeAlignment.
uint32_t PaddedInstructionSizeOfBuiltin(int i) const { uint32_t PaddedInstructionSizeOfBuiltin(int i) const {
return RoundUp<kCodeAlignment>(InstructionSizeOfBuiltin(i)); return PadAndAlign(InstructionSizeOfBuiltin(i));
} }
size_t CreateHash() const; size_t CreateHash() const;
...@@ -130,7 +130,7 @@ class EmbeddedData final { ...@@ -130,7 +130,7 @@ class EmbeddedData final {
return sizeof(struct Metadata) * kTableSize; return sizeof(struct Metadata) * kTableSize;
} }
static constexpr uint32_t RawDataOffset() { static constexpr uint32_t RawDataOffset() {
return RoundUp<kCodeAlignment>(MetadataOffset() + MetadataSize()); return PadAndAlign(MetadataOffset() + MetadataSize());
} }
private: private:
...@@ -141,6 +141,12 @@ class EmbeddedData final { ...@@ -141,6 +141,12 @@ class EmbeddedData final {
} }
const uint8_t* RawData() const { return data_ + RawDataOffset(); } const uint8_t* RawData() const { return data_ + RawDataOffset(); }
static constexpr int PadAndAlign(int size) {
// Ensure we have at least one byte trailing the actual builtin
// instructions which we can later fill with int3.
return RoundUp<kCodeAlignment>(size + 1);
}
void PrintStatistics() const; void PrintStatistics() const;
const uint8_t* data_; const uint8_t* data_;
......
...@@ -1716,6 +1716,15 @@ class ThreadedList final { ...@@ -1716,6 +1716,15 @@ class ThreadedList final {
V8_EXPORT_PRIVATE bool PassesFilter(Vector<const char> name, V8_EXPORT_PRIVATE bool PassesFilter(Vector<const char> name,
Vector<const char> filter); Vector<const char> filter);
// Zap the specified area with a specific byte pattern. This currently defaults
// to int3 on x64 and ia32. On other architectures this will produce unspecified
// instruction sequences.
// TODO(jgruber): Better support for other architectures.
V8_INLINE void ZapCode(Address addr, size_t size_in_bytes) {
static constexpr int kZapByte = 0xCC;
std::memset(reinterpret_cast<void*>(addr), kZapByte, size_in_bytes);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -444,9 +444,7 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer, ...@@ -444,9 +444,7 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer,
// caller in which case we can't be sure it's okay to overwrite // caller in which case we can't be sure it's okay to overwrite
// existing code in it. // existing code in it.
#ifdef DEBUG #ifdef DEBUG
if (own_buffer_) { if (own_buffer_) ZapCode(reinterpret_cast<Address>(buffer_), buffer_size_);
memset(buffer_, 0xCC, buffer_size_); // int3
}
#endif #endif
ReserveCodeTargetSpace(100); ReserveCodeTargetSpace(100);
...@@ -630,7 +628,7 @@ void Assembler::GrowBuffer() { ...@@ -630,7 +628,7 @@ void Assembler::GrowBuffer() {
// Clear the buffer in debug mode. Use 'int3' instructions to make // Clear the buffer in debug mode. Use 'int3' instructions to make
// sure to get into problems if we ever run uninitialized code. // sure to get into problems if we ever run uninitialized code.
#ifdef DEBUG #ifdef DEBUG
memset(desc.buffer, 0xCC, desc.buffer_size); ZapCode(reinterpret_cast<Address>(desc.buffer), desc.buffer_size);
#endif #endif
// Copy the data. // Copy the data.
......
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