summaryrefslogtreecommitdiffstats
path: root/llvm/tools/obj2yaml/dwarf2yaml.cpp
diff options
context:
space:
mode:
authorChris Bieneman <beanz@apple.com>2016-12-22 22:44:27 +0000
committerChris Bieneman <beanz@apple.com>2016-12-22 22:44:27 +0000
commite0e451d9278e12f5d6411565e0cb17b9c57362ce (patch)
treee231a8ec569f4d5451911996e3fc082a614ee733 /llvm/tools/obj2yaml/dwarf2yaml.cpp
parent1277833aa63056342f458d4b2f5fa549fb241749 (diff)
downloadbcm5719-llvm-e0e451d9278e12f5d6411565e0cb17b9c57362ce.tar.gz
bcm5719-llvm-e0e451d9278e12f5d6411565e0cb17b9c57362ce.zip
[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. llvm-svn: 290386
Diffstat (limited to 'llvm/tools/obj2yaml/dwarf2yaml.cpp')
-rw-r--r--llvm/tools/obj2yaml/dwarf2yaml.cpp117
1 files changed, 114 insertions, 3 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;
}
OpenPOWER on IntegriCloud