1 //===- DWARFDataExtractor.cpp ---------------------------------------------===// 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 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" 11 #include "llvm/BinaryFormat/Dwarf.h" 12 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 13 14 using namespace llvm; 15 16 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, 17 uint64_t *SecNdx) const { 18 if (SecNdx) 19 *SecNdx = -1ULL; 20 if (!Section) 21 return getUnsigned(Off, Size); 22 Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off); 23 if (!Rel) 24 return getUnsigned(Off, Size); 25 if (SecNdx) 26 *SecNdx = Rel->SectionIndex; 27 return getUnsigned(Off, Size) + Rel->Value; 28 } 29 30 Optional<uint64_t> 31 DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding, 32 uint64_t PCRelOffset) const { 33 if (Encoding == dwarf::DW_EH_PE_omit) 34 return None; 35 36 uint64_t Result = 0; 37 uint32_t OldOffset = *Offset; 38 // First get value 39 switch (Encoding & 0x0F) { 40 case dwarf::DW_EH_PE_absptr: 41 switch (getAddressSize()) { 42 case 2: 43 case 4: 44 case 8: 45 Result = getUnsigned(Offset, getAddressSize()); 46 break; 47 default: 48 return None; 49 } 50 break; 51 case dwarf::DW_EH_PE_uleb128: 52 Result = getULEB128(Offset); 53 break; 54 case dwarf::DW_EH_PE_sleb128: 55 Result = getSLEB128(Offset); 56 break; 57 case dwarf::DW_EH_PE_udata2: 58 Result = getUnsigned(Offset, 2); 59 break; 60 case dwarf::DW_EH_PE_udata4: 61 Result = getUnsigned(Offset, 4); 62 break; 63 case dwarf::DW_EH_PE_udata8: 64 Result = getUnsigned(Offset, 8); 65 break; 66 case dwarf::DW_EH_PE_sdata2: 67 Result = getSigned(Offset, 2); 68 break; 69 case dwarf::DW_EH_PE_sdata4: 70 Result = getSigned(Offset, 4); 71 break; 72 case dwarf::DW_EH_PE_sdata8: 73 Result = getSigned(Offset, 8); 74 break; 75 default: 76 return None; 77 } 78 // Then add relative offset, if required 79 switch (Encoding & 0x70) { 80 case dwarf::DW_EH_PE_absptr: 81 // do nothing 82 break; 83 case dwarf::DW_EH_PE_pcrel: 84 Result += PCRelOffset; 85 break; 86 case dwarf::DW_EH_PE_datarel: 87 case dwarf::DW_EH_PE_textrel: 88 case dwarf::DW_EH_PE_funcrel: 89 case dwarf::DW_EH_PE_aligned: 90 default: 91 *Offset = OldOffset; 92 return None; 93 } 94 95 return Result; 96 } 97