This patch adds support for YAML<->DWARF for debug_info sections.
This re-lands r290147, reverted in 290148, re-landed in r290204 after fixing the issue that caused bots to fail (thank you UBSan!), and reverted again in r290209 due to failures on big endian systems.
After adding support for preserving endianness, this should be good now.
llvm-svn: 290386
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
#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"
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;
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(); }
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 {
bool IsLittleEndian;
std::vector<Abbrev> AbbrevDecls;
PubSection GNUPubNames;
PubSection GNUPubTypes;
+
+ std::vector<Unit> CompileUnits;
bool isEmpty() const;
};
} // 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 {
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);
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)
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;
+}
+
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())
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);
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
--- /dev/null
+# 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:
#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) {
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;
}
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SwapByteOrder.h"
+#include <algorithm>
+
using namespace llvm;
template <typename T>
OS.write(Entry.Name.data(), Entry.Name.size());
OS.write('\0');
}
-}
\ No newline at end of file
+}
+
+void yaml2debug_info(raw_ostream &OS, const DWARFYAML::Data &DI) {
+
+ for (auto CU : DI.CompileUnits) {
+ writeInteger((uint32_t)CU.Length, OS, DI.IsLittleEndian);
+ writeInteger((uint16_t)CU.Version, OS, DI.IsLittleEndian);
+ writeInteger((uint32_t)CU.AbbrOffset, OS, DI.IsLittleEndian);
+ writeInteger((uint8_t)CU.AddrSize, OS, DI.IsLittleEndian);
+
+ 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:
+ writeVariableSizedInteger(FormVal->Value, CU.AddrSize, OS,
+ DI.IsLittleEndian);
+ 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;
+ writeVariableSizedInteger(FormVal->Value, writeSize, OS,
+ DI.IsLittleEndian);
+ 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();
+ writeInteger((uint8_t)writeSize, OS, DI.IsLittleEndian);
+ OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
+ FormVal->BlockData.size());
+ break;
+ }
+ case dwarf::DW_FORM_block2: {
+ auto writeSize = FormVal->BlockData.size();
+ writeInteger((uint16_t)writeSize, OS, DI.IsLittleEndian);
+ OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
+ FormVal->BlockData.size());
+ break;
+ }
+ case dwarf::DW_FORM_block4: {
+ auto writeSize = FormVal->BlockData.size();
+ writeInteger((uint32_t)writeSize, OS, DI.IsLittleEndian);
+ 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:
+ writeInteger((uint8_t)FormVal->Value, OS, DI.IsLittleEndian);
+ break;
+ case dwarf::DW_FORM_data2:
+ case dwarf::DW_FORM_ref2:
+ writeInteger((uint16_t)FormVal->Value, OS, DI.IsLittleEndian);
+ break;
+ case dwarf::DW_FORM_data4:
+ case dwarf::DW_FORM_ref4:
+ writeInteger((uint32_t)FormVal->Value, OS, DI.IsLittleEndian);
+ break;
+ case dwarf::DW_FORM_data8:
+ case dwarf::DW_FORM_ref8:
+ writeInteger((uint64_t)FormVal->Value, OS, DI.IsLittleEndian);
+ 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
+ writeInteger((uint32_t)FormVal->Value, OS, DI.IsLittleEndian);
+ break;
+ case dwarf::DW_FORM_ref_sig8:
+ writeInteger((uint64_t)FormVal->Value, OS, DI.IsLittleEndian);
+ break;
+ case dwarf::DW_FORM_GNU_addr_index:
+ case dwarf::DW_FORM_GNU_str_index:
+ encodeULEB128(FormVal->Value, OS);
+ break;
+ default:
+ break;
+ }
+ } while (Indirect);
+ }
+ }
+ }
+}
yaml2pubsection(OS, Obj.DWARF.PubNames, Obj.IsLittleEndian);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) {
yaml2pubsection(OS, Obj.DWARF.PubTypes, Obj.IsLittleEndian);
+ } else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) {
+ yaml2debug_info(OS, Obj.DWARF);
}
} else {
// Fills section data with 0xDEADBEEF
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);
#endif