[Lldb-commits] [lldb] a68ccda - Revert "[NFC] Refactor symbol table parsing."

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Wed Nov 17 18:08:23 PST 2021


Author: Greg Clayton
Date: 2021-11-17T18:07:28-08:00
New Revision: a68ccda203aad2cc4fd386d5e893237f09fa1ffb

URL: https://github.com/llvm/llvm-project/commit/a68ccda203aad2cc4fd386d5e893237f09fa1ffb
DIFF: https://github.com/llvm/llvm-project/commit/a68ccda203aad2cc4fd386d5e893237f09fa1ffb.diff

LOG: Revert "[NFC] Refactor symbol table parsing."

This reverts commit 951b107eedab1829f18049443f03339dbb0db165.

Buildbots were failing, there is a deadlock in /Users/gclayton/Documents/src/llvm/clean/llvm-project/lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s when ELF files try to relocate things.

Added: 
    

Modified: 
    lldb/include/lldb/Symbol/ObjectFile.h
    lldb/include/lldb/Symbol/Symtab.h
    lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
    lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
    lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
    lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
    lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
    lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
    lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
    lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
    lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
    lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
    lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
    lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
    lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
    lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
    lldb/source/Symbol/ObjectFile.cpp
    lldb/source/Symbol/Symtab.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index f1b9d4699319b..4ccd7f92064d5 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -322,26 +322,12 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
   /// Gets the symbol table for the currently selected architecture (and
   /// object for archives).
   ///
-  /// This function will manage when ParseSymtab(...) is called to actually do
-  /// the symbol table parsing in each plug-in. This function will take care of
-  /// taking all the necessary locks and finalizing the symbol table when the
-  /// symbol table does get parsed.
+  /// Symbol table parsing can be deferred by ObjectFile instances until this
+  /// accessor is called the first time.
   ///
   /// \return
   ///     The symbol table for this object file.
-  Symtab *GetSymtab();
-
-  /// Parse the symbol table into the provides symbol table object.
-  ///
-  /// Symbol table parsing will be done once when this function is called by
-  /// each object file plugin. All of the necessary locks will already be
-  /// acquired before this function is called and the symbol table object to
-  /// populate is supplied as an argument and doesn't need to be created by
-  /// each plug-in.
-  ///
-  /// \param
-  ///     The symbol table to populate.
-  virtual void ParseSymtab(Symtab &symtab) = 0;
+  virtual Symtab *GetSymtab() = 0;
 
   /// Perform relocations on the section if necessary.
   ///

diff  --git a/lldb/include/lldb/Symbol/Symtab.h b/lldb/include/lldb/Symbol/Symtab.h
index e5d21c1bf4b38..e1ad0dfd2eb8d 100644
--- a/lldb/include/lldb/Symbol/Symtab.h
+++ b/lldb/include/lldb/Symbol/Symtab.h
@@ -119,13 +119,20 @@ class Symtab {
       lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback);
   void FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
                            SymbolContextList &sc_list);
+  void CalculateSymbolSizes();
 
   void SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
                                 bool remove_duplicates) const;
 
   static void DumpSymbolHeader(Stream *s);
 
