summaryrefslogtreecommitdiffstats
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/obj2yaml/dwarf2yaml.cpp117
-rw-r--r--llvm/tools/yaml2obj/yaml2dwarf.cpp130
-rw-r--r--llvm/tools/yaml2obj/yaml2macho.cpp2
-rw-r--r--llvm/tools/yaml2obj/yaml2obj.h1
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
OpenPOWER on IntegriCloud