summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ObjectYAML/DWARFVisitor.cpp
diff options
context:
space:
mode:
authorChris Bieneman <beanz@apple.com>2017-03-06 20:52:12 +0000
committerChris Bieneman <beanz@apple.com>2017-03-06 20:52:12 +0000
commit8f471f72d1ac97babdd8bb8addff9cc73b8b7313 (patch)
tree013d2e75bce9ea8209df15021bd1a88ad322acca /llvm/lib/ObjectYAML/DWARFVisitor.cpp
parent23e323f284f5176303120198db6ae0530d724e99 (diff)
downloadbcm5719-llvm-8f471f72d1ac97babdd8bb8addff9cc73b8b7313.tar.gz
bcm5719-llvm-8f471f72d1ac97babdd8bb8addff9cc73b8b7313.zip
[ObjectYAML] NFC. Refactor DWARFYAML CompileUnit dump code
Summary: This patch refactors the DWARFYAML code for dumping compile units to use a visitor pattern. Using this design will, in the future, enable the DWARF YAML code to perform analysis and mutations of the DWARF DIEs. An example of such mutations would be calculating the length of a compile unit and updating the CU's Length field before writing the DIE. This support will make it easier to craft or modify DWARF tests by hand. Reviewers: lhames Subscribers: mgorny, fhahn, jgosnell, aprantl, llvm-commits Differential Revision: https://reviews.llvm.org/D30357 llvm-svn: 297067
Diffstat (limited to 'llvm/lib/ObjectYAML/DWARFVisitor.cpp')
-rw-r--r--llvm/lib/ObjectYAML/DWARFVisitor.cpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/llvm/lib/ObjectYAML/DWARFVisitor.cpp b/llvm/lib/ObjectYAML/DWARFVisitor.cpp
new file mode 100644
index 00000000000..8135b8bd651
--- /dev/null
+++ b/llvm/lib/ObjectYAML/DWARFVisitor.cpp
@@ -0,0 +1,167 @@
+//===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFVisitor.h"
+#include "llvm/ObjectYAML/DWARFYAML.h"
+
+using namespace llvm;
+
+template <typename T>
+void DWARFYAML::VisitorImpl<T>::onVariableSizeValue(uint64_t U, unsigned Size) {
+ switch (Size) {
+ case 8:
+ onValue((uint64_t)U);
+ break;
+ case 4:
+ onValue((uint32_t)U);
+ break;
+ case 2:
+ onValue((uint16_t)U);
+ break;
+ case 1:
+ onValue((uint8_t)U);
+ break;
+ default:
+ llvm_unreachable("Invalid integer write size.");
+ }
+}
+
+unsigned getRefSize(const DWARFYAML::Unit &Unit) {
+ if (Unit.Version == 2)
+ return Unit.AddrSize;
+ return Unit.Length.isDWARF64() ? 8 : 4;
+}
+
+template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() {
+ for (auto &Unit : DebugInfo.CompileUnits) {
+ onStartCompileUnit(Unit);
+ auto FirstAbbrevCode = Unit.Entries[0].AbbrCode;
+
+ for (auto &Entry : Unit.Entries) {
+ onStartDIE(Unit, Entry);
+ if (Entry.AbbrCode == 0u)
+ continue;
+ auto &Abbrev = DebugInfo.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) {
+ onForm(*AbbrForm, *FormVal);
+ dwarf::Form Form = AbbrForm->Form;
+ bool Indirect;
+ do {
+ Indirect = false;
+ switch (Form) {
+ case dwarf::DW_FORM_addr:
+ onVariableSizeValue(FormVal->Value, Unit.AddrSize);
+ break;
+ case dwarf::DW_FORM_ref_addr:
+ onVariableSizeValue(FormVal->Value, getRefSize(Unit));
+ break;
+ case dwarf::DW_FORM_exprloc:
+ case dwarf::DW_FORM_block:
+ onValue((uint64_t)FormVal->BlockData.size(), true);
+ onValue(
+ MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
+ FormVal->BlockData.size()),
+ ""));
+ break;
+ case dwarf::DW_FORM_block1: {
+ auto writeSize = FormVal->BlockData.size();
+ onValue((uint8_t)writeSize);
+ onValue(
+ MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
+ FormVal->BlockData.size()),
+ ""));
+ break;
+ }
+ case dwarf::DW_FORM_block2: {
+ auto writeSize = FormVal->BlockData.size();
+ onValue((uint16_t)writeSize);
+ onValue(
+ MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
+ FormVal->BlockData.size()),
+ ""));
+ break;
+ }
+ case dwarf::DW_FORM_block4: {
+ auto writeSize = FormVal->BlockData.size();
+ onValue((uint32_t)writeSize);
+ onValue(
+ MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
+ FormVal->BlockData.size()),
+ ""));
+ break;
+ }
+ case dwarf::DW_FORM_data1:
+ case dwarf::DW_FORM_ref1:
+ case dwarf::DW_FORM_flag:
+ onValue((uint8_t)FormVal->Value);
+ break;
+ case dwarf::DW_FORM_data2:
+ case dwarf::DW_FORM_ref2:
+ onValue((uint16_t)FormVal->Value);
+ break;
+ case dwarf::DW_FORM_data4:
+ case dwarf::DW_FORM_ref4:
+ onValue((uint32_t)FormVal->Value);
+ break;
+ case dwarf::DW_FORM_data8:
+ case dwarf::DW_FORM_ref8:
+ onValue((uint64_t)FormVal->Value);
+ break;
+ case dwarf::DW_FORM_sdata:
+ onValue((int64_t)FormVal->Value, true);
+ break;
+ case dwarf::DW_FORM_udata:
+ case dwarf::DW_FORM_ref_udata:
+ onValue((uint64_t)FormVal->Value, true);
+ break;
+ case dwarf::DW_FORM_string:
+ onValue(FormVal->CStr);
+ break;
+ case dwarf::DW_FORM_indirect:
+ onValue((uint64_t)FormVal->Value, true);
+ 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:
+ onVariableSizeValue(FormVal->Value, getRefSize(Unit));
+ break;
+ case dwarf::DW_FORM_ref_sig8:
+ onValue((uint64_t)FormVal->Value);
+ break;
+ case dwarf::DW_FORM_GNU_addr_index:
+ case dwarf::DW_FORM_GNU_str_index:
+ onValue((uint64_t)FormVal->Value, true);
+ break;
+ default:
+ break;
+ }
+ } while (Indirect);
+ }
+ onEndDIE(Unit, Entry);
+ }
+ onEndCompileUnit(Unit);
+ }
+}
+
+// Explicitly instantiate the two template expansions.
+template class DWARFYAML::VisitorImpl<DWARFYAML::Data>;
+template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>;
OpenPOWER on IntegriCloud