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