aboutsummaryrefslogtreecommitdiff
path: root/lib/ObjectYAML/DWARFVisitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ObjectYAML/DWARFVisitor.cpp')
-rw-r--r--lib/ObjectYAML/DWARFVisitor.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/lib/ObjectYAML/DWARFVisitor.cpp b/lib/ObjectYAML/DWARFVisitor.cpp
new file mode 100644
index 000000000000..36a9f7638bd4
--- /dev/null
+++ b/lib/ObjectYAML/DWARFVisitor.cpp
@@ -0,0 +1,178 @@
+//===--- 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 getOffsetSize(const DWARFYAML::Unit &Unit) {
+ return Unit.Length.isDWARF64() ? 8 : 4;
+}
+
+unsigned getRefSize(const DWARFYAML::Unit &Unit) {
+ if (Unit.Version == 2)
+ return Unit.AddrSize;
+ return getOffsetSize(Unit);
+}
+
+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:
+ case dwarf::DW_FORM_strx1:
+ case dwarf::DW_FORM_addrx1:
+ onValue((uint8_t)FormVal->Value);
+ break;
+ case dwarf::DW_FORM_data2:
+ case dwarf::DW_FORM_ref2:
+ case dwarf::DW_FORM_strx2:
+ case dwarf::DW_FORM_addrx2:
+ onValue((uint16_t)FormVal->Value);
+ break;
+ case dwarf::DW_FORM_data4:
+ case dwarf::DW_FORM_ref4:
+ case dwarf::DW_FORM_ref_sup4:
+ case dwarf::DW_FORM_strx4:
+ case dwarf::DW_FORM_addrx4:
+ onValue((uint32_t)FormVal->Value);
+ break;
+ case dwarf::DW_FORM_data8:
+ case dwarf::DW_FORM_ref8:
+ case dwarf::DW_FORM_ref_sup8:
+ 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:
+ onVariableSizeValue(FormVal->Value, getOffsetSize(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>;