From 10bc3362a1a8a3df2660bf65db0ec1ccab646e1b Mon Sep 17 00:00:00 2001 From: Stella Stamenova Date: Wed, 12 Jan 2022 08:53:19 -0800 Subject: [PATCH] Revert "[LLDB][NativePDB] Add support for inlined functions" This reverts commit 945aa520ef07a3edb655f3f38e4c3023658dd623. This commit broke the windows lldb bot. --- lldb/include/lldb/Symbol/LineTable.h | 2 +- .../SymbolFile/NativePDB/CompileUnitIndex.cpp | 19 - .../SymbolFile/NativePDB/CompileUnitIndex.h | 13 - .../NativePDB/SymbolFileNativePDB.cpp | 522 +++----------- .../NativePDB/SymbolFileNativePDB.h | 33 - .../NativePDB/Inputs/inline_sites.lldbinit | 17 - .../Shell/SymbolFile/NativePDB/inline_sites.s | 667 ------------------ 7 files changed, 95 insertions(+), 1178 deletions(-) delete mode 100644 lldb/test/Shell/SymbolFile/NativePDB/Inputs/inline_sites.lldbinit delete mode 100644 lldb/test/Shell/SymbolFile/NativePDB/inline_sites.s diff --git a/lldb/include/lldb/Symbol/LineTable.h b/lldb/include/lldb/Symbol/LineTable.h index b5121b29fe028..5cd22bd831eef 100644 --- a/lldb/include/lldb/Symbol/LineTable.h +++ b/lldb/include/lldb/Symbol/LineTable.h @@ -206,6 +206,7 @@ class LineTable { LineTable *LinkLineTable(const FileRangeMap &file_range_map); +protected: struct Entry { Entry() : line(0), is_start_of_statement(false), is_start_of_basic_block(false), @@ -302,7 +303,6 @@ class LineTable { uint16_t file_idx = 0; }; -protected: struct EntrySearchInfo { LineTable *line_table; lldb_private::Section *a_section; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp index d8f737612c257..9f09c0accc876 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -106,24 +106,6 @@ static void ParseExtendedInfo(PdbIndex &index, CompilandIndexItem &item) { } } -static void ParseInlineeLineTableForCompileUnit(CompilandIndexItem &item) { - for (const auto &ss : item.m_debug_stream.getSubsectionsArray()) { - if (ss.kind() != DebugSubsectionKind::InlineeLines) - continue; - - DebugInlineeLinesSubsectionRef inlinee_lines; - llvm::BinaryStreamReader reader(ss.getRecordData()); - if (llvm::Error error = inlinee_lines.initialize(reader)) { - consumeError(std::move(error)); - continue; - } - - for (const InlineeSourceLine &Line : inlinee_lines) { - item.m_inline_map[Line.Header->Inlinee] = Line; - } - } -} - CompilandIndexItem::CompilandIndexItem( PdbCompilandId id, llvm::pdb::ModuleDebugStreamRef debug_stream, llvm::pdb::DbiModuleDescriptor descriptor) @@ -160,7 +142,6 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { cci = std::make_unique( PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor)); ParseExtendedInfo(m_index, *cci); - ParseInlineeLineTableForCompileUnit(*cci); cci->m_strings.initialize(debug_stream.getSubsectionsArray()); PDBStringTable &strings = cantFail(m_index.pdb().getStringTable()); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h index 4ad27de986954..088de970cbf32 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h @@ -9,12 +9,10 @@ #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H -#include "lldb/Utility/RangeMap.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/Optional.h" -#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" @@ -71,17 +69,6 @@ struct CompilandIndexItem { // command line, etc. This usually contains exactly 5 items which // are references to other strings. llvm::SmallVector m_build_info; - - // Inlinee lines table in this compile unit. - std::map - m_inline_map; - - // It's the line table parsed from DEBUG_S_LINES sections, mapping the file - // address range to file index and source line number. - using GlobalLineTable = - lldb_private::RangeDataVector>; - GlobalLineTable m_global_line_table; }; /// Indexes information about all compile units. This is really just a map of diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 578b369945d01..e859b1d5a86cf 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -330,65 +330,31 @@ uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() { Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) { CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); - CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii); + + if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) { + // This is a function. It must be global. Creating the Function entry for + // it automatically creates a block for it. + CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii); + return GetOrCreateFunction(block_id, *comp_unit)->GetBlock(false); + } + + lldbassert(sym.kind() == S_BLOCK32); + + // This is a block. Its parent is either a function or another block. In + // either case, its parent can be viewed as a block (e.g. a function contains + // 1 big block. So just get the parent block and add this block to it. + BlockSym block(static_cast(sym.kind())); + cantFail(SymbolDeserializer::deserializeAs(sym, block)); + lldbassert(block.Parent != 0); + PdbCompilandSymId parent_id(block_id.modi, block.Parent); + Block &parent_block = GetOrCreateBlock(parent_id); lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id); BlockSP child_block = std::make_shared(opaque_block_uid); + parent_block.AddChild(child_block); - switch (sym.kind()) { - case S_GPROC32: - case S_LPROC32: { - // This is a function. It must be global. Creating the Function entry - // for it automatically creates a block for it. - FunctionSP func = GetOrCreateFunction(block_id, *comp_unit); - Block &block = func->GetBlock(false); - if (block.GetNumRanges() == 0) - block.AddRange(Block::Range(0, func->GetAddressRange().GetByteSize())); - return block; - } - case S_BLOCK32: { - // This is a block. Its parent is either a function or another block. In - // either case, its parent can be viewed as a block (e.g. a function - // contains 1 big block. So just get the parent block and add this block - // to it. - BlockSym block(static_cast(sym.kind())); - cantFail(SymbolDeserializer::deserializeAs(sym, block)); - lldbassert(block.Parent != 0); - PdbCompilandSymId parent_id(block_id.modi, block.Parent); - Block &parent_block = GetOrCreateBlock(parent_id); - parent_block.AddChild(child_block); - m_ast->GetOrCreateBlockDecl(block_id); - m_blocks.insert({opaque_block_uid, child_block}); - break; - } - case S_INLINESITE: { - // This ensures line table is parsed first so we have inline sites info. - comp_unit->GetLineTable(); - - std::shared_ptr inline_site = m_inline_sites[opaque_block_uid]; - Block &parent_block = GetOrCreateBlock(inline_site->parent_id); - parent_block.AddChild(child_block); - - // Copy ranges from InlineSite to Block. - for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) { - auto *entry = inline_site->ranges.GetEntryAtIndex(i); - child_block->AddRange( - Block::Range(entry->GetRangeBase(), entry->GetByteSize())); - } - child_block->FinalizeRanges(); - - // Get the inlined function callsite info. - Declaration &decl = inline_site->inline_function_info->GetDeclaration(); - Declaration &callsite = inline_site->inline_function_info->GetCallSite(); - child_block->SetInlinedFunctionInfo( - inline_site->inline_function_info->GetName().GetCString(), nullptr, - &decl, &callsite); - m_blocks.insert({opaque_block_uid, child_block}); - break; - } - default: - lldbassert(false && "Symbol is not a block!"); - } + m_ast->GetOrCreateBlockDecl(block_id); + m_blocks.insert({opaque_block_uid, child_block}); return *child_block; } @@ -1005,22 +971,16 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext( continue; if (type == PDB_SymType::Function) { sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get(); - Block &block = sc.function->GetBlock(true); - addr_t func_base = - sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); - addr_t offset = file_addr - func_base; - sc.block = block.FindInnermostBlockByOffset(offset); + sc.block = sc.GetFunctionBlock(); } if (type == PDB_SymType::Block) { sc.block = &GetOrCreateBlock(csid); sc.function = sc.block->CalculateSymbolContextFunction(); } - if (sc.function) - resolved_flags |= eSymbolContextFunction; - if (sc.block) - resolved_flags |= eSymbolContextBlock; - break; + resolved_flags |= eSymbolContextFunction; + resolved_flags |= eSymbolContextBlock; + break; } } @@ -1038,24 +998,43 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext( uint32_t SymbolFileNativePDB::ResolveSymbolContext( const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { - std::lock_guard guard(GetModuleMutex()); - const uint32_t prev_size = sc_list.GetSize(); - if (resolve_scope & eSymbolContextCompUnit) { - for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus; - ++cu_idx) { - CompileUnit *cu = ParseCompileUnitAtIndex(cu_idx).get(); - if (!cu) - continue; + return 0; +} - bool file_spec_matches_cu_file_spec = FileSpec::Match( - src_location_spec.GetFileSpec(), cu->GetPrimaryFile()); - if (file_spec_matches_cu_file_spec) { - cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list); - break; - } - } - } - return sc_list.GetSize() - prev_size; +static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence, + const CompilandIndexItem &cci, + lldb::addr_t base_addr, + uint32_t file_number, + const LineFragmentHeader &block, + const LineNumberEntry &cur) { + LineInfo cur_info(cur.Flags); + + if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto()) + return; + + uint64_t addr = base_addr + cur.Offset; + + bool is_statement = cur_info.isStatement(); + bool is_prologue = IsFunctionPrologue(cci, addr); + bool is_epilogue = IsFunctionEpilogue(cci, addr); + + uint32_t lno = cur_info.getStartLine(); + + table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number, + is_statement, false, is_prologue, is_epilogue, + false); +} + +static void TerminateLineSequence(LineTable &table, + const LineFragmentHeader &block, + lldb::addr_t base_addr, uint32_t file_number, + uint32_t last_line, + std::unique_ptr seq) { + // The end is always a terminal entry, so insert it regardless. + table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize, + last_line, 0, file_number, false, false, + false, false, true); + table.InsertSequence(seq.get()); } bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { @@ -1066,21 +1045,16 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { std::lock_guard guard(GetModuleMutex()); PdbSymUid cu_id(comp_unit.GetID()); lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); - uint16_t modi = cu_id.asCompiland().modi; - CompilandIndexItem *cii = m_index->compilands().GetCompiland(modi); - lldbassert(cii); - - // Parse DEBUG_S_LINES subsections first, then parse all S_INLINESITE records - // in this CU. Add line entries into the set first so that if there are line - // entries with same addres, the later is always more accurate than the - // former. - std::set line_set; + CompilandIndexItem *cci = + m_index->compilands().GetCompiland(cu_id.asCompiland().modi); + lldbassert(cci); + auto line_table = std::make_unique(&comp_unit); // This is basically a copy of the .debug$S subsections from all original COFF // object files merged together with address relocations applied. We are // looking for all DEBUG_S_LINES subsections. for (const DebugSubsectionRecord &dssr : - cii->m_debug_stream.getSubsectionsArray()) { + cci->m_debug_stream.getSubsectionsArray()) { if (dssr.kind() != DebugSubsectionKind::Lines) continue; @@ -1095,111 +1069,42 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { uint64_t virtual_addr = m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset); + const auto &checksums = cci->m_strings.checksums().getArray(); + const auto &strings = cci->m_strings.strings(); for (const LineColumnEntry &group : lines) { - llvm::Expected file_index_or_err = - GetFileIndex(*cii, group.NameIndex); - if (!file_index_or_err) + // Indices in this structure are actually offsets of records in the + // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index + // into the global PDB string table. + auto iter = checksums.at(group.NameIndex); + if (iter == checksums.end()) continue; - uint32_t file_index = file_index_or_err.get(); - lldbassert(!group.LineNumbers.empty()); - CompilandIndexItem::GlobalLineTable::Entry line_entry( - LLDB_INVALID_ADDRESS, 0); - for (const LineNumberEntry &entry : group.LineNumbers) { - LineInfo cur_info(entry.Flags); - - if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto()) - continue; - - uint64_t addr = virtual_addr + entry.Offset; - bool is_statement = cur_info.isStatement(); - bool is_prologue = IsFunctionPrologue(*cii, addr); - bool is_epilogue = IsFunctionEpilogue(*cii, addr); + llvm::Expected efn = + strings.getString(iter->FileNameOffset); + if (!efn) { + llvm::consumeError(efn.takeError()); + continue; + } - uint32_t lno = cur_info.getStartLine(); + // LLDB wants the index of the file in the list of support files. + auto fn_iter = llvm::find(cci->m_file_list, *efn); + lldbassert(fn_iter != cci->m_file_list.end()); + uint32_t file_index = std::distance(cci->m_file_list.begin(), fn_iter); - line_set.emplace(addr, lno, 0, file_index, is_statement, false, - is_prologue, is_epilogue, false); + std::unique_ptr sequence( + line_table->CreateLineSequenceContainer()); + lldbassert(!group.LineNumbers.empty()); - if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) { - line_entry.SetRangeEnd(addr); - cii->m_global_line_table.Append(line_entry); - } - line_entry.SetRangeBase(addr); - line_entry.data = {file_index, lno}; + for (const LineNumberEntry &entry : group.LineNumbers) { + AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr, + file_index, *lfh, entry); } LineInfo last_line(group.LineNumbers.back().Flags); - line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0, - file_index, false, false, false, false, true); - - if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) { - line_entry.SetRangeEnd(virtual_addr + lfh->CodeSize); - cii->m_global_line_table.Append(line_entry); - } + TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index, + last_line.getEndLine(), std::move(sequence)); } } - cii->m_global_line_table.Sort(); - - // Parse all S_INLINESITE in this CU. - const CVSymbolArray &syms = cii->m_debug_stream.getSymbolArray(); - for (auto iter = syms.begin(); iter != syms.end();) { - if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) { - ++iter; - continue; - } - - uint32_t record_offset = iter.offset(); - CVSymbol func_record = - cii->m_debug_stream.readSymbolAtOffset(record_offset); - SegmentOffsetLength sol = GetSegmentOffsetAndLength(func_record); - addr_t file_vm_addr = m_index->MakeVirtualAddress(sol.so); - AddressRange func_range(file_vm_addr, sol.length, - comp_unit.GetModule()->GetSectionList()); - Address func_base = func_range.GetBaseAddress(); - PdbCompilandSymId func_id{modi, record_offset}; - - // Iterate all S_INLINESITEs in the function. - auto parse_inline_sites = [&](SymbolKind kind, PdbCompilandSymId id) { - if (kind != S_INLINESITE) - return false; - - ParseInlineSite(id, func_base); - - for (const auto &line_entry : - m_inline_sites[toOpaqueUid(id)]->line_entries) { - // If line_entry is not terminal entry, remove previous line entry at - // the same address and insert new one. Terminal entry inside an inline - // site might not be terminal entry for its parent. - if (!line_entry.is_terminal_entry) - line_set.erase(line_entry); - line_set.insert(line_entry); - } - // No longer useful after adding to line_set. - m_inline_sites[toOpaqueUid(id)]->line_entries.clear(); - return true; - }; - ParseSymbolArrayInScope(func_id, parse_inline_sites); - // Jump to the end of the function record. - iter = syms.at(getScopeEndOffset(func_record)); - } - - cii->m_global_line_table.Clear(); - - // Add line entries in line_set to line_table. - auto line_table = std::make_unique(&comp_unit); - std::unique_ptr sequence( - line_table->CreateLineSequenceContainer()); - for (const auto &line_entry : line_set) { - line_table->AppendLineEntryToSequence( - sequence.get(), line_entry.file_addr, line_entry.line, - line_entry.column, line_entry.file_idx, - line_entry.is_start_of_statement, line_entry.is_start_of_basic_block, - line_entry.is_prologue_end, line_entry.is_epilogue_begin, - line_entry.is_terminal_entry); - } - line_table->InsertSequence(sequence.get()); - if (line_table->GetSize() == 0) return false; @@ -1212,33 +1117,6 @@ bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) { return false; } -llvm::Expected -SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii, - uint32_t file_id) { - auto index_iter = m_file_indexes.find(file_id); - if (index_iter != m_file_indexes.end()) - return index_iter->getSecond(); - const auto &checksums = cii.m_strings.checksums().getArray(); - const auto &strings = cii.m_strings.strings(); - // Indices in this structure are actually offsets of records in the - // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index - // into the global PDB string table. - auto iter = checksums.at(file_id); - if (iter == checksums.end()) - return llvm::make_error(raw_error_code::no_entry); - - llvm::Expected efn = strings.getString(iter->FileNameOffset); - if (!efn) { - return efn.takeError(); - } - - // LLDB wants the index of the file in the list of support files. - auto fn_iter = llvm::find(cii.m_file_list, *efn); - lldbassert(fn_iter != cii.m_file_list.end()); - m_file_indexes[file_id] = std::distance(cii.m_file_list.begin(), fn_iter); - return m_file_indexes[file_id]; -} - bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit, FileSpecList &support_files) { std::lock_guard guard(GetModuleMutex()); @@ -1263,220 +1141,11 @@ bool SymbolFileNativePDB::ParseImportedModules( return false; } -void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id, - Address func_addr) { - lldb::user_id_t opaque_uid = toOpaqueUid(id); - if (m_inline_sites.find(opaque_uid) != m_inline_sites.end()) - return; - - addr_t func_base = func_addr.GetFileAddress(); - CompilandIndexItem *cii = m_index->compilands().GetCompiland(id.modi); - CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(id.offset); - CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii); - - InlineSiteSym inline_site(static_cast(sym.kind())); - cantFail(SymbolDeserializer::deserializeAs(sym, inline_site)); - PdbCompilandSymId parent_id(id.modi, inline_site.Parent); - - std::shared_ptr inline_site_sp = - std::make_shared(parent_id); - - // Get the inlined function declaration info. - auto iter = cii->m_inline_map.find(inline_site.Inlinee); - if (iter == cii->m_inline_map.end()) - return; - InlineeSourceLine inlinee_line = iter->second; - - const FileSpecList &files = comp_unit->GetSupportFiles(); - FileSpec decl_file; - llvm::Expected file_index_or_err = - GetFileIndex(*cii, inlinee_line.Header->FileID); - if (!file_index_or_err) - return; - uint32_t decl_file_idx = file_index_or_err.get(); - decl_file = files.GetFileSpecAtIndex(decl_file_idx); - uint32_t decl_line = inlinee_line.Header->SourceLineNum; - std::unique_ptr decl_up = - std::make_unique(decl_file, decl_line); - - // Parse range and line info. - uint32_t code_offset = 0; - int32_t line_offset = 0; - bool has_base = false; - bool is_new_line_offset = false; - - bool is_start_of_statement = false; - // The first instruction is the prologue end. - bool is_prologue_end = true; - - auto change_code_offset = [&](uint32_t code_delta) { - if (has_base) { - inline_site_sp->ranges.Append(RangeSourceLineVector::Entry( - code_offset, code_delta, decl_line + line_offset)); - is_prologue_end = false; - is_start_of_statement = false; - } else { - is_start_of_statement = true; - } - has_base = true; - code_offset += code_delta; - - if (is_new_line_offset) { - LineTable::Entry line_entry(func_base + code_offset, - decl_line + line_offset, 0, decl_file_idx, - true, false, is_prologue_end, false, false); - inline_site_sp->line_entries.push_back(line_entry); - is_new_line_offset = false; - } - }; - auto change_code_length = [&](uint32_t length) { - inline_site_sp->ranges.Append(RangeSourceLineVector::Entry( - code_offset, length, decl_line + line_offset)); - has_base = false; - - LineTable::Entry end_line_entry(func_base + code_offset + length, - decl_line + line_offset, 0, decl_file_idx, - false, false, false, false, true); - inline_site_sp->line_entries.push_back(end_line_entry); - }; - auto change_line_offset = [&](int32_t line_delta) { - line_offset += line_delta; - if (has_base) { - LineTable::Entry line_entry( - func_base + code_offset, decl_line + line_offset, 0, decl_file_idx, - is_start_of_statement, false, is_prologue_end, false, false); - inline_site_sp->line_entries.push_back(line_entry); - } else { - // Add line entry in next call to change_code_offset. - is_new_line_offset = true; - } - }; - - for (auto &annot : inline_site.annotations()) { - switch (annot.OpCode) { - case BinaryAnnotationsOpCode::CodeOffset: - case BinaryAnnotationsOpCode::ChangeCodeOffset: - case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: - change_code_offset(annot.U1); - break; - case BinaryAnnotationsOpCode::ChangeLineOffset: - change_line_offset(annot.S1); - break; - case BinaryAnnotationsOpCode::ChangeCodeLength: - change_code_length(annot.U1); - code_offset += annot.U1; - break; - case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: - change_code_offset(annot.U1); - change_line_offset(annot.S1); - break; - case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: - change_code_offset(annot.U2); - change_code_length(annot.U1); - break; - default: - break; - } - } - - inline_site_sp->ranges.Sort(); - inline_site_sp->ranges.CombineConsecutiveEntriesWithEqualData(); - - // Get the inlined function callsite info. - std::unique_ptr callsite_up; - if (!inline_site_sp->ranges.IsEmpty()) { - auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0); - addr_t base_offset = entry->GetRangeBase(); - if (cii->m_debug_stream.readSymbolAtOffset(parent_id.offset).kind() == - S_INLINESITE) { - // Its parent is another inline site, lookup parent site's range vector - // for callsite line. - ParseInlineSite(parent_id, func_base); - std::shared_ptr parent_site = - m_inline_sites[toOpaqueUid(parent_id)]; - FileSpec &parent_decl_file = - parent_site->inline_function_info->GetDeclaration().GetFile(); - if (auto *parent_entry = - parent_site->ranges.FindEntryThatContains(base_offset)) { - callsite_up = - std::make_unique(parent_decl_file, parent_entry->data); - } - } else { - // Its parent is a function, lookup global line table for callsite. - if (auto *entry = cii->m_global_line_table.FindEntryThatContains( - func_base + base_offset)) { - const FileSpec &callsite_file = - files.GetFileSpecAtIndex(entry->data.first); - callsite_up = - std::make_unique(callsite_file, entry->data.second); - } - } - } - - // Get the inlined function name. - CVType inlinee_cvt = m_index->ipi().getType(inline_site.Inlinee); - std::string inlinee_name; - if (inlinee_cvt.kind() == LF_MFUNC_ID) { - MemberFuncIdRecord mfr; - cantFail( - TypeDeserializer::deserializeAs(inlinee_cvt, mfr)); - LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); - inlinee_name.append(std::string(types.getTypeName(mfr.ClassType))); - inlinee_name.append("::"); - inlinee_name.append(mfr.getName().str()); - } else if (inlinee_cvt.kind() == LF_FUNC_ID) { - FuncIdRecord fir; - cantFail(TypeDeserializer::deserializeAs(inlinee_cvt, fir)); - TypeIndex parent_idx = fir.getParentScope(); - if (!parent_idx.isNoneType()) { - LazyRandomTypeCollection &ids = m_index->ipi().typeCollection(); - inlinee_name.append(std::string(ids.getTypeName(parent_idx))); - inlinee_name.append("::"); - } - inlinee_name.append(fir.getName().str()); - } - inline_site_sp->inline_function_info = std::make_shared( - inlinee_name.c_str(), llvm::StringRef(), decl_up.get(), - callsite_up.get()); - - m_inline_sites[opaque_uid] = inline_site_sp; -} - size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) { std::lock_guard guard(GetModuleMutex()); - PdbCompilandSymId func_id = PdbSymUid(func.GetID()).asCompilandSym(); - // After we iterate through inline sites inside the function, we already get - // all the info needed, removing from the map to save memory. - std::set remove_uids; - auto parse_inline_sites = [&](SymbolKind kind, PdbCompilandSymId id) { - if (kind != S_INLINESITE) - return false; - GetOrCreateBlock(id); - remove_uids.insert(toOpaqueUid(id)); - return true; - }; - size_t count = ParseSymbolArrayInScope(func_id, parse_inline_sites); - for (uint64_t uid : remove_uids) { - m_inline_sites.erase(uid); - } - return count; -} - -size_t SymbolFileNativePDB::ParseSymbolArrayInScope( - PdbCompilandSymId parent_id, - llvm::function_ref fn) { - CompilandIndexItem *cii = m_index->compilands().GetCompiland(parent_id.modi); - CVSymbolArray syms = - cii->m_debug_stream.getSymbolArrayForScope(parent_id.offset); - - size_t count = 1; - for (auto iter = syms.begin(); iter != syms.end(); ++iter) { - PdbCompilandSymId child_id(parent_id.modi, iter.offset()); - if (fn(iter->kind(), child_id)) - ++count; - } - - return count; + GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym()); + // FIXME: Parse child blocks + return 1; } void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); } @@ -1727,9 +1396,6 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { } case S_BLOCK32: break; - case S_INLINESITE: - // TODO: Handle inline site case. - return 0; default: lldbassert(false && "Symbol is not a block!"); return 0; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index f1b6e34ca346b..56a5ec0a464d7 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -9,7 +9,6 @@ #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H -#include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/SymbolFile.h" #include "llvm/ADT/DenseMap.h" @@ -162,25 +161,6 @@ class SymbolFileNativePDB : public SymbolFile { void DumpClangAST(Stream &s) override; private: - struct LineTableEntryComparator { - bool operator()(const lldb_private::LineTable::Entry &lhs, - const lldb_private::LineTable::Entry &rhs) const { - return lhs.file_addr < rhs.file_addr; - } - }; - - // From address range relative to function base to source line number. - using RangeSourceLineVector = - lldb_private::RangeDataVector; - // InlineSite contains information in a S_INLINESITE record. - struct InlineSite { - PdbCompilandSymId parent_id; - std::shared_ptr inline_function_info; - RangeSourceLineVector ranges; - std::vector line_entries; - InlineSite(PdbCompilandSymId parent_id) : parent_id(parent_id){}; - }; - uint32_t CalculateNumCompileUnits() override; lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; @@ -245,16 +225,6 @@ class SymbolFileNativePDB : public SymbolFile { VariableList &variables); size_t ParseVariablesForBlock(PdbCompilandSymId block_id); - llvm::Expected GetFileIndex(const CompilandIndexItem &cii, - uint32_t file_id); - - size_t ParseSymbolArrayInScope( - PdbCompilandSymId parent, - llvm::function_ref - fn); - - void ParseInlineSite(PdbCompilandSymId inline_site_id, Address func_addr); - llvm::BumpPtrAllocator m_allocator; lldb::addr_t m_obj_load_address = 0; @@ -271,9 +241,6 @@ class SymbolFileNativePDB : public SymbolFile { llvm::DenseMap m_functions; llvm::DenseMap m_compilands; llvm::DenseMap m_types; - llvm::DenseMap> m_inline_sites; - // A map from file id in records to file index in support files. - llvm::DenseMap m_file_indexes; }; } // namespace npdb diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/inline_sites.lldbinit b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/inline_sites.lldbinit deleted file mode 100644 index 362e79252e66b..0000000000000 --- a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/inline_sites.lldbinit +++ /dev/null @@ -1,17 +0,0 @@ -image dump line-table a.cpp -v - -b a.cpp:5 -b a.h:5 -b a.h:6 -b a.h:7 -b b.h:6 -b c.h:6 - -image lookup -a 0x140001003 -v -image lookup -a 0x140001004 -v -image lookup -a 0x140001014 -v -image lookup -a 0x14000101a -v -image lookup -a 0x140001021 -v -image lookup -a 0x140001028 -v - -quit \ No newline at end of file diff --git a/lldb/test/Shell/SymbolFile/NativePDB/inline_sites.s b/lldb/test/Shell/SymbolFile/NativePDB/inline_sites.s deleted file mode 100644 index efe266e23a6ad..0000000000000 --- a/lldb/test/Shell/SymbolFile/NativePDB/inline_sites.s +++ /dev/null @@ -1,667 +0,0 @@ -# clang-format off -# REQUIRES: lld, x86 - -# RUN: llvm-mc -triple=x86_64-windows-msvc --filetype=obj %s > %t.obj -# RUN: lld-link -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -# RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \ -# RUN: %p/Inputs/inline_sites.lldbinit 2>&1 | FileCheck %s - -# Compiled from the following files, but replaced the call to abort with nop. -# a.cpp: -# #include "stdlib.h" -# #include "a.h" -# int main(int argc, char** argv) { -# Namespace1::foo(2); -# return 0; -# } -# a.h: -# #include "b.h" -# namespace Namespace1 { -# inline void foo(int x) { -# static volatile int gv_foo; -# ++gv_foo; -# if (!gv_foo) -# abort(); -# Class1::bar(x + 1); -# } -# } -# b.h: -# #include "c.h" -# class Class1 { -# public: -# inline static void bar(int x) { -# static volatile int gv_bar; -# ++gv_bar; -# Namespace2::Class2::func(x + 1); -# } -# }; -# c.h: -# namespace Namespace2{ -# class Class2{ -# public: -# inline static void func(int x) { -# static volatile int gv_func; -# gv_func += x; -# } -# }; -# } - -# CHECK: (lldb) image dump line-table a.cpp -v -# CHECK-NEXT: Line table for /tmp/a.cpp in -# CHECK-NEXT: 0x0000000140001000: /tmp/a.cpp:3 -# CHECK-NEXT: 0x0000000140001004: /tmp/a.h:5, is_start_of_statement = TRUE, is_prologue_end = TRUE -# CHECK-NEXT: 0x000000014000100a: /tmp/a.h:6 -# CHECK-NEXT: 0x0000000140001014: /tmp/b.h:6, is_start_of_statement = TRUE, is_prologue_end = TRUE -# CHECK-NEXT: 0x000000014000101a: /tmp/c.h:6, is_start_of_statement = TRUE, is_prologue_end = TRUE -# CHECK-NEXT: 0x0000000140001021: /tmp/a.cpp:5 -# CHECK-NEXT: 0x0000000140001028: /tmp/a.h:7, is_start_of_statement = TRUE -# CHECK-NEXT: 0x000000014000102a: /tmp/a.cpp:5, is_terminal_entry = TRUE - -# CEHCK: (lldb) b a.cpp:5 -# CHECK: Breakpoint 1: where = {{.*}}`main + 33 at a.cpp:5, address = 0x0000000140001021 -# CEHCK: (lldb) b a.h:5 -# CHECK: Breakpoint 2: where = {{.*}}`main + 4 [inlined] Namespace1::foo at a.h:5, address = 0x0000000140001004 -# CEHCK: (lldb) b a.h:6 -# CHECK: Breakpoint 3: where = {{.*}}`main + 10 [inlined] Namespace1::foo + 6 at a.h:6, address = 0x000000014000100a -# CEHCK: (lldb) b a.h:7 -# CHECK: Breakpoint 4: where = {{.*}}`main + 40 [inlined] Namespace1::foo at a.h:7, address = 0x0000000140001028 -# CEHCK: (lldb) b b.h:6 -# CHECK: Breakpoint 5: where = {{.*}}`main + 20 [inlined] Class1::bar at b.h:6, address = 0x0000000140001014 -# CEHCK: (lldb) b c.h:6 -# CHECK: Breakpoint 6: where = {{.*}}`main + 26 [inlined] Namespace2::Class2::func at c.h:6, address = 0x000000014000101a - -# CEHCK-LABEL: (lldb) image lookup -a 0x140001003 -v -# CHECK: Summary: {{.*}}`main + 3 at a.cpp:3 -# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x000000014000102a) -# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x14000102a) -# CHECK: LineEntry: [0x0000000140001000-0x0000000140001004): /tmp/a.cpp:3 - -# CEHCK-LABEL: (lldb) image lookup -a 0x140001004 -v -# CHECK: Summary: {{.*}}`main + 4 [inlined] Namespace1::foo at a.h:5 -# CHECK-NEXT: {{.*}}`main + 4 at a.cpp:4 -# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x000000014000102a) -# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x14000102a) -# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001021)[0x140001028-0x14000102a), name = "Namespace1::foo", decl = a.h:3 -# CHECK: LineEntry: [0x0000000140001004-0x000000014000100a): /tmp/a.h:5 - -# CEHCK-LABEL: (lldb) image lookup -a 0x140001014 -v -# CHECK: Summary: {{.*}}`main + 20 [inlined] Class1::bar at b.h:6 -# CHECK-NEXT: {{.*}}`main + 20 [inlined] Namespace1::foo + 16 at a.h:8 -# CHECK-NEXT: {{.*}}`main + 4 at a.cpp:4 -# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x000000014000102a) -# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x14000102a) -# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001021)[0x140001028-0x14000102a), name = "Namespace1::foo", decl = a.h:3 -# CHECK-NEXT: id = {{.*}}, range = [0x140001014-0x140001021), name = "Class1::bar", decl = b.h:4 -# CHECK: LineEntry: [0x0000000140001014-0x000000014000101a): /tmp/b.h:6 - -# CEHCK-LABEL: (lldb) image lookup -a 0x14000101a -v -# CHECK: Summary: {{.*}}`main + 26 [inlined] Namespace2::Class2::func at c.h:6 -# CHECK-NEXT: {{.*}}`main + 26 [inlined] Class1::bar + 6 at b.h:7 -# CHECK-NEXT: {{.*}}`main + 20 [inlined] Namespace1::foo + 16 at a.h:8 -# CHECK-NEXT: {{.*}}`main + 4 at a.cpp:4 -# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x000000014000102a) -# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x14000102a) -# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001021)[0x140001028-0x14000102a), name = "Namespace1::foo", decl = a.h:3 -# CHECK-NEXT: id = {{.*}}, range = [0x140001014-0x140001021), name = "Class1::bar", decl = b.h:4 -# CHECK-NEXT: id = {{.*}}, range = [0x14000101a-0x140001021), name = "Namespace2::Class2::func", decl = c.h:4 -# CHECK: LineEntry: [0x000000014000101a-0x0000000140001021): /tmp/c.h:6 - -# CEHCK-LABEL: (lldb) image lookup -a 0x140001021 -v -# CHECK: Summary: {{.*}}`main + 33 at a.cpp:5 -# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x000000014000102a) -# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x14000102a) -# CHECK: LineEntry: [0x0000000140001021-0x0000000140001028): /tmp/a.cpp:5 - -# CEHCK-LABEL: (lldb) image lookup -a 0x140001028 -v -# CHECK: Summary: {{.*}}`main + 40 [inlined] Namespace1::foo at a.h:7 -# CHECK-NEXT: {{.*}}`main + 40 at a.cpp:4 -# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x000000014000102a) -# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x14000102a) -# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001021)[0x140001028-0x14000102a), name = "Namespace1::foo", decl = a.h:3 -# CHECK: LineEntry: [0x0000000140001028-0x000000014000102a): /tmp/a.h:7 - - .text - .def @feat.00; - .scl 3; - .type 0; - .endef - .globl @feat.00 -.set @feat.00, 0 - .intel_syntax noprefix - .file "a.cpp" - .def main; - .scl 2; - .type 32; - .endef - .section .text,"xr",one_only,main - .globl main # -- Begin function main -main: # @main -.Lfunc_begin0: - .cv_func_id 0 - .cv_file 1 "/tmp/a.cpp" "4ECCDD2814054DCF80EA72F4349036C4" 1 - .cv_loc 0 1 3 0 # a.cpp:3:0 -.seh_proc main -# %bb.0: # %entry - #DEBUG_VALUE: main:argv <- $rdx - #DEBUG_VALUE: main:argc <- $ecx - #DEBUG_VALUE: foo:x <- 2 - sub rsp, 40 - .seh_stackalloc 40 - .seh_endprologue -.Ltmp0: - .cv_file 2 "/tmp/./a.h" "9E656AFA1B1B681265C87EEA8BBE073E" 1 - .cv_inline_site_id 1 within 0 inlined_at 1 4 0 - .cv_loc 1 2 5 0 # ./a.h:5:0 - inc dword ptr [rip + "?gv_foo@?1??foo@Namespace1@@YAXH@Z@4HC"] - .cv_loc 1 2 6 0 # ./a.h:6:0 - mov eax, dword ptr [rip + "?gv_foo@?1??foo@Namespace1@@YAXH@Z@4HC"] - test eax, eax - je .LBB0_2 -.Ltmp1: -# %bb.1: # %"?foo@Namespace1@@YAXH@Z.exit" - #DEBUG_VALUE: foo:x <- 2 - #DEBUG_VALUE: main:argc <- $ecx - #DEBUG_VALUE: main:argv <- $rdx - #DEBUG_VALUE: bar:x <- [DW_OP_plus_uconst 1, DW_OP_stack_value] 2 - .cv_file 3 "/tmp/./b.h" "BE52983EB17A3B0DA14E68A5CCBC4399" 1 - .cv_inline_site_id 2 within 1 inlined_at 2 8 0 - .cv_loc 2 3 6 0 # ./b.h:6:0 - inc dword ptr [rip + "?gv_bar@?1??bar@Class1@@SAXH@Z@4HC"] -.Ltmp2: - #DEBUG_VALUE: func:x <- 4 - .cv_file 4 "/tmp/./c.h" "D1B76A1C2A54DBEA648F3A11496166B8" 1 - .cv_inline_site_id 3 within 2 inlined_at 3 7 0 - .cv_loc 3 4 6 0 # ./c.h:6:0 - add dword ptr [rip + "?gv_func@?1??func@Class2@Namespace2@@SAXH@Z@4HC"], 4 -.Ltmp3: - .cv_loc 0 1 5 0 # a.cpp:5:0 - xor eax, eax - add rsp, 40 - ret -.Ltmp4: -.LBB0_2: # %if.then.i - #DEBUG_VALUE: foo:x <- 2 - #DEBUG_VALUE: main:argc <- $ecx - #DEBUG_VALUE: main:argv <- $rdx - .cv_loc 1 2 7 0 # ./a.h:7:0 - nop -.Ltmp5: - int3 -.Ltmp6: - #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rdx - #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $ecx -.Lfunc_end0: - .seh_endproc - # -- End function - .section .bss,"bw",discard,"?gv_foo@?1??foo@Namespace1@@YAXH@Z@4HC" - .globl "?gv_foo@?1??foo@Namespace1@@YAXH@Z@4HC" # @"?gv_foo@?1??foo@Namespace1@@YAXH@Z@4HC" - .p2align 2 -"?gv_foo@?1??foo@Namespace1@@YAXH@Z@4HC": - .long 0 # 0x0 - - .section .bss,"bw",discard,"?gv_bar@?1??bar@Class1@@SAXH@Z@4HC" - .globl "?gv_bar@?1??bar@Class1@@SAXH@Z@4HC" # @"?gv_bar@?1??bar@Class1@@SAXH@Z@4HC" - .p2align 2 -"?gv_bar@?1??bar@Class1@@SAXH@Z@4HC": - .long 0 # 0x0 - - .section .bss,"bw",discard,"?gv_func@?1??func@Class2@Namespace2@@SAXH@Z@4HC" - .globl "?gv_func@?1??func@Class2@Namespace2@@SAXH@Z@4HC" # @"?gv_func@?1??func@Class2@Namespace2@@SAXH@Z@4HC" - .p2align 2 -"?gv_func@?1??func@Class2@Namespace2@@SAXH@Z@4HC": - .long 0 # 0x0 - - .section .drectve,"yn" - .ascii " /DEFAULTLIB:libcmt.lib" - .ascii " /DEFAULTLIB:oldnames.lib" - .section .debug$S,"dr" - .p2align 2 - .long 4 # Debug section magic - .long 241 - .long .Ltmp8-.Ltmp7 # Subsection size -.Ltmp7: - .short .Ltmp10-.Ltmp9 # Record length -.Ltmp9: - .short 4353 # Record kind: S_OBJNAME - .long 0 # Signature - .asciz "/tmp/a-e5dd01.obj" # Object name - .p2align 2 -.Ltmp10: - .short .Ltmp12-.Ltmp11 # Record length -.Ltmp11: - .short 4412 # Record kind: S_COMPILE3 - .long 1 # Flags and language - .short 208 # CPUType - .short 14 # Frontend version - .short 0 - .short 0 - .short 0 - .short 14000 # Backend version - .short 0 - .short 0 - .short 0 - .asciz "clang version 14.0.0" # Null-terminated compiler version string - .p2align 2 -.Ltmp12: -.Ltmp8: - .p2align 2 - .long 246 # Inlinee lines subsection - .long .Ltmp14-.Ltmp13 # Subsection size -.Ltmp13: - .long 0 # Inlinee lines signature - - # Inlined function foo starts at ./a.h:3 - .long 4099 # Type index of inlined function - .cv_filechecksumoffset 2 # Offset into filechecksum table - .long 3 # Starting line number - - # Inlined function bar starts at ./b.h:4 - .long 4106 # Type index of inlined function - .cv_filechecksumoffset 3 # Offset into filechecksum table - .long 4 # Starting line number - - # Inlined function func starts at ./c.h:4 - .long 4113 # Type index of inlined function - .cv_filechecksumoffset 4 # Offset into filechecksum table - .long 4 # Starting line number -.Ltmp14: - .p2align 2 - .section .debug$S,"dr",associative,main - .p2align 2 - .long 4 # Debug section magic - .long 241 # Symbol subsection for main - .long .Ltmp16-.Ltmp15 # Subsection size -.Ltmp15: - .short .Ltmp18-.Ltmp17 # Record length -.Ltmp17: - .short 4423 # Record kind: S_GPROC32_ID - .long 0 # PtrParent - .long 0 # PtrEnd - .long 0 # PtrNext - .long .Lfunc_end0-main # Code size - .long 0 # Offset after prologue - .long 0 # Offset before epilogue - .long 4117 # Function type index - .secrel32 main # Function section relative address - .secidx main # Function section index - .byte 0 # Flags - .asciz "main" # Function name - .p2align 2 -.Ltmp18: - .short .Ltmp20-.Ltmp19 # Record length -.Ltmp19: - .short 4114 # Record kind: S_FRAMEPROC - .long 40 # FrameSize - .long 0 # Padding - .long 0 # Offset of padding - .long 0 # Bytes of callee saved registers - .long 0 # Exception handler offset - .short 0 # Exception handler section - .long 81920 # Flags (defines frame register) - .p2align 2 -.Ltmp20: - .short .Ltmp22-.Ltmp21 # Record length -.Ltmp21: - .short 4414 # Record kind: S_LOCAL - .long 116 # TypeIndex - .short 1 # Flags - .asciz "argc" - .p2align 2 -.Ltmp22: - .cv_def_range .Lfunc_begin0 .Ltmp5, reg, 18 - .short .Ltmp24-.Ltmp23 # Record length -.Ltmp23: - .short 4414 # Record kind: S_LOCAL - .long 4114 # TypeIndex - .short 1 # Flags - .asciz "argv" - .p2align 2 -.Ltmp24: - .cv_def_range .Lfunc_begin0 .Ltmp5, reg, 331 - .short .Ltmp26-.Ltmp25 # Record length -.Ltmp25: - .short 4365 # Record kind: S_GDATA32 - .long 4118 # Type - .secrel32 "?gv_foo@?1??foo@Namespace1@@YAXH@Z@4HC" # DataOffset - .secidx "?gv_foo@?1??foo@Namespace1@@YAXH@Z@4HC" # Segment - .asciz "Namespace1::foo::gv_foo" # Name - .p2align 2 -.Ltmp26: - .short .Ltmp28-.Ltmp27 # Record length -.Ltmp27: - .short 4365 # Record kind: S_GDATA32 - .long 4118 # Type - .secrel32 "?gv_bar@?1??bar@Class1@@SAXH@Z@4HC" # DataOffset - .secidx "?gv_bar@?1??bar@Class1@@SAXH@Z@4HC" # Segment - .asciz "Class1::bar::gv_bar" # Name - .p2align 2 -.Ltmp28: - .short .Ltmp30-.Ltmp29 # Record length -.Ltmp29: - .short 4365 # Record kind: S_GDATA32 - .long 4118 # Type - .secrel32 "?gv_func@?1??func@Class2@Namespace2@@SAXH@Z@4HC" # DataOffset - .secidx "?gv_func@?1??func@Class2@Namespace2@@SAXH@Z@4HC" # Segment - .asciz "Namespace2::Class2::func::gv_func" # Name - .p2align 2 -.Ltmp30: - .short .Ltmp32-.Ltmp31 # Record length -.Ltmp31: - .short 4429 # Record kind: S_INLINESITE - .long 0 # PtrParent - .long 0 # PtrEnd - .long 4099 # Inlinee type index - .cv_inline_linetable 1 2 3 .Lfunc_begin0 .Lfunc_end0 - .p2align 2 -.Ltmp32: - .short .Ltmp34-.Ltmp33 # Record length -.Ltmp33: - .short 4414 # Record kind: S_LOCAL - .long 116 # TypeIndex - .short 257 # Flags - .asciz "x" - .p2align 2 -.Ltmp34: - .short .Ltmp36-.Ltmp35 # Record length -.Ltmp35: - .short 4429 # Record kind: S_INLINESITE - .long 0 # PtrParent - .long 0 # PtrEnd - .long 4106 # Inlinee type index - .cv_inline_linetable 2 3 4 .Lfunc_begin0 .Lfunc_end0 - .p2align 2 -.Ltmp36: - .short .Ltmp38-.Ltmp37 # Record length -.Ltmp37: - .short 4414 # Record kind: S_LOCAL - .long 116 # TypeIndex - .short 257 # Flags - .asciz "x" - .p2align 2 -.Ltmp38: - .short .Ltmp40-.Ltmp39 # Record length -.Ltmp39: - .short 4429 # Record kind: S_INLINESITE - .long 0 # PtrParent - .long 0 # PtrEnd - .long 4113 # Inlinee type index - .cv_inline_linetable 3 4 4 .Lfunc_begin0 .Lfunc_end0 - .p2align 2 -.Ltmp40: - .short .Ltmp42-.Ltmp41 # Record length -.Ltmp41: - .short 4414 # Record kind: S_LOCAL - .long 116 # TypeIndex - .short 257 # Flags - .asciz "x" - .p2align 2 -.Ltmp42: - .short 2 # Record length - .short 4430 # Record kind: S_INLINESITE_END - .short 2 # Record length - .short 4430 # Record kind: S_INLINESITE_END - .short 2 # Record length - .short 4430 # Record kind: S_INLINESITE_END - .short 2 # Record length - .short 4431 # Record kind: S_PROC_ID_END -.Ltmp16: - .p2align 2 - .cv_linetable 0, main, .Lfunc_end0 - .section .debug$S,"dr" - .long 241 - .long .Ltmp44-.Ltmp43 # Subsection size -.Ltmp43: - .short .Ltmp46-.Ltmp45 # Record length -.Ltmp45: - .short 4360 # Record kind: S_UDT - .long 4103 # Type - .asciz "Class1" - .p2align 2 -.Ltmp46: - .short .Ltmp48-.Ltmp47 # Record length -.Ltmp47: - .short 4360 # Record kind: S_UDT - .long 4110 # Type - .asciz "Namespace2::Class2" - .p2align 2 -.Ltmp48: -.Ltmp44: - .p2align 2 - .cv_filechecksums # File index to string table offset subsection - .cv_stringtable # String table - .long 241 - .long .Ltmp50-.Ltmp49 # Subsection size -.Ltmp49: - .short .Ltmp52-.Ltmp51 # Record length -.Ltmp51: - .short 4428 # Record kind: S_BUILDINFO - .long 4121 # LF_BUILDINFO index - .p2align 2 -.Ltmp52: -.Ltmp50: - .p2align 2 - .section .debug$T,"dr" - .p2align 2 - .long 4 # Debug section magic - # StringId (0x1000) - .short 0x12 # Record length - .short 0x1605 # Record kind: LF_STRING_ID - .long 0x0 # Id - .asciz "Namespace1" # StringData - .byte 241 - # ArgList (0x1001) - .short 0xa # Record length - .short 0x1201 # Record kind: LF_ARGLIST - .long 0x1 # NumArgs - .long 0x74 # Argument: int - # Procedure (0x1002) - .short 0xe # Record length - .short 0x1008 # Record kind: LF_PROCEDURE - .long 0x3 # ReturnType: void - .byte 0x0 # CallingConvention: NearC - .byte 0x0 # FunctionOptions - .short 0x1 # NumParameters - .long 0x1001 # ArgListType: (int) - # FuncId (0x1003) - .short 0xe # Record length - .short 0x1601 # Record kind: LF_FUNC_ID - .long 0x1000 # ParentScope: Namespace1 - .long 0x1002 # FunctionType: void (int) - .asciz "foo" # Name - # Class (0x1004) - .short 0x2a # Record length - .short 0x1504 # Record kind: LF_CLASS - .short 0x0 # MemberCount - .short 0x280 # Properties ( ForwardReference (0x80) | HasUniqueName (0x200) ) - .long 0x0 # FieldList - .long 0x0 # DerivedFrom - .long 0x0 # VShape - .short 0x0 # SizeOf - .asciz "Class1" # Name - .asciz ".?AVClass1@@" # LinkageName - .byte 242 - .byte 241 - # MemberFunction (0x1005) - .short 0x1a # Record length - .short 0x1009 # Record kind: LF_MFUNCTION - .long 0x3 # ReturnType: void - .long 0x1004 # ClassType: Class1 - .long 0x0 # ThisType - .byte 0x0 # CallingConvention: NearC - .byte 0x0 # FunctionOptions - .short 0x1 # NumParameters - .long 0x1001 # ArgListType: (int) - .long 0x0 # ThisAdjustment - # FieldList (0x1006) - .short 0xe # Record length - .short 0x1203 # Record kind: LF_FIELDLIST - .short 0x1511 # Member kind: OneMethod ( LF_ONEMETHOD ) - .short 0xb # Attrs: Public, Static - .long 0x1005 # Type: void Class1::(int) - .asciz "bar" # Name - # Class (0x1007) - .short 0x2a # Record length - .short 0x1504 # Record kind: LF_CLASS - .short 0x1 # MemberCount - .short 0x200 # Properties ( HasUniqueName (0x200) ) - .long 0x1006 # FieldList: - .long 0x0 # DerivedFrom - .long 0x0 # VShape - .short 0x1 # SizeOf - .asciz "Class1" # Name - .asciz ".?AVClass1@@" # LinkageName - .byte 242 - .byte 241 - # StringId (0x1008) - .short 0x12 # Record length - .short 0x1605 # Record kind: LF_STRING_ID - .long 0x0 # Id - .asciz "/tmp/./b.h" # StringData - .byte 241 - # UdtSourceLine (0x1009) - .short 0xe # Record length - .short 0x1606 # Record kind: LF_UDT_SRC_LINE - .long 0x1007 # UDT: Class1 - .long 0x1008 # SourceFile: /tmp/./b.h - .long 0x2 # LineNumber - # MemberFuncId (0x100A) - .short 0xe # Record length - .short 0x1602 # Record kind: LF_MFUNC_ID - .long 0x1004 # ClassType: Class1 - .long 0x1005 # FunctionType: void Class1::(int) - .asciz "bar" # Name - # Class (0x100B) - .short 0x42 # Record length - .short 0x1504 # Record kind: LF_CLASS - .short 0x0 # MemberCount - .short 0x280 # Properties ( ForwardReference (0x80) | HasUniqueName (0x200) ) - .long 0x0 # FieldList - .long 0x0 # DerivedFrom - .long 0x0 # VShape - .short 0x0 # SizeOf - .asciz "Namespace2::Class2" # Name - .asciz ".?AVClass2@Namespace2@@" # LinkageName - .byte 243 - .byte 242 - .byte 241 - # MemberFunction (0x100C) - .short 0x1a # Record length - .short 0x1009 # Record kind: LF_MFUNCTION - .long 0x3 # ReturnType: void - .long 0x100b # ClassType: Namespace2::Class2 - .long 0x0 # ThisType - .byte 0x0 # CallingConvention: NearC - .byte 0x0 # FunctionOptions - .short 0x1 # NumParameters - .long 0x1001 # ArgListType: (int) - .long 0x0 # ThisAdjustment - # FieldList (0x100D) - .short 0x12 # Record length - .short 0x1203 # Record kind: LF_FIELDLIST - .short 0x1511 # Member kind: OneMethod ( LF_ONEMETHOD ) - .short 0xb # Attrs: Public, Static - .long 0x100c # Type: void Namespace2::Class2::(int) - .asciz "func" # Name - .byte 243 - .byte 242 - .byte 241 - # Class (0x100E) - .short 0x42 # Record length - .short 0x1504 # Record kind: LF_CLASS - .short 0x1 # MemberCount - .short 0x200 # Properties ( HasUniqueName (0x200) ) - .long 0x100d # FieldList: - .long 0x0 # DerivedFrom - .long 0x0 # VShape - .short 0x1 # SizeOf - .asciz "Namespace2::Class2" # Name - .asciz ".?AVClass2@Namespace2@@" # LinkageName - .byte 243 - .byte 242 - .byte 241 - # StringId (0x100F) - .short 0x12 # Record length - .short 0x1605 # Record kind: LF_STRING_ID - .long 0x0 # Id - .asciz "/tmp/./c.h" # StringData - .byte 241 - # UdtSourceLine (0x1010) - .short 0xe # Record length - .short 0x1606 # Record kind: LF_UDT_SRC_LINE - .long 0x100e # UDT: Namespace2::Class2 - .long 0x100f # SourceFile: /tmp/./c.h - .long 0x2 # LineNumber - # MemberFuncId (0x1011) - .short 0x12 # Record length - .short 0x1602 # Record kind: LF_MFUNC_ID - .long 0x100b # ClassType: Namespace2::Class2 - .long 0x100c # FunctionType: void Namespace2::Class2::(int) - .asciz "func" # Name - .byte 243 - .byte 242 - .byte 241 - # Pointer (0x1012) - .short 0xa # Record length - .short 0x1002 # Record kind: LF_POINTER - .long 0x670 # PointeeType: char* - .long 0x1000c # Attrs: [ Type: Near64, Mode: Pointer, SizeOf: 8 ] - # ArgList (0x1013) - .short 0xe # Record length - .short 0x1201 # Record kind: LF_ARGLIST - .long 0x2 # NumArgs - .long 0x74 # Argument: int - .long 0x1012 # Argument: char** - # Procedure (0x1014) - .short 0xe # Record length - .short 0x1008 # Record kind: LF_PROCEDURE - .long 0x74 # ReturnType: int - .byte 0x0 # CallingConvention: NearC - .byte 0x0 # FunctionOptions - .short 0x2 # NumParameters - .long 0x1013 # ArgListType: (int, char**) - # FuncId (0x1015) - .short 0x12 # Record length - .short 0x1601 # Record kind: LF_FUNC_ID - .long 0x0 # ParentScope - .long 0x1014 # FunctionType: int (int, char**) - .asciz "main" # Name - .byte 243 - .byte 242 - .byte 241 - # Modifier (0x1016) - .short 0xa # Record length - .short 0x1001 # Record kind: LF_MODIFIER - .long 0x74 # ModifiedType: int - .short 0x2 # Modifiers ( Volatile (0x2) ) - .byte 242 - .byte 241 - # StringId (0x1017) - .short 0xe # Record length - .short 0x1605 # Record kind: LF_STRING_ID - .long 0x0 # Id - .asciz "/tmp" # StringData - .byte 243 - .byte 242 - .byte 241 - # StringId (0x1018) - .short 0xe # Record length - .short 0x1605 # Record kind: LF_STRING_ID - .long 0x0 # Id - .asciz "a.cpp" # StringData - .byte 242 - .byte 241 - # BuildInfo (0x1019) - .short 0x1a # Record length - .short 0x1603 # Record kind: LF_BUILDINFO - .short 0x5 # NumArgs - .long 0x1017 # Argument: /tmp - .long 0x0 # Argument - .long 0x1018 # Argument: a.cpp - .long 0x0 # Argument - .long 0x0 # Argument - .byte 242 - .byte 241 - .addrsig - .addrsig_sym "?gv_foo@?1??foo@Namespace1@@YAXH@Z@4HC" - .addrsig_sym "?gv_bar@?1??bar@Class1@@SAXH@Z@4HC" - .addrsig_sym "?gv_func@?1??func@Class2@Namespace2@@SAXH@Z@4HC"