[ObjectYAML] Support for DWARF line tables

One more try... relanding r291541 with a fix to properly gate MaxOpsPerInst on DWARF version.

Description from r291541:

This patch re-lands r291470, which failed on Linux bots. The issue (I believe) was undefined behavior because the size of llvm::dwarf::LineNumberOps was not explcitly specified or consistently respected. The updated patch adds an explcit underlying type to the enum and preserves the size more correctly.

Original description:

This patch adds support for the DWARF debug_lines section. The line table state machine opcodes are preserved, so this can be used to test the state machine evaluation directly.

llvm-svn: 291546
This commit is contained in:
Chris Bieneman 2017-01-10 06:22:49 +00:00
parent 31783d0fe9
commit 42d02eba7a
10 changed files with 1004 additions and 13 deletions

View File

@ -85,6 +85,41 @@ struct Unit {
std::vector<Entry> Entries;
};
struct File {
StringRef Name;
uint64_t DirIdx;
uint64_t ModTime;
uint64_t Length;
};
struct LineTableOpcode {
dwarf::LineNumberOps Opcode;
uint64_t ExtLen;
dwarf::LineNumberExtendedOps SubOpcode;
uint64_t Data;
int64_t SData;
File FileEntry;
std::vector<llvm::yaml::Hex8> UnknownOpcodeData;
std::vector<llvm::yaml::Hex64> StandardOpcodeData;
};
struct LineTable {
uint32_t TotalLength;
uint64_t TotalLength64;
uint16_t Version;
uint64_t PrologueLength;
uint8_t MinInstLength;
uint8_t MaxOpsPerInst;
uint8_t DefaultIsStmt;
uint8_t LineBase;
uint8_t LineRange;
uint8_t OpcodeBase;
std::vector<uint8_t> StandardOpcodeLengths;
std::vector<StringRef> IncludeDirs;
std::vector<File> Files;
std::vector<LineTableOpcode> Opcodes;
};
struct Data {
bool IsLittleEndian;
std::vector<Abbrev> AbbrevDecls;
@ -98,6 +133,8 @@ struct Data {
std::vector<Unit> CompileUnits;
std::vector<LineTable> DebugLines;
bool isEmpty() const;
};
@ -105,6 +142,7 @@ struct Data {
} // namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
@ -115,6 +153,9 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
namespace llvm {
namespace yaml {
@ -159,6 +200,18 @@ template <> struct MappingTraits<DWARFYAML::FormValue> {
static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
};
template <> struct MappingTraits<DWARFYAML::File> {
static void mapping(IO &IO, DWARFYAML::File &File);
};
template <> struct MappingTraits<DWARFYAML::LineTableOpcode> {
static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode);
};
template <> struct MappingTraits<DWARFYAML::LineTable> {
static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
};
#define HANDLE_DW_TAG(unused, name) \
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
@ -169,6 +222,26 @@ template <> struct ScalarEnumerationTraits<dwarf::Tag> {
}
};
#define HANDLE_DW_LNS(unused, name) \
io.enumCase(value, "DW_LNS_" #name, dwarf::DW_LNS_##name);
template <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
static void enumeration(IO &io, dwarf::LineNumberOps &value) {
#include "llvm/Support/Dwarf.def"
io.enumFallback<Hex8>(value);
}
};
#define HANDLE_DW_LNE(unused, name) \
io.enumCase(value, "DW_LNE_" #name, dwarf::DW_LNE_##name);
template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
static void enumeration(IO &io, dwarf::LineNumberExtendedOps &value) {
#include "llvm/Support/Dwarf.def"
io.enumFallback<Hex16>(value);
}
};
#define HANDLE_DW_AT(unused, name) \
io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);

View File

@ -139,7 +139,6 @@ struct UniversalBinary {
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)

View File

