Commit 67392e9d authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[ubsan][ia32][x64] Assemblers: safely access unaligned memory locations

The Memory<T>(address) helper requires the address to be aligned. Since
values embedded into ia32/x64 code can in general be unaligned, we must
use ReadUnalignedValue/WriteUnalignedValue to manipulate them.

Bug: v8:3770
Change-Id: I12c3fc6aa09062dcc9188b6782ed4a35e1d684bd
Reviewed-on: https://chromium-review.googlesource.com/c/1436223Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59100}
parent 258371bd
......@@ -45,11 +45,11 @@ const char* CodeCommentsIterator::GetComment() const {
}
uint32_t CodeCommentsIterator::GetCommentSize() const {
return *reinterpret_cast<uint32_t*>(current_entry_ + kOffsetToCommentSize);
return ReadUnalignedValue<uint32_t>(current_entry_ + kOffsetToCommentSize);
}
uint32_t CodeCommentsIterator::GetPCOffset() const {
return *reinterpret_cast<uint32_t*>(current_entry_ + kOffsetToPCOffset);
return ReadUnalignedValue<uint32_t>(current_entry_ + kOffsetToPCOffset);
}
void CodeCommentsIterator::Next() {
......
......@@ -2642,7 +2642,11 @@ int TranslatedValue::GetChildrenCount() const {
}
uint64_t TranslatedState::GetUInt64Slot(Address fp, int slot_offset) {
#if V8_TARGET_ARCH_32_BIT
return ReadUnalignedValue<uint64_t>(fp + slot_offset);
#else
return Memory<uint64_t>(fp + slot_offset);
#endif
}
uint32_t TranslatedState::GetUInt32Slot(Address fp, int slot_offset) {
......
......@@ -91,19 +91,19 @@ int RelocInfo::target_address_size() {
HeapObject RelocInfo::target_object() {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
return HeapObject::cast(Object(Memory<Address>(pc_)));
return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
}
Handle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
return Handle<HeapObject>::cast(Memory<Handle<Object>>(pc_));
return Handle<HeapObject>::cast(ReadUnalignedValue<Handle<Object>>(pc_));
}
void RelocInfo::set_target_object(Heap* heap, HeapObject target,
WriteBarrierMode write_barrier_mode,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
Memory<Address>(pc_) = target->ptr();
WriteUnalignedValue(pc_, target->ptr());
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc_, sizeof(Address));
}
......@@ -114,13 +114,13 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
Address RelocInfo::target_external_reference() {
DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
return Memory<Address>(pc_);
return ReadUnalignedValue<Address>(pc_);
}
void RelocInfo::set_target_external_reference(
Address target, ICacheFlushMode icache_flush_mode) {
DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
Memory<Address>(pc_) = target;
WriteUnalignedValue(pc_, target);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc_, sizeof(Address));
}
......@@ -128,7 +128,7 @@ void RelocInfo::set_target_external_reference(
Address RelocInfo::target_internal_reference() {
DCHECK(rmode_ == INTERNAL_REFERENCE);
return Memory<Address>(pc_);
return ReadUnalignedValue<Address>(pc_);
}
......@@ -139,7 +139,7 @@ Address RelocInfo::target_internal_reference_address() {
Address RelocInfo::target_runtime_entry(Assembler* origin) {
DCHECK(IsRuntimeEntry(rmode_));
return static_cast<Address>(*reinterpret_cast<int32_t*>(pc_));
return ReadUnalignedValue<Address>(pc_);
}
void RelocInfo::set_target_runtime_entry(Address target,
......@@ -159,7 +159,7 @@ Address RelocInfo::target_off_heap_target() {
void RelocInfo::WipeOut() {
if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) ||
IsInternalReference(rmode_)) {
Memory<Address>(pc_) = kNullAddress;
WriteUnalignedValue(pc_, kNullAddress);
} else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) ||
IsOffHeapTarget(rmode_)) {
// Effectively write zero into the relocation.
......@@ -190,13 +190,13 @@ void RelocInfo::Visit(ObjectVisitor* visitor) {
}
void Assembler::emit(uint32_t x) {
*reinterpret_cast<uint32_t*>(pc_) = x;
WriteUnalignedValue(reinterpret_cast<Address>(pc_), x);
pc_ += sizeof(uint32_t);
}
void Assembler::emit_q(uint64_t x) {
*reinterpret_cast<uint64_t*>(pc_) = x;
WriteUnalignedValue(reinterpret_cast<Address>(pc_), x);
pc_ += sizeof(uint64_t);
}
......@@ -251,19 +251,19 @@ void Assembler::emit_b(Immediate x) {
void Assembler::emit_w(const Immediate& x) {
DCHECK(RelocInfo::IsNone(x.rmode_));
uint16_t value = static_cast<uint16_t>(x.immediate());
reinterpret_cast<uint16_t*>(pc_)[0] = value;
WriteUnalignedValue(reinterpret_cast<Address>(pc_), value);
pc_ += sizeof(uint16_t);
}
Address Assembler::target_address_at(Address pc, Address constant_pool) {
return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc);
return pc + sizeof(int32_t) + ReadUnalignedValue<int32_t>(pc);
}
void Assembler::set_target_address_at(Address pc, Address constant_pool,
Address target,
ICacheFlushMode icache_flush_mode) {
*reinterpret_cast<int32_t*>(pc) = target - (pc + sizeof(int32_t));
WriteUnalignedValue(pc, target - (pc + sizeof(int32_t)));
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, sizeof(int32_t));
}
......@@ -315,7 +315,7 @@ void Assembler::emit_near_disp(Label* L) {
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target, RelocInfo::Mode mode) {
Memory<Address>(pc) = target;
WriteUnalignedValue(pc, target);
}
......
......@@ -207,7 +207,7 @@ bool RelocInfo::IsInConstantPool() {
uint32_t RelocInfo::wasm_call_tag() const {
DCHECK(rmode_ == WASM_CALL || rmode_ == WASM_STUB_CALL);
return Memory<uint32_t>(pc_);
return ReadUnalignedValue<uint32_t>(pc_);
}
// -----------------------------------------------------------------------------
......@@ -297,7 +297,7 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
}
}
Address pc = reinterpret_cast<Address>(buffer_start_) + request.offset();
Memory<Handle<Object>>(pc) = object;
WriteUnalignedValue(pc, object);
}
}
......@@ -3199,8 +3199,8 @@ void Assembler::GrowBuffer() {
// Relocate internal references.
for (auto pos : internal_reference_positions_) {
int32_t* p = reinterpret_cast<int32_t*>(buffer_start_ + pos);
*p += pc_delta;
Address p = reinterpret_cast<Address>(buffer_start_ + pos);
WriteUnalignedValue(p, ReadUnalignedValue<int>(p) + pc_delta);
}
// Relocate pc-relative references.
......@@ -3277,7 +3277,7 @@ void Assembler::emit_operand(int code, Operand adr) {
pc_ -= sizeof(int32_t); // pc_ must be *at* disp32
RecordRelocInfo(adr.rmode_);
if (adr.rmode_ == RelocInfo::INTERNAL_REFERENCE) { // Fixup for labels
emit_label(*reinterpret_cast<Label**>(pc_));
emit_label(ReadUnalignedValue<Label*>(reinterpret_cast<Address>(pc_)));
} else {
pc_ += sizeof(int32_t);
}
......
......@@ -275,8 +275,8 @@ class V8_EXPORT_PRIVATE Operand {
inline void set_disp8(int8_t disp);
inline void set_dispr(int32_t disp, RelocInfo::Mode rmode) {
DCHECK(len_ == 1 || len_ == 2);
int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
*p = disp;
Address p = reinterpret_cast<Address>(&buf_[len_]);
WriteUnalignedValue(p, disp);
len_ += sizeof(int32_t);
rmode_ = rmode;
}
......@@ -1650,14 +1650,16 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void emit_sse_operand(Register dst, XMMRegister src);
void emit_sse_operand(XMMRegister dst, Register src);
byte* addr_at(int pos) { return buffer_start_ + pos; }
Address addr_at(int pos) {
return reinterpret_cast<Address>(buffer_start_ + pos);
}
private:
uint32_t long_at(int pos) {
return *reinterpret_cast<uint32_t*>(addr_at(pos));
return ReadUnalignedValue<uint32_t>(addr_at(pos));
}
void long_at_put(int pos, uint32_t x) {
*reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
WriteUnalignedValue(addr_at(pos), x);
}
// code emission
......
......@@ -16,6 +16,8 @@ namespace internal {
// proposal (http://wg21.link/p0593r2) to make it defined behaviour though.
template <class T>
T& Memory(Address addr) {
// {addr} must be aligned.
DCHECK_EQ(0, addr & (alignof(T) - 1));
return *reinterpret_cast<T*>(addr);
}
template <class T>
......@@ -26,23 +28,15 @@ T& Memory(byte* addr) {
template <typename V>
static inline V ReadUnalignedValue(Address p) {
ASSERT_TRIVIALLY_COPYABLE(V);
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM)
return *reinterpret_cast<const V*>(p);
#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM
V r;
memmove(&r, reinterpret_cast<void*>(p), sizeof(V));
memcpy(&r, reinterpret_cast<void*>(p), sizeof(V));
return r;
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM
}
template <typename V>
static inline void WriteUnalignedValue(Address p, V value) {
ASSERT_TRIVIALLY_COPYABLE(V);
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM)
*(reinterpret_cast<V*>(p)) = value;
#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM
memmove(reinterpret_cast<void*>(p), &value, sizeof(V));
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM
memcpy(reinterpret_cast<void*>(p), &value, sizeof(V));
}
static inline double ReadFloatValue(Address p) {
......
......@@ -135,12 +135,12 @@ void WriteVersion(Writer* writer) {
void SetWasmCalleeTag(RelocInfo* rinfo, uint32_t tag) {
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
DCHECK(rinfo->HasTargetAddressAddress());
*(reinterpret_cast<uint32_t*>(rinfo->target_address_address())) = tag;
WriteUnalignedValue(rinfo->target_address_address(), tag);
#elif V8_TARGET_ARCH_ARM64
Instruction* instr = reinterpret_cast<Instruction*>(rinfo->pc());
if (instr->IsLdrLiteralX()) {
Memory<Address>(rinfo->constant_pool_entry_address()) =
static_cast<Address>(tag);
WriteUnalignedValue(rinfo->constant_pool_entry_address(),
static_cast<Address>(tag));
} else {
DCHECK(instr->IsBranchAndLink() || instr->IsUnconditionalBranch());
instr->SetBranchImmTarget(
......@@ -160,12 +160,11 @@ void SetWasmCalleeTag(RelocInfo* rinfo, uint32_t tag) {
uint32_t GetWasmCalleeTag(RelocInfo* rinfo) {
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
return *(reinterpret_cast<uint32_t*>(rinfo->target_address_address()));
return ReadUnalignedValue<uint32_t>(rinfo->target_address_address());
#elif V8_TARGET_ARCH_ARM64
Instruction* instr = reinterpret_cast<Instruction*>(rinfo->pc());
if (instr->IsLdrLiteralX()) {
return static_cast<uint32_t>(
Memory<Address>(rinfo->constant_pool_entry_address()));
return ReadUnalignedValue<uint32_t>(rinfo->constant_pool_entry_address());
} else {
DCHECK(instr->IsBranchAndLink() || instr->IsUnconditionalBranch());
return static_cast<uint32_t>(instr->ImmPCOffset() / kInstrSize);
......
......@@ -24,12 +24,12 @@ bool CpuFeatures::SupportsWasmSimd128() { return IsSupported(SSE4_1); }
void Assembler::emitl(uint32_t x) {
Memory<uint32_t>(pc_) = x;
WriteUnalignedValue(reinterpret_cast<Address>(pc_), x);
pc_ += sizeof(uint32_t);
}
void Assembler::emitp(Address x, RelocInfo::Mode rmode) {
Memory<uintptr_t>(pc_) = x;
WriteUnalignedValue(reinterpret_cast<Address>(pc_), x);
if (!RelocInfo::IsNone(rmode)) {
RecordRelocInfo(rmode, x);
}
......@@ -38,13 +38,13 @@ void Assembler::emitp(Address x, RelocInfo::Mode rmode) {
void Assembler::emitq(uint64_t x) {
Memory<uint64_t>(pc_) = x;
WriteUnalignedValue(reinterpret_cast<Address>(pc_), x);
pc_ += sizeof(uint64_t);
}
void Assembler::emitw(uint16_t x) {
Memory<uint16_t>(pc_) = x;
WriteUnalignedValue(reinterpret_cast<Address>(pc_), x);
pc_ += sizeof(uint16_t);
}
......@@ -233,13 +233,13 @@ void Assembler::emit_vex_prefix(Register reg, Register vreg, Operand rm,
Address Assembler::target_address_at(Address pc, Address constant_pool) {
return Memory<int32_t>(pc) + pc + 4;
return ReadUnalignedValue<int32_t>(pc) + pc + 4;
}
void Assembler::set_target_address_at(Address pc, Address constant_pool,
Address target,
ICacheFlushMode icache_flush_mode) {
Memory<int32_t>(pc) = static_cast<int32_t>(target - pc - 4);
WriteUnalignedValue(pc, static_cast<int32_t>(target - pc - 4));
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, sizeof(int32_t));
}
......@@ -247,7 +247,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target, RelocInfo::Mode mode) {
Memory<Address>(pc) = target;
WriteUnalignedValue(pc, target);
}
......@@ -268,11 +268,11 @@ int Assembler::deserialization_special_target_size(
}
Handle<Code> Assembler::code_target_object_handle_at(Address pc) {
return GetCodeTarget(Memory<int32_t>(pc));
return GetCodeTarget(ReadUnalignedValue<int32_t>(pc));
}
Address Assembler::runtime_entry_at(Address pc) {
return Memory<int32_t>(pc) + options().code_range_start;
return ReadUnalignedValue<int32_t>(pc) + options().code_range_start;
}
// -----------------------------------------------------------------------------
......@@ -281,10 +281,11 @@ Address Assembler::runtime_entry_at(Address pc) {
// The modes possibly affected by apply must be in kApplyMask.
void RelocInfo::apply(intptr_t delta) {
if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) {
Memory<int32_t>(pc_) -= static_cast<int32_t>(delta);
WriteUnalignedValue(
pc_, ReadUnalignedValue<int32_t>(pc_) - static_cast<int32_t>(delta));
} else if (IsInternalReference(rmode_)) {
// absolute code pointer inside code object moves with the code object.
Memory<Address>(pc_) += delta;
// Absolute code pointer inside code object moves with the code object.
WriteUnalignedValue(pc_, ReadUnalignedValue<Address>(pc_) + delta);
}
}
......@@ -317,13 +318,13 @@ int RelocInfo::target_address_size() {
HeapObject RelocInfo::target_object() {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
return HeapObject::cast(Object(Memory<Address>(pc_)));
return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
}
Handle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
if (rmode_ == EMBEDDED_OBJECT) {
return Handle<HeapObject>::cast(Memory<Handle<Object>>(pc_));
return Handle<HeapObject>::cast(ReadUnalignedValue<Handle<Object>>(pc_));
} else {
return origin->code_target_object_handle_at(pc_);
}
......@@ -331,13 +332,13 @@ Handle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
Address RelocInfo::target_external_reference() {
DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
return Memory<Address>(pc_);
return ReadUnalignedValue<Address>(pc_);
}
void RelocInfo::set_target_external_reference(
Address target, ICacheFlushMode icache_flush_mode) {
DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
Memory<Address>(pc_) = target;
WriteUnalignedValue(pc_, target);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc_, sizeof(Address));
}
......@@ -345,7 +346,7 @@ void RelocInfo::set_target_external_reference(
Address RelocInfo::target_internal_reference() {
DCHECK(rmode_ == INTERNAL_REFERENCE);
return Memory<Address>(pc_);
return ReadUnalignedValue<Address>(pc_);
}
......@@ -358,7 +359,7 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
WriteBarrierMode write_barrier_mode,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
Memory<Address>(pc_) = target->ptr();
WriteUnalignedValue(pc_, target->ptr());
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc_, sizeof(Address));
}
......@@ -383,13 +384,13 @@ void RelocInfo::set_target_runtime_entry(Address target,
Address RelocInfo::target_off_heap_target() {
DCHECK(IsOffHeapTarget(rmode_));
return Memory<Address>(pc_);
return ReadUnalignedValue<Address>(pc_);
}
void RelocInfo::WipeOut() {
if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) ||
IsInternalReference(rmode_) || IsOffHeapTarget(rmode_)) {
Memory<Address>(pc_) = kNullAddress;
WriteUnalignedValue(pc_, kNullAddress);
} else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) {
// Effectively write zero into the relocation.
Assembler::set_target_address_at(pc_, constant_pool_,
......
......@@ -126,7 +126,7 @@ void CpuFeatures::PrintFeatures() {
uint32_t RelocInfo::wasm_call_tag() const {
DCHECK(rmode_ == WASM_CALL || rmode_ == WASM_STUB_CALL);
return Memory<uint32_t>(pc_);
return ReadUnalignedValue<uint32_t>(pc_);
}
// -----------------------------------------------------------------------------
......@@ -200,7 +200,8 @@ class OperandBuilder {
int32_t disp_value = 0;
if (mode == 0x80 || is_baseless) {
// Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
disp_value = *bit_cast<const int32_t*>(&operand.data().buf[disp_offset]);
disp_value = ReadUnalignedValue<int32_t>(
reinterpret_cast<Address>(&operand.data().buf[disp_offset]));
} else if (mode == 0x40) {
// Mode 1: Byte displacement.
disp_value = static_cast<signed char>(operand.data().buf[disp_offset]);
......@@ -215,8 +216,8 @@ class OperandBuilder {
// Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
data_.buf[0] = (modrm & 0x3F) | (is_baseless ? 0x00 : 0x80);
data_.len = disp_offset + 4;
Memory<int32_t>(reinterpret_cast<Address>(&data_.buf[disp_offset])) =
disp_value;
WriteUnalignedValue(reinterpret_cast<Address>(&data_.buf[disp_offset]),
disp_value);
} else if (disp_value != 0 || (base_reg == 0x05)) {
// Need 8 bits of displacement.
data_.buf[0] = (modrm & 0x3F) | 0x40; // Mode 1.
......@@ -260,15 +261,15 @@ class OperandBuilder {
void set_disp32(int disp) {
DCHECK(data_.len == 1 || data_.len == 2);
int32_t* p = reinterpret_cast<int32_t*>(&data_.buf[data_.len]);
*p = disp;
Address p = reinterpret_cast<Address>(&data_.buf[data_.len]);
WriteUnalignedValue(p, disp);
data_.len += sizeof(int32_t);
}
void set_disp64(int64_t disp) {
DCHECK_EQ(1, data_.len);
int64_t* p = reinterpret_cast<int64_t*>(&data_.buf[data_.len]);
*p = disp;
Address p = reinterpret_cast<Address>(&data_.buf[data_.len]);
WriteUnalignedValue(p, disp);
data_.len += sizeof(disp);
}
......@@ -328,14 +329,14 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
case HeapObjectRequest::kHeapNumber: {
Handle<HeapNumber> object =
isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
Memory<Handle<Object>>(pc) = object;
WriteUnalignedValue(pc, object);
break;
}
case HeapObjectRequest::kStringConstant: {
const StringConstantBase* str = request.string();
CHECK_NOT_NULL(str);
Handle<String> allocated = str->AllocateStringConstant(isolate);
Memory<Handle<Object>>(pc) = allocated;
WriteUnalignedValue(pc, allocated);
break;
}
}
......@@ -372,11 +373,9 @@ bool ConstPool::TryRecordEntry(intptr_t data, RelocInfo::Mode mode) {
return AddSharedEntry(raw_data, offset);
}
bool ConstPool::IsMoveRipRelative(byte* instr) {
if ((*reinterpret_cast<uint32_t*>(instr) & kMoveRipRelativeMask) ==
kMoveRipRelativeInstr)
return true;
return false;
bool ConstPool::IsMoveRipRelative(Address instr) {
return (ReadUnalignedValue<uint32_t>(instr) & kMoveRipRelativeMask) ==
kMoveRipRelativeInstr;
}
void ConstPool::Clear() { entries_.clear(); }
......@@ -397,13 +396,13 @@ void ConstPool::PatchEntries() {
DCHECK_LT(constant_entry_offset, it->second);
int32_t disp32 =
constant_entry_offset - (it->second + kRipRelativeDispSize);
byte* disp_addr = assm_->addr_at(it->second);
Address disp_addr = assm_->addr_at(it->second);
// Check if the instruction is actually a rip-relative move.
DCHECK(IsMoveRipRelative(disp_addr - kMoveRipRelativeDispOffset));
// The displacement of the rip-relative move should be 0 before patching.
DCHECK(*reinterpret_cast<uint32_t*>(disp_addr) == 0);
*reinterpret_cast<int32_t*>(disp_addr) = disp32;
DCHECK(ReadUnalignedValue<uint32_t>(disp_addr) == 0);
WriteUnalignedValue(disp_addr, disp32);
}
}
Clear();
......@@ -518,7 +517,7 @@ void Assembler::bind_to(Label* L, int pos) {
if (current >= 4 && long_at(current - 4) == 0) {
// Absolute address.
intptr_t imm64 = reinterpret_cast<intptr_t>(buffer_start_ + pos);
*reinterpret_cast<intptr_t*>(addr_at(current - 4)) = imm64;
WriteUnalignedValue(addr_at(current - 4), imm64);
internal_reference_positions_.push_back(current - 4);
} else {
// Relative address, relative to point after address.
......@@ -532,7 +531,7 @@ void Assembler::bind_to(Label* L, int pos) {
if (current >= 4 && long_at(current - 4) == 0) {
// Absolute address.
intptr_t imm64 = reinterpret_cast<intptr_t>(buffer_start_ + pos);
*reinterpret_cast<intptr_t*>(addr_at(current - 4)) = imm64;
WriteUnalignedValue(addr_at(current - 4), imm64);
internal_reference_positions_.push_back(current - 4);
} else {
// Relative address, relative to point after address.
......@@ -629,8 +628,8 @@ void Assembler::GrowBuffer() {
// Relocate internal references.
for (auto pos : internal_reference_positions_) {
intptr_t* p = reinterpret_cast<intptr_t*>(buffer_start_ + pos);
*p += pc_delta;
Address p = reinterpret_cast<Address>(buffer_start_ + pos);
WriteUnalignedValue(p, ReadUnalignedValue<intptr_t>(p) + pc_delta);
}
DCHECK(!buffer_overflow());
......@@ -648,7 +647,8 @@ void Assembler::emit_operand(int code, Operand adr) {
// Recognize RIP relative addressing.
if (adr.data().buf[0] == 5) {
DCHECK_EQ(9u, length);
Label* label = *bit_cast<Label* const*>(&adr.data().buf[1]);
Label* label = ReadUnalignedValue<Label*>(
reinterpret_cast<Address>(&adr.data().buf[1]));
if (label->is_bound()) {
int offset =
label->pos() - pc_offset() - sizeof(int32_t) + adr.data().addend;
......
......@@ -268,7 +268,7 @@ class ConstPool {
bool AddSharedEntry(uint64_t data, int offset);
// Check if the instruction is a rip-relative move.
bool IsMoveRipRelative(byte* instr);
bool IsMoveRipRelative(Address instr);
Assembler* assm_;
......@@ -1806,12 +1806,14 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void call(Operand operand);
private:
byte* addr_at(int pos) { return buffer_start_ + pos; }
uint32_t long_at(int pos) {
return *reinterpret_cast<uint32_t*>(addr_at(pos));
Address addr_at(int pos) {
return reinterpret_cast<Address>(buffer_start_ + pos);
}
uint32_t long_at(int pos) {
return ReadUnalignedValue<uint32_t>(addr_at(pos));
}
void long_at_put(int pos, uint32_t x) {
*reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
WriteUnalignedValue(addr_at(pos), x);
}
// code emission
......
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