blob: 03e3174613962ade66aa14cc14b29c38986d0878 [file] [log] [blame]
Paul Robinson17536b92017-06-29 16:52:08 +00001//===- 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"
Rafael Auler86fb7bf2018-03-08 00:46:53 +000011#include "llvm/BinaryFormat/Dwarf.h"
Rafael Espindolac398e672017-07-19 22:27:28 +000012#include "llvm/DebugInfo/DWARF/DWARFContext.h"
Paul Robinson17536b92017-06-29 16:52:08 +000013
14using namespace llvm;
15
16uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
17 uint64_t *SecNdx) const {
George Rimar2f95c8b2017-09-04 10:30:39 +000018 if (SecNdx)
19 *SecNdx = -1ULL;
Rafael Espindolac398e672017-07-19 22:27:28 +000020 if (!Section)
Paul Robinson17536b92017-06-29 16:52:08 +000021 return getUnsigned(Off, Size);
Rafael Espindolac398e672017-07-19 22:27:28 +000022 Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off);
23 if (!Rel)
Paul Robinson17536b92017-06-29 16:52:08 +000024 return getUnsigned(Off, Size);
25 if (SecNdx)
Rafael Espindolac398e672017-07-19 22:27:28 +000026 *SecNdx = Rel->SectionIndex;
27 return getUnsigned(Off, Size) + Rel->Value;
Paul Robinson17536b92017-06-29 16:52:08 +000028}
Rafael Auler86fb7bf2018-03-08 00:46:53 +000029
30Optional<uint64_t>
31DWARFDataExtractor::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}