@ -207,7 +207,7 @@ enum DiscriminantList {
};
/// Line Number Standard Opcode Encodings.
enum LineNumberOps {
enum LineNumberOps : uint8_t {
#define HANDLE_DW_LNS(ID, NAME) DW_LNS_##NAME = ID,
#include "llvm/Support/Dwarf.def"
};

View File

@ -27,17 +27,18 @@ void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
IO.setContext(&DWARF);
IO.mapOptional("debug_str", DWARF.DebugStrings);
IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
if(!DWARF.ARanges.empty() || !IO.outputting())
if (!DWARF.ARanges.empty() || !IO.outputting())
IO.mapOptional("debug_aranges", DWARF.ARanges);
if(!DWARF.PubNames.Entries.empty() || !IO.outputting())
if (!DWARF.PubNames.Entries.empty() || !IO.outputting())
IO.mapOptional("debug_pubnames", DWARF.PubNames);
if(!DWARF.PubTypes.Entries.empty() || !IO.outputting())
if (!DWARF.PubTypes.Entries.empty() || !IO.outputting())
IO.mapOptional("debug_pubtypes", DWARF.PubTypes);
if(!DWARF.GNUPubNames.Entries.empty() || !IO.outputting())
if (!DWARF.GNUPubNames.Entries.empty() || !IO.outputting())
IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);
if(!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
if (!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);
IO.mapOptional("debug_info", DWARF.CompileUnits);
IO.mapOptional("debug_line", DWARF.DebugLines);
IO.setContext(&oldContext);
}
@ -62,7 +63,7 @@ void MappingTraits<DWARFYAML::ARangeDescriptor>::mapping(
}
void MappingTraits<DWARFYAML::ARange>::mapping(IO &IO,
DWARFYAML::ARange &Range) {
DWARFYAML::ARange &Range) {
IO.mapRequired("Length", Range.Length);
IO.mapRequired("Version", Range.Version);
IO.mapRequired("CuOffset", Range.CuOffset);
@ -106,15 +107,61 @@ void MappingTraits<DWARFYAML::Entry>::mapping(IO &IO, DWARFYAML::Entry &Entry) {
IO.mapRequired("Values", Entry.Values);
}
void MappingTraits<DWARFYAML::FormValue>::mapping(IO &IO,
DWARFYAML::FormValue &FormValue) {
void MappingTraits<DWARFYAML::FormValue>::mapping(
IO &IO, DWARFYAML::FormValue &FormValue) {
IO.mapOptional("Value", FormValue.Value);
if(!FormValue.CStr.empty() || !IO.outputting())
if (!FormValue.CStr.empty() || !IO.outputting())
IO.mapOptional("CStr", FormValue.CStr);
if(!FormValue.BlockData.empty() || !IO.outputting())
if (!FormValue.BlockData.empty() || !IO.outputting())
IO.mapOptional("BlockData", FormValue.BlockData);
}
void MappingTraits<DWARFYAML::File>::mapping(IO &IO, DWARFYAML::File &File) {
IO.mapRequired("Name", File.Name);
IO.mapRequired("DirIdx", File.DirIdx);
IO.mapRequired("ModTime", File.ModTime);
IO.mapRequired("Length", File.Length);
}
void MappingTraits<DWARFYAML::LineTableOpcode>::mapping(
IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode) {
IO.mapRequired("Opcode", LineTableOpcode.Opcode);
if (LineTableOpcode.Opcode == dwarf::DW_LNS_extended_op) {
IO.mapRequired("ExtLen", LineTableOpcode.ExtLen);
IO.mapRequired("SubOpcode", LineTableOpcode.SubOpcode);
}
if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())
IO.mapOptional("UnknownOpcodeData", LineTableOpcode.UnknownOpcodeData);
if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())
IO.mapOptional("StandardOpcodeData", LineTableOpcode.StandardOpcodeData);
if (!LineTableOpcode.FileEntry.Name.empty() || !IO.outputting())
IO.mapOptional("FileEntry", LineTableOpcode.FileEntry);
if (LineTableOpcode.Opcode == dwarf::DW_LNS_advance_line || !IO.outputting())
IO.mapOptional("SData", LineTableOpcode.SData);
IO.mapOptional("Data", LineTableOpcode.Data);
}
void MappingTraits<DWARFYAML::LineTable>::mapping(
IO &IO, DWARFYAML::LineTable &LineTable) {
IO.mapRequired("TotalLength", LineTable.TotalLength);
if (LineTable.TotalLength == UINT32_MAX)
IO.mapRequired("TotalLength64", LineTable.TotalLength64);
IO.mapRequired("Version", LineTable.Version);
IO.mapRequired("PrologueLength", LineTable.PrologueLength);
IO.mapRequired("MinInstLength", LineTable.MinInstLength);
if(LineTable.Version >= 4)
IO.mapRequired("MaxOpsPerInst", LineTable.MaxOpsPerInst);
IO.mapRequired("DefaultIsStmt", LineTable.DefaultIsStmt);
IO.mapRequired("LineBase", LineTable.LineBase);
IO.mapRequired("LineRange", LineTable.LineRange);
IO.mapRequired("OpcodeBase", LineTable.OpcodeBase);
IO.mapRequired("StandardOpcodeLengths", LineTable.StandardOpcodeLengths);
IO.mapRequired("IncludeDirs", LineTable.IncludeDirs);
IO.mapRequired("Files", LineTable.Files);
IO.mapRequired("Opcodes", LineTable.Opcodes);
}
} // namespace llvm::yaml
} // namespace llvm

