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