Line data Source code
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 :
16 77432 : uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
17 : uint64_t *SecNdx) const {
18 77432 : if (SecNdx)
19 16783 : *SecNdx = -1ULL;
20 77432 : if (!Section)
21 3867 : return getUnsigned(Off, Size);
22 73565 : Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off);
23 73565 : if (!Rel)
24 59643 : return getUnsigned(Off, Size);
25 13922 : if (SecNdx)
26 1233 : *SecNdx = Rel->SectionIndex;
27 13922 : return getUnsigned(Off, Size) + Rel->Value;
28 : }
29 :
30 : Optional<uint64_t>
31 498 : DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding,
32 : uint64_t PCRelOffset) const {
33 498 : if (Encoding == dwarf::DW_EH_PE_omit)
34 : return None;
35 :
36 : uint64_t Result = 0;
37 498 : uint32_t OldOffset = *Offset;
38 : // First get value
39 498 : switch (Encoding & 0x0F) {
40 207 : case dwarf::DW_EH_PE_absptr:
41 207 : switch (getAddressSize()) {
42 207 : case 2:
43 : case 4:
44 : case 8:
45 207 : Result = getUnsigned(Offset, getAddressSize());
46 : break;
47 : default:
48 : return None;
49 : }
50 207 : break;
51 0 : case dwarf::DW_EH_PE_uleb128:
52 0 : Result = getULEB128(Offset);
53 0 : break;
54 0 : case dwarf::DW_EH_PE_sleb128:
55 0 : Result = getSLEB128(Offset);
56 0 : break;
57 0 : case dwarf::DW_EH_PE_udata2:
58 0 : Result = getUnsigned(Offset, 2);
59 0 : break;
60 7 : case dwarf::DW_EH_PE_udata4:
61 7 : Result = getUnsigned(Offset, 4);
62 7 : break;
63 0 : case dwarf::DW_EH_PE_udata8:
64 0 : Result = getUnsigned(Offset, 8);
65 0 : break;
66 0 : case dwarf::DW_EH_PE_sdata2:
67 0 : Result = getSigned(Offset, 2);
68 0 : break;
69 280 : case dwarf::DW_EH_PE_sdata4:
70 280 : Result = getSigned(Offset, 4);
71 280 : break;
72 4 : case dwarf::DW_EH_PE_sdata8:
73 4 : Result = getSigned(Offset, 8);
74 4 : break;
75 : default:
76 : return None;
77 : }
78 : // Then add relative offset, if required
79 498 : switch (Encoding & 0x70) {
80 : case dwarf::DW_EH_PE_absptr:
81 : // do nothing
82 : break;
83 468 : case dwarf::DW_EH_PE_pcrel:
84 468 : Result += PCRelOffset;
85 468 : break;
86 0 : 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 0 : *Offset = OldOffset;
92 : return None;
93 : }
94 :
95 : return Result;
96 : }
|