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