1//===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9//===----------------------------------------------------------------------===// 10 11#include "DWARFVisitor.h" 12#include "llvm/ObjectYAML/DWARFYAML.h" 13 14using namespace llvm; 15 16template <typename T> 17void DWARFYAML::VisitorImpl<T>::onVariableSizeValue(uint64_t U, unsigned Size) { 18 switch (Size) { 19 case 8: 20 onValue((uint64_t)U); 21 break; 22 case 4: 23 onValue((uint32_t)U); 24 break; 25 case 2: 26 onValue((uint16_t)U); 27 break; 28 case 1: 29 onValue((uint8_t)U); 30 break; 31 default: 32 llvm_unreachable("Invalid integer write size."); 33 } 34} 35 36static unsigned getOffsetSize(const DWARFYAML::Unit &Unit) { 37 return Unit.Length.isDWARF64() ? 8 : 4; 38} 39 40static unsigned getRefSize(const DWARFYAML::Unit &Unit) { 41 if (Unit.Version == 2) 42 return Unit.AddrSize; 43 return getOffsetSize(Unit); 44} 45 46template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() { 47 for (auto &Unit : DebugInfo.CompileUnits) { 48 onStartCompileUnit(Unit); 49 auto FirstAbbrevCode = Unit.Entries[0].AbbrCode; 50 51 for (auto &Entry : Unit.Entries) { 52 onStartDIE(Unit, Entry); 53 if (Entry.AbbrCode == 0u) 54 continue; 55 auto &Abbrev = DebugInfo.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode]; 56 auto FormVal = Entry.Values.begin(); 57 auto AbbrForm = Abbrev.Attributes.begin(); 58 for (; 59 FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end(); 60 ++FormVal, ++AbbrForm) { 61 onForm(*AbbrForm, *FormVal); 62 dwarf::Form Form = AbbrForm->Form; 63 bool Indirect; 64 do { 65 Indirect = false; 66 switch (Form) { 67 case dwarf::DW_FORM_addr: 68 onVariableSizeValue(FormVal->Value, Unit.AddrSize); 69 break; 70 case dwarf::DW_FORM_ref_addr: 71 onVariableSizeValue(FormVal->Value, getRefSize(Unit)); 72 break; 73 case dwarf::DW_FORM_exprloc: 74 case dwarf::DW_FORM_block: 75 onValue((uint64_t)FormVal->BlockData.size(), true); 76 onValue( 77 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], 78 FormVal->BlockData.size()), 79 "")); 80 break; 81 case dwarf::DW_FORM_block1: { 82 auto writeSize = FormVal->BlockData.size(); 83 onValue((uint8_t)writeSize); 84 onValue( 85 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], 86 FormVal->BlockData.size()), 87 "")); 88 break; 89 } 90 case dwarf::DW_FORM_block2: { 91 auto writeSize = FormVal->BlockData.size(); 92 onValue((uint16_t)writeSize); 93 onValue( 94 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], 95 FormVal->BlockData.size()), 96 "")); 97 break; 98 } 99 case dwarf::DW_FORM_block4: { 100 auto writeSize = FormVal->BlockData.size(); 101 onValue((uint32_t)writeSize); 102 onValue( 103 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], 104 FormVal->BlockData.size()), 105 "")); 106 break; 107 } 108 case dwarf::DW_FORM_data1: 109 case dwarf::DW_FORM_ref1: 110 case dwarf::DW_FORM_flag: 111 case dwarf::DW_FORM_strx1: 112 case dwarf::DW_FORM_addrx1: 113 onValue((uint8_t)FormVal->Value); 114 break; 115 case dwarf::DW_FORM_data2: 116 case dwarf::DW_FORM_ref2: 117 case dwarf::DW_FORM_strx2: 118 case dwarf::DW_FORM_addrx2: 119 onValue((uint16_t)FormVal->Value); 120 break; 121 case dwarf::DW_FORM_data4: 122 case dwarf::DW_FORM_ref4: 123 case dwarf::DW_FORM_ref_sup4: 124 case dwarf::DW_FORM_strx4: 125 case dwarf::DW_FORM_addrx4: 126 onValue((uint32_t)FormVal->Value); 127 break; 128 case dwarf::DW_FORM_data8: 129 case dwarf::DW_FORM_ref8: 130 case dwarf::DW_FORM_ref_sup8: 131 onValue((uint64_t)FormVal->Value); 132 break; 133 case dwarf::DW_FORM_sdata: 134 onValue((int64_t)FormVal->Value, true); 135 break; 136 case dwarf::DW_FORM_udata: 137 case dwarf::DW_FORM_ref_udata: 138 onValue((uint64_t)FormVal->Value, true); 139 break; 140 case dwarf::DW_FORM_string: 141 onValue(FormVal->CStr); 142 break; 143 case dwarf::DW_FORM_indirect: 144 onValue((uint64_t)FormVal->Value, true); 145 Indirect = true; 146 Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value); 147 ++FormVal; 148 break; 149 case dwarf::DW_FORM_strp: 150 case dwarf::DW_FORM_sec_offset: 151 case dwarf::DW_FORM_GNU_ref_alt: 152 case dwarf::DW_FORM_GNU_strp_alt: 153 case dwarf::DW_FORM_line_strp: 154 case dwarf::DW_FORM_strp_sup: 155 onVariableSizeValue(FormVal->Value, getOffsetSize(Unit)); 156 break; 157 case dwarf::DW_FORM_ref_sig8: 158 onValue((uint64_t)FormVal->Value); 159 break; 160 case dwarf::DW_FORM_GNU_addr_index: 161 case dwarf::DW_FORM_GNU_str_index: 162 onValue((uint64_t)FormVal->Value, true); 163 break; 164 default: 165 break; 166 } 167 } while (Indirect); 168 } 169 onEndDIE(Unit, Entry); 170 } 171 onEndCompileUnit(Unit); 172 } 173} 174 175// Explicitly instantiate the two template expansions. 176template class DWARFYAML::VisitorImpl<DWARFYAML::Data>; 177template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>; 178