[Lldb-commits] [lldb] r332162 - [LLDB] Support GNU-style compressed debug sections (.zdebug)

Davide Italiano via lldb-commits lldb-commits at lists.llvm.org
Fri May 11 17:29:25 PDT 2018


Author: davide
Date: Fri May 11 17:29:25 2018
New Revision: 332162

URL: http://llvm.org/viewvc/llvm-project?rev=332162&view=rev
Log:
[LLDB] Support GNU-style compressed debug sections (.zdebug)

Patch by Erik Welander!

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

Added:
    lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/
    lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/TestCompressedDebugInfo.py
    lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/a.c
Modified:
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp

Added: lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/Makefile?rev=332162&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/Makefile Fri May 11 17:29:25 2018
@@ -0,0 +1,16 @@
+LEVEL := ../../make
+
+C_SOURCES := a.c
+
+all: compressed.out compressed.gnu.out
+
+compressed.out: a.out
+	$(OBJCOPY) --compress-debug-sections=zlib $< $@
+
+compressed.gnu.out: a.out
+	$(OBJCOPY) --compress-debug-sections=zlib-gnu $< $@
+
+include $(LEVEL)/Makefile.rules
+
+clean::
+	$(RM) -f a.o main compressed.out compressed.gnu.out

Added: lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/TestCompressedDebugInfo.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/TestCompressedDebugInfo.py?rev=332162&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/TestCompressedDebugInfo.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/TestCompressedDebugInfo.py Fri May 11 17:29:25 2018
@@ -0,0 +1,46 @@
+""" Tests that compressed debug info sections are used. """
+import os
+import lldb
+import sys
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestCompressedDebugInfo(TestBase):
+  mydir = TestBase.compute_mydir(__file__)
+
+  def setUp(self):
+    TestBase.setUp(self)
+
+  @no_debug_info_test  # Prevent the genaration of the dwarf version of this test
+  @skipUnlessPlatform(["linux"])
+  def test_compressed_debug_info(self):
+    """Tests that the 'frame variable' works with compressed debug info."""
+
+    self.build()
+    process = lldbutil.run_to_source_breakpoint(
+        self, "main", lldb.SBFileSpec("a.c"), exe_name="compressed.out")[1]
+
+    # The process should be stopped at a breakpoint, and the z variable should
+    # be in the top frame.
+    self.assertTrue(process.GetState() == lldb.eStateStopped,
+                    STOPPED_DUE_TO_BREAKPOINT)
+    frame = process.GetThreadAtIndex(0).GetFrameAtIndex(0)
+    self.assertTrue(frame.FindVariable("z").IsValid(), "z is not valid")
+
+  @no_debug_info_test  # Prevent the genaration of the dwarf version of this test
+  @skipUnlessPlatform(["linux"])
+  def test_compressed_debug_info_gnu(self):
+    """Tests that the 'frame variable' works with gnu-style compressed debug info."""
+
+    self.build()
+    process = lldbutil.run_to_source_breakpoint(
+        self, "main", lldb.SBFileSpec("a.c"), exe_name="compressed.gnu.out")[1]
+
+    # The process should be stopped at a breakpoint, and the z variable should
+    # be in the top frame.
+    self.assertTrue(process.GetState() == lldb.eStateStopped,
+                    STOPPED_DUE_TO_BREAKPOINT)
+    frame = process.GetThreadAtIndex(0).GetFrameAtIndex(0)
+    self.assertTrue(frame.FindVariable("z").IsValid(), "z is not valid")

Added: lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/a.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/a.c?rev=332162&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/a.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/a.c Fri May 11 17:29:25 2018
@@ -0,0 +1,4 @@
+int main() {
+  int z = 2;
+  return z;
+}

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=332162&r1=332161&r2=332162&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Fri May 11 17:29:25 2018
@@ -1757,6 +1757,63 @@ lldb::user_id_t ObjectFileELF::GetSectio
   return 0;
 }
 