-  void Finalize();
+  void Finalize() {
+    // Shrink to fit the symbols so we don't waste memory
+    if (m_symbols.capacity() > m_symbols.size()) {
+      collection new_symbols(m_symbols.begin(), m_symbols.end());
+      m_symbols.swap(new_symbols);
+    }
+  }
 
   void AppendSymbolNamesToMap(const IndexCollection &indexes,
                               bool add_demangled, bool add_mangled,

diff  --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index ce701fd823fdf..bad730512ff49 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -116,10 +116,9 @@ bool ObjectFileBreakpad::ParseHeader() {
   return true;
 }
 
-void ObjectFileBreakpad::ParseSymtab(Symtab &symtab) {
-  // Nothing to do for breakpad files, all information is parsed as debug info
-  // which means "lldb_private::Function" objects are used, or symbols are added
-  // by the SymbolFileBreakpad::AddSymbols(...) function in the symbol file.
+Symtab *ObjectFileBreakpad::GetSymtab() {
+  // TODO
+  return nullptr;
 }
 
 void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {

diff  --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
index f04e0b4dd7a7a..c320c7ad3e2e7 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -71,7 +71,7 @@ class ObjectFileBreakpad : public ObjectFile {
     return AddressClass::eInvalid;
   }
 
-  void ParseSymtab(lldb_private::Symtab &symtab) override;
+  Symtab *GetSymtab() override;
 
   bool IsStripped() override { return false; }
 

diff  --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index ec57e0c1f54ec..8e0f228a988f2 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2687,132 +2687,155 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
   return 0;
 }
 
-void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
+Symtab *ObjectFileELF::GetSymtab() {
   ModuleSP module_sp(GetModule());
   if (!module_sp)
-    return;
-
-  Progress progress(
-      llvm::formatv("Parsing symbol table for {0}",
-                    m_file.GetFilename().AsCString("<Unknown>")));
-  ElapsedTime elapsed(module_sp->GetSymtabParseTime());
+    return nullptr;
 
   // We always want to use the main object file so we (hopefully) only have one
   // cached copy of our symtab, dynamic sections, etc.
   ObjectFile *module_obj_file = module_sp->GetObjectFile();
   if (module_obj_file && module_obj_file != this)
-    return module_obj_file->ParseSymtab(lldb_symtab);
+    return module_obj_file->GetSymtab();
+
+  if (m_symtab_up == nullptr) {
+    Progress progress(
+        llvm::formatv("Parsing symbol table for {0}",
+                      m_file.GetFilename().AsCString("<Unknown>")));
+    ElapsedTime elapsed(module_sp->GetSymtabParseTime());
+    SectionList *section_list = module_sp->GetSectionList();
+    if (!section_list)
+      return nullptr;
 
-  SectionList *section_list = module_sp->GetSectionList();
-  if (!section_list)
-    return;
+    uint64_t symbol_id = 0;
+    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+
+    // Sharable objects and dynamic executables usually have 2 distinct symbol
+    // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
+    // smaller version of the symtab that only contains global symbols. The
+    // information found in the dynsym is therefore also found in the symtab,
+    // while the reverse is not necessarily true.
+    Section *symtab =
+        section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
+    if (symtab) {
+      m_symtab_up = std::make_unique<Symtab>(symtab->GetObjectFile());
+      symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);
+    }
 
-  uint64_t symbol_id = 0;
-  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+    // The symtab section is non-allocable and can be stripped, while the
+    // .dynsym section which should always be always be there. To support the
+    // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
+    // section, nomatter if .symtab was already parsed or not. This is because
+    // minidebuginfo normally removes the .symtab symbols which have their
+    // matching .dynsym counterparts.
+    if (!symtab ||
+        GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
+      Section *dynsym =
+          section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
+              .get();
+      if (dynsym) {
+        if (!m_symtab_up)
+          m_symtab_up = std::make_unique<Symtab>(dynsym->GetObjectFile());
+        symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym);
+      }
+    }
 
-  // Sharable objects and dynamic executables usually have 2 distinct symbol
-  // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
-  // smaller version of the symtab that only contains global symbols. The
-  // information found in the dynsym is therefore also found in the symtab,
-  // while the reverse is not necessarily true.
-  Section *symtab =
-      section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
-  if (symtab)
-    symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
-
-  // The symtab section is non-allocable and can be stripped, while the
-  // .dynsym section which should always be always be there. To support the
-  // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
-  // section, nomatter if .symtab was already parsed or not. This is because
-  // minidebuginfo normally removes the .symtab symbols which have their
-  // matching .dynsym counterparts.
-  if (!symtab ||
-      GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
-    Section *dynsym =
-        section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
-            .get();
-    if (dynsym)
-      symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
-  }
-
-  // DT_JMPREL
-  //      If present, this entry's d_ptr member holds the address of
-  //      relocation
-  //      entries associated solely with the procedure linkage table.
-  //      Separating
-  //      these relocation entries lets the dynamic linker ignore them during
-  //      process initialization, if lazy binding is enabled. If this entry is
-  //      present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
-  //      also be present.
-  const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
-  if (symbol) {
-    // Synthesize trampoline symbols to help navigate the PLT.
-    addr_t addr = symbol->d_ptr;
-    Section *reloc_section =
-        section_list->FindSectionContainingFileAddress(addr).get();
-    if (reloc_section) {
-      user_id_t reloc_id = reloc_section->GetID();
-      const ELFSectionHeaderInfo *reloc_header =
-          GetSectionHeaderByIndex(reloc_id);
-      if (reloc_header)
-        ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id);
+    // DT_JMPREL
+    //      If present, this entry's d_ptr member holds the address of
+    //      relocation
+    //      entries associated solely with the procedure linkage table.
+    //      Separating
+    //      these relocation entries lets the dynamic linker ignore them during
+    //      process initialization, if lazy binding is enabled. If this entry is
+    //      present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
+    //      also be present.
+    const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
+    if (symbol) {
+      // Synthesize trampoline symbols to help navigate the PLT.
+      addr_t addr = symbol->d_ptr;
+      Section *reloc_section =
+          section_list->FindSectionContainingFileAddress(addr).get();
+      if (reloc_section) {
+        user_id_t reloc_id = reloc_section->GetID();
+        const ELFSectionHeaderInfo *reloc_header =
+            GetSectionHeaderByIndex(reloc_id);
+        if (reloc_header) {
+          if (m_symtab_up == nullptr)
+            m_symtab_up =
+                std::make_unique<Symtab>(reloc_section->GetObjectFile());
+
+          ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
+                                 reloc_id);
+        }
+      }
+    }
+
+    if (DWARFCallFrameInfo *eh_frame =
+            GetModule()->GetUnwindTable().GetEHFrameInfo()) {
+      if (m_symtab_up == nullptr)
+        m_symtab_up = std::make_unique<Symtab>(this);
+      ParseUnwindSymbols(m_symtab_up.get(), eh_frame);
     }
-  }
 
-  if (DWARFCallFrameInfo *eh_frame =
-          GetModule()->GetUnwindTable().GetEHFrameInfo()) {
-    ParseUnwindSymbols(&lldb_symtab, eh_frame);
-  }
-
-  // In the event that there's no symbol entry for the entry point we'll
-  // artificially create one. We delegate to the symtab object the figuring
-  // out of the proper size, this will usually make it span til the next
-  // symbol it finds in the section. This means that if there are missing
-  // symbols the entry point might span beyond its function definition.
-  // We're fine with this as it doesn't make it worse than not having a
-  // symbol entry at all.
-  if (CalculateType() == eTypeExecutable) {
-    ArchSpec arch = GetArchitecture();
-    auto entry_point_addr = GetEntryPointAddress();
-    bool is_valid_entry_point =
-        entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
-    addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
-    if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress(
-                                    entry_point_file_addr)) {
-      uint64_t symbol_id = lldb_symtab.GetNumSymbols();
-      // Don't set the name for any synthetic symbols, the Symbol
-      // object will generate one if needed when the name is accessed
-      // via accessors.
-      SectionSP section_sp = entry_point_addr.GetSection();
-      Symbol symbol(
-          /*symID=*/symbol_id,
-          /*name=*/llvm::StringRef(), // Name will be auto generated.
-          /*type=*/eSymbolTypeCode,
-          /*external=*/true,
-          /*is_debug=*/false,
-          /*is_trampoline=*/false,
-          /*is_artificial=*/true,
-          /*section_sp=*/section_sp,
-          /*offset=*/0,
-          /*size=*/0, // FDE can span multiple symbols so don't use its size.
-          /*size_is_valid=*/false,
-          /*contains_linker_annotations=*/false,
-          /*flags=*/0);
-      // When the entry point is arm thumb we need to explicitly set its
-      // class address to reflect that. This is important because expression
-      // evaluation relies on correctly setting a breakpoint at this
-      // address.
-      if (arch.GetMachine() == llvm::Triple::arm &&
-          (entry_point_file_addr & 1)) {
-        symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
-        m_address_class_map[entry_point_file_addr ^ 1] =
-            AddressClass::eCodeAlternateISA;
-      } else {
-        m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
+    // If we still don't have any symtab then create an empty instance to avoid
+    // do the section lookup next time.
+    if (m_symtab_up == nullptr)
+      m_symtab_up = std::make_unique<Symtab>(this);
+
+    // In the event that there's no symbol entry for the entry point we'll
+    // artificially create one. We delegate to the symtab object the figuring
+    // out of the proper size, this will usually make it span til the next
+    // symbol it finds in the section. This means that if there are missing
+    // symbols the entry point might span beyond its function definition.
+    // We're fine with this as it doesn't make it worse than not having a
+    // symbol entry at all.
+    if (CalculateType() == eTypeExecutable) {
+      ArchSpec arch = GetArchitecture();
+      auto entry_point_addr = GetEntryPointAddress();
+      bool is_valid_entry_point =
+          entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
+      addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
+      if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress(
+                                      entry_point_file_addr)) {
+        uint64_t symbol_id = m_symtab_up->GetNumSymbols();
+        // Don't set the name for any synthetic symbols, the Symbol
+        // object will generate one if needed when the name is accessed
+        // via accessors.
+        SectionSP section_sp = entry_point_addr.GetSection();
+        Symbol symbol(
+            /*symID=*/symbol_id,
+            /*name=*/llvm::StringRef(), // Name will be auto generated.
+            /*type=*/eSymbolTypeCode,
+            /*external=*/true,
+            /*is_debug=*/false,
+            /*is_trampoline=*/false,
+            /*is_artificial=*/true,
+            /*section_sp=*/section_sp,
+            /*offset=*/0,
+            /*size=*/0, // FDE can span multiple symbols so don't use its size.
+            /*size_is_valid=*/false,
+            /*contains_linker_annotations=*/false,
+            /*flags=*/0);
+        // When the entry point is arm thumb we need to explicitly set its
+        // class address to reflect that. This is important because expression
+        // evaluation relies on correctly setting a breakpoint at this
+        // address.
+        if (arch.GetMachine() == llvm::Triple::arm &&
+            (entry_point_file_addr & 1)) {
+          symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
+          m_address_class_map[entry_point_file_addr ^ 1] =
+              AddressClass::eCodeAlternateISA;
+        } else {
+          m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
+        }
+        m_symtab_up->AddSymbol(symbol);
       }
-      lldb_symtab.AddSymbol(symbol);
     }
+
+    m_symtab_up->CalculateSymbolSizes();
   }
+
+  return m_symtab_up.get();
 }
 
 void ObjectFileELF::RelocateSection(lldb_private::Section *section)

