Mercurial > hg > CbC > CbC_llvm
comparison lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===- DWARFDataExtractor.cpp ---------------------------------------------===// | 1 //===- DWARFDataExtractor.cpp ---------------------------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 | 8 |
10 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" | 9 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" |
10 #include "llvm/BinaryFormat/Dwarf.h" | |
11 #include "llvm/DebugInfo/DWARF/DWARFContext.h" | 11 #include "llvm/DebugInfo/DWARF/DWARFContext.h" |
12 | 12 |
13 using namespace llvm; | 13 using namespace llvm; |
14 | 14 |
15 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_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(uint64_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 uint64_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 | |
101 // The following is temporary code aimed to preserve compatibility with | |
102 // existing code which uses 32-bit offsets. | |
103 // It will be removed when migration to 64-bit offsets is finished. | |
104 | |
105 namespace { | |
106 | |
107 class WrapOffset { | |
108 uint64_t Offset64; | |
109 uint32_t *Offset32; | |
110 | |
111 public: | |
112 WrapOffset(uint32_t *Offset) | |
113 : Offset64(*Offset), Offset32(Offset) {} | |
114 ~WrapOffset() { *Offset32 = Offset64; } | |
115 operator uint64_t *() { return &Offset64; } | |
116 }; | |
117 | |
118 } | |
119 | |
15 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, | 120 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, |
16 uint64_t *SecNdx) const { | 121 uint64_t *SecNdx) const { |
17 if (SecNdx) | 122 return getRelocatedValue(Size, WrapOffset(Off), SecNdx); |
18 *SecNdx = -1ULL; | |
19 if (!Section) | |
20 return getUnsigned(Off, Size); | |
21 Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off); | |
22 if (!Rel) | |
23 return getUnsigned(Off, Size); | |
24 if (SecNdx) | |
25 *SecNdx = Rel->SectionIndex; | |
26 return getUnsigned(Off, Size) + Rel->Value; | |
27 } | 123 } |
124 | |
125 Optional<uint64_t> | |
126 DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding, | |
127 uint64_t PCRelOffset) const { | |
128 return getEncodedPointer(WrapOffset(Offset), Encoding, PCRelOffset); | |
129 } |