View File

@ -451,6 +451,58 @@ DWARF:
- Value: 0x0000000000000001
- AbbrCode: 0x00000000
Values:
debug_line:
- TotalLength: 65
Version: 2
PrologueLength: 36
MinInstLength: 1
DefaultIsStmt: 1
LineBase: 251
LineRange: 14
OpcodeBase: 13
StandardOpcodeLengths:
- 0
- 1
- 1
- 1
- 1
- 0
- 0
- 0
- 1
- 0
- 0
- 1
IncludeDirs:
Files:
- Name: hello_world.c
DirIdx: 0
ModTime: 0
Length: 0
Opcodes:
- Opcode: DW_LNS_extended_op
ExtLen: 9
SubOpcode: DW_LNE_set_address
Data: 4294971216
- Opcode: 0x14
Data: 4294971216
- Opcode: DW_LNS_set_column
Data: 3
- Opcode: DW_LNS_set_prologue_end
Data: 3
- Opcode: DW_LNS_const_add_pc
Data: 3
- Opcode: 0xBB
Data: 3
- Opcode: 0xBB
Data: 3
- Opcode: DW_LNS_advance_pc
Data: 11
- Opcode: DW_LNS_extended_op
ExtLen: 1
SubOpcode: DW_LNE_end_sequence
Data: 11
...
...

View File