diff  --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 031615a3658cd..5738e5cf60d57 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -110,7 +110,7 @@ class ObjectFileELF : public lldb_private::ObjectFile {
 
   lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
 
-  void ParseSymtab(lldb_private::Symtab &symtab) override;
+  lldb_private::Symtab *GetSymtab() override;
 
   bool IsStripped() override;
 
@@ -123,7 +123,7 @@ class ObjectFileELF : public lldb_private::ObjectFile {
   lldb_private::UUID GetUUID() override;
 
   /// Return the contents of the .gnu_debuglink section, if the object file
-  /// contains it.
+  /// contains it. 
   llvm::Optional<lldb_private::FileSpec> GetDebugLink();
 
   uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
@@ -384,7 +384,7 @@ class ObjectFileELF : public lldb_private::ObjectFile {
                               lldb_private::UUID &uuid);
 
   bool AnySegmentHasPhysicalAddress();
-
+  
   /// Takes the .gnu_debugdata and returns the decompressed object file that is
   /// stored within that section.
   ///

diff  --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index ca93374548891..bec0099517c8f 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -106,10 +106,23 @@ uint32_t ObjectFileJIT::GetAddressByteSize() const {
   return m_data.GetAddressByteSize();
 }
 
-void ObjectFileJIT::ParseSymtab(Symtab &symtab) {
-  ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
-  if (delegate_sp)
-    delegate_sp->PopulateSymtab(this, symtab);
+Symtab *ObjectFileJIT::GetSymtab() {
+  ModuleSP module_sp(GetModule());
+  if (module_sp) {
+    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+    if (m_symtab_up == nullptr) {
+      ElapsedTime elapsed(module_sp->GetSymtabParseTime());
+      m_symtab_up = std::make_unique<Symtab>(this);
+      std::lock_guard<std::recursive_mutex> symtab_guard(
+          m_symtab_up->GetMutex());
+      ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
+      if (delegate_sp)
+        delegate_sp->PopulateSymtab(this, *m_symtab_up);
+      // TODO: get symbols from delegate
+      m_symtab_up->Finalize();
+    }
+  }
+  return m_symtab_up.get();
 }
 
 bool ObjectFileJIT::IsStripped() {

diff  --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index be31139df549e..03ac001988a01 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -67,7 +67,7 @@ class ObjectFileJIT : public lldb_private::ObjectFile {
 
   uint32_t GetAddressByteSize() const override;
 
-  void ParseSymtab(lldb_private::Symtab &symtab) override;
+  lldb_private::Symtab *GetSymtab() override;
 
   bool IsStripped() override;
 

diff  --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 573e763f1c0fd..6d6ad1a6cc002 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1311,6 +1311,22 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
   return AddressClass::eUnknown;
 }
 
+Symtab *ObjectFileMachO::GetSymtab() {
+  ModuleSP module_sp(GetModule());
+  if (module_sp) {
+    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+    if (m_symtab_up == nullptr) {
+      ElapsedTime elapsed(module_sp->GetSymtabParseTime());
+      m_symtab_up = std::make_unique<Symtab>(this);
+      std::lock_guard<std::recursive_mutex> symtab_guard(
+          m_symtab_up->GetMutex());
+      ParseSymtab();
+      m_symtab_up->Finalize();
+    }
+  }
+  return m_symtab_up.get();
+}
+
 bool ObjectFileMachO::IsStripped() {
   if (m_dysymtab.cmd == 0) {
     ModuleSP module_sp(GetModule());
@@ -2217,12 +2233,12 @@ ParseNList(DataExtractor &nlist_data, lldb::offset_t &nlist_data_offset,
 
 enum { DebugSymbols = true, NonDebugSymbols = false };
 
-void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
+size_t ObjectFileMachO::ParseSymtab() {
   LLDB_SCOPED_TIMERF("ObjectFileMachO::ParseSymtab () module = %s",
                      m_file.GetFilename().AsCString(""));
   ModuleSP module_sp(GetModule());
   if (!module_sp)
-    return;
+    return 0;
 
   Progress progress(llvm::formatv("Parsing symbol table for {0}",
                                   m_file.GetFilename().AsCString("<Unknown>")));
@@ -2272,7 +2288,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
       // Read in the rest of the symtab load command
       if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) ==
           nullptr) // fill in symoff, nsyms, stroff, strsize fields
-        return;
+        return 0;
       break;
 
     case LC_DYLD_INFO:
@@ -2331,11 +2347,12 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
   }
 
   if (!symtab_load_command.cmd)
-    return;
+    return 0;
 
+  Symtab *symtab = m_symtab_up.get();
   SectionList *section_list = GetSectionList();
   if (section_list == nullptr)
-    return;
+    return 0;
 
   const uint32_t addr_byte_size = m_data.GetAddressByteSize();
   const ByteOrder byte_order = m_data.GetByteOrder();
@@ -2472,7 +2489,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
 
     // We shouldn't have exports data from both the LC_DYLD_INFO command
     // AND the LC_DYLD_EXPORTS_TRIE command in the same binary:
-    lldbassert(!((dyld_info.export_size > 0)
+    lldbassert(!((dyld_info.export_size > 0) 
                  && (exports_trie_load_command.datasize > 0)));
     if (dyld_info.export_size > 0) {
       dyld_trie_data.SetData(m_data, dyld_info.export_off,
@@ -2864,10 +2881,10 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
 
                 // The normal nlist code cannot correctly size the Symbols
                 // array, we need to allocate it here.
-                sym = symtab.Resize(
+                sym = symtab->Resize(
                     symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
                     unmapped_local_symbols_found - m_dysymtab.nlocalsym);
-                num_syms = symtab.GetNumSymbols();
+                num_syms = symtab->GetNumSymbols();
 
                 nlist_data_offset =
                     local_symbols_info.nlistOffset +
@@ -2999,7 +3016,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
                             // original
                             // STAB entry so we don't have
                             // to hunt for it later
-                            symtab.SymbolAtIndex(N_FUN_indexes.back())
+                            symtab->SymbolAtIndex(N_FUN_indexes.back())
                                 ->SetByteSize(nlist.n_value);
                             N_FUN_indexes.pop_back();
                             // We don't really need the end function STAB as
@@ -3079,7 +3096,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
                             // index of this N_SO so that we can always skip
                             // the entire N_SO if we need to navigate more
                             // quickly at the source level when parsing STABS
-                            symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
+                            symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
                             symbol_ptr->SetByteSize(sym_idx);
                             symbol_ptr->SetSizeIsSibling(true);
                           }
@@ -3186,7 +3203,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
                         // quickly at the source level when parsing STABS
                         if (!N_INCL_indexes.empty()) {
                           symbol_ptr =
-                              symtab.SymbolAtIndex(N_INCL_indexes.back());
+                              symtab->SymbolAtIndex(N_INCL_indexes.back());
                           symbol_ptr->SetByteSize(sym_idx + 1);
                           symbol_ptr->SetSizeIsSibling(true);
                           N_INCL_indexes.pop_back();
@@ -3251,7 +3268,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
                                                                  nlist.n_value);
                         if (!N_BRAC_indexes.empty()) {
                           symbol_ptr =
-                              symtab.SymbolAtIndex(N_BRAC_indexes.back());
+                              symtab->SymbolAtIndex(N_BRAC_indexes.back());
                           symbol_ptr->SetByteSize(sym_idx + 1);
                           symbol_ptr->SetSizeIsSibling(true);
                           N_BRAC_indexes.pop_back();
@@ -3289,7 +3306,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
                         // parsing STABS
                         if (!N_COMM_indexes.empty()) {
                           symbol_ptr =
-                              symtab.SymbolAtIndex(N_COMM_indexes.back());
+                              symtab->SymbolAtIndex(N_COMM_indexes.back());
                           symbol_ptr->SetByteSize(sym_idx + 1);
                           symbol_ptr->SetSizeIsSibling(true);
                           N_COMM_indexes.pop_back();
@@ -3789,8 +3806,8 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
     // symbols, create it now.
     if (sym == nullptr) {
       sym =
-          symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
-      num_syms = symtab.GetNumSymbols();
+          symtab->Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
+      num_syms = symtab->GetNumSymbols();
     }
 
     if (unmapped_local_symbols_found) {
@@ -3924,7 +3941,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
             if (!N_FUN_indexes.empty()) {
               // Copy the size of the function into the original STAB entry
               // so we don't have to hunt for it later
-              symtab.SymbolAtIndex(N_FUN_indexes.back())
+              symtab->SymbolAtIndex(N_FUN_indexes.back())
                   ->SetByteSize(nlist.n_value);
               N_FUN_indexes.pop_back();
               // We don't really need the end function STAB as it contains
@@ -3998,7 +4015,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
               // N_SO so that we can always skip the entire N_SO if we need
               // to navigate more quickly at the source level when parsing
               // STABS
-              symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
+              symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
               symbol_ptr->SetByteSize(sym_idx);
               symbol_ptr->SetSizeIsSibling(true);
             }
@@ -4092,7 +4109,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
           // N_EINCL so that we can always skip the entire symbol if we need
           // to navigate more quickly at the source level when parsing STABS
           if (!N_INCL_indexes.empty()) {
-            symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
+            symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
             symbol_ptr->SetByteSize(sym_idx + 1);
             symbol_ptr->SetSizeIsSibling(true);
             N_INCL_indexes.pop_back();
@@ -4151,7 +4168,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
           // quickly at the source level when parsing STABS
           symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
           if (!N_BRAC_indexes.empty()) {
-            symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
+            symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
             symbol_ptr->SetByteSize(sym_idx + 1);
             symbol_ptr->SetSizeIsSibling(true);
             N_BRAC_indexes.pop_back();
@@ -4185,7 +4202,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
           // we need to navigate more quickly at the source level when
           // parsing STABS
           if (!N_COMM_indexes.empty()) {
-            symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
+            symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
             symbol_ptr->SetByteSize(sym_idx + 1);
             symbol_ptr->SetSizeIsSibling(true);
             N_COMM_indexes.pop_back();
@@ -4641,7 +4658,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
 
   if (num_syms < sym_idx + trie_symbol_table_augment_count) {
     num_syms = sym_idx + trie_symbol_table_augment_count;
-    sym = symtab.Resize(num_syms);
+    sym = symtab->Resize(num_syms);
   }
   uint32_t synthetic_sym_id = symtab_load_command.nsyms;
 
@@ -4690,7 +4707,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
     if (num_synthetic_function_symbols > 0) {
       if (num_syms < sym_idx + num_synthetic_function_symbols) {
         num_syms = sym_idx + num_synthetic_function_symbols;
-        sym = symtab.Resize(num_syms);
+        sym = symtab->Resize(num_syms);
       }
       for (i = 0; i < function_starts_count; ++i) {
         const FunctionStarts::Entry *func_start_entry =
@@ -4745,7 +4762,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
   // symbols.
   if (sym_idx < num_syms) {
     num_syms = sym_idx;
-    sym = symtab.Resize(num_syms);
+    sym = symtab->Resize(num_syms);
   }
 
   // Now synthesize indirect symbols
@@ -4790,11 +4807,11 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
               if (index_pos != end_index_pos) {
                 // We have a remapping from the original nlist index to a
                 // current symbol index, so just look this up by index
-                stub_symbol = symtab.SymbolAtIndex(index_pos->second);
+                stub_symbol = symtab->SymbolAtIndex(index_pos->second);
               } else {
                 // We need to lookup a symbol using the original nlist symbol
                 // index since this index is coming from the S_SYMBOL_STUBS
-                stub_symbol = symtab.FindSymbolByID(stub_sym_id);
+                stub_symbol = symtab->FindSymbolByID(stub_sym_id);
               }
 
               if (stub_symbol) {
@@ -4817,7 +4834,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
                   // Make a synthetic symbol to describe the trampoline stub
                   Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
                   if (sym_idx >= num_syms) {
-                    sym = symtab.Resize(++num_syms);
+                    sym = symtab->Resize(++num_syms);
                     stub_symbol = nullptr; // this pointer no longer valid
                   }
                   sym[sym_idx].SetID(synthetic_sym_id++);
@@ -4856,7 +4873,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
             indirect_symbol_names.end()) {
           // Make a synthetic symbol to describe re-exported symbol.
           if (sym_idx >= num_syms)
-            sym = symtab.Resize(++num_syms);
+            sym = symtab->Resize(++num_syms);
           sym[sym_idx].SetID(synthetic_sym_id++);
           sym[sym_idx].GetMangled() = Mangled(e.entry.name);
           sym[sym_idx].SetType(eSymbolTypeReExported);
@@ -4871,6 +4888,18 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
       }
     }
   }
+
+  //        StreamFile s(stdout, false);
+  //        s.Printf ("Symbol table before CalculateSymbolSizes():\n");
+  //        symtab->Dump(&s, NULL, eSortOrderNone);
+  // Set symbol byte sizes correctly since mach-o nlist entries don't have
+  // sizes
+  symtab->CalculateSymbolSizes();
+
+  //        s.Printf ("Symbol table after CalculateSymbolSizes():\n");
+  //        symtab->Dump(&s, NULL, eSortOrderNone);
+
+  return symtab->GetNumSymbols();
 }
 
 void ObjectFileMachO::Dump(Stream *s) {

diff  --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index b3a941a957222..29f07b0546a71 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -92,7 +92,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
 
   lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
 
-  void ParseSymtab(lldb_private::Symtab &symtab) override;
+  lldb_private::Symtab *GetSymtab() override;
 
   bool IsStripped() override;
 

diff  --git a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
index da999d2b55a75..36e71e21332fb 100644
--- a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
+++ b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
@@ -68,7 +68,7 @@ class ObjectFilePDB : public ObjectFile {
 
   bool IsExecutable() const override { return false; }
 
-  void ParseSymtab(lldb_private::Symtab &symtab) override {}
+  Symtab *GetSymtab() override { return nullptr; }
 
   bool IsStripped() override { return false; }
 

diff  --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index f69f3c300ae78..5c7489e35049b 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -589,125 +589,139 @@ llvm::StringRef ObjectFilePECOFF::GetSectionName(const section_header_t &sect) {
   return hdr_name;
 }
 
-void ObjectFilePECOFF::ParseSymtab(Symtab &symtab) {
-  SectionList *sect_list = GetSectionList();
-  const uint32_t num_syms = m_coff_header.nsyms;
-  if (m_file && num_syms > 0 && m_coff_header.symoff > 0) {
-    const uint32_t symbol_size = 18;
-    const size_t symbol_data_size = num_syms * symbol_size;
-    // Include the 4-byte string table size at the end of the symbols
-    DataExtractor symtab_data =
-        ReadImageData(m_coff_header.symoff, symbol_data_size + 4);
-    lldb::offset_t offset = symbol_data_size;
-    const uint32_t strtab_size = symtab_data.GetU32(&offset);
-    if (strtab_size > 0) {
-      DataExtractor strtab_data = ReadImageData(
-          m_coff_header.symoff + symbol_data_size, strtab_size);
-
-      offset = 0;
-      std::string symbol_name;
-      Symbol *symbols = symtab.Resize(num_syms);
-      for (uint32_t i = 0; i < num_syms; ++i) {
-        coff_symbol_t symbol;
-        const uint32_t symbol_offset = offset;
-        const char *symbol_name_cstr = nullptr;
-        // If the first 4 bytes of the symbol string are zero, then they
-        // are followed by a 4-byte string table offset. Else these
-        // 8 bytes contain the symbol name
-        if (symtab_data.GetU32(&offset) == 0) {
-          // Long string that doesn't fit into the symbol table name, so
-          // now we must read the 4 byte string table offset
-          uint32_t strtab_offset = symtab_data.GetU32(&offset);
-          symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
-          symbol_name.assign(symbol_name_cstr);
-        } else {
-          // Short string that fits into the symbol table name which is 8
-          // bytes
-          offset += sizeof(symbol.name) - 4; // Skip remaining
-          symbol_name_cstr = symtab_data.PeekCStr(symbol_offset);
-          if (symbol_name_cstr == nullptr)
-            break;
-          symbol_name.assign(symbol_name_cstr, sizeof(symbol.name));
-        }
-        symbol.value = symtab_data.GetU32(&offset);
-        symbol.sect = symtab_data.GetU16(&offset);
-        symbol.type = symtab_data.GetU16(&offset);
-        symbol.storage = symtab_data.GetU8(&offset);
-        symbol.naux = symtab_data.GetU8(&offset);
-        symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
-        if ((int16_t)symbol.sect >= 1) {
-          Address symbol_addr(sect_list->FindSectionByID(symbol.sect),
-                              symbol.value);
-          symbols[i].GetAddressRef() = symbol_addr;
-          symbols[i].SetType(MapSymbolType(symbol.type));
-        }
-
-        if (symbol.naux > 0) {
-          i += symbol.naux;
-          offset += symbol.naux * symbol_size;
+// GetNListSymtab
+Symtab *ObjectFilePECOFF::GetSymtab() {
+  ModuleSP module_sp(GetModule());
+  if (module_sp) {
+    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+    if (m_symtab_up == nullptr) {
+      ElapsedTime elapsed(module_sp->GetSymtabParseTime());
+      SectionList *sect_list = GetSectionList();
+      m_symtab_up = std::make_unique<Symtab>(this);
+      std::lock_guard<std::recursive_mutex> guard(m_symtab_up->GetMutex());
+
+      const uint32_t num_syms = m_coff_header.nsyms;
+
+      if (m_file && num_syms > 0 && m_coff_header.symoff > 0) {
+        const uint32_t symbol_size = 18;
+        const size_t symbol_data_size = num_syms * symbol_size;
+        // Include the 4-byte string table size at the end of the symbols
+        DataExtractor symtab_data =
+            ReadImageData(m_coff_header.symoff, symbol_data_size + 4);
+        lldb::offset_t offset = symbol_data_size;
+        const uint32_t strtab_size = symtab_data.GetU32(&offset);
+        if (strtab_size > 0) {
+          DataExtractor strtab_data = ReadImageData(
+              m_coff_header.symoff + symbol_data_size, strtab_size);
+
+          offset = 0;
+          std::string symbol_name;
+          Symbol *symbols = m_symtab_up->Resize(num_syms);
+          for (uint32_t i = 0; i < num_syms; ++i) {
+            coff_symbol_t symbol;
+            const uint32_t symbol_offset = offset;
+            const char *symbol_name_cstr = nullptr;
+            // If the first 4 bytes of the symbol string are zero, then they
+            // are followed by a 4-byte string table offset. Else these
+            // 8 bytes contain the symbol name
+            if (symtab_data.GetU32(&offset) == 0) {
+              // Long string that doesn't fit into the symbol table name, so
+              // now we must read the 4 byte string table offset
+              uint32_t strtab_offset = symtab_data.GetU32(&offset);
+              symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
+              symbol_name.assign(symbol_name_cstr);
+            } else {
+              // Short string that fits into the symbol table name which is 8
+              // bytes
+              offset += sizeof(symbol.name) - 4; // Skip remaining
+              symbol_name_cstr = symtab_data.PeekCStr(symbol_offset);
+              if (symbol_name_cstr == nullptr)
+                break;
+              symbol_name.assign(symbol_name_cstr, sizeof(symbol.name));
+            }
+            symbol.value = symtab_data.GetU32(&offset);
+            symbol.sect = symtab_data.GetU16(&offset);
+            symbol.type = symtab_data.GetU16(&offset);
+            symbol.storage = symtab_data.GetU8(&offset);
+            symbol.naux = symtab_data.GetU8(&offset);
+            symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
+            if ((int16_t)symbol.sect >= 1) {
+              Address symbol_addr(sect_list->FindSectionByID(symbol.sect),
+                                  symbol.value);
+              symbols[i].GetAddressRef() = symbol_addr;
+              symbols[i].SetType(MapSymbolType(symbol.type));
+            }
+
+            if (symbol.naux > 0) {
+              i += symbol.naux;
+              offset += symbol.naux * symbol_size;
+            }
+          }
         }
       }
-    }
-  }
 
-  // Read export header
-  if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() &&
-      m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 &&
-      m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) {
-    export_directory_entry export_table;
-    uint32_t data_start =
-        m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;
+      // Read export header
+      if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() &&
+          m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 &&
+          m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) {
+        export_directory_entry export_table;
+        uint32_t data_start =
+            m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;
+
+        DataExtractor symtab_data = ReadImageDataByRVA(
+            data_start, m_coff_header_opt.data_dirs[0].vmsize);
+        lldb::offset_t offset = 0;
+
+        // Read export_table header
+        export_table.characteristics = symtab_data.GetU32(&offset);
+        export_table.time_date_stamp = symtab_data.GetU32(&offset);
+        export_table.major_version = symtab_data.GetU16(&offset);
+        export_table.minor_version = symtab_data.GetU16(&offset);
+        export_table.name = symtab_data.GetU32(&offset);
+        export_table.base = symtab_data.GetU32(&offset);
+        export_table.number_of_functions = symtab_data.GetU32(&offset);
+        export_table.number_of_names = symtab_data.GetU32(&offset);
+        export_table.address_of_functions = symtab_data.GetU32(&offset);
+        export_table.address_of_names = symtab_data.GetU32(&offset);
+        export_table.address_of_name_ordinals = symtab_data.GetU32(&offset);
+
+        bool has_ordinal = export_table.address_of_name_ordinals != 0;
+
+        lldb::offset_t name_offset = export_table.address_of_names - data_start;
+        lldb::offset_t name_ordinal_offset =
+            export_table.address_of_name_ordinals - data_start;
+
+        Symbol *symbols = m_symtab_up->Resize(export_table.number_of_names);
+
+        std::string symbol_name;
+
+        // Read each export table entry
+        for (size_t i = 0; i < export_table.number_of_names; ++i) {
+          uint32_t name_ordinal =
+              has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i;
+          uint32_t name_address = symtab_data.GetU32(&name_offset);
+
+          const char *symbol_name_cstr =
+              symtab_data.PeekCStr(name_address - data_start);
+          symbol_name.assign(symbol_name_cstr);
 
-    DataExtractor symtab_data = ReadImageDataByRVA(
-        data_start, m_coff_header_opt.data_dirs[0].vmsize);
-    lldb::offset_t offset = 0;
+          lldb::offset_t function_offset = export_table.address_of_functions -
+                                           data_start +
+                                           sizeof(uint32_t) * name_ordinal;
+          uint32_t function_rva = symtab_data.GetU32(&function_offset);
 
-    // Read export_table header
-    export_table.characteristics = symtab_data.GetU32(&offset);
-    export_table.time_date_stamp = symtab_data.GetU32(&offset);
-    export_table.major_version = symtab_data.GetU16(&offset);
-    export_table.minor_version = symtab_data.GetU16(&offset);
-    export_table.name = symtab_data.GetU32(&offset);
-    export_table.base = symtab_data.GetU32(&offset);
-    export_table.number_of_functions = symtab_data.GetU32(&offset);
-    export_table.number_of_names = symtab_data.GetU32(&offset);
-    export_table.address_of_functions = symtab_data.GetU32(&offset);
-    export_table.address_of_names = symtab_data.GetU32(&offset);
-    export_table.address_of_name_ordinals = symtab_data.GetU32(&offset);
-
-    bool has_ordinal = export_table.address_of_name_ordinals != 0;
-
-    lldb::offset_t name_offset = export_table.address_of_names - data_start;
-    lldb::offset_t name_ordinal_offset =
-        export_table.address_of_name_ordinals - data_start;
-
-    Symbol *symbols = symtab.Resize(export_table.number_of_names);
-
-    std::string symbol_name;
-
-    // Read each export table entry
-    for (size_t i = 0; i < export_table.number_of_names; ++i) {
-      uint32_t name_ordinal =
-          has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i;
-      uint32_t name_address = symtab_data.GetU32(&name_offset);
-
-      const char *symbol_name_cstr =
-          symtab_data.PeekCStr(name_address - data_start);
-      symbol_name.assign(symbol_name_cstr);
-
-      lldb::offset_t function_offset = export_table.address_of_functions -
-                                        data_start +
-                                        sizeof(uint32_t) * name_ordinal;
-      uint32_t function_rva = symtab_data.GetU32(&function_offset);
-
-      Address symbol_addr(m_coff_header_opt.image_base + function_rva,
-                          sect_list);
-      symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
-      symbols[i].GetAddressRef() = symbol_addr;
-      symbols[i].SetType(lldb::eSymbolTypeCode);
-      symbols[i].SetDebug(true);
+          Address symbol_addr(m_coff_header_opt.image_base + function_rva,
+                              sect_list);
+          symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
+          symbols[i].GetAddressRef() = symbol_addr;
+          symbols[i].SetType(lldb::eSymbolTypeCode);
+          symbols[i].SetDebug(true);
+        }
+      }
+      m_symtab_up->CalculateSymbolSizes();
     }
   }
+  return m_symtab_up.get();
 }
 
 std::unique_ptr<CallFrameInfo> ObjectFilePECOFF::CreateCallFrameInfo() {

diff  --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index b7de24d1d418c..876b83264f6fb 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -107,7 +107,7 @@ class ObjectFilePECOFF : public lldb_private::ObjectFile {
   //    virtual lldb_private::AddressClass
   //    GetAddressClass (lldb::addr_t file_addr);
 
-  void ParseSymtab(lldb_private::Symtab &symtab) override;
+  lldb_private::Symtab *GetSymtab() override;
 
   bool IsStripped() override;
 

diff  --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 7445f8311c500..0e6329885528b 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -246,7 +246,7 @@ bool ObjectFileWasm::ParseHeader() {
   return true;
 }
 
-void ObjectFileWasm::ParseSymtab(Symtab &symtab) {}
+Symtab *ObjectFileWasm::GetSymtab() { return nullptr; }
 
 static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
   if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) {

diff  --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
index d7b5bc22caadb..44939b6d4ea0e 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -78,7 +78,7 @@ class ObjectFileWasm : public ObjectFile {
     return AddressClass::eInvalid;
   }
 
-  void ParseSymtab(lldb_private::Symtab &symtab) override;
+  Symtab *GetSymtab() override;
 
   bool IsStripped() override { return !!GetExternalDebugInfoFileSpec(); }
 

diff  --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 162697bed7e93..736cfa0700886 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -73,7 +73,7 @@ class PlaceholderObjectFile : public ObjectFile {
   bool IsExecutable() const override { return false; }
   ArchSpec GetArchitecture() override { return m_arch; }
   UUID GetUUID() override { return m_uuid; }
-  void ParseSymtab(lldb_private::Symtab &symtab) override {}
+  Symtab *GetSymtab() override { return m_symtab_up.get(); }
   bool IsStripped() override { return true; }
   ByteOrder GetByteOrder() const override { return m_arch.GetByteOrder(); }
 

diff  --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index 9d23f1baf9315..b07674af3bd9f 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -500,7 +500,7 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
 
   for (Symbol &symbol : symbols)
     symtab.AddSymbol(std::move(symbol));
-  symtab.Finalize();
+  symtab.CalculateSymbolSizes();
 }
 
 llvm::Expected<lldb::addr_t>
@@ -927,3 +927,4 @@ uint64_t SymbolFileBreakpad::GetDebugInfoSize() {
   // Breakpad files are all debug info.
   return m_objfile_sp->GetByteSize();
 }
+

diff  --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index db0ae241be7ec..45dfc4b9a1525 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1421,6 +1421,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
                ));
   }
 
+  symtab.CalculateSymbolSizes();
   symtab.Finalize();
 }
 

diff  --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp
index dec42c4a7fcac..101af01341a20 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -715,20 +715,3 @@ void llvm::format_provider<ObjectFile::Strata>::format(
     break;
   }
 }
-
-
-Symtab *ObjectFile::GetSymtab() {
-  ModuleSP module_sp(GetModule());
-  if (module_sp) {
-    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-    if (!m_symtab_up) {
-      ElapsedTime elapsed(module_sp->GetSymtabParseTime());
-      m_symtab_up = std::make_unique<Symtab>(this);
-      std::lock_guard<std::recursive_mutex> symtab_guard(
-          m_symtab_up->GetMutex());
-      ParseSymtab(*m_symtab_up);
-      m_symtab_up->Finalize();
-    }
-  }
-  return m_symtab_up.get();
-}

diff  --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp
index c67955523bfb1..19c1fee2bb381 100644
--- a/lldb/source/Symbol/Symtab.cpp
+++ b/lldb/source/Symbol/Symtab.cpp
@@ -997,15 +997,10 @@ void Symtab::InitAddressIndexes() {
   }
 }
 
-void Symtab::Finalize() {
+void Symtab::CalculateSymbolSizes() {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  // Calculate the size of symbols inside InitAddressIndexes.
+  // Size computation happens inside InitAddressIndexes.
   InitAddressIndexes();
-  // Shrink to fit the symbols so we don't waste memory
-  if (m_symbols.capacity() > m_symbols.size()) {
-    collection new_symbols(m_symbols.begin(), m_symbols.end());
-    m_symbols.swap(new_symbols);
-  }
 }
 
 Symbol *Symtab::FindSymbolAtFileAddress(addr_t file_addr) {


        


More information about the lldb-commits mailing list