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> E = Obj->find(*Section, *Off); 22 uint64_t A = getUnsigned(Off, Size); 23 if (!E) 24 return A; 25 if (SecNdx) 26 *SecNdx = E->SectionIndex; 27 return E->Resolver(E->Reloc, E->SymbolValue, A); 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