@ -0,0 +1,596 @@
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x01000007
cpusubtype: 0x00000003
filetype: 0x0000000A
ncmds: 7
sizeofcmds: 1848
flags: 0x00000000
reserved: 0x00000000
LoadCommands:
- cmd: LC_UUID
cmdsize: 24
uuid: B4D48511-37F4-3ED4-AFA7-1683DCE69AC4
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 4096
nsyms: 2
stroff: 4128
strsize: 28
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __PAGEZERO
vmaddr: 0
vmsize: 4294967296
fileoff: 0
filesize: 0
maxprot: 0
initprot: 0
nsects: 0
flags: 0
- cmd: LC_SEGMENT_64
cmdsize: 472
segname: __TEXT
vmaddr: 4294967296
vmsize: 4096
fileoff: 0
filesize: 0
maxprot: 7
initprot: 5
nsects: 5
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0000000100000F50
size: 52
offset: 0x00000000
align: 4
reloff: 0x00000000
nreloc: 0
flags: 0x80000400
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __stubs
segname: __TEXT
addr: 0x0000000100000F84
size: 6
offset: 0x00000000
align: 1
reloff: 0x00000000
nreloc: 0
flags: 0x80000408
reserved1: 0x00000000
reserved2: 0x00000006
reserved3: 0x00000000
- sectname: __stub_helper
segname: __TEXT
addr: 0x0000000100000F8C
size: 26
offset: 0x00000000
align: 2
reloff: 0x00000000
nreloc: 0
flags: 0x80000400
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __cstring
segname: __TEXT
addr: 0x0000000100000FA6
size: 14
offset: 0x00000000
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000002
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __unwind_info
segname: __TEXT
addr: 0x0000000100000FB4
size: 72
offset: 0x00000000
align: 2
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_SEGMENT_64
cmdsize: 232
segname: __DATA
vmaddr: 4294971392
vmsize: 4096
fileoff: 0
filesize: 0
maxprot: 7
initprot: 3
nsects: 2
flags: 0
Sections:
- sectname: __nl_symbol_ptr
segname: __DATA
addr: 0x0000000100001000
size: 16
offset: 0x00000000
align: 3
reloff: 0x00000000
nreloc: 0
flags: 0x00000006
reserved1: 0x00000001
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __la_symbol_ptr
segname: __DATA
addr: 0x0000000100001010
size: 8
offset: 0x00000000
align: 3
reloff: 0x00000000
nreloc: 0
flags: 0x00000007
reserved1: 0x00000003
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __LINKEDIT
vmaddr: 4294975488
vmsize: 4096
fileoff: 4096
filesize: 60
maxprot: 7
initprot: 1
nsects: 0
flags: 0
- cmd: LC_SEGMENT_64
cmdsize: 952
segname: __DWARF
vmaddr: 4294979584
vmsize: 4096
fileoff: 8192
filesize: 764
maxprot: 7
initprot: 3
nsects: 11
flags: 0
Sections:
- sectname: __debug_line
segname: __DWARF
addr: 0x0000000100003000
size: 69
offset: 0x00002000
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_pubnames
segname: __DWARF
addr: 0x0000000100003045
size: 27
offset: 0x00002045
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_pubtypes
segname: __DWARF
addr: 0x0000000100003060
size: 35
offset: 0x00002060
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_aranges
segname: __DWARF
addr: 0x0000000100003083
size: 48
offset: 0x00002083
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_info
segname: __DWARF
addr: 0x00000001000030B3
size: 121
offset: 0x000020B3
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_abbrev
segname: __DWARF
addr: 0x000000010000312C
size: 76
offset: 0x0000212C
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_str
segname: __DWARF
addr: 0x0000000100003178
size: 142
offset: 0x00002178
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_names
segname: __DWARF
addr: 0x0000000100003206
size: 60
offset: 0x00002206
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_namespac
segname: __DWARF
addr: 0x0000000100003242
size: 36
offset: 0x00002242
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_types
segname: __DWARF
addr: 0x0000000100003266
size: 114
offset: 0x00002266
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_objc
segname: __DWARF
addr: 0x00000001000032D8
size: 36
offset: 0x000022D8
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
LinkEditData:
NameList:
- n_strx: 2
n_type: 0x0F
n_sect: 1
n_desc: 16
n_value: 4294967296
- n_strx: 22
n_type: 0x0F
n_sect: 1
n_desc: 0
n_value: 4294971216
StringTable:
- ''
- ''
- __mh_execute_header
- _main
DWARF:
debug_str:
- ''
- 'clang version 4.0.0 (trunk 288923) (llvm/trunk 288991)'
- hello_world.c
- /Users/cbieneman/dev/open-source/llvm-build-rel
- main
- argc
- argv
- int
- char
debug_abbrev:
- Code: 0x00000001
Tag: DW_TAG_compile_unit
Children: DW_CHILDREN_yes
Attributes:
- Attribute: DW_AT_producer
Form: DW_FORM_strp
- Attribute: DW_AT_language
Form: DW_FORM_data2
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_stmt_list
Form: DW_FORM_sec_offset
- Attribute: DW_AT_comp_dir
Form: DW_FORM_strp
- Attribute: DW_AT_low_pc
Form: DW_FORM_addr
- Attribute: DW_AT_high_pc
Form: DW_FORM_data4
- Code: 0x00000002
Tag: DW_TAG_subprogram
Children: DW_CHILDREN_yes
Attributes:
- Attribute: DW_AT_low_pc
Form: DW_FORM_addr
- Attribute: DW_AT_high_pc
Form: DW_FORM_data4
- Attribute: DW_AT_frame_base
Form: DW_FORM_exprloc
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Attribute: DW_AT_prototyped
Form: DW_FORM_flag_present
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Attribute: DW_AT_external
Form: DW_FORM_flag_present
- Code: 0x00000003
Tag: DW_TAG_formal_parameter
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_location
Form: DW_FORM_exprloc
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Code: 0x00000004
Tag: DW_TAG_base_type
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_encoding
Form: DW_FORM_data1
- Attribute: DW_AT_byte_size
Form: DW_FORM_data1
- Code: 0x00000005
Tag: DW_TAG_pointer_type
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_type
Form: DW_FORM_ref4
debug_aranges:
- Length: 44
Version: 2
CuOffset: 0
AddrSize: 8
SegSize: 0
Descriptors:
- Address: 0x0000000100000F50
Length: 52
debug_pubnames:
Length: 23
Version: 2
UnitOffset: 0
UnitSize: 121
Entries:
- DieOffset: 0x0000002A
Name: main
debug_pubtypes:
Length: 31
Version: 2
UnitOffset: 0
UnitSize: 121
Entries:
- DieOffset: 0x00000060
Name: int
- DieOffset: 0x00000071
Name: char
debug_info:
- Length: 117
Version: 4
AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
Values:
- Value: 0x0000000000000001
- Value: 0x000000000000000C
- Value: 0x0000000000000038
- Value: 0x0000000000000000
- Value: 0x0000000000000046
- Value: 0x0000000100000F50
- Value: 0x0000000000000034
- AbbrCode: 0x00000002
Values:
- Value: 0x0000000100000F50
- Value: 0x0000000000000034
- Value: 0x0000000000000001
BlockData:
- 0x56
- Value: 0x0000000000000076
- Value: 0x0000000000000001
- Value: 0x0000000000000003
- Value: 0x0000000000000001
- Value: 0x0000000000000060
- Value: 0x0000000000000001
- AbbrCode: 0x00000003
Values:
- Value: 0x0000000000000002
BlockData:
- 0x91
- 0x78
- Value: 0x000000000000007B
- Value: 0x0000000000000001
- Value: 0x0000000000000003
- Value: 0x0000000000000060
- AbbrCode: 0x00000003
Values:
- Value: 0x0000000000000002
BlockData:
- 0x91
- 0x70
- Value: 0x0000000000000080
- Value: 0x0000000000000001
- Value: 0x0000000000000003
- Value: 0x0000000000000067
- AbbrCode: 0x00000000
Values:
- AbbrCode: 0x00000004
Values:
- Value: 0x0000000000000085
- Value: 0x0000000000000005
- Value: 0x0000000000000004
- AbbrCode: 0x00000005
Values:
- Value: 0x000000000000006C
- AbbrCode: 0x00000005
Values:
- Value: 0x0000000000000071
- AbbrCode: 0x00000004
Values:
- Value: 0x0000000000000089
- Value: 0x0000000000000006
- Value: 0x0000000000000001
- AbbrCode: 0x00000000
Values:
debug_line:
- TotalLength: 65
Version: 2
PrologueLength: 36
MinInstLength: 1
MaxOpsPerInst: 0
DefaultIsStmt: 1
LineBase: 251
LineRange: 14
OpcodeBase: 13
StandardOpcodeLengths:
- 0
- 1
- 1
- 1
- 1
- 0
- 0
- 0
- 1
- 0
- 0
- 1
IncludeDirs:
Files:
- Name: hello_world.c
DirIdx: 0
ModTime: 0
Length: 0
Opcodes:
- Opcode: DW_LNS_extended_op
ExtLen: 9
SubOpcode: DW_LNE_set_address
Data: 4294971216
- Opcode: 0x14
Data: 4294971216
- Opcode: DW_LNS_set_column
Data: 3
- Opcode: DW_LNS_set_prologue_end
Data: 3
- Opcode: DW_LNS_const_add_pc
Data: 3
- Opcode: 0xBB
Data: 3
- Opcode: 0xBB
Data: 3
- Opcode: DW_LNS_advance_pc
Data: 11
- Opcode: DW_LNS_extended_op
ExtLen: 1
SubOpcode: DW_LNE_end_sequence
Data: 11
...
#CHECK: debug_line:
#CHECK: - TotalLength: 65
#CHECK: Version: 2
#CHECK: PrologueLength: 36
#CHECK: MinInstLength: 1
#CHECK: DefaultIsStmt: 1
#CHECK: LineBase: 251
#CHECK: LineRange: 14
#CHECK: OpcodeBase: 13
#CHECK: StandardOpcodeLengths:
#CHECK: - 0
#CHECK: - 1
#CHECK: - 1
#CHECK: - 1
#CHECK: - 1
#CHECK: - 0
#CHECK: - 0
#CHECK: - 0
#CHECK: - 1
#CHECK: - 0
#CHECK: - 0
#CHECK: - 1
#CHECK: IncludeDirs:
#CHECK: Files:
#CHECK: - Name: hello_world.c
#CHECK: DirIdx: 0
#CHECK: ModTime: 0
#CHECK: Length: 0
#CHECK: Opcodes:
#CHECK: - Opcode: DW_LNS_extended_op
#CHECK: ExtLen: 9
#CHECK: SubOpcode: DW_LNE_set_address
#CHECK: Data: 4294971216
#CHECK: - Opcode: 0x14
#CHECK: Data: 4294971216
#CHECK: - Opcode: DW_LNS_set_column
#CHECK: Data: 3
#CHECK: - Opcode: DW_LNS_set_prologue_end
#CHECK: Data: 3
#CHECK: - Opcode: DW_LNS_const_add_pc
#CHECK: Data: 3
#CHECK: - Opcode: 0xBB
#CHECK: Data: 3
#CHECK: - Opcode: 0xBB
#CHECK: Data: 3
#CHECK: - Opcode: DW_LNS_advance_pc
#CHECK: Data: 11
#CHECK: - Opcode: DW_LNS_extended_op
#CHECK: ExtLen: 1
#CHECK: SubOpcode: DW_LNE_end_sequence
#CHECK: Data: 11
#CHECK: ...