+static SectionType getSectionType(llvm::StringRef section_name) {
+  if (!section_name.startswith(".")) {
+    return eSectionTypeOther;
+  }
+
+  // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section,
+  // http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
+  // MISSING? .debug-index -
+  // http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
+  return llvm::StringSwitch<SectionType>(section_name.drop_front(1))
+      .Case("text", eSectionTypeCode)
+      .Case("data", eSectionTypeData)
+      .Case("bss", eSectionTypeZeroFill)
+      .Case("tdata", eSectionTypeData)
+      .Case("tbss", eSectionTypeZeroFill)
+      // Abbreviations used in the .debug_info section
+      .Case("debug_abbrev", eSectionTypeDWARFDebugAbbrev)
+      .Case("debug_abbrev.dwo", eSectionTypeDWARFDebugAbbrev)
+      .Case("debug_addr", eSectionTypeDWARFDebugAddr)
+      // Lookup table for mapping addresses to compilation units
+      .Case("debug_aranges", eSectionTypeDWARFDebugAranges)
+      .Case("debug_cu_index", eSectionTypeDWARFDebugCuIndex)
+      // Call frame information
+      .Case("debug_frame", eSectionTypeDWARFDebugFrame)
+      // The core DWARF information section
+      .Case("debug_info", eSectionTypeDWARFDebugInfo)
+      .Case("debug_info.dwo", eSectionTypeDWARFDebugInfo)
+      // Line number information
+      .Case("debug_line", eSectionTypeDWARFDebugLine)
+      .Case("debug_line.dwo", eSectionTypeDWARFDebugLine)
+      // Location lists used in DW_AT_location attributes
+      .Case("debug_loc", eSectionTypeDWARFDebugLoc)
+      .Case("debug_loc.dwo", eSectionTypeDWARFDebugLoc)
+      // Macro information
+      .Case("debug_macinfo", eSectionTypeDWARFDebugMacInfo)
+      .Case("debug_macro", eSectionTypeDWARFDebugMacro)
+      .Case("debug_macro.dwo", eSectionTypeDWARFDebugMacro)
+      // Lookup table for mapping object and function names to compilation units
+      .Case("debug_pubnames", eSectionTypeDWARFDebugPubNames)
+      // Lookup table for mapping type names to compilation units
+      .Case("debug_pubtypes", eSectionTypeDWARFDebugPubTypes)
+      // Address ranges used in DW_AT_ranges attributes
+      .Case("debug_ranges", eSectionTypeDWARFDebugRanges)
+      // String table used in .debug_info
+      .Case("debug_str", eSectionTypeDWARFDebugStr)
+      .Case("debug_str.dwo", eSectionTypeDWARFDebugStr)
+      .Case("debug_str_offsets", eSectionTypeDWARFDebugStrOffsets)
+      .Case("debug_str_offsets.dwo", eSectionTypeDWARFDebugStrOffsets)
+      .Case("debug_types", eSectionTypeDWARFDebugTypes)
+      .Case("gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink)
+      .Case("eh_frame", eSectionTypeEHFrame)
+      .Case("ARM.exidx", eSectionTypeARMexidx)
+      .Case("ARM.extab", eSectionTypeARMextab)
+      .Case("gosymtab", eSectionTypeGoSymtab)
+      .Default(eSectionTypeOther);
+}
+
 void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
   if (!m_sections_ap.get() && ParseSectionHeaders()) {
     m_sections_ap.reset(new SectionList());
@@ -1771,137 +1828,14 @@ void ObjectFileELF::CreateSections(Secti
          I != m_section_headers.end(); ++I) {
       const ELFSectionHeaderInfo &header = *I;
 
-      ConstString &name = I->section_name;
+      llvm::StringRef section_name = I->section_name.GetStringRef();
       const uint64_t file_size =
           header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
       const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
 
-      static ConstString g_sect_name_text(".text");
-      static ConstString g_sect_name_data(".data");
-      static ConstString g_sect_name_bss(".bss");
-      static ConstString g_sect_name_tdata(".tdata");
-      static ConstString g_sect_name_tbss(".tbss");
-      static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev");
-      static ConstString g_sect_name_dwarf_debug_addr(".debug_addr");
-      static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges");
-      static ConstString g_sect_name_dwarf_debug_cu_index(".debug_cu_index");
-      static ConstString g_sect_name_dwarf_debug_frame(".debug_frame");
-      static ConstString g_sect_name_dwarf_debug_info(".debug_info");
-      static ConstString g_sect_name_dwarf_debug_line(".debug_line");
-      static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
-      static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
-      static ConstString g_sect_name_dwarf_debug_macro(".debug_macro");
-      static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames");
-      static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
-      static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
-      static ConstString g_sect_name_dwarf_debug_str(".debug_str");
-      static ConstString g_sect_name_dwarf_debug_str_offsets(
-          ".debug_str_offsets");
-      static ConstString g_sect_name_dwarf_debug_abbrev_dwo(
-          ".debug_abbrev.dwo");
-      static ConstString g_sect_name_dwarf_debug_info_dwo(".debug_info.dwo");
-      static ConstString g_sect_name_dwarf_debug_line_dwo(".debug_line.dwo");
-      static ConstString g_sect_name_dwarf_debug_macro_dwo(".debug_macro.dwo");
-      static ConstString g_sect_name_dwarf_debug_loc_dwo(".debug_loc.dwo");
-      static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo");
-      static ConstString g_sect_name_dwarf_debug_str_offsets_dwo(
-          ".debug_str_offsets.dwo");
-      static ConstString g_sect_name_dwarf_debug_types(".debug_types");
-      static ConstString g_sect_name_eh_frame(".eh_frame");
-      static ConstString g_sect_name_arm_exidx(".ARM.exidx");
-      static ConstString g_sect_name_arm_extab(".ARM.extab");
-      static ConstString g_sect_name_go_symtab(".gosymtab");
-      static ConstString g_sect_name_dwarf_gnu_debugaltlink(".gnu_debugaltlink");
-
-      SectionType sect_type = eSectionTypeOther;
-
-      bool is_thread_specific = false;
-
-      if (name == g_sect_name_text)
-        sect_type = eSectionTypeCode;
-      else if (name == g_sect_name_data)
-        sect_type = eSectionTypeData;
-      else if (name == g_sect_name_bss)
-        sect_type = eSectionTypeZeroFill;
-      else if (name == g_sect_name_tdata) {
-        sect_type = eSectionTypeData;
-        is_thread_specific = true;
-      } else if (name == g_sect_name_tbss) {
-        sect_type = eSectionTypeZeroFill;
-        is_thread_specific = true;
-      }
-      // .debug_abbrev – Abbreviations used in the .debug_info section
-      // .debug_aranges – Lookup table for mapping addresses to compilation
-      // units .debug_frame – Call frame information .debug_info – The core
-      // DWARF information section .debug_line – Line number information
-      // .debug_loc – Location lists used in DW_AT_location attributes
-      // .debug_macinfo – Macro information .debug_pubnames – Lookup table
-      // for mapping object and function names to compilation units
-      // .debug_pubtypes – Lookup table for mapping type names to compilation
-      // units .debug_ranges – Address ranges used in DW_AT_ranges attributes
-      // .debug_str – String table used in .debug_info MISSING?
-      // .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section,
-      // http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html MISSING?
-      // .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build
-      // /gdb-add-index?pathrev=144644 MISSING? .debug_types - Type
-      // descriptions from DWARF 4? See
-      // http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
-      else if (name == g_sect_name_dwarf_debug_abbrev)
-        sect_type = eSectionTypeDWARFDebugAbbrev;
-      else if (name == g_sect_name_dwarf_debug_addr)
-        sect_type = eSectionTypeDWARFDebugAddr;
-      else if (name == g_sect_name_dwarf_debug_aranges)
-        sect_type = eSectionTypeDWARFDebugAranges;
-      else if (name == g_sect_name_dwarf_debug_cu_index)
-        sect_type = eSectionTypeDWARFDebugCuIndex;
-      else if (name == g_sect_name_dwarf_debug_frame)
-        sect_type = eSectionTypeDWARFDebugFrame;
-      else if (name == g_sect_name_dwarf_debug_info)
-        sect_type = eSectionTypeDWARFDebugInfo;
-      else if (name == g_sect_name_dwarf_debug_line)
-        sect_type = eSectionTypeDWARFDebugLine;
-      else if (name == g_sect_name_dwarf_debug_loc)
-        sect_type = eSectionTypeDWARFDebugLoc;
-      else if (name == g_sect_name_dwarf_debug_macinfo)
-        sect_type = eSectionTypeDWARFDebugMacInfo;
-      else if (name == g_sect_name_dwarf_debug_macro)
-        sect_type = eSectionTypeDWARFDebugMacro;
-      else if (name == g_sect_name_dwarf_debug_pubnames)
-        sect_type = eSectionTypeDWARFDebugPubNames;
-      else if (name == g_sect_name_dwarf_debug_pubtypes)
-        sect_type = eSectionTypeDWARFDebugPubTypes;
-      else if (name == g_sect_name_dwarf_debug_ranges)
-        sect_type = eSectionTypeDWARFDebugRanges;
-      else if (name == g_sect_name_dwarf_debug_str)
-        sect_type = eSectionTypeDWARFDebugStr;
-      else if (name == g_sect_name_dwarf_debug_types)
-        sect_type = eSectionTypeDWARFDebugTypes;
-      else if (name == g_sect_name_dwarf_debug_str_offsets)
-        sect_type = eSectionTypeDWARFDebugStrOffsets;
-      else if (name == g_sect_name_dwarf_debug_abbrev_dwo)
-        sect_type = eSectionTypeDWARFDebugAbbrev;
-      else if (name == g_sect_name_dwarf_debug_info_dwo)
-        sect_type = eSectionTypeDWARFDebugInfo;
-      else if (name == g_sect_name_dwarf_debug_line_dwo)
-        sect_type = eSectionTypeDWARFDebugLine;
-      else if (name == g_sect_name_dwarf_debug_macro_dwo)
-        sect_type = eSectionTypeDWARFDebugMacro;
-      else if (name == g_sect_name_dwarf_debug_loc_dwo)
-        sect_type = eSectionTypeDWARFDebugLoc;
-      else if (name == g_sect_name_dwarf_debug_str_dwo)
-        sect_type = eSectionTypeDWARFDebugStr;
-      else if (name == g_sect_name_dwarf_debug_str_offsets_dwo)
-        sect_type = eSectionTypeDWARFDebugStrOffsets;
-      else if (name == g_sect_name_eh_frame)
-        sect_type = eSectionTypeEHFrame;
-      else if (name == g_sect_name_arm_exidx)
-        sect_type = eSectionTypeARMexidx;
-      else if (name == g_sect_name_arm_extab)
-        sect_type = eSectionTypeARMextab;
-      else if (name == g_sect_name_go_symtab)
-        sect_type = eSectionTypeGoSymtab;
-      else if (name == g_sect_name_dwarf_gnu_debugaltlink)
-        sect_type = eSectionTypeDWARFGNUDebugAltLink;
+      SectionType sect_type = getSectionType(section_name);
+      bool is_thread_specific =
+          section_name.equals(".tdata") || section_name.equals(".tbss");
 
       const uint32_t permissions =
           ((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0u) |
@@ -1966,7 +1900,7 @@ void ObjectFileELF::CreateSections(Secti
           this, // ObjectFile to which this section belongs and should read
                 // section data from.
           SectionIndex(I),     // Section ID.
-          name,                // Section name.
+          I->section_name,     // Section name.
           sect_type,           // Section type.
           addr,                // VM address.
           vm_size,             // VM size in bytes of this section.
@@ -2858,7 +2792,7 @@ Symtab *ObjectFileELF::GetSymtab() {
 
 void ObjectFileELF::RelocateSection(lldb_private::Section *section)
 {
-  static const char *debug_prefix = ".debug";
+  static const llvm::StringRef debug_prefix(".debug");
 
   // Set relocated bit so we stop getting called, regardless of whether we
   // actually relocate.
@@ -2868,18 +2802,18 @@ void ObjectFileELF::RelocateSection(lldb
   if (CalculateType() != eTypeObjectFile)
     return;
 
-  const char *section_name = section->GetName().GetCString();
+  llvm::StringRef section_name = section->GetName().GetStringRef();
   // Can't relocate that which can't be named
-  if (section_name == nullptr)
+  if (section_name.empty())
     return;
 
   // We don't relocate non-debug sections at the moment
-  if (strncmp(section_name, debug_prefix, strlen(debug_prefix)))
+  if (section_name.startswith(debug_prefix))
     return;
 
   // Relocation section names to look for
-  std::string needle = std::string(".rel") + section_name;
-  std::string needlea = std::string(".rela") + section_name;
+  std::string needle = std::string(".rel") + section_name.str();
+  std::string needlea = std::string(".rela") + section_name.str();
 
   for (SectionHeaderCollIter I = m_section_headers.begin();
        I != m_section_headers.end(); ++I) {
@@ -2905,7 +2839,7 @@ void ObjectFileELF::ParseUnwindSymbols(S
 
   // First we save the new symbols into a separate list and add them to the
   // symbol table after we colleced all symbols we want to add. This is
-  // neccessary because adding a new symbol invalidates the internal index of
+  // necessary because adding a new symbol invalidates the internal index of
   // the symtab what causing the next lookup to be slow because it have to
   // recalculate the index first.
   std::vector<Symbol> new_symbols;




More information about the lldb-commits mailing list