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
getRelocatedValue(uint32_t Size,uint32_t * Off,uint64_t * SecNdx) const16 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>
getEncodedPointer(uint32_t * Offset,uint8_t Encoding,uint64_t PCRelOffset) const31 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