View File

@ -127,7 +127,7 @@ void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
NewValue.Value = 0xDEADBEEFDEADBEEF;
DWARFDie DIEWrapper(CU.get(), &DIE);
auto FormValue = DIEWrapper.getAttributeValue(AttrSpec.Attr);
if(!FormValue)
if (!FormValue)
return;
auto Form = FormValue.getValue().getForm();
bool indirect = false;
@ -211,11 +211,137 @@ void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
}
}
bool dumpFileEntry(DataExtractor &Data, uint32_t &Offset,
DWARFYAML::File &File) {
File.Name = Data.getCStr(&Offset);
if (File.Name.empty())
return false;
File.DirIdx = Data.getULEB128(&Offset);
File.ModTime = Data.getULEB128(&Offset);
File.Length = Data.getULEB128(&Offset);
return true;
}
void dumpDebugLines(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
for (const auto &CU : DCtx.compile_units()) {
auto CUDIE = CU->getUnitDIE();
if (!CUDIE)
continue;
if (auto StmtOffset =
CUDIE.getAttributeValueAsSectionOffset(dwarf::DW_AT_stmt_list)) {
DWARFYAML::LineTable DebugLines;
DataExtractor LineData(DCtx.getLineSection().Data, DCtx.isLittleEndian(),
CU->getAddressByteSize());
uint32_t Offset = *StmtOffset;
uint64_t SizeOfPrologueLength = 4;
DebugLines.TotalLength = LineData.getU32(&Offset);
uint64_t LineTableLength = DebugLines.TotalLength;
if (DebugLines.TotalLength == UINT32_MAX) {
DebugLines.TotalLength64 = LineData.getU64(&Offset);
LineTableLength = DebugLines.TotalLength64;
SizeOfPrologueLength = 8;
}
DebugLines.Version = LineData.getU16(&Offset);
DebugLines.PrologueLength =
LineData.getUnsigned(&Offset, SizeOfPrologueLength);
const uint64_t EndPrologue = DebugLines.PrologueLength + Offset;
DebugLines.MinInstLength = LineData.getU8(&Offset);
if (DebugLines.Version >= 4)
DebugLines.MaxOpsPerInst = LineData.getU8(&Offset);
DebugLines.DefaultIsStmt = LineData.getU8(&Offset);
DebugLines.LineBase = LineData.getU8(&Offset);
DebugLines.LineRange = LineData.getU8(&Offset);
DebugLines.OpcodeBase = LineData.getU8(&Offset);
DebugLines.StandardOpcodeLengths.reserve(DebugLines.OpcodeBase - 1);
for (uint8_t i = 1; i < DebugLines.OpcodeBase; ++i)
DebugLines.StandardOpcodeLengths.push_back(LineData.getU8(&Offset));
while (Offset < EndPrologue) {
StringRef Dir = LineData.getCStr(&Offset);
if (!Dir.empty())
DebugLines.IncludeDirs.push_back(Dir);
else
break;
}
while (Offset < EndPrologue) {
DWARFYAML::File TmpFile;
if (dumpFileEntry(LineData, Offset, TmpFile))
DebugLines.Files.push_back(TmpFile);
else
break;
}
const uint64_t LineEnd =
LineTableLength + *StmtOffset + SizeOfPrologueLength;
while (Offset < LineEnd) {
DWARFYAML::LineTableOpcode NewOp;
NewOp.Opcode = (dwarf::LineNumberOps)LineData.getU8(&Offset);
if (NewOp.Opcode == 0) {
auto StartExt = Offset;
NewOp.ExtLen = LineData.getULEB128(&Offset);
NewOp.SubOpcode =
(dwarf::LineNumberExtendedOps)LineData.getU8(&Offset);
switch (NewOp.SubOpcode) {
case dwarf::DW_LNE_set_address:
case dwarf::DW_LNE_set_discriminator:
NewOp.Data = LineData.getAddress(&Offset);
break;
case dwarf::DW_LNE_define_file:
dumpFileEntry(LineData, Offset, NewOp.FileEntry);
break;
case dwarf::DW_LNE_end_sequence:
break;
default:
while (Offset < StartExt + NewOp.ExtLen)
NewOp.UnknownOpcodeData.push_back(LineData.getU8(&Offset));
}
} else if (NewOp.Opcode < DebugLines.OpcodeBase) {
switch (NewOp.Opcode) {
case dwarf::DW_LNS_copy:
case dwarf::DW_LNS_negate_stmt:
case dwarf::DW_LNS_set_basic_block:
case dwarf::DW_LNS_const_add_pc:
case dwarf::DW_LNS_set_prologue_end:
case dwarf::DW_LNS_set_epilogue_begin:
break;
case dwarf::DW_LNS_advance_pc:
case dwarf::DW_LNS_set_file:
case dwarf::DW_LNS_set_column:
case dwarf::DW_LNS_set_isa:
NewOp.Data = LineData.getULEB128(&Offset);
break;
case dwarf::DW_LNS_advance_line:
NewOp.SData = LineData.getSLEB128(&Offset);
break;
case dwarf::DW_LNS_fixed_advance_pc:
NewOp.Data = LineData.getU16(&Offset);
break;
default:
for (uint8_t i = 0;
i < DebugLines.StandardOpcodeLengths[NewOp.Opcode - 1]; ++i)
NewOp.StandardOpcodeData.push_back(LineData.getULEB128(&Offset));
}
}
DebugLines.Opcodes.push_back(NewOp);
}
Y.DebugLines.push_back(DebugLines);
}
}
}
std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
dumpDebugAbbrev(DCtx, Y);
dumpDebugStrings(DCtx, Y);
dumpDebugARanges(DCtx, Y);
dumpDebugPubSections(DCtx, Y);
dumpDebugInfo(DCtx, Y);
dumpDebugLines(DCtx, Y);
return obj2yaml_error::success;
}

