ObjectFile[ELF]: Refactor gnu_debuglink interface
authorPavel Labath <pavel@labath.sk>
Mon, 5 Aug 2019 09:55:07 +0000 (09:55 +0000)
committerPavel Labath <pavel@labath.sk>
Mon, 5 Aug 2019 09:55:07 +0000 (09:55 +0000)
Summary:
The contents of the gnu_debuglink section were passed through the
GetDebugSymbolFilePaths interface, which was more generic than needed.
As the only class implementing this function is ObjectFileELF, we can
modify the function to return just a single FileSpec (instead of a
list). Also, since the SymbolVendorELF already assumes ELF object files,
we don't have to make this method available on the generic ObjectFile
interface -- instead we can put it on ObjectFileELF directly.

This change also makes is so that if the Module has an explicit symbol
file spec set, we disregard the value the value of the debug link
(instead of doing a secondary lookup using that). I think it makes sense
to honor the users wishes if he had explicitly set the symbol file spec,
and this seems to be consistent with what SymbolVendorMacOSX is doing
(SymbolVendorMacOSX.cpp:125).

The main reason for making these changes is to make the treatment of
build-ids and debug links simpler in the follow-up patch.

Reviewers: clayborg, jankratochvil, mgorny, espindola

Subscribers: emaste, arichardson, MaskRay, lldb-commits

Differential Revision: https://reviews.llvm.org/D65560

llvm-svn: 367824

lldb/include/lldb/Symbol/ObjectFile.h
lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp

index 76cc055..f9bc2f2 100644 (file)
@@ -370,17 +370,6 @@ public:
   ///     returned.
   virtual UUID GetUUID() = 0;
 
-  /// Gets the symbol file spec list for this object file.
-  ///
-  /// If the object file format contains a debug symbol file link, the values
-  /// will be returned in the FileSpecList.
-  ///
-  /// \return
-  ///     Returns filespeclist.
-  virtual lldb_private::FileSpecList GetDebugSymbolFilePaths() {
-    return FileSpecList();
-  }
-
   /// Gets the file spec list of libraries re-exported by this object file.
   ///
   /// If the object file format has the notion of one library re-exporting the
index 2ce6a34..cb4bba0 100644 (file)
@@ -85,8 +85,6 @@ public:
 
   UUID GetUUID() override { return m_uuid; }
 
-  FileSpecList GetDebugSymbolFilePaths() override { return FileSpecList(); }
-
   uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
 
   Type CalculateType() override { return eTypeDebugInfo; }
index b107afc..50d6b8f 100644 (file)
@@ -816,14 +816,10 @@ UUID ObjectFileELF::GetUUID() {
   return m_uuid;
 }
 
-lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() {
-  FileSpecList file_spec_list;
-
-  if (!m_gnu_debuglink_file.empty()) {
-    FileSpec file_spec(m_gnu_debuglink_file);
-    file_spec_list.Append(file_spec);
-  }
-  return file_spec_list;
+llvm::Optional<FileSpec> ObjectFileELF::GetDebugLink() {
+  if (m_gnu_debuglink_file.empty())
+    return llvm::None;
+  return FileSpec(m_gnu_debuglink_file);
 }
 
 uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) {
index 2a21377..f58618f 100644 (file)
@@ -122,7 +122,9 @@ public:
 
   lldb_private::UUID GetUUID() override;
 
-  lldb_private::FileSpecList GetDebugSymbolFilePaths() override;
+  /// Return the contents of the .gnu_debuglink section, if the object file
+  /// contains it. 
+  llvm::Optional<lldb_private::FileSpec> GetDebugLink();
 
   uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
 
index 92953f0..a850a10 100644 (file)
@@ -71,86 +71,76 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
   if (!uuid)
     return nullptr;
 
-  // Get the .gnu_debuglink file (if specified).
-  FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
-
-  // If the module specified a filespec, use it first.
-  FileSpec debug_symbol_fspec(module_sp->GetSymbolFileFileSpec());
-  if (debug_symbol_fspec)
-    file_spec_list.Insert(0, debug_symbol_fspec);
+  // If the module specified a filespec, use that.
+  FileSpec fspec = module_sp->GetSymbolFileFileSpec();
+  // Otherwise, try gnu_debuglink, if one exists.
+  if (!fspec)
+    fspec = obj_file->GetDebugLink().getValueOr(FileSpec());
 
   // If we have no debug symbol files, then nothing to do.
-  if (file_spec_list.IsEmpty())
+  if (!fspec)
     return nullptr;
 
   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
   Timer scoped_timer(func_cat, "SymbolVendorELF::CreateInstance (module = %s)",
                      module_sp->GetFileSpec().GetPath().c_str());
 
-  for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx) {
-    ModuleSpec module_spec;
-    const FileSpec fspec = file_spec_list.GetFileSpecAtIndex(idx);
-
-    module_spec.GetFileSpec() = obj_file->GetFileSpec();
-    FileSystem::Instance().Resolve(module_spec.GetFileSpec());
-    module_spec.GetSymbolFileSpec() = fspec;
-    module_spec.GetUUID() = uuid;
-    FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
-    FileSpec dsym_fspec =
-        Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
-    if (dsym_fspec) {
-      DataBufferSP dsym_file_data_sp;
-      lldb::offset_t dsym_file_data_offset = 0;
-      ObjectFileSP dsym_objfile_sp =
-          ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0,
-                                 FileSystem::Instance().GetByteSize(dsym_fspec),
-                                 dsym_file_data_sp, dsym_file_data_offset);
-      if (dsym_objfile_sp) {
-        // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
-        // be able to figure this out consistently as the symbol file may not
-        // have stripped the code sections, etc.
-        dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
-
-        SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
-        if (symbol_vendor) {
-          // Get the module unified section list and add our debug sections to
-          // that.
-          SectionList *module_section_list = module_sp->GetSectionList();
-          SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
-
-          static const SectionType g_sections[] = {
-              eSectionTypeDWARFDebugAbbrev,   eSectionTypeDWARFDebugAddr,
-              eSectionTypeDWARFDebugAranges,  eSectionTypeDWARFDebugCuIndex,
-              eSectionTypeDWARFDebugFrame,    eSectionTypeDWARFDebugInfo,
-              eSectionTypeDWARFDebugLine,     eSectionTypeDWARFDebugLoc,
-              eSectionTypeDWARFDebugMacInfo,  eSectionTypeDWARFDebugPubNames,
-              eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
-              eSectionTypeDWARFDebugStr,      eSectionTypeDWARFDebugStrOffsets,
-              eSectionTypeELFSymbolTable,     eSectionTypeDWARFGNUDebugAltLink,
-          };
-          for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
-               ++idx) {
-            SectionType section_type = g_sections[idx];
-            SectionSP section_sp(
-                objfile_section_list->FindSectionByType(section_type, true));
-            if (section_sp) {
-              SectionSP module_section_sp(
-                  module_section_list->FindSectionByType(section_type, true));
-              if (module_section_sp)
-                module_section_list->ReplaceSection(module_section_sp->GetID(),
-                                                    section_sp);
-              else
-                module_section_list->AddSection(section_sp);
-            }
-          }
-
-          symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
-          return symbol_vendor;
-        }
-      }
+  ModuleSpec module_spec;
+
+  module_spec.GetFileSpec() = obj_file->GetFileSpec();
+  FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+  module_spec.GetSymbolFileSpec() = fspec;
+  module_spec.GetUUID() = uuid;
+  FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
+  FileSpec dsym_fspec =
+      Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+  if (!dsym_fspec)
+    return nullptr;
+
+  DataBufferSP dsym_file_data_sp;
+  lldb::offset_t dsym_file_data_offset = 0;
+  ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
+      module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec),
+      dsym_file_data_sp, dsym_file_data_offset);
+  if (!dsym_objfile_sp)
+    return nullptr;
+
+  // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
+  // be able to figure this out consistently as the symbol file may not
+  // have stripped the code sections, etc.
+  dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
+
+  SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
+
+  // Get the module unified section list and add our debug sections to
+  // that.
+  SectionList *module_section_list = module_sp->GetSectionList();
+  SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
+
+  static const SectionType g_sections[] = {
+      eSectionTypeDWARFDebugAbbrev,   eSectionTypeDWARFDebugAddr,
+      eSectionTypeDWARFDebugAranges,  eSectionTypeDWARFDebugCuIndex,
+      eSectionTypeDWARFDebugFrame,    eSectionTypeDWARFDebugInfo,
+      eSectionTypeDWARFDebugLine,     eSectionTypeDWARFDebugLoc,
+      eSectionTypeDWARFDebugMacInfo,  eSectionTypeDWARFDebugPubNames,
+      eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
+      eSectionTypeDWARFDebugStr,      eSectionTypeDWARFDebugStrOffsets,
+      eSectionTypeELFSymbolTable,     eSectionTypeDWARFGNUDebugAltLink,
+  };
+  for (SectionType section_type : g_sections) {
+    if (SectionSP section_sp =
+            objfile_section_list->FindSectionByType(section_type, true)) {
+      if (SectionSP module_section_sp =
+              module_section_list->FindSectionByType(section_type, true))
+        module_section_list->ReplaceSection(module_section_sp->GetID(),
+                                            section_sp);
+      else
+        module_section_list->AddSection(section_sp);
     }
   }
-  return nullptr;
+
+  symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
+  return symbol_vendor;
 }
 
 // PluginInterface protocol