17 RegisterState* register_state);
20 return *
reinterpret_cast<i::Address*
>(address);
25const uint8_t* CalculateEnd(
const void*
start,
size_t length_in_bytes) {
28 const uint8_t* start_as_byte =
reinterpret_cast<const uint8_t*
>(
start);
29 return start_as_byte + length_in_bytes;
33 return pc >= code_range.
start &&
39bool PCIsInCodePages(
size_t code_pages_length,
const MemoryRange* code_pages,
41 DCHECK(std::is_sorted(code_pages, code_pages + code_pages_length,
42 [](
const MemoryRange& a,
const MemoryRange& b) {
43 return a.start < b.start;
46 MemoryRange fake_range{
pc, 1};
48 std::upper_bound(code_pages, code_pages + code_pages_length, fake_range,
49 [](
const MemoryRange& a,
const MemoryRange& b) {
50 return a.start < b.start;
53 if (it == code_pages)
return false;
55 return it->start <=
pc &&
pc < CalculateEnd(it->start, it->length_in_bytes);
58bool IsInJSEntryRange(
const JSEntryStubs& entry_stubs,
void*
pc) {
59 return PCIsInCodeRange(entry_stubs.js_entry_stub.code,
pc) ||
60 PCIsInCodeRange(entry_stubs.js_construct_entry_stub.code,
pc) ||
61 PCIsInCodeRange(entry_stubs.js_run_microtasks_entry_stub.code,
pc);
64bool IsInUnsafeJSEntryRange(
const JSEntryStubs& entry_stubs,
void*
pc) {
65 return IsInJSEntryRange(entry_stubs,
pc);
73bool AddressIsInStack(
const void* address,
const void* stack_base,
74 const void* stack_top) {
75 return address <= stack_base && address >= stack_top;
78void* GetReturnAddressFromFP(
void* fp,
void*
pc,
79 const JSEntryStubs& entry_stubs) {
80 int caller_pc_offset = i::CommonFrameConstants::kCallerPCOffset;
82#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
83 if (IsInJSEntryRange(entry_stubs,
pc)) {
84 caller_pc_offset = i::EntryFrameConstants::kDirectCallerPCOffset;
89 return reinterpret_cast<void*
>(i::PointerAuthentication::StripPAC(ret_addr));
92void* GetCallerFPFromFP(
void* fp,
void*
pc,
const JSEntryStubs& entry_stubs) {
93 int caller_fp_offset = i::CommonFrameConstants::kCallerFPOffset;
94#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
95 if (IsInJSEntryRange(entry_stubs,
pc)) {
96 caller_fp_offset = i::EntryFrameConstants::kDirectCallerFPOffset;
99 return reinterpret_cast<void*
>(
103void* GetCallerSPFromFP(
void* fp,
void*
pc,
const JSEntryStubs& entry_stubs) {
104 int caller_sp_offset = i::CommonFrameConstants::kCallerSPOffset;
105#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
106 if (IsInJSEntryRange(entry_stubs,
pc)) {
107 caller_sp_offset = i::EntryFrameConstants::kDirectCallerSPOffset;
110 return reinterpret_cast<void*
>(
reinterpret_cast<i::Address>(fp) +
117 size_t code_pages_length,
120 const void* stack_base) {
121 const void* stack_top = register_state->
sp;
123 void*
pc = register_state->
pc;
124 if (
PCIsInV8(code_pages_length, code_pages,
pc) &&
125 !IsInUnsafeJSEntryRange(entry_stubs,
pc)) {
126 void* current_fp = register_state->
fp;
127 if (!AddressIsInStack(current_fp, stack_base, stack_top))
return false;
131 void* next_pc = GetReturnAddressFromFP(current_fp,
pc, entry_stubs);
132 while (
PCIsInV8(code_pages_length, code_pages, next_pc)) {
133 current_fp = GetCallerFPFromFP(current_fp,
pc, entry_stubs);
134 if (!AddressIsInStack(current_fp, stack_base, stack_top))
return false;
136 next_pc = GetReturnAddressFromFP(current_fp,
pc, entry_stubs);
139 void* final_sp = GetCallerSPFromFP(current_fp,
pc, entry_stubs);
140 if (!AddressIsInStack(final_sp, stack_base, stack_top))
return false;
141 register_state->
sp = final_sp;
147 void* final_fp = GetCallerFPFromFP(current_fp,
pc, entry_stubs);
148 register_state->
fp = final_fp;
150 register_state->
pc = next_pc;
153 register_state->
lr =
nullptr;
155 if (IsInJSEntryRange(entry_stubs,
pc)) {
165 return pc && PCIsInCodePages(code_pages_length, code_pages,
pc);
static bool PCIsInV8(size_t code_pages_length, const MemoryRange *code_pages, void *pc)
static bool TryUnwindV8Frames(const JSEntryStubs &entry_stubs, size_t code_pages_length, const MemoryRange *code_pages, RegisterState *register_state, const void *stack_base)
void GetCalleeSavedRegistersFromEntryFrame(void *fp, RegisterState *register_state)
i::Address Load(i::Address address)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK(condition)