[ObjectYAML] Support for DWARF debug_info section

This patch adds support for YAML<->DWARF for debug_info sections.

This re-lands r290147, after fixing the issue that caused bots to fail (thank you UBSan!).

llvm-svn: 290204
This commit is contained in:
Chris Bieneman 2016-12-20 21:35:31 +00:00
parent 151c456858
commit ffc4aef542
11 changed files with 857 additions and 8 deletions

View File

@ -82,6 +82,8 @@ public:
Optional<uint64_t> getAsAddress() const;
Optional<uint64_t> getAsSectionOffset() const;
Optional<ArrayRef<uint8_t>> getAsBlock() const;
Optional<uint64_t> getAsCStringOffset() const;
Optional<uint64_t> getAsReferenceUVal() const;
/// Get the fixed byte size for a given form.
///
/// If the form always has a fixed valid byte size that doesn't depend on a

View File

@ -11,6 +11,7 @@
#define LLVM_LIB_DEBUGINFO_DWARFUNIT_H
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
@ -127,6 +128,8 @@ class DWARFUnit {
uint64_t BaseAddr;
// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntry> DieArray;
typedef iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>
die_iterator_range;
class DWOHolder {
object::OwningBinary<object::ObjectFile> DWOFile;
@ -288,6 +291,11 @@ public:
return 0;
}
die_iterator_range dies() {
extractDIEsIfNeeded(false);
return die_iterator_range(DieArray.begin(), DieArray.end());
}
private:
/// Size in bytes of the .debug_info data associated with this compile unit.
size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }

View File

@ -66,6 +66,25 @@ struct PubSection {
std::vector<PubEntry> Entries;
};
struct FormValue {
llvm::yaml::Hex64 Value;
StringRef CStr;
std::vector<llvm::yaml::Hex8> BlockData;
};
struct Entry {
llvm::yaml::Hex32 AbbrCode;
std::vector<FormValue> Values;
};
struct Unit {
uint32_t Length;
uint16_t Version;
uint32_t AbbrOffset;
uint8_t AddrSize;
std::vector<Entry> Entries;
};
struct Data {
std::vector<Abbrev> AbbrevDecls;
std::vector<StringRef> DebugStrings;
@ -75,6 +94,8 @@ struct Data {
PubSection GNUPubNames;
PubSection GNUPubTypes;
std::vector<Unit> CompileUnits;
bool isEmpty() const;
};
@ -82,12 +103,17 @@ struct Data {
} // namespace llvm::DWARFYAML
} // namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
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)
namespace llvm {
namespace yaml {
@ -120,6 +146,18 @@ template <> struct MappingTraits<DWARFYAML::PubSection> {
static void mapping(IO &IO, DWARFYAML::PubSection &Section);
};
template <> struct MappingTraits<DWARFYAML::Unit> {
static void mapping(IO &IO, DWARFYAML::Unit &Unit);
};
template <> struct MappingTraits<DWARFYAML::Entry> {
static void mapping(IO &IO, DWARFYAML::Entry &Entry);
};
template <> struct MappingTraits<DWARFYAML::FormValue> {
static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
};
#define HANDLE_DW_TAG(unused, name) \
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);

View File

@ -138,7 +138,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::Hex8)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)

View File

@ -661,3 +661,15 @@ Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
return makeArrayRef(Value.data, Value.uval);
}
Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
if (!isFormClass(FC_String) && Form == DW_FORM_string)
return None;
return Value.uval;
}
Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
if (!isFormClass(FC_Reference))
return None;
return Value.uval;
}

View File

