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