23#include "llvm/ADT/StringExtras.h"
93 : m_obj(&obj), m_section_type(
toString(section_type)),
94 m_next_section_idx(bookmark.section), m_current_line(bookmark.offset) {
109 const SectionList &list = *m_obj->GetSectionList();
111 while (m_next_line != llvm::StringRef::npos ||
112 m_next_section_idx < num_sections) {
113 if (m_next_line != llvm::StringRef::npos) {
114 m_current_line = m_next_line;
120 if (sect.
GetName() != m_section_type)
123 m_obj->ReadSectionData(§, data);
124 m_section_text = toStringRef(data.
GetData());
128 m_current_line = m_next_line;
132llvm::iterator_range<SymbolFileBreakpad::LineIterator>
141class SupportFileMap {
145 size_t operator[](
size_t file) {
146 return m_map.try_emplace(file, m_map.size() + 1).first->second;
152 llvm::ArrayRef<FileSpec> all_files);
155 llvm::DenseMap<size_t, size_t> m_map;
160 llvm::ArrayRef<FileSpec> all_files) {
161 std::vector<FileSpec> result;
162 result.resize(m_map.size() + 1);
164 for (
const auto &KV : m_map) {
165 if (KV.first < all_files.size())
166 result[KV.second] = all_files[KV.first];
215 if (record && record->FileNum <
m_files->size())
216 spec = (*m_files)[record->FileNum];
219 auto cu_sp = std::make_shared<CompileUnit>(
221 nullptr, std::make_shared<SupportFile>(spec), index,
238 LLDB_LOG(log,
"Unable to fetch the base address of object file. Skipping "
239 "symtab population.");
251 addr_t address = record->Address + base;
255 section_sp, address - section_sp->GetFileAddress(), record->Size);
257 func_sp = std::make_shared<Function>(&comp_unit,
id, 0, func_name,
301 std::vector<Block *> blocks;
302 blocks.push_back(&func.
GetBlock(
false));
304 size_t blocks_added = 0;
310 size_t last_added_nest_level = 0;
313 if (record->InlineNestLevel == 0 ||
314 record->InlineNestLevel <= last_added_nest_level + 1) {
315 last_added_nest_level = record->InlineNestLevel;
316 BlockSP block_sp = blocks[record->InlineNestLevel]->CreateChild(
317 It.GetBookmark().offset);
319 if (record->CallSiteFileNum <
m_files->size())
320 callsite_file = (*m_files)[record->CallSiteFileNum];
321 llvm::StringRef name;
323 name = (*m_inline_origins)[record->OriginNum];
325 Declaration callsite(callsite_file, record->CallSiteLineNum);
326 block_sp->SetInlinedFunctionInfo(name.str().c_str(),
329 for (
const auto &range : record->Ranges) {
333 block_sp->FinalizeRanges();
335 if (record->InlineNestLevel + 1 >= blocks.size()) {
336 blocks.resize(blocks.size() + 1);
338 blocks[record->InlineNestLevel + 1] = block_sp.get();
356 LLDB_LOG(log,
"Failed to parse: {0}. Skipping record.", line);
362 (*m_inline_origins)[record->Number] = record->Name;
368 SymbolContextItem resolve_scope,
371 if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry |
372 eSymbolContextFunction | eSymbolContextBlock)))
382 SymbolContextItem result = eSymbolContextCompUnit;
383 if (resolve_scope & eSymbolContextLineEntry) {
386 result |= eSymbolContextLineEntry;
390 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
394 result |= eSymbolContextFunction;
395 if (resolve_scope & eSymbolContextBlock) {
396 Block &block = func_sp->GetBlock(
true);
401 result |= eSymbolContextBlock;
413 if (!(resolve_scope & eSymbolContextCompUnit))
416 uint32_t old_size = sc_list.
GetSize();
421 return sc_list.
GetSize() - old_size;
435 if (func_sp && name == func_sp->GetNameNoArguments()) {
439 sc.
module_sp = func_sp->CalculateSymbolContextModule();
446 bool include_inlines,
456 LLDB_LOG(log,
"Unable to fetch the base address of object file. Skipping "
457 "symtab population.");
462 llvm::DenseSet<addr_t> found_symbol_addresses;
463 std::vector<Symbol> symbols;
464 auto add_symbol = [&](
addr_t address, std::optional<addr_t> size,
465 llvm::StringRef name) {
470 "Ignoring symbol {0}, whose address ({1}) is outside of the "
471 "object file. Mismatched symbol file?",
477 if (!found_symbol_addresses.insert(address).second)
479 symbols.emplace_back(
483 AddressRange(section_sp, address - section_sp->GetFileAddress(),
485 size.has_value(),
false, 0);
490 add_symbol(record->Address, std::nullopt, record->Name);
492 LLDB_LOG(log,
"Failed to parse: {0}. Skipping record.", line);
495 for (
Symbol &symbol : symbols)
500llvm::Expected<lldb::addr_t>
508 return record->ParameterSize;
510 return llvm::createStringError(llvm::inconvertibleErrorCode(),
511 "Parameter size unknown.");
514static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
520 llvm::StringRef lhs, rest;
521 std::tie(lhs, rest) = getToken(unwind_rules);
522 if (!lhs.consume_back(
":"))
526 llvm::StringRef::size_type pos = rest.find(
": ");
527 if (pos == llvm::StringRef::npos) {
529 unwind_rules = llvm::StringRef();
530 return std::make_pair(lhs, rest);
534 pos = rest.rfind(
' ', pos);
535 if (pos == llvm::StringRef::npos)
538 llvm::StringRef rhs = rest.take_front(pos);
539 unwind_rules = rest.drop_front(pos);
540 return std::make_pair(lhs, rhs);
546 llvm::StringRef name) {
547 if (triple.isX86() || triple.isMIPS()) {
550 if (!name.consume_front(
"$"))
559 llvm::StringRef name) {
569 ToDWARF(node,
dwarf);
571 std::memcpy(saved,
dwarf.GetData(),
dwarf.GetSize());
572 return {saved,
dwarf.GetSize()};
580 llvm::BumpPtrAllocator node_alloc;
581 llvm::Triple triple =
m_objfile_sp->GetArchitecture().GetTriple();
582 while (
auto rule =
GetRule(unwind_rules)) {
584 llvm::StringRef lhs = rule->first;
587 LLDB_LOG(log,
"Could not parse `{0}` as unwind rhs.", rule->second);
593 llvm::StringRef name = symbol.
GetName();
594 if (name ==
".cfa" && lhs !=
".cfa")
595 return postfix::MakeNode<postfix::InitialValueNode>(node_alloc);
599 return postfix::MakeNode<postfix::RegisterNode>(
606 LLDB_LOG(log,
"Resolving symbols in `{0}` failed.", rule->second);
619 LLDB_LOG(log,
"Invalid register `{0}` in unwind rule.", lhs);
621 if (unwind_rules.empty())
624 LLDB_LOG(log,
"Could not parse `{0}` as an unwind rule.", unwind_rules);
651 assert(init_record && init_record->Size &&
652 "Record already parsed successfully in ParseUnwindData!");
655 plan_sp->SetSourceName(
"breakpad STACK CFI");
656 plan_sp->SetUnwindPlanValidAtAllInstructions(
eLazyBoolNo);
659 plan_sp->SetPlanValidAddressRange(
660 AddressRange(base + init_record->Address, *init_record->Size,
663 auto row_sp = std::make_shared<UnwindPlan::Row>();
664 row_sp->SetOffset(0);
667 plan_sp->AppendRow(row_sp);
668 for (++It; It != End; ++It) {
675 row_sp = std::make_shared<UnwindPlan::Row>(*row_sp);
676 row_sp->SetOffset(record->Address - init_record->Address);
679 plan_sp->AppendRow(row_sp);
694 assert(record &&
"Record already parsed successfully in ParseUnwindData!");
697 plan_sp->SetSourceName(
"breakpad STACK WIN");
698 plan_sp->SetUnwindPlanValidAtAllInstructions(
eLazyBoolNo);
701 plan_sp->SetPlanValidAddressRange(
705 auto row_sp = std::make_shared<UnwindPlan::Row>();
706 row_sp->SetOffset(0);
708 llvm::BumpPtrAllocator node_alloc;
709 std::vector<std::pair<llvm::StringRef, postfix::Node *>> program =
712 if (program.empty()) {
713 LLDB_LOG(log,
"Invalid unwind rule: {0}.", record->ProgramString);
716 auto it = program.begin();
717 llvm::Triple triple =
m_objfile_sp->GetArchitecture().GetTriple();
718 const auto &symbol_resolver =
720 llvm::StringRef name = symbol.GetName();
721 for (
const auto &rule : llvm::make_range(program.begin(), it)) {
722 if (rule.first == name)
726 return postfix::MakeNode<postfix::RegisterNode>(
733 auto *symbol = llvm::dyn_cast<postfix::SymbolNode>(it->second);
734 if (symbol && symbol->GetName() ==
".raSearch") {
735 row_sp->GetCFAValue().SetRaSearch(record->LocalSize +
736 record->SavedRegisterSize);
739 LLDB_LOG(log,
"Resolving symbols in `{0}` failed.",
740 record->ProgramString);
743 llvm::ArrayRef<uint8_t> saved =
SaveAsDWARF(*it->second);
744 row_sp->GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
750 it->second = postfix::MakeNode<postfix::InitialValueNode>(node_alloc);
754 for (++it; it != program.end(); ++it) {
761 LLDB_LOG(log,
"Resolving symbols in `{0}` failed.",
762 record->ProgramString);
766 llvm::ArrayRef<uint8_t> saved =
SaveAsDWARF(*it->second);
772 plan_sp->AppendRow(row_sp);
794 LLDB_LOG(log,
"Failed to parse: {0}. Skipping record.", line);
798 if (record->Number >=
m_files->size())
799 m_files->resize(record->Number + 1);
801 .value_or(FileSpec::Style::native);
802 (*m_files)[record->Number] =
FileSpec(record->Name, style);
814 LLDB_LOG(log,
"SymbolFile parsing failed: Unable to fetch the base address "
826 LLDB_LOG(log,
"Failed to parse: {0}. Skipping record.", *It);
837 "How did we create compile units without a base address?");
840 std::vector<std::unique_ptr<LineSequence>> sequences;
841 std::unique_ptr<LineSequence> line_seq_up =
843 std::optional<addr_t> next_addr;
844 auto finish_sequence = [&]() {
846 line_seq_up.get(), *next_addr, 0, 0,
850 sequences.push_back(std::move(line_seq_up));
857 for (++It; It != End; ++It) {
866 record->Address += base;
868 if (next_addr && *next_addr != record->Address) {
873 line_seq_up.get(), record->Address, record->LineNum, 0,
874 map[record->FileNum],
true,
877 next_addr = record->Address + record->Size;
881 data.
line_table_up = std::make_unique<LineTable>(&cu, std::move(sequences));
893 LLDB_LOG(log,
"SymbolFile parsing failed: Unable to fetch the base address "
902 base + record->Address, *record->Size, It.GetBookmark()));
904 LLDB_LOG(log,
"Failed to parse: {0}. Skipping record.", *It);
912 base + record->RVA, record->CodeSize, It.GetBookmark()));
914 LLDB_LOG(log,
"Failed to parse: {0}. Skipping record.", *It);
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_PLUGIN_DEFINE(PluginName)
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > GetRule(llvm::StringRef &unwind_rules)
static const RegisterInfo * ResolveRegister(const llvm::Triple &triple, const SymbolFile::RegisterInfoResolver &resolver, llvm::StringRef name)
static const RegisterInfo * ResolveRegisterOrRA(const llvm::Triple &triple, const SymbolFile::RegisterInfoResolver &resolver, llvm::StringRef name)
llvm::StringRef m_section_text
Bookmark GetBookmark() const
llvm::StringRef operator*() const
const LineIterator & operator++()
ConstString m_section_type
friend bool operator!=(const LineIterator &lhs, const LineIterator &rhs)
LineIterator(ObjectFile &obj)
LineIterator(ObjectFile &obj, Record::Kind section_type)
uint32_t m_next_section_idx
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
A section + offset based address class.
lldb::addr_t GetFileAddress() const
Get the file address.
lldb::addr_t GetOffset() const
Get the section relative offset value.
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
A class that describes a single lexical block.
Block * FindInnermostBlockByOffset(const lldb::addr_t offset)
A class that describes a compilation unit.
const FileSpec & GetPrimaryFile() const
Return the primary source spec associated with this compile unit.
void ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list, RealpathPrefixes *realpath_prefixes=nullptr)
Resolve symbol contexts by file and line.
void SetLineTable(LineTable *line_table)
Set the line table for the compile unit.
void AddFunction(lldb::FunctionSP &function_sp)
Add a function to this compile unit.
lldb::FunctionSP FindFunctionByUID(lldb::user_id_t uid)
Finds a function by user ID.
LineTable * GetLineTable()
Get the line table for the compile unit.
Represents a generic declaration context in a program.
A uniqued constant string class.
A class that describes the declaration location of a lldb object.
static std::optional< Style > GuessPathStyle(llvm::StringRef absolute_path)
Attempt to guess path style for a given path string.
llvm::sys::path::Style Style
A class that describes a function.
const AddressRange & GetAddressRange()
DEPRECATED: Use GetAddressRanges instead.
CompileUnit * GetCompileUnit()
Get accessor for the compile unit that owns this function.
Block & GetBlock(bool can_create)
Get accessor for the block list.
static std::unique_ptr< LineSequence > CreateLineSequenceContainer()
bool FindLineEntryByAddress(const Address &so_addr, LineEntry &line_entry, uint32_t *index_ptr=nullptr)
Find a line entry that contains the section offset address so_addr.
static void AppendLineEntryToSequence(LineSequence *sequence, lldb::addr_t file_addr, uint32_t line, uint16_t column, uint16_t file_idx, bool is_start_of_statement, bool is_start_of_basic_block, bool is_prologue_end, bool is_epilogue_begin, bool is_terminal_entry)
A class that handles mangled names.
void SetValue(ConstString name)
Set the string value in this object.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A class that encapsulates name lookup information.
ConstString GetLookupName() const
A class that describes an executable image and its associated object and symbol files.
virtual SectionList * GetSectionList()
Get the unified section list for the module.
A plug-in interface definition class for object file parsers.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
virtual size_t ReadSectionData(Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
size_t GetNumSections(uint32_t depth) const
lldb::SectionSP FindSectionContainingFileAddress(lldb::addr_t addr, uint32_t depth=UINT32_MAX) const
lldb::SectionSP GetSectionAtIndex(size_t idx) const
ConstString GetName() const
"lldb/Core/SourceLocationSpec.h" A source location specifier class.
@ eBinary
Get and put data as binary instead of as the default string mode.
A list of support files for a CompileUnit.
void Append(const FileSpec &file)
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
Block * block
The Block for a given query.
lldb::ModuleSP module_sp
The Module for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
LineEntry line_entry
The LineEntry for a given query.
lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override
lldb::ObjectFileSP m_objfile_sp
void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp)
uint32_t GetNumCompileUnits() override
virtual std::recursive_mutex & GetModuleMutex() const
Symbols file subclasses should override this to return the Module that owns the TypeSystem that this ...
Address GetAddress() const
uint32_t AddSymbol(const Symbol &symbol)
void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len)
void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len)
void SetRegisterInfo(uint32_t reg_num, const AbstractRegisterLocation register_location)
static std::optional< FileRecord > parse(llvm::StringRef Line)
static std::optional< FuncRecord > parse(llvm::StringRef Line)
static std::optional< InlineOriginRecord > parse(llvm::StringRef Line)
static std::optional< InlineRecord > parse(llvm::StringRef Line)
static std::optional< LineRecord > parse(llvm::StringRef Line)
static std::optional< PublicRecord > parse(llvm::StringRef Line)
static std::optional< Kind > classify(llvm::StringRef Line)
Attempt to guess the kind of the record present in the argument without doing a full parse.
static std::optional< StackCFIRecord > parse(llvm::StringRef Line)
static std::optional< StackWinRecord > parse(llvm::StringRef Line)
std::unique_ptr< LineTable > line_table_up
std::optional< FileSpecList > support_files
size_t ParseBlocksRecursive(Function &func) override
uint64_t GetDebugInfoSize(bool load_all_debug_info=false) override
Metrics gathering functions.
size_t ParseFunctions(CompileUnit &comp_unit) override
uint32_t CalculateAbilities() override
static void DebuggerInitialize(Debugger &debugger)
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override
lldb::UnwindPlanSP ParseCFIUnwindPlan(const Bookmark &bookmark, const RegisterInfoResolver &resolver)
uint32_t CalculateNumCompileUnits() override
static llvm::StringRef GetPluginNameStatic()
lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark, const RegisterInfoResolver &resolver)
llvm::ArrayRef< uint8_t > SaveAsDWARF(postfix::Node &node)
lldb::addr_t GetBaseFileAddress()
bool ParseCFIUnwindRow(llvm::StringRef unwind_rules, const RegisterInfoResolver &resolver, UnwindPlan::Row &row)
lldb::UnwindPlanSP GetUnwindPlan(const Address &address, const RegisterInfoResolver &resolver) override
llvm::Expected< lldb::addr_t > GetParameterStackSize(Symbol &symbol) override
Return the number of stack bytes taken up by the parameters to this function.
std::optional< std::vector< llvm::StringRef > > m_inline_origins
static llvm::StringRef GetPluginDescriptionStatic()
std::optional< std::vector< FileSpec > > m_files
bool ParseLineTable(CompileUnit &comp_unit) override
uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) override
static SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp)
void FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, bool include_inlines, SymbolContextList &sc_list) override
static char ID
LLVM RTTI support.
void AddSymbols(Symtab &symtab) override
bool ParseSupportFiles(CompileUnit &comp_unit, SupportFileList &support_files) override
std::optional< CompUnitMap > m_cu_data
std::optional< UnwindData > m_unwind_data
llvm::BumpPtrAllocator m_allocator
void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data)
void ParseInlineOriginRecords()
lldb::FunctionSP GetOrCreateFunction(CompileUnit &comp_unit)
llvm::iterator_range< LineIterator > lines(Record::Kind section_type)
The base class for all nodes in the parsed postfix tree.
A node representing a symbolic reference to a named entity.
llvm::StringRef GetName() const
#define LLDB_INVALID_ADDRESS
#define LLDB_REGNUM_GENERIC_PC
llvm::StringRef toString(Record::Kind K)
Node * ParseOneExpression(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc)
Parse the given postfix expression.
bool ResolveSymbols(Node *&node, llvm::function_ref< Node *(SymbolNode &symbol)> replacer)
A utility function for "resolving" SymbolNodes.
std::vector< std::pair< llvm::StringRef, Node * > > ParseFPOProgram(llvm::StringRef prog, llvm::BumpPtrAllocator &alloc)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
const char * toString(AppleArm64ExceptionClass EC)
std::shared_ptr< lldb_private::Function > FunctionSP
std::shared_ptr< lldb_private::Block > BlockSP
@ eLanguageTypeUnknown
Unknown or invalid language value.
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::CompileUnit > CompUnitSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
virtual const RegisterInfo * ResolveNumber(lldb::RegisterKind kind, uint32_t number) const =0
virtual const RegisterInfo * ResolveName(llvm::StringRef name) const =0
lldb::user_id_t GetID() const
Get accessor for the user ID.