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 uint64_t R = E->Resolver(E->Reloc, E->SymbolValue, A); 28 if (E->Reloc2) 29 R = E->Resolver(*E->Reloc2, E->SymbolValue2, R); 30 return R; 31 } 32 33 Optional<uint64_t> 34 DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding, 35 uint64_t PCRelOffset) const { 36 if (Encoding == dwarf::DW_EH_PE_omit) 37 return None; 38 39 uint64_t Result = 0; 40 uint32_t OldOffset = *Offset; 41 // First get value 42 switch (Encoding & 0x0F) { 43 case dwarf::DW_EH_PE_absptr: 44 switch (getAddressSize()) { 45 case 2: 46 case 4: 47 case 8: 48 Result = getUnsigned(Offset, getAddressSize()); 49 break; 50 default: 51 return None; 52 } 53 break; 54 case dwarf::DW_EH_PE_uleb128: 55 Result = getULEB128(Offset); 56 break; 57 case dwarf::DW_EH_PE_sleb128: 58 Result = getSLEB128(Offset); 59 break; 60 case dwarf::DW_EH_PE_udata2: 61 Result = getUnsigned(Offset, 2); 62 break; 63 case dwarf::DW_EH_PE_udata4: 64 Result = getUnsigned(Offset, 4); 65 break; 66 case dwarf::DW_EH_PE_udata8: 67 Result = getUnsigned(Offset, 8); 68 break; 69 case dwarf::DW_EH_PE_sdata2: 70 Result = getSigned(Offset, 2); 71 break; 72 case dwarf::DW_EH_PE_sdata4: 73 Result = getSigned(Offset, 4); 74 break; 75 case dwarf::DW_EH_PE_sdata8: 76 Result = getSigned(Offset, 8); 77 break; 78 default: 79 return None; 80 } 81 // Then add relative offset, if required 82 switch (Encoding & 0x70) { 83 case dwarf::DW_EH_PE_absptr: 84 // do nothing 85 break; 86 case dwarf::DW_EH_PE_pcrel: 87 Result += PCRelOffset; 88 break; 89 case dwarf::DW_EH_PE_datarel: 90 case dwarf::DW_EH_PE_textrel: 91 case dwarf::DW_EH_PE_funcrel: 92 case dwarf::DW_EH_PE_aligned: 93 default: 94 *Offset = OldOffset; 95 return None; 96 } 97 98 return Result; 99 } 100