bool UnwindAssembly_x86::FirstNonPrologueInsn( AddressRange &func, const ExecutionContext &exe_ctx, Address &first_non_prologue_insn) { if (!func.GetBaseAddress().IsValid()) return false; Target *target = exe_ctx.GetTargetPtr(); if (target == nullptr) return false; if (m_assembly_inspection_engine == nullptr) return false; const bool prefer_file_cache = true; std::vector<uint8_t> function_text(func.GetByteSize()); Status error; if (target->ReadMemory(func.GetBaseAddress(), prefer_file_cache, function_text.data(), func.GetByteSize(), error) == func.GetByteSize()) { size_t offset; if (m_assembly_inspection_engine->FindFirstNonPrologueInstruction( function_text.data(), func.GetByteSize(), offset)) { first_non_prologue_insn = func.GetBaseAddress(); first_non_prologue_insn.Slide(offset); } return true; } return false; }
bool Block::GetStartAddress (Address &addr) { if (m_ranges.IsEmpty()) return false; Function *function = CalculateSymbolContextFunction(); if (function) { addr = function->GetAddressRange().GetBaseAddress(); addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase ()); return true; } return false; }
uint32_t Symbol::GetPrologueByteSize () { if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver) { if (!m_type_data_resolved) { m_type_data_resolved = true; const Address &base_address = m_addr_range.GetBaseAddress(); Function *function = base_address.CalculateSymbolContextFunction(); if (function) { // Functions have line entries which can also potentially have end of prologue information. // So if this symbol points to a function, use the prologue information from there. m_type_data = function->GetPrologueByteSize(); } else { ModuleSP module_sp (base_address.GetModule()); SymbolContext sc; if (module_sp) { uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress (base_address, eSymbolContextLineEntry, sc); if (resolved_flags & eSymbolContextLineEntry) { // Default to the end of the first line entry. m_type_data = sc.line_entry.range.GetByteSize(); // Set address for next line. Address addr (base_address); addr.Slide (m_type_data); // Check the first few instructions and look for one that has a line number that is // different than the first entry. This is also done in Function::GetPrologueByteSize(). uint16_t total_offset = m_type_data; for (int idx = 0; idx < 6; ++idx) { SymbolContext sc_temp; resolved_flags = module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextLineEntry, sc_temp); // Make sure we got line number information... if (!(resolved_flags & eSymbolContextLineEntry)) break; // If this line number is different than our first one, use it and we're done. if (sc_temp.line_entry.line != sc.line_entry.line) { m_type_data = total_offset; break; } // Slide addr up to the next line address. addr.Slide (sc_temp.line_entry.range.GetByteSize()); total_offset += sc_temp.line_entry.range.GetByteSize(); // If we've gone too far, bail out. if (total_offset >= m_addr_range.GetByteSize()) break; } // Sanity check - this may be a function in the middle of code that has debug information, but // not for this symbol. So the line entries surrounding us won't lie inside our function. // In that case, the line entry will be bigger than we are, so we do that quick check and // if that is true, we just return 0. if (m_type_data >= m_addr_range.GetByteSize()) m_type_data = 0; } else { // TODO: expose something in Process to figure out the // size of a function prologue. m_type_data = 0; } } } } return m_type_data; } return 0; }
BreakpointLocationSP BreakpointResolver::AddLocation(Address loc_addr, bool *new_location) { loc_addr.Slide(m_offset); return m_breakpoint->AddLocation(loc_addr, new_location); }