diff options
Diffstat (limited to 'llvm/tools')
| -rw-r--r-- | llvm/tools/obj2yaml/dwarf2yaml.cpp | 117 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2dwarf.cpp | 130 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2macho.cpp | 2 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2obj.h | 1 |
4 files changed, 246 insertions, 4 deletions
diff --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp index 0fd646e23b9..cf8b3e5b927 100644 --- a/llvm/tools/obj2yaml/dwarf2yaml.cpp +++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp @@ -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; } diff --git a/llvm/tools/yaml2obj/yaml2dwarf.cpp b/llvm/tools/yaml2obj/yaml2dwarf.cpp index 525c44ce7ab..283b0df0f62 100644 --- a/llvm/tools/yaml2obj/yaml2dwarf.cpp +++ b/llvm/tools/yaml2obj/yaml2dwarf.cpp @@ -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'); } -}
\ 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); + } + } + } +} diff --git a/llvm/tools/yaml2obj/yaml2macho.cpp b/llvm/tools/yaml2obj/yaml2macho.cpp index 13414502c03..a41ec55d73b 100644 --- a/llvm/tools/yaml2obj/yaml2macho.cpp +++ b/llvm/tools/yaml2obj/yaml2macho.cpp @@ -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 diff --git a/llvm/tools/yaml2obj/yaml2obj.h b/llvm/tools/yaml2obj/yaml2obj.h index 756fe496196..7cad4ca8675 100644 --- a/llvm/tools/yaml2obj/yaml2obj.h +++ b/llvm/tools/yaml2obj/yaml2obj.h @@ -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 |

