[DebugInfo] Dump a .debug_line section, including line-number program,
without any compile units. Differential Revision: https://reviews.llvm.org/D40114 llvm-svn: 318842
This commit is contained in:
parent
c492500e7e
commit
511b54cadc
|
@ -219,7 +219,7 @@ public:
|
|||
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<Row>;
|
||||
|
@ -237,7 +237,7 @@ public:
|
|||
};
|
||||
|
||||
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:
|
||||
|
|
|
@ -342,10 +342,9 @@ void DWARFContext::dump(
|
|||
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.
|
||||
|
|
|
@ -383,7 +383,7 @@ DWARFDebugLine::getLineTable(uint32_t Offset) const {
|
|||
}
|
||||
|
||||
const DWARFDebugLine::LineTable *
|
||||
DWARFDebugLine::getOrParseLineTable(const DWARFDataExtractor &DebugLineData,
|
||||
DWARFDebugLine::getOrParseLineTable(DWARFDataExtractor &DebugLineData,
|
||||
uint32_t Offset, const DWARFUnit *U) {
|
||||
std::pair<LineTableIter, bool> Pos =
|
||||
LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
|
||||
|
@ -395,7 +395,7 @@ DWARFDebugLine::getOrParseLineTable(const DWARFDataExtractor &DebugLineData,
|
|||
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 @@ bool DWARFDebugLine::LineTable::parse(const DWARFDataExtractor &DebugLineData,
|
|||
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 @@ bool DWARFDebugLine::LineTable::parse(const DWARFDataExtractor &DebugLineData,
|
|||
// 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);
|
||||
|
|
|
@ -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
|
|
@ -13,3 +13,33 @@ 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
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue