1 | //===- Target.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_ELF_TARGET_H |
10 | #define LLD_ELF_TARGET_H |
11 | |
12 | #include "Config.h" |
13 | #include "InputSection.h" |
14 | #include "lld/Common/ErrorHandler.h" |
15 | #include "llvm/ADT/StringExtras.h" |
16 | #include "llvm/Object/ELF.h" |
17 | #include "llvm/Object/ELFTypes.h" |
18 | #include "llvm/Support/Compiler.h" |
19 | #include "llvm/Support/MathExtras.h" |
20 | #include <array> |
21 | |
22 | namespace lld { |
23 | std::string toString(elf::RelType type); |
24 | |
25 | namespace elf { |
26 | class Defined; |
27 | class InputFile; |
28 | class Symbol; |
29 | |
30 | class TargetInfo { |
31 | public: |
32 | virtual uint32_t calcEFlags() const { return 0; } |
33 | virtual RelExpr getRelExpr(RelType type, const Symbol &s, |
34 | const uint8_t *loc) const = 0; |
35 | virtual RelType getDynRel(RelType type) const { return 0; } |
36 | virtual void (uint8_t *buf) const {} |
37 | virtual void (uint8_t *buf) const {} |
38 | virtual void writeGotPlt(uint8_t *buf, const Symbol &s) const {}; |
39 | virtual void writeIgotPlt(uint8_t *buf, const Symbol &s) const {} |
40 | virtual int64_t getImplicitAddend(const uint8_t *buf, RelType type) const; |
41 | virtual int getTlsGdRelaxSkip(RelType type) const { return 1; } |
42 | |
43 | // If lazy binding is supported, the first entry of the PLT has code |
44 | // to call the dynamic linker to resolve PLT entries the first time |
45 | // they are called. This function writes that code. |
46 | virtual void (uint8_t *buf) const {} |
47 | |
48 | virtual void writePlt(uint8_t *buf, const Symbol &sym, |
49 | uint64_t pltEntryAddr) const {} |
50 | virtual void writeIplt(uint8_t *buf, const Symbol &sym, |
51 | uint64_t pltEntryAddr) const { |
52 | // All but PPC32 and PPC64 use the same format for .plt and .iplt entries. |
53 | writePlt(buf, sym, pltEntryAddr); |
54 | } |
55 | virtual void writeIBTPlt(uint8_t *buf, size_t numEntries) const {} |
56 | virtual void (InputSection &isec) const {} |
57 | virtual void addPltSymbols(InputSection &isec, uint64_t off) const {} |
58 | |
59 | // Returns true if a relocation only uses the low bits of a value such that |
60 | // all those bits are in the same page. For example, if the relocation |
61 | // only uses the low 12 bits in a system with 4k pages. If this is true, the |
62 | // bits will always have the same value at runtime and we don't have to emit |
63 | // a dynamic relocation. |
64 | virtual bool usesOnlyLowPageBits(RelType type) const; |
65 | |
66 | // Decide whether a Thunk is needed for the relocation from File |
67 | // targeting S. |
68 | virtual bool needsThunk(RelExpr expr, RelType relocType, |
69 | const InputFile *file, uint64_t branchAddr, |
70 | const Symbol &s, int64_t a) const; |
71 | |
72 | // On systems with range extensions we place collections of Thunks at |
73 | // regular spacings that enable the majority of branches reach the Thunks. |
74 | // a value of 0 means range extension thunks are not supported. |
75 | virtual uint32_t getThunkSectionSpacing() const { return 0; } |
76 | |
77 | // The function with a prologue starting at Loc was compiled with |
78 | // -fsplit-stack and it calls a function compiled without. Adjust the prologue |
79 | // to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks. |
80 | // The symbols st_other flags are needed on PowerPC64 for determining the |
81 | // offset to the split-stack prologue. |
82 | virtual bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end, |
83 | uint8_t stOther) const; |
84 | |
85 | // Return true if we can reach dst from src with RelType type. |
86 | virtual bool inBranchRange(RelType type, uint64_t src, |
87 | uint64_t dst) const; |
88 | |
89 | virtual void relocate(uint8_t *loc, const Relocation &rel, |
90 | uint64_t val) const = 0; |
91 | void relocateNoSym(uint8_t *loc, RelType type, uint64_t val) const { |
92 | relocate(loc, rel: Relocation{.expr: R_NONE, .type: type, .offset: 0, .addend: 0, .sym: nullptr}, val); |
93 | } |
94 | virtual void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const; |
95 | |
96 | // Do a linker relaxation pass and return true if we changed something. |
97 | virtual bool relaxOnce(int pass) const { return false; } |
98 | // Do finalize relaxation after collecting relaxation infos. |
99 | virtual void finalizeRelax(int passes) const {} |
100 | |
101 | virtual void applyJumpInstrMod(uint8_t *loc, JumpModType type, |
102 | JumpModType val) const {} |
103 | |
104 | virtual ~TargetInfo(); |
105 | |
106 | // This deletes a jump insn at the end of the section if it is a fall thru to |
107 | // the next section. Further, if there is a conditional jump and a direct |
108 | // jump consecutively, it tries to flip the conditional jump to convert the |
109 | // direct jump into a fall thru and delete it. Returns true if a jump |
110 | // instruction can be deleted. |
111 | virtual bool deleteFallThruJmpInsn(InputSection &is, InputFile *file, |
112 | InputSection *nextIS) const { |
113 | return false; |
114 | } |
115 | |
116 | unsigned defaultCommonPageSize = 4096; |
117 | unsigned defaultMaxPageSize = 4096; |
118 | |
119 | uint64_t getImageBase() const; |
120 | |
121 | // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got. |
122 | bool gotBaseSymInGotPlt = false; |
123 | |
124 | static constexpr RelType noneRel = 0; |
125 | RelType copyRel; |
126 | RelType gotRel; |
127 | RelType pltRel; |
128 | RelType relativeRel; |
129 | RelType iRelativeRel; |
130 | RelType symbolicRel; |
131 | RelType tlsDescRel; |
132 | RelType tlsGotRel; |
133 | RelType tlsModuleIndexRel; |
134 | RelType tlsOffsetRel; |
135 | unsigned gotEntrySize = config->wordsize; |
136 | unsigned pltEntrySize; |
137 | unsigned ; |
138 | unsigned ipltEntrySize; |
139 | |
140 | // At least on x86_64 positions 1 and 2 are used by the first plt entry |
141 | // to support lazy loading. |
142 | unsigned = 3; |
143 | |
144 | // On PPC ELF V2 abi, the first entry in the .got is the .TOC. |
145 | unsigned = 0; |
146 | |
147 | // On PPC ELF V2 abi, the dynamic section needs DT_PPC64_OPT (DT_LOPROC + 3) |
148 | // to be set to 0x2 if there can be multiple TOC's. Although we do not emit |
149 | // multiple TOC's, there can be a mix of TOC and NOTOC addressing which |
150 | // is functionally equivalent. |
151 | int ppc64DynamicSectionOpt = 0; |
152 | |
153 | bool needsThunks = false; |
154 | |
155 | // A 4-byte field corresponding to one or more trap instructions, used to pad |
156 | // executable OutputSections. |
157 | std::array<uint8_t, 4> trapInstr; |
158 | |
159 | // Stores the NOP instructions of different sizes for the target and is used |
160 | // to pad sections that are relaxed. |
161 | std::optional<std::vector<std::vector<uint8_t>>> nopInstrs; |
162 | |
163 | // If a target needs to rewrite calls to __morestack to instead call |
164 | // __morestack_non_split when a split-stack enabled caller calls a |
165 | // non-split-stack callee this will return true. Otherwise returns false. |
166 | bool needsMoreStackNonSplit = true; |
167 | |
168 | virtual RelExpr adjustTlsExpr(RelType type, RelExpr expr) const; |
169 | virtual RelExpr adjustGotPcExpr(RelType type, int64_t addend, |
170 | const uint8_t *loc) const; |
171 | |
172 | protected: |
173 | // On FreeBSD x86_64 the first page cannot be mmaped. |
174 | // On Linux this is controlled by vm.mmap_min_addr. At least on some x86_64 |
175 | // installs this is set to 65536, so the first 15 pages cannot be used. |
176 | // Given that, the smallest value that can be used in here is 0x10000. |
177 | uint64_t defaultImageBase = 0x10000; |
178 | }; |
179 | |
180 | TargetInfo *getAArch64TargetInfo(); |
181 | TargetInfo *getAMDGPUTargetInfo(); |
182 | TargetInfo *getARMTargetInfo(); |
183 | TargetInfo *getAVRTargetInfo(); |
184 | TargetInfo *getHexagonTargetInfo(); |
185 | TargetInfo *getLoongArchTargetInfo(); |
186 | TargetInfo *getMSP430TargetInfo(); |
187 | TargetInfo *getPPC64TargetInfo(); |
188 | TargetInfo *getPPCTargetInfo(); |
189 | TargetInfo *getRISCVTargetInfo(); |
190 | TargetInfo *getSPARCV9TargetInfo(); |
191 | TargetInfo *getSystemZTargetInfo(); |
192 | TargetInfo *getX86TargetInfo(); |
193 | TargetInfo *getX86_64TargetInfo(); |
194 | template <class ELFT> TargetInfo *getMipsTargetInfo(); |
195 | |
196 | struct ErrorPlace { |
197 | InputSectionBase *isec; |
198 | std::string loc; |
199 | std::string srcLoc; |
200 | }; |
201 | |
202 | // Returns input section and corresponding source string for the given location. |
203 | ErrorPlace getErrorPlace(const uint8_t *loc); |
204 | |
205 | static inline std::string getErrorLocation(const uint8_t *loc) { |
206 | return getErrorPlace(loc).loc; |
207 | } |
208 | |
209 | void processArmCmseSymbols(); |
210 | |
211 | void writePPC32GlinkSection(uint8_t *buf, size_t numEntries); |
212 | |
213 | unsigned getPPCDFormOp(unsigned secondaryOp); |
214 | unsigned getPPCDSFormOp(unsigned secondaryOp); |
215 | |
216 | // In the PowerPC64 Elf V2 abi a function can have 2 entry points. The first |
217 | // is a global entry point (GEP) which typically is used to initialize the TOC |
218 | // pointer in general purpose register 2. The second is a local entry |
219 | // point (LEP) which bypasses the TOC pointer initialization code. The |
220 | // offset between GEP and LEP is encoded in a function's st_other flags. |
221 | // This function will return the offset (in bytes) from the global entry-point |
222 | // to the local entry-point. |
223 | unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther); |
224 | |
225 | // Write a prefixed instruction, which is a 4-byte prefix followed by a 4-byte |
226 | // instruction (regardless of endianness). Therefore, the prefix is always in |
227 | // lower memory than the instruction. |
228 | void writePrefixedInstruction(uint8_t *loc, uint64_t insn); |
229 | |
230 | void addPPC64SaveRestore(); |
231 | uint64_t getPPC64TocBase(); |
232 | uint64_t getAArch64Page(uint64_t expr); |
233 | template <typename ELFT> void writeARMCmseImportLib(); |
234 | uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type); |
235 | void riscvFinalizeRelax(int passes); |
236 | void mergeRISCVAttributesSections(); |
237 | void addArmInputSectionMappingSymbols(); |
238 | void addArmSyntheticSectionMappingSymbol(Defined *); |
239 | void sortArmMappingSymbols(); |
240 | void convertArmInstructionstoBE8(InputSection *sec, uint8_t *buf); |
241 | void createTaggedSymbols(const SmallVector<ELFFileBase *, 0> &files); |
242 | void initSymbolAnchors(); |
243 | |
244 | LLVM_LIBRARY_VISIBILITY extern const TargetInfo *target; |
245 | TargetInfo *getTarget(); |
246 | |
247 | template <class ELFT> bool isMipsPIC(const Defined *sym); |
248 | |
249 | void reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v, |
250 | int64_t min, uint64_t max); |
251 | void reportRangeError(uint8_t *loc, int64_t v, int n, const Symbol &sym, |
252 | const Twine &msg); |
253 | |
254 | // Make sure that V can be represented as an N bit signed integer. |
255 | inline void checkInt(uint8_t *loc, int64_t v, int n, const Relocation &rel) { |
256 | if (v != llvm::SignExtend64(X: v, B: n)) |
257 | reportRangeError(loc, rel, v: Twine(v), min: llvm::minIntN(N: n), max: llvm::maxIntN(N: n)); |
258 | } |
259 | |
260 | // Make sure that V can be represented as an N bit unsigned integer. |
261 | inline void checkUInt(uint8_t *loc, uint64_t v, int n, const Relocation &rel) { |
262 | if ((v >> n) != 0) |
263 | reportRangeError(loc, rel, v: Twine(v), min: 0, max: llvm::maxUIntN(N: n)); |
264 | } |
265 | |
266 | // Make sure that V can be represented as an N bit signed or unsigned integer. |
267 | inline void checkIntUInt(uint8_t *loc, uint64_t v, int n, |
268 | const Relocation &rel) { |
269 | // For the error message we should cast V to a signed integer so that error |
270 | // messages show a small negative value rather than an extremely large one |
271 | if (v != (uint64_t)llvm::SignExtend64(X: v, B: n) && (v >> n) != 0) |
272 | reportRangeError(loc, rel, v: Twine((int64_t)v), min: llvm::minIntN(N: n), |
273 | max: llvm::maxUIntN(N: n)); |
274 | } |
275 | |
276 | inline void checkAlignment(uint8_t *loc, uint64_t v, int n, |
277 | const Relocation &rel) { |
278 | if ((v & (n - 1)) != 0) |
279 | error(msg: getErrorLocation(loc) + "improper alignment for relocation " + |
280 | lld::toString(type: rel.type) + ": 0x" + llvm::utohexstr(X: v) + |
281 | " is not aligned to " + Twine(n) + " bytes" ); |
282 | } |
283 | |
284 | // Endianness-aware read/write. |
285 | inline uint16_t read16(const void *p) { |
286 | return llvm::support::endian::read16(P: p, E: config->endianness); |
287 | } |
288 | |
289 | inline uint32_t read32(const void *p) { |
290 | return llvm::support::endian::read32(P: p, E: config->endianness); |
291 | } |
292 | |
293 | inline uint64_t read64(const void *p) { |
294 | return llvm::support::endian::read64(P: p, E: config->endianness); |
295 | } |
296 | |
297 | inline void write16(void *p, uint16_t v) { |
298 | llvm::support::endian::write16(P: p, V: v, E: config->endianness); |
299 | } |
300 | |
301 | inline void write32(void *p, uint32_t v) { |
302 | llvm::support::endian::write32(P: p, V: v, E: config->endianness); |
303 | } |
304 | |
305 | inline void write64(void *p, uint64_t v) { |
306 | llvm::support::endian::write64(P: p, V: v, E: config->endianness); |
307 | } |
308 | |
309 | // Overwrite a ULEB128 value and keep the original length. |
310 | inline uint64_t overwriteULEB128(uint8_t *bufLoc, uint64_t val) { |
311 | while (*bufLoc & 0x80) { |
312 | *bufLoc++ = 0x80 | (val & 0x7f); |
313 | val >>= 7; |
314 | } |
315 | *bufLoc = val; |
316 | return val; |
317 | } |
318 | } // namespace elf |
319 | } // namespace lld |
320 | |
321 | #ifdef __clang__ |
322 | #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" |
323 | #endif |
324 | #define invokeELFT(f, ...) \ |
325 | switch (config->ekind) { \ |
326 | case lld::elf::ELF32LEKind: \ |
327 | f<llvm::object::ELF32LE>(__VA_ARGS__); \ |
328 | break; \ |
329 | case lld::elf::ELF32BEKind: \ |
330 | f<llvm::object::ELF32BE>(__VA_ARGS__); \ |
331 | break; \ |
332 | case lld::elf::ELF64LEKind: \ |
333 | f<llvm::object::ELF64LE>(__VA_ARGS__); \ |
334 | break; \ |
335 | case lld::elf::ELF64BEKind: \ |
336 | f<llvm::object::ELF64BE>(__VA_ARGS__); \ |
337 | break; \ |
338 | default: \ |
339 | llvm_unreachable("unknown config->ekind"); \ |
340 | } |
341 | |
342 | #endif |
343 | |