From 8f471f72d1ac97babdd8bb8addff9cc73b8b7313 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Mon, 6 Mar 2017 20:52:12 +0000 Subject: [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 --- llvm/lib/ObjectYAML/DWARFVisitor.cpp | 167 +++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 llvm/lib/ObjectYAML/DWARFVisitor.cpp (limited to 'llvm/lib/ObjectYAML/DWARFVisitor.cpp') 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 +void DWARFYAML::VisitorImpl::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 void DWARFYAML::VisitorImpl::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((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; +template class DWARFYAML::VisitorImpl; -- cgit v1.2.3