mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-26 04:34:41 +00:00
[ObjectYAML] Support for DWARF debug_info section
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290386 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
869904bdc2
commit
7d466455bd
@ -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
|
||||
|
@ -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;
|
||||
@ -293,6 +296,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(); }
|
||||
|
@ -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 {
|
||||
bool IsLittleEndian;
|
||||
std::vector<Abbrev> AbbrevDecls;
|
||||
@ -76,6 +95,8 @@ struct Data {
|
||||
|
||||
PubSection GNUPubNames;
|
||||
PubSection GNUPubTypes;
|
||||
|
||||
std::vector<Unit> CompileUnits;
|
||||
|
||||
bool isEmpty() const;
|
||||
};
|
||||
@ -83,12 +104,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 {
|
||||
@ -121,6 +147,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);
|
||||
|
||||
|
@ -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::Hex8)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
525
test/ObjectYAML/MachO/DWARF-debug_info.yaml
Normal file
525
test/ObjectYAML/MachO/DWARF-debug_info.yaml
Normal 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:
|
@ -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;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/SwapByteOrder.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
template <typename T>
|
||||
@ -104,4 +106,130 @@ void yaml2pubsection(raw_ostream &OS, const DWARFYAML::PubSection &Sect,
|
||||
OS.write(Entry.Name.data(), Entry.Name.size());
|
||||
OS.write('\0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,6 +278,8 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) {
|
||||
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
|
||||
|
@ -45,5 +45,6 @@ void yaml2debug_aranges(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user