Index: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -219,7 +219,7 @@ void clear(); /// Parse prologue and all rows. - bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, + bool parse(DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, const DWARFUnit *U, raw_ostream *OS = nullptr); using RowVector = std::vector; @@ -237,7 +237,7 @@ }; const LineTable *getLineTable(uint32_t Offset) const; - const LineTable *getOrParseLineTable(const DWARFDataExtractor &DebugLineData, + const LineTable *getOrParseLineTable(DWARFDataExtractor &DebugLineData, uint32_t Offset, const DWARFUnit *U); private: Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -342,10 +342,9 @@ while (Offset < LineData.getData().size()) { DWARFUnit *U = nullptr; auto It = LineToUnit.find(Offset); - if (It != LineToUnit.end()) { + if (It != LineToUnit.end()) U = It->second; - LineData.setAddressSize(U->getAddressByteSize()); - } + LineData.setAddressSize(U ? U->getAddressByteSize() : 0); DWARFDebugLine::LineTable LineTable; if (DumpOffset && Offset != *DumpOffset) { // Find the size of this part of the line table section and skip it. Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -383,7 +383,7 @@ } const DWARFDebugLine::LineTable * -DWARFDebugLine::getOrParseLineTable(const DWARFDataExtractor &DebugLineData, +DWARFDebugLine::getOrParseLineTable(DWARFDataExtractor &DebugLineData, uint32_t Offset, const DWARFUnit *U) { std::pair Pos = LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable())); @@ -395,7 +395,7 @@ return LT; } -bool DWARFDebugLine::LineTable::parse(const DWARFDataExtractor &DebugLineData, +bool DWARFDebugLine::LineTable::parse(DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, const DWARFUnit *U, raw_ostream *OS) { const uint32_t DebugLineOffset = *OffsetPtr; @@ -414,6 +414,13 @@ const uint32_t EndOffset = DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength(); + // See if we should tell the data extractor the address size. + if (DebugLineData.getAddressSize() == 0) + DebugLineData.setAddressSize(Prologue.getAddressSize()); + else + assert(Prologue.getAddressSize() == 0 || + Prologue.getAddressSize() == DebugLineData.getAddressSize()); + ParsingState State(this); while (*OffsetPtr < EndOffset) { @@ -467,6 +474,13 @@ // relocatable address. All of the other statement program opcodes // that affect the address register add a delta to it. This instruction // stores a relocatable value into it instead. + // + // Make sure the extractor knows the address size. If not, infer it + // from the size of the operand. + if (DebugLineData.getAddressSize() == 0) + DebugLineData.setAddressSize(Len - 1); + else + assert(DebugLineData.getAddressSize() == Len - 1); State.Row.Address = DebugLineData.getRelocatedAddress(OffsetPtr); if (OS) *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address); Index: llvm/trunk/test/DebugInfo/X86/dwarfdump-line-only.s =================================================================== --- llvm/trunk/test/DebugInfo/X86/dwarfdump-line-only.s +++ llvm/trunk/test/DebugInfo/X86/dwarfdump-line-only.s @@ -0,0 +1,93 @@ +# Test object to verify dwarfdump handles dumping a DWARF v5 line table +# without an associated unit. +# FIXME: Support FORM_strp in this situation. +# +# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \ +# RUN: llvm-dwarfdump -v - | FileCheck %s + + .section .text + # Dummy function +foo: ret + + .section .debug_line,"",@progbits +# CHECK-LABEL: .debug_line contents: + +# DWARF v5 line-table header. +LH_5_start: + .long LH_5_end-LH_5_version # Length of Unit (DWARF-32 format) +LH_5_version: + .short 5 # DWARF version number + .byte 8 # Address Size + .byte 0 # Segment Selector Size + .long LH_5_header_end-LH_5_params # Length of Prologue +LH_5_params: + .byte 1 # Minimum Instruction Length + .byte 1 # Maximum Operations per Instruction + .byte 1 # Default is_stmt + .byte -5 # Line Base + .byte 14 # Line Range + .byte 13 # Opcode Base + .byte 0 # Standard Opcode Lengths + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 0 + .byte 0 + .byte 0 + .byte 1 + .byte 0 + .byte 0 + .byte 1 + # Directory table format + .byte 1 # One element per directory entry + .byte 1 # DW_LNCT_path + .byte 0x08 # DW_FORM_string + # Directory table entries + .byte 2 # Two directory entries + .asciz "Directory1" + .asciz "Directory2" + # File table format + .byte 4 # Four elements per file entry + .byte 2 # DW_LNCT_directory_index + .byte 0x0b # DW_FORM_data1 + .byte 1 # DW_LNCT_path + .byte 0x08 # DW_FORM_string + .byte 3 # DW_LNCT_timestamp + .byte 0x0f # DW_FORM_udata + .byte 4 # DW_LNCT_size + .byte 0x0f # DW_FORM_udata + # File table entries + .byte 2 # Two file entries + .byte 2 + .asciz "File1" + .byte 0x51 + .byte 0x52 + .byte 1 + .asciz "File2" + .byte 0x53 + .byte 0x54 +LH_5_header_end: + # Minimal line number program with an address in it, which shows + # we picked up the address size from the line-table header. + .byte 0 + .byte 9 + .byte 2 # DW_LNE_set_address + .quad .text + .byte 0 + .byte 1 + .byte 1 # DW_LNE_end_sequence +LH_5_end: + +# CHECK: Line table prologue: +# CHECK: version: 5 +# CHECK: address_size: 8 +# CHECK: seg_select_size: 0 +# CHECK: max_ops_per_inst: 1 +# CHECK: include_directories[ 1] = 'Directory1' +# CHECK: include_directories[ 2] = 'Directory2' +# CHECK-NOT: include_directories +# CHECK: file_names[ 1] 2 0x00000051 0x00000052 File1{{$}} +# CHECK: file_names[ 2] 1 0x00000053 0x00000054 File2{{$}} +# CHECK-NOT: file_names +# CHECK: 0x0000000000000000 {{.*}} is_stmt end_sequence Index: llvm/trunk/test/DebugInfo/dwarfdump-64-bit-dwarf.test =================================================================== --- llvm/trunk/test/DebugInfo/dwarfdump-64-bit-dwarf.test +++ llvm/trunk/test/DebugInfo/dwarfdump-64-bit-dwarf.test @@ -13,3 +13,33 @@ CHECK: line_range: 14 CHECK: opcode_base: 13 CHECK: is_stmt end_sequence + +CHECK: total_length: 0x0000007c +CHECK: version: 2 +CHECK:prologue_length: 0x00000048 +CHECK:min_inst_length: 1 +CHECK:default_is_stmt: 1 +CHECK: line_base: -5 +CHECK: line_range: 14 +CHECK: opcode_base: 13 +CHECK: is_stmt end_sequence + +CHECK: total_length: 0x00000094 +CHECK: version: 2 +CHECK:prologue_length: 0x00000044 +CHECK:min_inst_length: 1 +CHECK:default_is_stmt: 1 +CHECK: line_base: -5 +CHECK: line_range: 14 +CHECK: opcode_base: 13 +CHECK: is_stmt end_sequence + +CHECK: total_length: 0x0000007c +CHECK: version: 2 +CHECK:prologue_length: 0x00000048 +CHECK:min_inst_length: 1 +CHECK:default_is_stmt: 1 +CHECK: line_base: -5 +CHECK: line_range: 14 +CHECK: opcode_base: 13 +CHECK: is_stmt end_sequence