@ -22,8 +22,9 @@ bool DWARFYAML::Data::isEmpty() const {
namespace yaml {
void MappingTraits<DWARFYAML::Data>::mapping(
IO &IO, DWARFYAML::Data &DWARF) {
void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
auto oldContext = IO.getContext();
IO.setContext(&DWARF);
IO.mapOptional("debug_str", DWARF.DebugStrings);
IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
if(!DWARF.ARanges.empty() || !IO.outputting())
@ -36,10 +37,12 @@ void MappingTraits<DWARFYAML::Data>::mapping(
IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);
if(!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);
IO.mapOptional("debug_info", DWARF.CompileUnits);
IO.setContext(&oldContext);
}
void MappingTraits<DWARFYAML::Abbrev>::mapping(
IO &IO, DWARFYAML::Abbrev &Abbrev) {
void MappingTraits<DWARFYAML::Abbrev>::mapping(IO &IO,
DWARFYAML::Abbrev &Abbrev) {
IO.mapRequired("Code", Abbrev.Code);
IO.mapRequired("Tag", Abbrev.Tag);
IO.mapRequired("Children", Abbrev.Children);
@ -90,6 +93,28 @@ void MappingTraits<DWARFYAML::PubSection>::mapping(
IO.setContext(OldContext);
}
void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {
IO.mapRequired("Length", Unit.Length);
IO.mapRequired("Version", Unit.Version);
IO.mapRequired("AbbrOffset", Unit.AbbrOffset);
IO.mapRequired("AddrSize", Unit.AddrSize);
IO.mapOptional("Entries", Unit.Entries);
}
void MappingTraits<DWARFYAML::Entry>::mapping(IO &IO, DWARFYAML::Entry &Entry) {
IO.mapRequired("AbbrCode", Entry.AbbrCode);
IO.mapRequired("Values", Entry.Values);
}
void MappingTraits<DWARFYAML::FormValue>::mapping(IO &IO,
DWARFYAML::FormValue &FormValue) {
IO.mapOptional("Value", FormValue.Value);
if(!FormValue.CStr.empty() || !IO.outputting())
IO.mapOptional("CStr", FormValue.CStr);
if(!FormValue.BlockData.empty() || !IO.outputting())
IO.mapOptional("BlockData", FormValue.BlockData);
}
} // namespace llvm::yaml
} // namespace llvm

View File

@ -0,0 +1,525 @@
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x01000007
cpusubtype: 0x00000003
filetype: 0x0000000A
ncmds: 5
sizeofcmds: 1800
flags: 0x00000000
reserved: 0x00000000
LoadCommands:
- 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_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_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:
...
#CHECK: DWARF:
#CHECK: debug_info:
#CHECK: - Length: 117
#CHECK: Version: 4
#CHECK: AbbrOffset: 0
#CHECK: AddrSize: 8
#CHECK: Entries:
#CHECK: - AbbrCode: 0x00000001
#CHECK: Values:
#CHECK: - Value: 0x0000000000000001
#CHECK: - Value: 0x000000000000000C
#CHECK: - Value: 0x0000000000000038
#CHECK: - Value: 0x0000000000000000
#CHECK: - Value: 0x0000000000000046
#CHECK: - Value: 0x0000000100000F50
#CHECK: - Value: 0x0000000000000034
#CHECK: - AbbrCode: 0x00000002
#CHECK: Values:
#CHECK: - Value: 0x0000000100000F50
#CHECK: - Value: 0x0000000000000034
#CHECK: - Value: 0x0000000000000001
#CHECK: BlockData:
#CHECK: - 0x56
#CHECK: - Value: 0x0000000000000076
#CHECK: - Value: 0x0000000000000001
#CHECK: - Value: 0x0000000000000003
#CHECK: - Value: 0x0000000000000001
#CHECK: - Value: 0x0000000000000060
#CHECK: - Value: 0x0000000000000001
#CHECK: - AbbrCode: 0x00000003
#CHECK: Values:
#CHECK: - Value: 0x0000000000000002
#CHECK: BlockData:
#CHECK: - 0x91
#CHECK: - 0x78
#CHECK: - Value: 0x000000000000007B
#CHECK: - Value: 0x0000000000000001
#CHECK: - Value: 0x0000000000000003
#CHECK: - Value: 0x0000000000000060
#CHECK: - AbbrCode: 0x00000003
#CHECK: Values:
#CHECK: - Value: 0x0000000000000002
#CHECK: BlockData:
#CHECK: - 0x91
#CHECK: - 0x70
#CHECK: - Value: 0x0000000000000080
#CHECK: - Value: 0x0000000000000001
#CHECK: - Value: 0x0000000000000003
#CHECK: - Value: 0x0000000000000067
#CHECK: - AbbrCode: 0x00000000
#CHECK: Values:
#CHECK: - AbbrCode: 0x00000004
#CHECK: Values:
#CHECK: - Value: 0x0000000000000085
#CHECK: - Value: 0x0000000000000005
#CHECK: - Value: 0x0000000000000004
#CHECK: - AbbrCode: 0x00000005
#CHECK: Values:
#CHECK: - Value: 0x000000000000006C
#CHECK: - AbbrCode: 0x00000005
#CHECK: Values:
#CHECK: - Value: 0x0000000000000071
#CHECK: - AbbrCode: 0x00000004
#CHECK: Values:
#CHECK: - Value: 0x0000000000000089
#CHECK: - Value: 0x0000000000000006
#CHECK: - Value: 0x0000000000000001
#CHECK: - AbbrCode: 0x00000000
#CHECK: Values:

View File

@ -10,8 +10,11 @@
#include "Error.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/ObjectYAML/DWARFYAML.h"
#include <algorithm>
using namespace llvm;
void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
@ -99,12 +102,120 @@ void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection());
}
std::error_code dwarf2yaml(DWARFContextInMemory &DCtx,
DWARFYAML::Data &Y) {
void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
for (const auto &CU : DCtx.compile_units()) {
DWARFYAML::Unit NewUnit;
NewUnit.Length = CU->getLength();
NewUnit.Version = CU->getVersion();
NewUnit.AbbrOffset = CU->getAbbreviations()->getOffset();
NewUnit.AddrSize = CU->getAddressByteSize();
for (auto DIE : CU->dies()) {
DWARFYAML::Entry NewEntry;
DataExtractor EntryData = CU->getDebugInfoExtractor();
uint32_t offset = DIE.getOffset();
assert(EntryData.isValidOffset(offset) && "Invalid DIE Offset");
if (!EntryData.isValidOffset(offset))
continue;
NewEntry.AbbrCode = EntryData.getULEB128(&offset);
auto AbbrevDecl = DIE.getAbbreviationDeclarationPtr();
if (AbbrevDecl) {
for (const auto &AttrSpec : AbbrevDecl->attributes()) {
DWARFYAML::FormValue NewValue;
NewValue.Value = 0xDEADBEEFDEADBEEF;
DWARFDie DIEWrapper(CU.get(), &DIE);
auto FormValue = DIEWrapper.getAttributeValue(AttrSpec.Attr);
if(!FormValue)
return;
auto Form = FormValue.getValue().getForm();
bool indirect = false;
do {
indirect = false;
switch (Form) {
case dwarf::DW_FORM_addr:
case dwarf::DW_FORM_GNU_addr_index:
if (auto Val = FormValue.getValue().getAsAddress())
NewValue.Value = Val.getValue();
break;
case dwarf::DW_FORM_ref_addr:
case dwarf::DW_FORM_ref1:
case dwarf::DW_FORM_ref2:
case dwarf::DW_FORM_ref4:
case dwarf::DW_FORM_ref8:
case dwarf::DW_FORM_ref_udata:
case dwarf::DW_FORM_ref_sig8:
if (auto Val = FormValue.getValue().getAsReferenceUVal())
NewValue.Value = Val.getValue();
break;
case dwarf::DW_FORM_exprloc:
case dwarf::DW_FORM_block:
case dwarf::DW_FORM_block1:
case dwarf::DW_FORM_block2:
case dwarf::DW_FORM_block4:
if (auto Val = FormValue.getValue().getAsBlock()) {
auto BlockData = Val.getValue();
std::copy(BlockData.begin(), BlockData.end(),
std::back_inserter(NewValue.BlockData));
}
NewValue.Value = NewValue.BlockData.size();
break;
case dwarf::DW_FORM_data1:
case dwarf::DW_FORM_flag:
case dwarf::DW_FORM_data2:
case dwarf::DW_FORM_data4:
case dwarf::DW_FORM_data8:
case dwarf::DW_FORM_sdata:
case dwarf::DW_FORM_udata:
if (auto Val = FormValue.getValue().getAsUnsignedConstant())
NewValue.Value = Val.getValue();
break;
case dwarf::DW_FORM_string:
if (auto Val = FormValue.getValue().getAsCString())
NewValue.CStr = Val.getValue();
break;
case dwarf::DW_FORM_indirect:
indirect = true;
if (auto Val = FormValue.getValue().getAsUnsignedConstant()) {
NewValue.Value = Val.getValue();
NewEntry.Values.push_back(NewValue);
Form = static_cast<dwarf::Form>(Val.getValue());
}
break;
case dwarf::DW_FORM_strp:
case dwarf::DW_FORM_sec_offset:
case dwarf::DW_FORM_GNU_ref_alt:
case dwarf::DW_FORM_GNU_strp_alt:
case dwarf::DW_FORM_line_strp:
case dwarf::DW_FORM_strp_sup:
case dwarf::DW_FORM_ref_sup:
case dwarf::DW_FORM_GNU_str_index:
if (auto Val = FormValue.getValue().getAsCStringOffset())
NewValue.Value = Val.getValue();
break;
case dwarf::DW_FORM_flag_present:
NewValue.Value = 1;
break;
default:
break;
}
} while (indirect);
NewEntry.Values.push_back(NewValue);
}
}
NewUnit.Entries.push_back(NewEntry);
}
Y.CompileUnits.push_back(NewUnit);
}
}
std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
dumpDebugAbbrev(DCtx, Y);
dumpDebugStrings(DCtx, Y);
dumpDebugARanges(DCtx, Y);
dumpDebugPubSections(DCtx, Y);
dumpDebugInfo(DCtx, Y);
return obj2yaml_error::success;
}