View File

@ -233,3 +233,98 @@ void yaml2debug_info(raw_ostream &OS, const DWARFYAML::Data &DI) {
}
}
}
void yaml2FileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
OS.write(File.Name.data(), File.Name.size());
OS.write('\0');
encodeULEB128(File.DirIdx, OS);
encodeULEB128(File.ModTime, OS);
encodeULEB128(File.Length, OS);
}
void yaml2debug_line(raw_ostream &OS, const DWARFYAML::Data &DI) {
for (const auto LineTable : DI.DebugLines) {
writeInteger((uint32_t)LineTable.TotalLength, OS, DI.IsLittleEndian);
uint64_t SizeOfPrologueLength = 4;
if (LineTable.TotalLength == UINT32_MAX) {
writeInteger((uint64_t)LineTable.TotalLength64, OS, DI.IsLittleEndian);
SizeOfPrologueLength = 8;
}
writeInteger((uint16_t)LineTable.Version, OS, DI.IsLittleEndian);
writeVariableSizedInteger(LineTable.PrologueLength, SizeOfPrologueLength,
OS, DI.IsLittleEndian);
writeInteger((uint8_t)LineTable.MinInstLength, OS, DI.IsLittleEndian);
if (LineTable.Version >= 4)
writeInteger((uint8_t)LineTable.MaxOpsPerInst, OS, DI.IsLittleEndian);
writeInteger((uint8_t)LineTable.DefaultIsStmt, OS, DI.IsLittleEndian);
writeInteger((uint8_t)LineTable.LineBase, OS, DI.IsLittleEndian);
writeInteger((uint8_t)LineTable.LineRange, OS, DI.IsLittleEndian);
writeInteger((uint8_t)LineTable.OpcodeBase, OS, DI.IsLittleEndian);
for (auto OpcodeLength : LineTable.StandardOpcodeLengths)
writeInteger((uint8_t)OpcodeLength, OS, DI.IsLittleEndian);
for (auto IncludeDir : LineTable.IncludeDirs) {
OS.write(IncludeDir.data(), IncludeDir.size());
OS.write('\0');
}
OS.write('\0');
for (auto File : LineTable.Files)
yaml2FileEntry(OS, File);
OS.write('\0');
for (auto Op : LineTable.Opcodes) {
writeInteger((uint8_t)Op.Opcode, OS, DI.IsLittleEndian);
if (Op.Opcode == 0) {
encodeULEB128(Op.ExtLen, OS);
writeInteger((uint8_t)Op.SubOpcode, OS, DI.IsLittleEndian);
switch (Op.SubOpcode) {
case dwarf::DW_LNE_set_address:
case dwarf::DW_LNE_set_discriminator:
writeVariableSizedInteger(Op.Data, DI.CompileUnits[0].AddrSize, OS,
DI.IsLittleEndian);
break;
case dwarf::DW_LNE_define_file:
yaml2FileEntry(OS, Op.FileEntry);
break;
case dwarf::DW_LNE_end_sequence:
break;
default:
for (auto OpByte : Op.UnknownOpcodeData)
writeInteger((uint8_t)OpByte, OS, DI.IsLittleEndian);
}
} else if (Op.Opcode < LineTable.OpcodeBase) {
switch (Op.Opcode) {
case dwarf::DW_LNS_copy:
case dwarf::DW_LNS_negate_stmt:
case dwarf::DW_LNS_set_basic_block:
case dwarf::DW_LNS_const_add_pc:
case dwarf::DW_LNS_set_prologue_end:
case dwarf::DW_LNS_set_epilogue_begin:
break;
case dwarf::DW_LNS_advance_pc:
case dwarf::DW_LNS_set_file:
case dwarf::DW_LNS_set_column:
case dwarf::DW_LNS_set_isa:
encodeULEB128(Op.Data, OS);
break;
case dwarf::DW_LNS_advance_line:
encodeSLEB128(Op.SData, OS);
break;
case dwarf::DW_LNS_fixed_advance_pc:
writeInteger((uint16_t)Op.Data, OS, DI.IsLittleEndian);
break;
default:
for (auto OpData : Op.StandardOpcodeData) {
encodeULEB128(OpData, OS);
}
}
}
}
}
}

View File

@ -280,6 +280,8 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) {
yaml2pubsection(OS, Obj.DWARF.PubTypes, Obj.IsLittleEndian);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) {
yaml2debug_info(OS, Obj.DWARF);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_line", 16)) {
yaml2debug_line(OS, Obj.DWARF);
}
} else {
// Fills section data with 0xDEADBEEF

View File

@ -46,5 +46,6 @@ void yaml2pubsection(llvm::raw_ostream &OS,
const llvm::DWARFYAML::PubSection &Sect,
bool IsLittleEndian);
void yaml2debug_info(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
void yaml2debug_line(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
#endif