]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/ELF/Relocations.h
Update lld to trunk r290819 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / ELF / Relocations.h
1 //===- Relocations.h -------------------------------------------*- C++ -*-===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLD_ELF_RELOCATIONS_H
11 #define LLD_ELF_RELOCATIONS_H
12
13 #include "lld/Core/LLVM.h"
14
15 namespace lld {
16 namespace elf {
17 class SymbolBody;
18 class InputSectionData;
19 template <class ELFT> class InputSection;
20 template <class ELFT> class InputSectionBase;
21
22 // List of target-independent relocation types. Relocations read
23 // from files are converted to these types so that the main code
24 // doesn't have to know about architecture-specific details.
25 enum RelExpr {
26   R_ABS,
27   R_GOT,
28   R_GOTONLY_PC,
29   R_GOTONLY_PC_FROM_END,
30   R_GOTREL,
31   R_GOTREL_FROM_END,
32   R_GOT_FROM_END,
33   R_GOT_OFF,
34   R_GOT_PAGE_PC,
35   R_GOT_PC,
36   R_HINT,
37   R_MIPS_GOT_LOCAL_PAGE,
38   R_MIPS_GOT_OFF,
39   R_MIPS_GOT_OFF32,
40   R_MIPS_GOTREL,
41   R_MIPS_TLSGD,
42   R_MIPS_TLSLD,
43   R_NEG_TLS,
44   R_PAGE_PC,
45   R_PC,
46   R_PLT,
47   R_PLT_PC,
48   R_PLT_PAGE_PC,
49   R_PPC_OPD,
50   R_PPC_PLT_OPD,
51   R_PPC_TOC,
52   R_RELAX_GOT_PC,
53   R_RELAX_GOT_PC_NOPIC,
54   R_RELAX_TLS_GD_TO_IE,
55   R_RELAX_TLS_GD_TO_IE_END,
56   R_RELAX_TLS_GD_TO_IE_ABS,
57   R_RELAX_TLS_GD_TO_IE_PAGE_PC,
58   R_RELAX_TLS_GD_TO_LE,
59   R_RELAX_TLS_GD_TO_LE_NEG,
60   R_RELAX_TLS_IE_TO_LE,
61   R_RELAX_TLS_LD_TO_LE,
62   R_SIZE,
63   R_THUNK_ABS,
64   R_THUNK_PC,
65   R_THUNK_PLT_PC,
66   R_TLS,
67   R_TLSDESC,
68   R_TLSDESC_PAGE,
69   R_TLSDESC_CALL,
70   R_TLSGD,
71   R_TLSGD_PC,
72   R_TLSLD,
73   R_TLSLD_PC,
74 };
75
76 // Build a bitmask with one bit set for each RelExpr.
77 //
78 // Constexpr function arguments can't be used in static asserts, so we
79 // use template arguments to build the mask.
80 // But function template partial specializations don't exist (needed
81 // for base case of the recursion), so we need a dummy struct.
82 template <RelExpr... Exprs> struct RelExprMaskBuilder {
83   static inline uint64_t build() { return 0; }
84 };
85
86 // Specialization for recursive case.
87 template <RelExpr Head, RelExpr... Tail>
88 struct RelExprMaskBuilder<Head, Tail...> {
89   static inline uint64_t build() {
90     static_assert(0 <= Head && Head < 64,
91                   "RelExpr is too large for 64-bit mask!");
92     return (uint64_t(1) << Head) | RelExprMaskBuilder<Tail...>::build();
93   }
94 };
95
96 // Return true if `Expr` is one of `Exprs`.
97 // There are fewer than 64 RelExpr's, so we can represent any set of
98 // RelExpr's as a constant bit mask and test for membership with a
99 // couple cheap bitwise operations.
100 template <RelExpr... Exprs> bool isRelExprOneOf(RelExpr Expr) {
101   assert(0 <= Expr && (int)Expr < 64 && "RelExpr is too large for 64-bit mask!");
102   return (uint64_t(1) << Expr) & RelExprMaskBuilder<Exprs...>::build();
103 }
104
105 // Architecture-neutral representation of relocation.
106 struct Relocation {
107   RelExpr Expr;
108   uint32_t Type;
109   uint64_t Offset;
110   uint64_t Addend;
111   SymbolBody *Sym;
112 };
113
114 template <class ELFT> void scanRelocations(InputSectionBase<ELFT> &);
115
116 template <class ELFT> void createThunks(InputSectionBase<ELFT> &);
117
118 template <class ELFT>
119 static inline typename ELFT::uint getAddend(const typename ELFT::Rel &Rel) {
120   return 0;
121 }
122
123 template <class ELFT>
124 static inline typename ELFT::uint getAddend(const typename ELFT::Rela &Rel) {
125   return Rel.r_addend;
126 }
127 }
128 }
129
130 #endif