View File

@ -17,6 +17,8 @@
#include "llvm/Support/LEB128.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
void ZeroFillBytes(raw_ostream &OS, size_t Size) {
@ -80,3 +82,127 @@ void yaml2pubsection(raw_ostream &OS, const DWARFYAML::PubSection &Sect) {
OS.write('\0');
}
}
void yaml2debug_info(raw_ostream &OS, const DWARFYAML::Data &DI) {
for (auto CU : DI.CompileUnits) {
OS.write(reinterpret_cast<char *>(&CU.Length), 4);
OS.write(reinterpret_cast<char *>(&CU.Version), 2);
OS.write(reinterpret_cast<char *>(&CU.AbbrOffset), 4);
OS.write(reinterpret_cast<char *>(&CU.AddrSize), 1);
auto FirstAbbrevCode = CU.Entries[0].AbbrCode;
for (auto Entry : CU.Entries) {
encodeULEB128(Entry.AbbrCode, OS);
if(Entry.AbbrCode == 0u)
continue;
bool Indirect = false;
assert(Entry.AbbrCode-FirstAbbrevCode < DI.AbbrevDecls.size() &&
"Out of range AbbCode");
auto &Abbrev = DI.AbbrevDecls[Entry.AbbrCode-FirstAbbrevCode];
auto FormVal = Entry.Values.begin();
auto AbbrForm = Abbrev.Attributes.begin();
for (;
FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
++FormVal, ++AbbrForm) {
dwarf::Form Form = AbbrForm->Form;
do {
bool Indirect = false;
switch (Form) {
case dwarf::DW_FORM_addr:
OS.write(reinterpret_cast<char *>(&FormVal->Value), CU.AddrSize);
break;
case dwarf::DW_FORM_ref_addr: {
// TODO: Handle DWARF32/DWARF64 after Line Table data is done
auto writeSize = CU.Version == 2 ? CU.AddrSize : 4;
OS.write(reinterpret_cast<char *>(&FormVal->Value), writeSize);
break;
}
case dwarf::DW_FORM_exprloc:
case dwarf::DW_FORM_block:
encodeULEB128(FormVal->BlockData.size(), OS);
OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
FormVal->BlockData.size());
break;
case dwarf::DW_FORM_block1: {
auto writeSize = FormVal->BlockData.size();
OS.write(reinterpret_cast<char *>(&writeSize), 1);
OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
FormVal->BlockData.size());
break;
}
case dwarf::DW_FORM_block2: {
auto writeSize = FormVal->BlockData.size();
OS.write(reinterpret_cast<char *>(&writeSize), 2);
OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
FormVal->BlockData.size());
break;
}
case dwarf::DW_FORM_block4: {
auto writeSize = FormVal->BlockData.size();
OS.write(reinterpret_cast<char *>(&writeSize), 4);
OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
FormVal->BlockData.size());
break;
}
case dwarf::DW_FORM_data1:
case dwarf::DW_FORM_ref1:
case dwarf::DW_FORM_flag:
OS.write(reinterpret_cast<char *>(&FormVal->Value), 1);
break;
case dwarf::DW_FORM_data2:
case dwarf::DW_FORM_ref2:
OS.write(reinterpret_cast<char *>(&FormVal->Value), 2);
break;
case dwarf::DW_FORM_data4:
case dwarf::DW_FORM_ref4:
OS.write(reinterpret_cast<char *>(&FormVal->Value), 4);
break;
case dwarf::DW_FORM_data8:
case dwarf::DW_FORM_ref8:
OS.write(reinterpret_cast<char *>(&FormVal->Value), 8);
break;
case dwarf::DW_FORM_sdata:
encodeSLEB128(FormVal->Value, OS);
break;
case dwarf::DW_FORM_udata:
case dwarf::DW_FORM_ref_udata:
encodeULEB128(FormVal->Value, OS);
break;
case dwarf::DW_FORM_string:
OS.write(FormVal->CStr.data(), FormVal->CStr.size());
OS.write('\0');
break;
case dwarf::DW_FORM_indirect:
encodeULEB128(FormVal->Value, OS);
Indirect = true;
Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
++FormVal;
break;
case dwarf::DW_FORM_strp:
case dwarf::DW_FORM_sec_offset:
case dwarf::DW_FORM_GNU_ref_alt:
case dwarf::DW_FORM_GNU_strp_alt:
case dwarf::DW_FORM_line_strp:
case dwarf::DW_FORM_strp_sup:
case dwarf::DW_FORM_ref_sup:
// TODO: Handle DWARF32/64
OS.write(reinterpret_cast<char *>(&FormVal->Value), 4);
break;
case dwarf::DW_FORM_ref_sig8:
OS.write(reinterpret_cast<char *>(&FormVal->Value), 8);
break;
case dwarf::DW_FORM_GNU_addr_index:
case dwarf::DW_FORM_GNU_str_index:
encodeULEB128(FormVal->Value, OS);
break;
default:
break;
}
} while (Indirect);
}
}
}
}

View File

@ -398,6 +398,8 @@ Error MachOWriter::writeDWARFData(raw_ostream &OS,
yaml2pubsection(OS, Obj.DWARF.PubNames);
} else if (0 == strncmp(&Section.sectname[0], "__debug_pubtypes", 16)) {
yaml2pubsection(OS, Obj.DWARF.PubTypes);
} else if (0 == strncmp(&Section.sectname[0], "__debug_info", 16)) {
yaml2debug_info(OS, Obj.DWARF);
}
}
return Error::success();

View File

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