Mercurial > hg > CbC > CbC_llvm
comparison lld/MachO/Relocations.h @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | |
children | c4bab56944e8 |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
1 //===- Relocations.h --------------------------------------------*- C++ -*-===// | |
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 #ifndef LLD_MACHO_RELOCATIONS_H | |
10 #define LLD_MACHO_RELOCATIONS_H | |
11 | |
12 #include "llvm/ADT/BitmaskEnum.h" | |
13 #include "llvm/ADT/PointerUnion.h" | |
14 #include "llvm/BinaryFormat/MachO.h" | |
15 #include "llvm/Support/Endian.h" | |
16 | |
17 #include <cstddef> | |
18 #include <cstdint> | |
19 | |
20 namespace lld { | |
21 namespace macho { | |
22 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); | |
23 | |
24 class Symbol; | |
25 class InputSection; | |
26 | |
27 enum class RelocAttrBits { | |
28 _0 = 0, // invalid | |
29 PCREL = 1 << 0, // Value is PC-relative offset | |
30 ABSOLUTE = 1 << 1, // Value is an absolute address or fixed offset | |
31 BYTE4 = 1 << 2, // 4 byte datum | |
32 BYTE8 = 1 << 3, // 8 byte datum | |
33 EXTERN = 1 << 4, // Can have an external symbol | |
34 LOCAL = 1 << 5, // Can have a local symbol | |
35 ADDEND = 1 << 6, // *_ADDEND paired prefix reloc | |
36 SUBTRAHEND = 1 << 7, // *_SUBTRACTOR paired prefix reloc | |
37 BRANCH = 1 << 8, // Value is branch target | |
38 GOT = 1 << 9, // References a symbol in the Global Offset Table | |
39 TLV = 1 << 10, // References a thread-local symbol | |
40 LOAD = 1 << 11, // Relaxable indirect load | |
41 POINTER = 1 << 12, // Non-relaxable indirect load (pointer is taken) | |
42 UNSIGNED = 1 << 13, // *_UNSIGNED relocs | |
43 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ (1 << 14) - 1), | |
44 }; | |
45 // Note: SUBTRACTOR always pairs with UNSIGNED (a delta between two symbols). | |
46 | |
47 struct RelocAttrs { | |
48 llvm::StringRef name; | |
49 RelocAttrBits bits; | |
50 bool hasAttr(RelocAttrBits b) const { return (bits & b) == b; } | |
51 }; | |
52 | |
53 struct Reloc { | |
54 uint8_t type = llvm::MachO::GENERIC_RELOC_INVALID; | |
55 bool pcrel = false; | |
56 uint8_t length = 0; | |
57 // The offset from the start of the subsection that this relocation belongs | |
58 // to. | |
59 uint64_t offset = 0; | |
60 // Adding this offset to the address of the referent symbol or subsection | |
61 // gives the destination that this relocation refers to. | |
62 int64_t addend = 0; | |
63 llvm::PointerUnion<Symbol *, InputSection *> referent = nullptr; | |
64 }; | |
65 | |
66 bool validateSymbolRelocation(const Symbol *, const InputSection *, | |
67 const Reloc &); | |
68 | |
69 /* | |
70 * v: The value the relocation is attempting to encode | |
71 * bits: The number of bits actually available to encode this relocation | |
72 */ | |
73 void reportRangeError(const Reloc &, const llvm::Twine &v, uint8_t bits, | |
74 int64_t min, uint64_t max); | |
75 | |
76 struct SymbolDiagnostic { | |
77 const Symbol *symbol; | |
78 llvm::StringRef reason; | |
79 }; | |
80 | |
81 void reportRangeError(SymbolDiagnostic, const llvm::Twine &v, uint8_t bits, | |
82 int64_t min, uint64_t max); | |
83 | |
84 template <typename Diagnostic> | |
85 inline void checkInt(Diagnostic d, int64_t v, int bits) { | |
86 if (v != llvm::SignExtend64(v, bits)) | |
87 reportRangeError(d, llvm::Twine(v), bits, llvm::minIntN(bits), | |
88 llvm::maxIntN(bits)); | |
89 } | |
90 | |
91 template <typename Diagnostic> | |
92 inline void checkUInt(Diagnostic d, uint64_t v, int bits) { | |
93 if ((v >> bits) != 0) | |
94 reportRangeError(d, llvm::Twine(v), bits, 0, llvm::maxUIntN(bits)); | |
95 } | |
96 | |
97 inline void writeAddress(uint8_t *loc, uint64_t addr, uint8_t length) { | |
98 switch (length) { | |
99 case 2: | |
100 llvm::support::endian::write32le(loc, addr); | |
101 break; | |
102 case 3: | |
103 llvm::support::endian::write64le(loc, addr); | |
104 break; | |
105 default: | |
106 llvm_unreachable("invalid r_length"); | |
107 } | |
108 } | |
109 | |
110 extern const RelocAttrs invalidRelocAttrs; | |
111 | |
112 } // namespace macho | |
113 } // namespace lld | |
114 | |
115 #endif |