Index: lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/Makefile =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/Makefile +++ lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/Makefile @@ -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 Index: lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/TestCompressedDebugInfo.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/TestCompressedDebugInfo.py +++ lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/TestCompressedDebugInfo.py @@ -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") Index: lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/a.c =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/a.c +++ lldb/trunk/packages/Python/lldbsuite/test/linux/compressed-debug-info/a.c @@ -0,0 +1,4 @@ +int main() { + int z = 2; + return z; +} Index: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1757,6 +1757,63 @@ 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(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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 new_symbols;