1//===- ARM.cpp ------------------------------------------------------------===//
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#include "InputFiles.h"
10#include "OutputSections.h"
11#include "RelocScan.h"
12#include "SymbolTable.h"
13#include "Symbols.h"
14#include "SyntheticSections.h"
15#include "Target.h"
16#include "lld/Common/Filesystem.h"
17#include "llvm/BinaryFormat/ELF.h"
18#include "llvm/Support/Endian.h"
19
20using namespace llvm;
21using namespace llvm::support::endian;
22using namespace llvm::support;
23using namespace llvm::ELF;
24using namespace lld;
25using namespace lld::elf;
26using namespace llvm::object;
27
28namespace {
29class ARM final : public TargetInfo {
30public:
31 ARM(Ctx &);
32 uint32_t calcEFlags() const override;
33 RelExpr getRelExpr(RelType type, const Symbol &s,
34 const uint8_t *loc) const override;
35 RelType getDynRel(RelType type) const override;
36 int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
37 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
38 void writeIgotPlt(uint8_t *buf, const Symbol &s) const override;
39 void writePltHeader(uint8_t *buf) const override;
40 void writePlt(uint8_t *buf, const Symbol &sym,
41 uint64_t pltEntryAddr) const override;
42 void addPltSymbols(InputSection &isec, uint64_t off) const override;
43 void addPltHeaderSymbols(InputSection &isd) const override;
44 bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
45 uint64_t branchAddr, const Symbol &s,
46 int64_t a) const override;
47 uint32_t getThunkSectionSpacing() const override;
48 bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
49 void relocate(uint8_t *loc, const Relocation &rel,
50 uint64_t val) const override;
51 template <class ELFT, class RelTy>
52 void scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels);
53 void scanSection(InputSectionBase &sec) override {
54 if (ctx.arg.ekind == ELF32BEKind)
55 elf::scanSection1<ARM, ELF32BE>(target&: *this, sec);
56 else
57 elf::scanSection1<ARM, ELF32LE>(target&: *this, sec);
58 }
59
60 DenseMap<InputSection *, SmallVector<const Defined *, 0>> sectionMap;
61
62private:
63 void encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
64 int group, bool check) const;
65};
66enum class CodeState { Data = 0, Thumb = 2, Arm = 4 };
67} // namespace
68
69ARM::ARM(Ctx &ctx) : TargetInfo(ctx) {
70 copyRel = R_ARM_COPY;
71 relativeRel = R_ARM_RELATIVE;
72 iRelativeRel = R_ARM_IRELATIVE;
73 gotRel = R_ARM_GLOB_DAT;
74 pltRel = R_ARM_JUMP_SLOT;
75 symbolicRel = R_ARM_ABS32;
76 tlsGotRel = R_ARM_TLS_TPOFF32;
77 tlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
78 tlsOffsetRel = R_ARM_TLS_DTPOFF32;
79 pltHeaderSize = 32;
80 pltEntrySize = 16;
81 ipltEntrySize = 16;
82 trapInstr = {0xd4, 0xd4, 0xd4, 0xd4};
83 needsThunks = true;
84 defaultMaxPageSize = 65536;
85}
86
87uint32_t ARM::calcEFlags() const {
88 // The ABIFloatType is used by loaders to detect the floating point calling
89 // convention.
90 uint32_t abiFloatType = 0;
91
92 // Set the EF_ARM_BE8 flag in the ELF header, if ELF file is big-endian
93 // with BE-8 code.
94 uint32_t armBE8 = 0;
95
96 if (ctx.arg.armVFPArgs == ARMVFPArgKind::Base ||
97 ctx.arg.armVFPArgs == ARMVFPArgKind::Default)
98 abiFloatType = EF_ARM_ABI_FLOAT_SOFT;
99 else if (ctx.arg.armVFPArgs == ARMVFPArgKind::VFP)
100 abiFloatType = EF_ARM_ABI_FLOAT_HARD;
101
102 if (!ctx.arg.isLE && ctx.arg.armBe8)
103 armBE8 = EF_ARM_BE8;
104
105 // We don't currently use any features incompatible with EF_ARM_EABI_VER5,
106 // but we don't have any firm guarantees of conformance. Linux AArch64
107 // kernels (as of 2016) require an EABI version to be set.
108 return EF_ARM_EABI_VER5 | abiFloatType | armBE8;
109}
110
111// Only needed to support relocations used by relocateNonAlloc and
112// preprocessRelocs.
113RelExpr ARM::getRelExpr(RelType type, const Symbol &s,
114 const uint8_t *loc) const {
115 switch (type) {
116 case R_ARM_ABS32:
117 return R_ABS;
118 case R_ARM_REL32:
119 return R_PC;
120 case R_ARM_SBREL32:
121 return RE_ARM_SBREL;
122 case R_ARM_TLS_LDO32:
123 return R_DTPREL;
124 case R_ARM_NONE:
125 return R_NONE;
126 default:
127 Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v
128 << ") against symbol " << &s;
129 return R_NONE;
130 }
131}
132
133template <class ELFT, class RelTy>
134void ARM::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
135 RelocScan rs(ctx, &sec);
136 sec.relocations.reserve(N: rels.size());
137 for (auto it = rels.begin(); it != rels.end(); ++it) {
138 const RelTy &rel = *it;
139 uint32_t symIdx = rel.getSymbol(false);
140 Symbol &sym = sec.getFile<ELFT>()->getSymbol(symIdx);
141 uint64_t offset = rel.r_offset;
142 RelType type = rel.getType(false);
143 if (type == R_ARM_NONE)
144 continue;
145 if (sym.isUndefined() && symIdx != 0 &&
146 rs.maybeReportUndefined(sym&: cast<Undefined>(Val&: sym), offset))
147 continue;
148 int64_t addend = rs.getAddend<ELFT>(rel, type);
149 RelExpr expr;
150 switch (type) {
151 case R_ARM_V4BX:
152 continue;
153
154 // Absolute relocations:
155 case R_ARM_ABS32:
156 case R_ARM_MOVW_ABS_NC:
157 case R_ARM_MOVT_ABS:
158 case R_ARM_THM_MOVW_ABS_NC:
159 case R_ARM_THM_MOVT_ABS:
160 case R_ARM_THM_ALU_ABS_G0_NC:
161 case R_ARM_THM_ALU_ABS_G1_NC:
162 case R_ARM_THM_ALU_ABS_G2_NC:
163 case R_ARM_THM_ALU_ABS_G3:
164 expr = R_ABS;
165 break;
166
167 // PC-relative relocations:
168 case R_ARM_THM_JUMP8:
169 case R_ARM_THM_JUMP11:
170 case R_ARM_MOVW_PREL_NC:
171 case R_ARM_MOVT_PREL:
172 case R_ARM_REL32:
173 case R_ARM_THM_MOVW_PREL_NC:
174 case R_ARM_THM_MOVT_PREL:
175 rs.processR_PC(type, offset, addend, sym);
176 continue;
177 // R_PC variant (place aligned down to 4-byte boundary):
178 case R_ARM_ALU_PC_G0:
179 case R_ARM_ALU_PC_G0_NC:
180 case R_ARM_ALU_PC_G1:
181 case R_ARM_ALU_PC_G1_NC:
182 case R_ARM_ALU_PC_G2:
183 case R_ARM_LDR_PC_G0:
184 case R_ARM_LDR_PC_G1:
185 case R_ARM_LDR_PC_G2:
186 case R_ARM_LDRS_PC_G0:
187 case R_ARM_LDRS_PC_G1:
188 case R_ARM_LDRS_PC_G2:
189 case R_ARM_THM_ALU_PREL_11_0:
190 case R_ARM_THM_PC8:
191 case R_ARM_THM_PC12:
192 expr = RE_ARM_PCA;
193 break;
194
195 // PLT-generating relocations:
196 case R_ARM_CALL:
197 case R_ARM_JUMP24:
198 case R_ARM_PC24:
199 case R_ARM_PLT32:
200 case R_ARM_PREL31:
201 case R_ARM_THM_JUMP19:
202 case R_ARM_THM_JUMP24:
203 case R_ARM_THM_CALL:
204 rs.processR_PLT_PC(type, offset, addend, sym);
205 continue;
206
207 // GOT relocations:
208 case R_ARM_GOT_BREL:
209 expr = R_GOT_OFF;
210 break;
211 case R_ARM_GOT_PREL:
212 expr = R_GOT_PC;
213 break;
214 case R_ARM_GOTOFF32:
215 ctx.in.got->hasGotOffRel.store(i: true, m: std::memory_order_relaxed);
216 expr = R_GOTREL;
217 break;
218 case R_ARM_BASE_PREL:
219 ctx.in.got->hasGotOffRel.store(i: true, m: std::memory_order_relaxed);
220 expr = R_GOTONLY_PC;
221 break;
222
223 // RE_ARM_SBREL relocations:
224 case R_ARM_SBREL32:
225 case R_ARM_MOVW_BREL_NC:
226 case R_ARM_MOVW_BREL:
227 case R_ARM_MOVT_BREL:
228 case R_ARM_THM_MOVW_BREL_NC:
229 case R_ARM_THM_MOVW_BREL:
230 case R_ARM_THM_MOVT_BREL:
231 expr = RE_ARM_SBREL;
232 break;
233
234 // Platform-specific relocations:
235 case R_ARM_TARGET1:
236 expr = ctx.arg.target1Rel ? R_PC : R_ABS;
237 break;
238 case R_ARM_TARGET2:
239 if (ctx.arg.target2 == Target2Policy::Rel)
240 expr = R_PC;
241 else if (ctx.arg.target2 == Target2Policy::Abs)
242 expr = R_ABS;
243 else
244 expr = R_GOT_PC;
245 break;
246
247 // TLS relocations (no optimization):
248 case R_ARM_TLS_LE32:
249 if (rs.checkTlsLe(offset, sym, type))
250 continue;
251 expr = R_TPREL;
252 break;
253 case R_ARM_TLS_IE32:
254 rs.handleTlsIe<false>(ieExpr: R_GOT_PC, type, offset, addend, sym);
255 continue;
256 case R_ARM_TLS_GD32:
257 sym.setFlags(NEEDS_TLSGD);
258 sec.addReloc(r: {.expr: R_TLSGD_PC, .type: type, .offset: offset, .addend: addend, .sym: &sym});
259 continue;
260 case R_ARM_TLS_LDM32:
261 ctx.needsTlsLd.store(i: true, m: std::memory_order_relaxed);
262 sec.addReloc(r: {.expr: R_TLSLD_PC, .type: type, .offset: offset, .addend: addend, .sym: &sym});
263 continue;
264 case R_ARM_TLS_LDO32:
265 expr = R_DTPREL;
266 break;
267
268 default:
269 Err(ctx) << getErrorLoc(ctx, loc: sec.content().data() + offset)
270 << "unknown relocation (" << type.v << ") against symbol "
271 << &sym;
272 continue;
273 }
274 rs.process(expr, type, offset, sym, addend);
275 }
276}
277
278RelType ARM::getDynRel(RelType type) const {
279 if ((type == R_ARM_ABS32) || (type == R_ARM_TARGET1 && !ctx.arg.target1Rel))
280 return R_ARM_ABS32;
281 return R_ARM_NONE;
282}
283
284void ARM::writeGotPlt(uint8_t *buf, const Symbol &) const {
285 write32(ctx, p: buf, v: ctx.in.plt->getVA());
286}
287
288void ARM::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
289 // An ARM entry is the address of the ifunc resolver function.
290 write32(ctx, p: buf, v: s.getVA(ctx));
291}
292
293// Long form PLT Header that does not have any restrictions on the displacement
294// of the .plt from the .got.plt.
295static void writePltHeaderLong(Ctx &ctx, uint8_t *buf) {
296 write32(ctx, p: buf + 0, v: 0xe52de004); // str lr, [sp,#-4]!
297 write32(ctx, p: buf + 4, v: 0xe59fe004); // ldr lr, L2
298 write32(ctx, p: buf + 8, v: 0xe08fe00e); // L1: add lr, pc, lr
299 write32(ctx, p: buf + 12, v: 0xe5bef008); // ldr pc, [lr, #8]
300 write32(ctx, p: buf + 16, v: 0x00000000); // L2: .word &(.got.plt) - L1 - 8
301 write32(ctx, p: buf + 20, v: 0xd4d4d4d4); // Pad to 32-byte boundary
302 write32(ctx, p: buf + 24, v: 0xd4d4d4d4); // Pad to 32-byte boundary
303 write32(ctx, p: buf + 28, v: 0xd4d4d4d4);
304 uint64_t gotPlt = ctx.in.gotPlt->getVA();
305 uint64_t l1 = ctx.in.plt->getVA() + 8;
306 write32(ctx, p: buf + 16, v: gotPlt - l1 - 8);
307}
308
309// True if we should use Thumb PLTs, which currently require Thumb2, and are
310// only used if the target does not have the ARM ISA.
311static bool useThumbPLTs(Ctx &ctx) {
312 return ctx.arg.armHasThumb2ISA && !ctx.arg.armHasArmISA;
313}
314
315// The default PLT header requires the .got.plt to be within 128 Mb of the
316// .plt in the positive direction.
317void ARM::writePltHeader(uint8_t *buf) const {
318 if (useThumbPLTs(ctx)) {
319 // The instruction sequence for thumb:
320 //
321 // 0: b500 push {lr}
322 // 2: f8df e008 ldr.w lr, [pc, #0x8] @ 0xe <func+0xe>
323 // 6: 44fe add lr, pc
324 // 8: f85e ff08 ldr pc, [lr, #8]!
325 // e: .word .got.plt - .plt - 16
326 //
327 // At 0x8, we want to jump to .got.plt, the -16 accounts for 8 bytes from
328 // `pc` in the add instruction and 8 bytes for the `lr` adjustment.
329 //
330 uint64_t offset = ctx.in.gotPlt->getVA() - ctx.in.plt->getVA() - 16;
331 assert(llvm::isUInt<32>(offset) && "This should always fit into a 32-bit offset");
332 write16(ctx, p: buf + 0, v: 0xb500);
333 // Split into two halves to support endianness correctly.
334 write16(ctx, p: buf + 2, v: 0xf8df);
335 write16(ctx, p: buf + 4, v: 0xe008);
336 write16(ctx, p: buf + 6, v: 0x44fe);
337 // Split into two halves to support endianness correctly.
338 write16(ctx, p: buf + 8, v: 0xf85e);
339 write16(ctx, p: buf + 10, v: 0xff08);
340 write32(ctx, p: buf + 12, v: offset);
341
342 memcpy(dest: buf + 16, src: trapInstr.data(), n: 4); // Pad to 32-byte boundary
343 memcpy(dest: buf + 20, src: trapInstr.data(), n: 4);
344 memcpy(dest: buf + 24, src: trapInstr.data(), n: 4);
345 memcpy(dest: buf + 28, src: trapInstr.data(), n: 4);
346 } else {
347 // Use a similar sequence to that in writePlt(), the difference is the
348 // calling conventions mean we use lr instead of ip. The PLT entry is
349 // responsible for saving lr on the stack, the dynamic loader is responsible
350 // for reloading it.
351 const uint32_t pltData[] = {
352 0xe52de004, // L1: str lr, [sp,#-4]!
353 0xe28fe600, // add lr, pc, #0x0NN00000 &(.got.plt - L1 - 4)
354 0xe28eea00, // add lr, lr, #0x000NN000 &(.got.plt - L1 - 4)
355 0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)
356 };
357
358 uint64_t offset = ctx.in.gotPlt->getVA() - ctx.in.plt->getVA() - 4;
359 if (!llvm::isUInt<27>(x: offset)) {
360 // We cannot encode the Offset, use the long form.
361 writePltHeaderLong(ctx, buf);
362 return;
363 }
364 write32(ctx, p: buf + 0, v: pltData[0]);
365 write32(ctx, p: buf + 4, v: pltData[1] | ((offset >> 20) & 0xff));
366 write32(ctx, p: buf + 8, v: pltData[2] | ((offset >> 12) & 0xff));
367 write32(ctx, p: buf + 12, v: pltData[3] | (offset & 0xfff));
368 memcpy(dest: buf + 16, src: trapInstr.data(), n: 4); // Pad to 32-byte boundary
369 memcpy(dest: buf + 20, src: trapInstr.data(), n: 4);
370 memcpy(dest: buf + 24, src: trapInstr.data(), n: 4);
371 memcpy(dest: buf + 28, src: trapInstr.data(), n: 4);
372 }
373}
374
375void ARM::addPltHeaderSymbols(InputSection &isec) const {
376 if (useThumbPLTs(ctx)) {
377 addSyntheticLocal(ctx, name: "$t", type: STT_NOTYPE, value: 0, size: 0, section&: isec);
378 addSyntheticLocal(ctx, name: "$d", type: STT_NOTYPE, value: 12, size: 0, section&: isec);
379 } else {
380 addSyntheticLocal(ctx, name: "$a", type: STT_NOTYPE, value: 0, size: 0, section&: isec);
381 addSyntheticLocal(ctx, name: "$d", type: STT_NOTYPE, value: 16, size: 0, section&: isec);
382 }
383}
384
385// Long form PLT entries that do not have any restrictions on the displacement
386// of the .plt from the .got.plt.
387static void writePltLong(Ctx &ctx, uint8_t *buf, uint64_t gotPltEntryAddr,
388 uint64_t pltEntryAddr) {
389 write32(ctx, p: buf + 0, v: 0xe59fc004); // ldr ip, L2
390 write32(ctx, p: buf + 4, v: 0xe08cc00f); // L1: add ip, ip, pc
391 write32(ctx, p: buf + 8, v: 0xe59cf000); // ldr pc, [ip]
392 write32(ctx, p: buf + 12, v: 0x00000000); // L2: .word Offset(&(.got.plt) - L1 - 8
393 uint64_t l1 = pltEntryAddr + 4;
394 write32(ctx, p: buf + 12, v: gotPltEntryAddr - l1 - 8);
395}
396
397// The default PLT entries require the .got.plt to be within 128 Mb of the
398// .plt in the positive direction.
399void ARM::writePlt(uint8_t *buf, const Symbol &sym,
400 uint64_t pltEntryAddr) const {
401 if (!useThumbPLTs(ctx)) {
402 uint64_t offset = sym.getGotPltVA(ctx) - pltEntryAddr - 8;
403
404 // The PLT entry is similar to the example given in Appendix A of ELF for
405 // the Arm Architecture. Instead of using the Group Relocations to find the
406 // optimal rotation for the 8-bit immediate used in the add instructions we
407 // hard code the most compact rotations for simplicity. This saves a load
408 // instruction over the long plt sequences.
409 const uint32_t pltData[] = {
410 0xe28fc600, // L1: add ip, pc, #0x0NN00000 Offset(&(.got.plt) - L1 - 8
411 0xe28cca00, // add ip, ip, #0x000NN000 Offset(&(.got.plt) - L1 - 8
412 0xe5bcf000, // ldr pc, [ip, #0x00000NNN] Offset(&(.got.plt) - L1 - 8
413 };
414 if (!llvm::isUInt<27>(x: offset)) {
415 // We cannot encode the Offset, use the long form.
416 writePltLong(ctx, buf, gotPltEntryAddr: sym.getGotPltVA(ctx), pltEntryAddr);
417 return;
418 }
419 write32(ctx, p: buf + 0, v: pltData[0] | ((offset >> 20) & 0xff));
420 write32(ctx, p: buf + 4, v: pltData[1] | ((offset >> 12) & 0xff));
421 write32(ctx, p: buf + 8, v: pltData[2] | (offset & 0xfff));
422 memcpy(dest: buf + 12, src: trapInstr.data(), n: 4); // Pad to 16-byte boundary
423 } else {
424 uint64_t offset = sym.getGotPltVA(ctx) - pltEntryAddr - 12;
425 assert(llvm::isUInt<32>(offset) && "This should always fit into a 32-bit offset");
426
427 // A PLT entry will be:
428 //
429 // movw ip, #<lower 16 bits>
430 // movt ip, #<upper 16 bits>
431 // add ip, pc
432 // L1: ldr.w pc, [ip]
433 // b L1
434 //
435 // where ip = r12 = 0xc
436
437 // movw ip, #<lower 16 bits>
438 write16(ctx, p: buf + 2, v: 0x0c00); // use `ip`
439 relocateNoSym(loc: buf, type: R_ARM_THM_MOVW_ABS_NC, val: offset);
440
441 // movt ip, #<upper 16 bits>
442 write16(ctx, p: buf + 6, v: 0x0c00); // use `ip`
443 relocateNoSym(loc: buf + 4, type: R_ARM_THM_MOVT_ABS, val: offset);
444
445 write16(ctx, p: buf + 8, v: 0x44fc); // add ip, pc
446 write16(ctx, p: buf + 10, v: 0xf8dc); // ldr.w pc, [ip] (bottom half)
447 write16(ctx, p: buf + 12, v: 0xf000); // ldr.w pc, [ip] (upper half)
448 write16(ctx, p: buf + 14, v: 0xe7fc); // Branch to previous instruction
449 }
450}
451
452void ARM::addPltSymbols(InputSection &isec, uint64_t off) const {
453 if (useThumbPLTs(ctx)) {
454 addSyntheticLocal(ctx, name: "$t", type: STT_NOTYPE, value: off, size: 0, section&: isec);
455 } else {
456 addSyntheticLocal(ctx, name: "$a", type: STT_NOTYPE, value: off, size: 0, section&: isec);
457 addSyntheticLocal(ctx, name: "$d", type: STT_NOTYPE, value: off + 12, size: 0, section&: isec);
458 }
459}
460
461bool ARM::needsThunk(RelExpr expr, RelType type, const InputFile *file,
462 uint64_t branchAddr, const Symbol &s,
463 int64_t a) const {
464 // If s is an undefined weak symbol and does not have a PLT entry then it will
465 // be resolved as a branch to the next instruction. If it is hidden, its
466 // binding has been converted to local, so we just check isUndefined() here. A
467 // undefined non-weak symbol will have been errored.
468 if (s.isUndefined() && !s.isInPlt(ctx))
469 return false;
470 // A state change from ARM to Thumb and vice versa must go through an
471 // interworking thunk if the relocation type is not R_ARM_CALL or
472 // R_ARM_THM_CALL.
473 switch (type) {
474 case R_ARM_PC24:
475 case R_ARM_PLT32:
476 case R_ARM_JUMP24:
477 // Source is ARM, all PLT entries are ARM so no interworking required.
478 // Otherwise we need to interwork if STT_FUNC Symbol has bit 0 set (Thumb).
479 assert(!useThumbPLTs(ctx) &&
480 "If the source is ARM, we should not need Thumb PLTs");
481 if (s.isFunc() && expr == R_PC && (s.getVA(ctx) & 1))
482 return true;
483 [[fallthrough]];
484 case R_ARM_CALL: {
485 uint64_t dst = (expr == R_PLT_PC) ? s.getPltVA(ctx) : s.getVA(ctx);
486 return !inBranchRange(type, src: branchAddr, dst: dst + a) ||
487 (!ctx.arg.armHasBlx && (s.getVA(ctx) & 1));
488 }
489 case R_ARM_THM_JUMP19:
490 case R_ARM_THM_JUMP24:
491 // Source is Thumb, when all PLT entries are ARM interworking is required.
492 // Otherwise we need to interwork if STT_FUNC Symbol has bit 0 clear (ARM).
493 if ((expr == R_PLT_PC && !useThumbPLTs(ctx)) ||
494 (s.isFunc() && (s.getVA(ctx) & 1) == 0))
495 return true;
496 [[fallthrough]];
497 case R_ARM_THM_CALL: {
498 uint64_t dst = (expr == R_PLT_PC) ? s.getPltVA(ctx) : s.getVA(ctx);
499 return !inBranchRange(type, src: branchAddr, dst: dst + a) ||
500 (!ctx.arg.armHasBlx && (s.getVA(ctx) & 1) == 0);
501 }
502 }
503 return false;
504}
505
506uint32_t ARM::getThunkSectionSpacing() const {
507 // The placing of pre-created ThunkSections is controlled by the value
508 // thunkSectionSpacing returned by getThunkSectionSpacing(). The aim is to
509 // place the ThunkSection such that all branches from the InputSections
510 // prior to the ThunkSection can reach a Thunk placed at the end of the
511 // ThunkSection. Graphically:
512 // | up to thunkSectionSpacing .text input sections |
513 // | ThunkSection |
514 // | up to thunkSectionSpacing .text input sections |
515 // | ThunkSection |
516
517 // Pre-created ThunkSections are spaced roughly 16MiB apart on ARMv7. This
518 // is to match the most common expected case of a Thumb 2 encoded BL, BLX or
519 // B.W:
520 // ARM B, BL, BLX range +/- 32MiB
521 // Thumb B.W, BL, BLX range +/- 16MiB
522 // Thumb B<cc>.W range +/- 1MiB
523 // If a branch cannot reach a pre-created ThunkSection a new one will be
524 // created so we can handle the rare cases of a Thumb 2 conditional branch.
525 // We intentionally use a lower size for thunkSectionSpacing than the maximum
526 // branch range so the end of the ThunkSection is more likely to be within
527 // range of the branch instruction that is furthest away. The value we shorten
528 // thunkSectionSpacing by is set conservatively to allow us to create 16,384
529 // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
530 // one of the Thunks going out of range.
531
532 // On Arm the thunkSectionSpacing depends on the range of the Thumb Branch
533 // range. On earlier Architectures such as ARMv4, ARMv5 and ARMv6 (except
534 // ARMv6T2) the range is +/- 4MiB.
535
536 return (ctx.arg.armJ1J2BranchEncoding) ? 0x1000000 - 0x30000
537 : 0x400000 - 0x7500;
538}
539
540bool ARM::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
541 if ((dst & 0x1) == 0)
542 // Destination is ARM, if ARM caller then Src is already 4-byte aligned.
543 // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
544 // destination will be 4 byte aligned.
545 src &= ~0x3;
546 else
547 // Bit 0 == 1 denotes Thumb state, it is not part of the range.
548 dst &= ~0x1;
549
550 int64_t offset = llvm::SignExtend64<32>(x: dst - src);
551 switch (type) {
552 case R_ARM_PC24:
553 case R_ARM_PLT32:
554 case R_ARM_JUMP24:
555 case R_ARM_CALL:
556 return llvm::isInt<26>(x: offset);
557 case R_ARM_THM_JUMP19:
558 return llvm::isInt<21>(x: offset);
559 case R_ARM_THM_JUMP24:
560 case R_ARM_THM_CALL:
561 return ctx.arg.armJ1J2BranchEncoding ? llvm::isInt<25>(x: offset)
562 : llvm::isInt<23>(x: offset);
563 default:
564 return true;
565 }
566}
567
568// Helper to produce message text when LLD detects that a CALL relocation to
569// a non STT_FUNC symbol that may result in incorrect interworking between ARM
570// or Thumb.
571static void stateChangeWarning(Ctx &ctx, uint8_t *loc, RelType relt,
572 const Symbol &s) {
573 assert(!s.isFunc());
574 const ErrorPlace place = getErrorPlace(ctx, loc);
575 std::string hint;
576 if (!place.srcLoc.empty())
577 hint = "; " + place.srcLoc;
578 if (s.isSection()) {
579 // Section symbols must be defined and in a section. Users cannot change
580 // the type. Use the section name as getName() returns an empty string.
581 Warn(ctx) << place.loc << "branch and link relocation: " << relt
582 << " to STT_SECTION symbol " << cast<Defined>(Val: s).section->name
583 << " ; interworking not performed" << hint;
584 } else {
585 // Warn with hint on how to alter the symbol type.
586 Warn(ctx)
587 << getErrorLoc(ctx, loc) << "branch and link relocation: " << relt
588 << " to non STT_FUNC symbol: " << s.getName()
589 << " interworking not performed; consider using directive '.type "
590 << s.getName()
591 << ", %function' to give symbol type STT_FUNC if interworking between "
592 "ARM and Thumb is required"
593 << hint;
594 }
595}
596
597// Rotate a 32-bit unsigned value right by a specified amt of bits.
598static uint32_t rotr32(uint32_t val, uint32_t amt) {
599 assert(amt < 32 && "Invalid rotate amount");
600 return (val >> amt) | (val << ((32 - amt) & 31));
601}
602
603static std::pair<uint32_t, uint32_t> getRemAndLZForGroup(unsigned group,
604 uint32_t val) {
605 uint32_t rem, lz;
606 do {
607 lz = llvm::countl_zero(Val: val) & ~1;
608 rem = val;
609 if (lz == 32) // implies rem == 0
610 break;
611 val &= 0xffffff >> lz;
612 } while (group--);
613 return {rem, lz};
614}
615
616void ARM::encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
617 int group, bool check) const {
618 // ADD/SUB (immediate) add = bit23, sub = bit22
619 // immediate field carries is a 12-bit modified immediate, made up of a 4-bit
620 // even rotate right and an 8-bit immediate.
621 uint32_t opcode = 0x00800000;
622 if (val >> 63) {
623 opcode = 0x00400000;
624 val = -val;
625 }
626 uint32_t imm, lz;
627 std::tie(args&: imm, args&: lz) = getRemAndLZForGroup(group, val);
628 uint32_t rot = 0;
629 if (lz < 24) {
630 imm = rotr32(val: imm, amt: 24 - lz);
631 rot = (lz + 8) << 7;
632 }
633 if (check && imm > 0xff)
634 Err(ctx) << getErrorLoc(ctx, loc) << "unencodeable immediate " << val
635 << " for relocation " << rel.type;
636 write32(ctx, p: loc,
637 v: (read32(ctx, p: loc) & 0xff3ff000) | opcode | rot | (imm & 0xff));
638}
639
640static void encodeLdrGroup(Ctx &ctx, uint8_t *loc, const Relocation &rel,
641 uint64_t val, int group) {
642 // R_ARM_LDR_PC_Gn is S + A - P, we have ((S + A) | T) - P, if S is a
643 // function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear
644 // bottom bit to recover S + A - P.
645 if (rel.sym->isFunc())
646 val &= ~0x1;
647 // LDR (literal) u = bit23
648 uint32_t opcode = 0x00800000;
649 if (val >> 63) {
650 opcode = 0x0;
651 val = -val;
652 }
653 uint32_t imm = getRemAndLZForGroup(group, val).first;
654 checkUInt(ctx, loc, v: imm, n: 12, rel);
655 write32(ctx, p: loc, v: (read32(ctx, p: loc) & 0xff7ff000) | opcode | imm);
656}
657
658static void encodeLdrsGroup(Ctx &ctx, uint8_t *loc, const Relocation &rel,
659 uint64_t val, int group) {
660 // R_ARM_LDRS_PC_Gn is S + A - P, we have ((S + A) | T) - P, if S is a
661 // function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear
662 // bottom bit to recover S + A - P.
663 if (rel.sym->isFunc())
664 val &= ~0x1;
665 // LDRD/LDRH/LDRSB/LDRSH (literal) u = bit23
666 uint32_t opcode = 0x00800000;
667 if (val >> 63) {
668 opcode = 0x0;
669 val = -val;
670 }
671 uint32_t imm = getRemAndLZForGroup(group, val).first;
672 checkUInt(ctx, loc, v: imm, n: 8, rel);
673 write32(ctx, p: loc,
674 v: (read32(ctx, p: loc) & 0xff7ff0f0) | opcode | ((imm & 0xf0) << 4) |
675 (imm & 0xf));
676}
677
678void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
679 switch (rel.type) {
680 case R_ARM_ABS32:
681 case R_ARM_BASE_PREL:
682 case R_ARM_GOTOFF32:
683 case R_ARM_GOT_BREL:
684 case R_ARM_GOT_PREL:
685 case R_ARM_REL32:
686 case R_ARM_RELATIVE:
687 case R_ARM_SBREL32:
688 case R_ARM_TARGET1:
689 case R_ARM_TARGET2:
690 case R_ARM_TLS_GD32:
691 case R_ARM_TLS_IE32:
692 case R_ARM_TLS_LDM32:
693 case R_ARM_TLS_LDO32:
694 case R_ARM_TLS_LE32:
695 case R_ARM_TLS_TPOFF32:
696 case R_ARM_TLS_DTPOFF32:
697 write32(ctx, p: loc, v: val);
698 break;
699 case R_ARM_PREL31:
700 checkInt(ctx, loc, v: val, n: 31, rel);
701 write32(ctx, p: loc, v: (read32(ctx, p: loc) & 0x80000000) | (val & ~0x80000000));
702 break;
703 case R_ARM_CALL: {
704 // R_ARM_CALL is used for BL and BLX instructions, for symbols of type
705 // STT_FUNC we choose whether to write a BL or BLX depending on the
706 // value of bit 0 of Val. With bit 0 == 1 denoting Thumb. If the symbol is
707 // not of type STT_FUNC then we must preserve the original instruction.
708 assert(rel.sym); // R_ARM_CALL is always reached via relocate().
709 bool bit0Thumb = val & 1;
710 bool isBlx = (read32(ctx, p: loc) & 0xfe000000) == 0xfa000000;
711 // lld 10.0 and before always used bit0Thumb when deciding to write a BLX
712 // even when type not STT_FUNC.
713 if (!rel.sym->isFunc() && isBlx != bit0Thumb)
714 stateChangeWarning(ctx, loc, relt: rel.type, s: *rel.sym);
715 if (rel.sym->isFunc() ? bit0Thumb : isBlx) {
716 // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
717 checkInt(ctx, loc, v: val, n: 26, rel);
718 write32(ctx, p: loc,
719 v: 0xfa000000 | // opcode
720 ((val & 2) << 23) | // H
721 ((val >> 2) & 0x00ffffff)); // imm24
722 break;
723 }
724 // BLX (always unconditional) instruction to an ARM Target, select an
725 // unconditional BL.
726 write32(ctx, p: loc, v: 0xeb000000 | (read32(ctx, p: loc) & 0x00ffffff));
727 // fall through as BL encoding is shared with B
728 }
729 [[fallthrough]];
730 case R_ARM_JUMP24:
731 case R_ARM_PC24:
732 case R_ARM_PLT32:
733 checkInt(ctx, loc, v: val, n: 26, rel);
734 write32(ctx, p: loc,
735 v: (read32(ctx, p: loc) & ~0x00ffffff) | ((val >> 2) & 0x00ffffff));
736 break;
737 case R_ARM_THM_JUMP8:
738 // We do a 9 bit check because val is right-shifted by 1 bit.
739 checkInt(ctx, loc, v: val, n: 9, rel);
740 write16(ctx, p: loc, v: (read16(ctx, p: loc) & 0xff00) | ((val >> 1) & 0x00ff));
741 break;
742 case R_ARM_THM_JUMP11:
743 // We do a 12 bit check because val is right-shifted by 1 bit.
744 checkInt(ctx, loc, v: val, n: 12, rel);
745 write16(ctx, p: loc, v: (read16(ctx, p: loc) & 0xf800) | ((val >> 1) & 0x07ff));
746 break;
747 case R_ARM_THM_JUMP19:
748 // Encoding T3: Val = S:J2:J1:imm6:imm11:0
749 checkInt(ctx, loc, v: val, n: 21, rel);
750 write16(ctx, p: loc,
751 v: (read16(ctx, p: loc) & 0xfbc0) | // opcode cond
752 ((val >> 10) & 0x0400) | // S
753 ((val >> 12) & 0x003f)); // imm6
754 write16(ctx, p: loc + 2,
755 v: 0x8000 | // opcode
756 ((val >> 8) & 0x0800) | // J2
757 ((val >> 5) & 0x2000) | // J1
758 ((val >> 1) & 0x07ff)); // imm11
759 break;
760 case R_ARM_THM_CALL: {
761 // R_ARM_THM_CALL is used for BL and BLX instructions, for symbols of type
762 // STT_FUNC we choose whether to write a BL or BLX depending on the
763 // value of bit 0 of Val. With bit 0 == 0 denoting ARM, if the symbol is
764 // not of type STT_FUNC then we must preserve the original instruction.
765 // PLT entries are always ARM state so we know we need to interwork.
766 assert(rel.sym); // R_ARM_THM_CALL is always reached via relocate().
767 bool bit0Thumb = val & 1;
768 bool useThumb = bit0Thumb || useThumbPLTs(ctx);
769 bool isBlx = (read16(ctx, p: loc + 2) & 0x1000) == 0;
770 // lld 10.0 and before always used bit0Thumb when deciding to write a BLX
771 // even when type not STT_FUNC.
772 if (!rel.sym->isFunc() && !rel.sym->isInPlt(ctx) && isBlx == useThumb)
773 stateChangeWarning(ctx, loc, relt: rel.type, s: *rel.sym);
774 if ((rel.sym->isFunc() || rel.sym->isInPlt(ctx)) ? !useThumb : isBlx) {
775 // We are writing a BLX. Ensure BLX destination is 4-byte aligned. As
776 // the BLX instruction may only be two byte aligned. This must be done
777 // before overflow check.
778 val = alignTo(Value: val, Align: 4);
779 write16(ctx, p: loc + 2, v: read16(ctx, p: loc + 2) & ~0x1000);
780 } else {
781 write16(ctx, p: loc + 2, v: (read16(ctx, p: loc + 2) & ~0x1000) | 1 << 12);
782 }
783 if (!ctx.arg.armJ1J2BranchEncoding) {
784 // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
785 // different encoding rules and range due to J1 and J2 always being 1.
786 checkInt(ctx, loc, v: val, n: 23, rel);
787 write16(ctx, p: loc,
788 v: 0xf000 | // opcode
789 ((val >> 12) & 0x07ff)); // imm11
790 write16(ctx, p: loc + 2,
791 v: (read16(ctx, p: loc + 2) & 0xd000) | // opcode
792 0x2800 | // J1 == J2 == 1
793 ((val >> 1) & 0x07ff)); // imm11
794 break;
795 }
796 }
797 // Fall through as rest of encoding is the same as B.W
798 [[fallthrough]];
799 case R_ARM_THM_JUMP24:
800 // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
801 checkInt(ctx, loc, v: val, n: 25, rel);
802 write16(ctx, p: loc,
803 v: 0xf000 | // opcode
804 ((val >> 14) & 0x0400) | // S
805 ((val >> 12) & 0x03ff)); // imm10
806 write16(ctx, p: loc + 2,
807 v: (read16(ctx, p: loc + 2) & 0xd000) | // opcode
808 (((~(val >> 10)) ^ (val >> 11)) & 0x2000) | // J1
809 (((~(val >> 11)) ^ (val >> 13)) & 0x0800) | // J2
810 ((val >> 1) & 0x07ff)); // imm11
811 break;
812 case R_ARM_MOVW_ABS_NC:
813 case R_ARM_MOVW_PREL_NC:
814 case R_ARM_MOVW_BREL_NC:
815 write32(ctx, p: loc,
816 v: (read32(ctx, p: loc) & ~0x000f0fff) | ((val & 0xf000) << 4) |
817 (val & 0x0fff));
818 break;
819 case R_ARM_MOVT_ABS:
820 case R_ARM_MOVT_PREL:
821 case R_ARM_MOVT_BREL:
822 write32(ctx, p: loc,
823 v: (read32(ctx, p: loc) & ~0x000f0fff) | (((val >> 16) & 0xf000) << 4) |
824 ((val >> 16) & 0xfff));
825 break;
826 case R_ARM_THM_MOVT_ABS:
827 case R_ARM_THM_MOVT_PREL:
828 case R_ARM_THM_MOVT_BREL:
829 // Encoding T1: A = imm4:i:imm3:imm8
830
831 write16(ctx, p: loc,
832 v: 0xf2c0 | // opcode
833 ((val >> 17) & 0x0400) | // i
834 ((val >> 28) & 0x000f)); // imm4
835
836 write16(ctx, p: loc + 2,
837 v: (read16(ctx, p: loc + 2) & 0x8f00) | // opcode
838 ((val >> 12) & 0x7000) | // imm3
839 ((val >> 16) & 0x00ff)); // imm8
840 break;
841 case R_ARM_THM_MOVW_ABS_NC:
842 case R_ARM_THM_MOVW_PREL_NC:
843 case R_ARM_THM_MOVW_BREL_NC:
844 // Encoding T3: A = imm4:i:imm3:imm8
845 write16(ctx, p: loc,
846 v: 0xf240 | // opcode
847 ((val >> 1) & 0x0400) | // i
848 ((val >> 12) & 0x000f)); // imm4
849 write16(ctx, p: loc + 2,
850 v: (read16(ctx, p: loc + 2) & 0x8f00) | // opcode
851 ((val << 4) & 0x7000) | // imm3
852 (val & 0x00ff)); // imm8
853 break;
854 case R_ARM_THM_ALU_ABS_G3:
855 write16(ctx, p: loc, v: (read16(ctx, p: loc) & ~0x00ff) | ((val >> 24) & 0x00ff));
856 break;
857 case R_ARM_THM_ALU_ABS_G2_NC:
858 write16(ctx, p: loc, v: (read16(ctx, p: loc) & ~0x00ff) | ((val >> 16) & 0x00ff));
859 break;
860 case R_ARM_THM_ALU_ABS_G1_NC:
861 write16(ctx, p: loc, v: (read16(ctx, p: loc) & ~0x00ff) | ((val >> 8) & 0x00ff));
862 break;
863 case R_ARM_THM_ALU_ABS_G0_NC:
864 write16(ctx, p: loc, v: (read16(ctx, p: loc) & ~0x00ff) | (val & 0x00ff));
865 break;
866 case R_ARM_ALU_PC_G0:
867 encodeAluGroup(loc, rel, val, group: 0, check: true);
868 break;
869 case R_ARM_ALU_PC_G0_NC:
870 encodeAluGroup(loc, rel, val, group: 0, check: false);
871 break;
872 case R_ARM_ALU_PC_G1:
873 encodeAluGroup(loc, rel, val, group: 1, check: true);
874 break;
875 case R_ARM_ALU_PC_G1_NC:
876 encodeAluGroup(loc, rel, val, group: 1, check: false);
877 break;
878 case R_ARM_ALU_PC_G2:
879 encodeAluGroup(loc, rel, val, group: 2, check: true);
880 break;
881 case R_ARM_LDR_PC_G0:
882 encodeLdrGroup(ctx, loc, rel, val, group: 0);
883 break;
884 case R_ARM_LDR_PC_G1:
885 encodeLdrGroup(ctx, loc, rel, val, group: 1);
886 break;
887 case R_ARM_LDR_PC_G2:
888 encodeLdrGroup(ctx, loc, rel, val, group: 2);
889 break;
890 case R_ARM_LDRS_PC_G0:
891 encodeLdrsGroup(ctx, loc, rel, val, group: 0);
892 break;
893 case R_ARM_LDRS_PC_G1:
894 encodeLdrsGroup(ctx, loc, rel, val, group: 1);
895 break;
896 case R_ARM_LDRS_PC_G2:
897 encodeLdrsGroup(ctx, loc, rel, val, group: 2);
898 break;
899 case R_ARM_THM_ALU_PREL_11_0: {
900 // ADR encoding T2 (sub), T3 (add) i:imm3:imm8
901 int64_t imm = val;
902 uint16_t sub = 0;
903 if (imm < 0) {
904 imm = -imm;
905 sub = 0x00a0;
906 }
907 checkUInt(ctx, loc, v: imm, n: 12, rel);
908 write16(ctx, p: loc, v: (read16(ctx, p: loc) & 0xfb0f) | sub | (imm & 0x800) >> 1);
909 write16(ctx, p: loc + 2,
910 v: (read16(ctx, p: loc + 2) & 0x8f00) | (imm & 0x700) << 4 |
911 (imm & 0xff));
912 break;
913 }
914 case R_ARM_THM_PC8:
915 // ADR and LDR literal encoding T1 positive offset only imm8:00
916 // R_ARM_THM_PC8 is S + A - Pa, we have ((S + A) | T) - Pa, if S is a
917 // function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear
918 // bottom bit to recover S + A - Pa.
919 if (rel.sym->isFunc())
920 val &= ~0x1;
921 checkUInt(ctx, loc, v: val, n: 10, rel);
922 checkAlignment(ctx, loc, v: val, n: 4, rel);
923 write16(ctx, p: loc, v: (read16(ctx, p: loc) & 0xff00) | (val & 0x3fc) >> 2);
924 break;
925 case R_ARM_THM_PC12: {
926 // LDR (literal) encoding T2, add = (U == '1') imm12
927 // imm12 is unsigned
928 // R_ARM_THM_PC12 is S + A - Pa, we have ((S + A) | T) - Pa, if S is a
929 // function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear
930 // bottom bit to recover S + A - Pa.
931 if (rel.sym->isFunc())
932 val &= ~0x1;
933 int64_t imm12 = val;
934 uint16_t u = 0x0080;
935 if (imm12 < 0) {
936 imm12 = -imm12;
937 u = 0;
938 }
939 checkUInt(ctx, loc, v: imm12, n: 12, rel);
940 write16(ctx, p: loc, v: read16(ctx, p: loc) | u);
941 write16(ctx, p: loc + 2, v: (read16(ctx, p: loc + 2) & 0xf000) | imm12);
942 break;
943 }
944 default:
945 llvm_unreachable("unknown relocation");
946 }
947}
948
949int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
950 switch (type) {
951 default:
952 InternalErr(ctx, buf) << "cannot read addend for relocation " << type;
953 return 0;
954 case R_ARM_ABS32:
955 case R_ARM_BASE_PREL:
956 case R_ARM_GLOB_DAT:
957 case R_ARM_GOTOFF32:
958 case R_ARM_GOT_BREL:
959 case R_ARM_GOT_PREL:
960 case R_ARM_IRELATIVE:
961 case R_ARM_REL32:
962 case R_ARM_RELATIVE:
963 case R_ARM_SBREL32:
964 case R_ARM_TARGET1:
965 case R_ARM_TARGET2:
966 case R_ARM_TLS_DTPMOD32:
967 case R_ARM_TLS_DTPOFF32:
968 case R_ARM_TLS_GD32:
969 case R_ARM_TLS_IE32:
970 case R_ARM_TLS_LDM32:
971 case R_ARM_TLS_LE32:
972 case R_ARM_TLS_LDO32:
973 case R_ARM_TLS_TPOFF32:
974 return SignExtend64<32>(x: read32(ctx, p: buf));
975 case R_ARM_PREL31:
976 return SignExtend64<31>(x: read32(ctx, p: buf));
977 case R_ARM_CALL:
978 case R_ARM_JUMP24:
979 case R_ARM_PC24:
980 case R_ARM_PLT32:
981 return SignExtend64<26>(x: read32(ctx, p: buf) << 2);
982 case R_ARM_THM_JUMP8:
983 return SignExtend64<9>(x: read16(ctx, p: buf) << 1);
984 case R_ARM_THM_JUMP11:
985 return SignExtend64<12>(x: read16(ctx, p: buf) << 1);
986 case R_ARM_THM_JUMP19: {
987 // Encoding T3: A = S:J2:J1:imm10:imm6:0
988 uint16_t hi = read16(ctx, p: buf);
989 uint16_t lo = read16(ctx, p: buf + 2);
990 return SignExtend64<20>(x: ((hi & 0x0400) << 10) | // S
991 ((lo & 0x0800) << 8) | // J2
992 ((lo & 0x2000) << 5) | // J1
993 ((hi & 0x003f) << 12) | // imm6
994 ((lo & 0x07ff) << 1)); // imm11:0
995 }
996 case R_ARM_THM_CALL:
997 if (!ctx.arg.armJ1J2BranchEncoding) {
998 // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
999 // different encoding rules and range due to J1 and J2 always being 1.
1000 uint16_t hi = read16(ctx, p: buf);
1001 uint16_t lo = read16(ctx, p: buf + 2);
1002 return SignExtend64<22>(x: ((hi & 0x7ff) << 12) | // imm11
1003 ((lo & 0x7ff) << 1)); // imm11:0
1004 break;
1005 }
1006 [[fallthrough]];
1007 case R_ARM_THM_JUMP24: {
1008 // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
1009 // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
1010 uint16_t hi = read16(ctx, p: buf);
1011 uint16_t lo = read16(ctx, p: buf + 2);
1012 return SignExtend64<24>(x: ((hi & 0x0400) << 14) | // S
1013 (~((lo ^ (hi << 3)) << 10) & 0x00800000) | // I1
1014 (~((lo ^ (hi << 1)) << 11) & 0x00400000) | // I2
1015 ((hi & 0x003ff) << 12) | // imm0
1016 ((lo & 0x007ff) << 1)); // imm11:0
1017 }
1018 // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
1019 // MOVT is in the range -32768 <= A < 32768
1020 case R_ARM_MOVW_ABS_NC:
1021 case R_ARM_MOVT_ABS:
1022 case R_ARM_MOVW_PREL_NC:
1023 case R_ARM_MOVT_PREL:
1024 case R_ARM_MOVW_BREL_NC:
1025 case R_ARM_MOVT_BREL: {
1026 uint64_t val = read32(ctx, p: buf) & 0x000f0fff;
1027 return SignExtend64<16>(x: ((val & 0x000f0000) >> 4) | (val & 0x00fff));
1028 }
1029 case R_ARM_THM_MOVW_ABS_NC:
1030 case R_ARM_THM_MOVT_ABS:
1031 case R_ARM_THM_MOVW_PREL_NC:
1032 case R_ARM_THM_MOVT_PREL:
1033 case R_ARM_THM_MOVW_BREL_NC:
1034 case R_ARM_THM_MOVT_BREL: {
1035 // Encoding T3: A = imm4:i:imm3:imm8
1036 uint16_t hi = read16(ctx, p: buf);
1037 uint16_t lo = read16(ctx, p: buf + 2);
1038 return SignExtend64<16>(x: ((hi & 0x000f) << 12) | // imm4
1039 ((hi & 0x0400) << 1) | // i
1040 ((lo & 0x7000) >> 4) | // imm3
1041 (lo & 0x00ff)); // imm8
1042 }
1043 case R_ARM_THM_ALU_ABS_G0_NC:
1044 case R_ARM_THM_ALU_ABS_G1_NC:
1045 case R_ARM_THM_ALU_ABS_G2_NC:
1046 case R_ARM_THM_ALU_ABS_G3:
1047 return read16(ctx, p: buf) & 0xff;
1048 case R_ARM_ALU_PC_G0:
1049 case R_ARM_ALU_PC_G0_NC:
1050 case R_ARM_ALU_PC_G1:
1051 case R_ARM_ALU_PC_G1_NC:
1052 case R_ARM_ALU_PC_G2: {
1053 // 12-bit immediate is a modified immediate made up of a 4-bit even
1054 // right rotation and 8-bit constant. After the rotation the value
1055 // is zero-extended. When bit 23 is set the instruction is an add, when
1056 // bit 22 is set it is a sub.
1057 uint32_t instr = read32(ctx, p: buf);
1058 uint32_t val = rotr32(val: instr & 0xff, amt: ((instr & 0xf00) >> 8) * 2);
1059 return (instr & 0x00400000) ? -val : val;
1060 }
1061 case R_ARM_LDR_PC_G0:
1062 case R_ARM_LDR_PC_G1:
1063 case R_ARM_LDR_PC_G2: {
1064 // ADR (literal) add = bit23, sub = bit22
1065 // LDR (literal) u = bit23 unsigned imm12
1066 bool u = read32(ctx, p: buf) & 0x00800000;
1067 uint32_t imm12 = read32(ctx, p: buf) & 0xfff;
1068 return u ? imm12 : -imm12;
1069 }
1070 case R_ARM_LDRS_PC_G0:
1071 case R_ARM_LDRS_PC_G1:
1072 case R_ARM_LDRS_PC_G2: {
1073 // LDRD/LDRH/LDRSB/LDRSH (literal) u = bit23 unsigned imm8
1074 uint32_t opcode = read32(ctx, p: buf);
1075 bool u = opcode & 0x00800000;
1076 uint32_t imm4l = opcode & 0xf;
1077 uint32_t imm4h = (opcode & 0xf00) >> 4;
1078 return u ? (imm4h | imm4l) : -(imm4h | imm4l);
1079 }
1080 case R_ARM_THM_ALU_PREL_11_0: {
1081 // Thumb2 ADR, which is an alias for a sub or add instruction with an
1082 // unsigned immediate.
1083 // ADR encoding T2 (sub), T3 (add) i:imm3:imm8
1084 uint16_t hi = read16(ctx, p: buf);
1085 uint16_t lo = read16(ctx, p: buf + 2);
1086 uint64_t imm = (hi & 0x0400) << 1 | // i
1087 (lo & 0x7000) >> 4 | // imm3
1088 (lo & 0x00ff); // imm8
1089 // For sub, addend is negative, add is positive.
1090 return (hi & 0x00f0) ? -imm : imm;
1091 }
1092 case R_ARM_THM_PC8:
1093 // ADR and LDR (literal) encoding T1
1094 // From ELF for the ARM Architecture the initial signed addend is formed
1095 // from an unsigned field using expression (((imm8:00 + 4) & 0x3ff) – 4)
1096 // this trick permits the PC bias of -4 to be encoded using imm8 = 0xff
1097 return ((((read16(ctx, p: buf) & 0xff) << 2) + 4) & 0x3ff) - 4;
1098 case R_ARM_THM_PC12: {
1099 // LDR (literal) encoding T2, add = (U == '1') imm12
1100 bool u = read16(ctx, p: buf) & 0x0080;
1101 uint64_t imm12 = read16(ctx, p: buf + 2) & 0x0fff;
1102 return u ? imm12 : -imm12;
1103 }
1104 case R_ARM_NONE:
1105 case R_ARM_V4BX:
1106 case R_ARM_JUMP_SLOT:
1107 // These relocations are defined as not having an implicit addend.
1108 return 0;
1109 }
1110}
1111
1112static bool isArmMapSymbol(const Symbol *b) {
1113 return b->getName() == "$a" || b->getName().starts_with(Prefix: "$a.");
1114}
1115
1116static bool isThumbMapSymbol(const Symbol *s) {
1117 return s->getName() == "$t" || s->getName().starts_with(Prefix: "$t.");
1118}
1119
1120static bool isDataMapSymbol(const Symbol *b) {
1121 return b->getName() == "$d" || b->getName().starts_with(Prefix: "$d.");
1122}
1123
1124void elf::sortArmMappingSymbols(Ctx &ctx) {
1125 // For each input section make sure the mapping symbols are sorted in
1126 // ascending order.
1127 for (auto &kv : static_cast<ARM &>(*ctx.target).sectionMap) {
1128 SmallVector<const Defined *, 0> &mapSyms = kv.second;
1129 llvm::stable_sort(Range&: mapSyms, C: [](const Defined *a, const Defined *b) {
1130 return a->value < b->value;
1131 });
1132 }
1133}
1134
1135void elf::addArmInputSectionMappingSymbols(Ctx &ctx) {
1136 // Collect mapping symbols for every executable input sections.
1137 // The linker generated mapping symbols for all the synthetic
1138 // sections are adding into the sectionmap through the function
1139 // addArmSyntheitcSectionMappingSymbol.
1140 auto &sectionMap = static_cast<ARM &>(*ctx.target).sectionMap;
1141 for (ELFFileBase *file : ctx.objectFiles) {
1142 for (Symbol *sym : file->getLocalSymbols()) {
1143 auto *def = dyn_cast<Defined>(Val: sym);
1144 if (!def)
1145 continue;
1146 if (!isArmMapSymbol(b: def) && !isDataMapSymbol(b: def) &&
1147 !isThumbMapSymbol(s: def))
1148 continue;
1149 if (auto *sec = cast_if_present<InputSection>(Val: def->section))
1150 if (sec->flags & SHF_EXECINSTR)
1151 sectionMap[sec].push_back(Elt: def);
1152 }
1153 }
1154}
1155
1156// Synthetic sections are not backed by an ELF file where we can access the
1157// symbol table, instead mapping symbols added to synthetic sections are stored
1158// in the synthetic symbol table. Due to the presence of strip (--strip-all),
1159// we can not rely on the synthetic symbol table retaining the mapping symbols.
1160// Instead we record the mapping symbols locally.
1161void elf::addArmSyntheticSectionMappingSymbol(Defined *sym) {
1162 if (!isArmMapSymbol(b: sym) && !isDataMapSymbol(b: sym) && !isThumbMapSymbol(s: sym))
1163 return;
1164 if (auto *sec = cast_if_present<InputSection>(Val: sym->section))
1165 if (sec->flags & SHF_EXECINSTR)
1166 static_cast<ARM &>(*sec->file->ctx.target).sectionMap[sec].push_back(Elt: sym);
1167}
1168
1169static void toLittleEndianInstructions(uint8_t *buf, uint64_t start,
1170 uint64_t end, uint64_t width) {
1171 CodeState curState = static_cast<CodeState>(width);
1172 if (curState == CodeState::Arm)
1173 for (uint64_t i = start; i < end; i += width)
1174 write32le(P: buf + i, V: read32be(P: buf + i));
1175
1176 if (curState == CodeState::Thumb)
1177 for (uint64_t i = start; i < end; i += width)
1178 write16le(P: buf + i, V: read16be(P: buf + i));
1179}
1180
1181// Arm BE8 big endian format requires instructions to be little endian, with
1182// the initial contents big-endian. Convert the big-endian instructions to
1183// little endian leaving literal data untouched. We use mapping symbols to
1184// identify half open intervals of Arm code [$a, non $a) and Thumb code
1185// [$t, non $t) and convert these to little endian a word or half word at a
1186// time respectively.
1187void elf::convertArmInstructionstoBE8(Ctx &ctx, InputSection *sec,
1188 uint8_t *buf) {
1189 auto &sectionMap = static_cast<ARM &>(*ctx.target).sectionMap;
1190 auto it = sectionMap.find(Val: sec);
1191 if (it == sectionMap.end())
1192 return;
1193
1194 SmallVector<const Defined *, 0> &mapSyms = it->second;
1195
1196 if (mapSyms.empty())
1197 return;
1198
1199 CodeState curState = CodeState::Data;
1200 uint64_t start = 0, width = 0, size = sec->getSize();
1201 for (auto &msym : mapSyms) {
1202 CodeState newState = CodeState::Data;
1203 if (isThumbMapSymbol(s: msym))
1204 newState = CodeState::Thumb;
1205 else if (isArmMapSymbol(b: msym))
1206 newState = CodeState::Arm;
1207
1208 if (newState == curState)
1209 continue;
1210
1211 if (curState != CodeState::Data) {
1212 width = static_cast<uint64_t>(curState);
1213 toLittleEndianInstructions(buf, start, end: msym->value, width);
1214 }
1215 start = msym->value;
1216 curState = newState;
1217 }
1218
1219 // Passed last mapping symbol, may need to reverse
1220 // up to end of section.
1221 if (curState != CodeState::Data) {
1222 width = static_cast<uint64_t>(curState);
1223 toLittleEndianInstructions(buf, start, end: size, width);
1224 }
1225}
1226
1227// The Arm Cortex-M Security Extensions (CMSE) splits a system into two parts;
1228// the non-secure and secure states with the secure state inaccessible from the
1229// non-secure state, apart from an area of memory in secure state called the
1230// secure gateway which is accessible from non-secure state. The secure gateway
1231// contains one or more entry points which must start with a landing pad
1232// instruction SG. Arm recommends that the secure gateway consists only of
1233// secure gateway veneers, which are made up of a SG instruction followed by a
1234// branch to the destination in secure state. Full details can be found in Arm
1235// v8-M Security Extensions Requirements on Development Tools.
1236//
1237// The CMSE model of software development requires the non-secure and secure
1238// states to be developed as two separate programs. The non-secure developer is
1239// provided with an import library defining symbols describing the entry points
1240// in the secure gateway. No additional linker support is required for the
1241// non-secure state.
1242//
1243// Development of the secure state requires linker support to manage the secure
1244// gateway veneers. The management consists of:
1245// - Creation of new secure gateway veneers based on symbol conventions.
1246// - Checking the address of existing secure gateway veneers.
1247// - Warning when existing secure gateway veneers removed.
1248//
1249// The secure gateway veneers are created in an import library, which is just an
1250// ELF object with a symbol table. The import library is controlled by two
1251// command line options:
1252// --in-implib (specify an input import library from a previous revision of the
1253// program).
1254// --out-implib (specify an output import library to be created by the linker).
1255//
1256// The input import library is used to manage consistency of the secure entry
1257// points. The output import library is for new and updated secure entry points.
1258//
1259// The symbol convention that identifies secure entry functions is the prefix
1260// __acle_se_ for a symbol called name the linker is expected to create a secure
1261// gateway veneer if symbols __acle_se_name and name have the same address.
1262// After creating a secure gateway veneer the symbol name labels the secure
1263// gateway veneer and the __acle_se_name labels the function definition.
1264//
1265// The LLD implementation:
1266// - Reads an existing import library with importCmseSymbols().
1267// - Determines which new secure gateway veneers to create and redirects calls
1268// within the secure state to the __acle_se_ prefixed symbol with
1269// processArmCmseSymbols().
1270// - Models the SG veneers as a synthetic section.
1271
1272// Initialize symbols. symbols is a parallel array to the corresponding ELF
1273// symbol table.
1274template <class ELFT> void ObjFile<ELFT>::importCmseSymbols() {
1275 ArrayRef<Elf_Sym> eSyms = getELFSyms<ELFT>();
1276 // Error for local symbols. The symbol at index 0 is LOCAL. So skip it.
1277 for (size_t i = 1, end = firstGlobal; i != end; ++i) {
1278 Err(ctx) << "CMSE symbol '" << CHECK2(eSyms[i].getName(stringTable), this)
1279 << "' in import library '" << this << "' is not global";
1280 }
1281
1282 for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) {
1283 const Elf_Sym &eSym = eSyms[i];
1284 Defined *sym = reinterpret_cast<Defined *>(make<SymbolUnion>());
1285
1286 // Initialize symbol fields.
1287 memset(s: static_cast<void *>(sym), c: 0, n: sizeof(Symbol));
1288 sym->setName(CHECK2(eSyms[i].getName(stringTable), this));
1289 sym->value = eSym.st_value;
1290 sym->size = eSym.st_size;
1291 sym->type = eSym.getType();
1292 sym->binding = eSym.getBinding();
1293 sym->stOther = eSym.st_other;
1294
1295 if (eSym.st_shndx != SHN_ABS) {
1296 Err(ctx) << "CMSE symbol '" << sym->getName() << "' in import library '"
1297 << this << "' is not absolute";
1298 continue;
1299 }
1300
1301 if (!(eSym.st_value & 1) || (eSym.getType() != STT_FUNC)) {
1302 Err(ctx) << "CMSE symbol '" << sym->getName() << "' in import library '"
1303 << this << "' is not a Thumb function definition";
1304 continue;
1305 }
1306
1307 if (ctx.symtab->cmseImportLib.contains(Key: sym->getName())) {
1308 Err(ctx) << "CMSE symbol '" << sym->getName()
1309 << "' is multiply defined in import library '" << this << "'";
1310 continue;
1311 }
1312
1313 if (eSym.st_size != ACLESESYM_SIZE) {
1314 Warn(ctx) << "CMSE symbol '" << sym->getName() << "' in import library '"
1315 << this << "' does not have correct size of " << ACLESESYM_SIZE
1316 << " bytes";
1317 }
1318
1319 ctx.symtab->cmseImportLib[sym->getName()] = sym;
1320 }
1321}
1322
1323// Check symbol attributes of the acleSeSym, sym pair.
1324// Both symbols should be global/weak Thumb code symbol definitions.
1325static std::string checkCmseSymAttributes(Ctx &ctx, Symbol *acleSeSym,
1326 Symbol *sym) {
1327 auto check = [&](Symbol *s, StringRef type) -> std::optional<std::string> {
1328 auto d = dyn_cast_or_null<Defined>(Val: s);
1329 if (!(d && d->isFunc() && (d->value & 1)))
1330 return (Twine(toStr(ctx, f: s->file)) + ": cmse " + type + " symbol '" +
1331 s->getName() + "' is not a Thumb function definition")
1332 .str();
1333 if (!d->section)
1334 return (Twine(toStr(ctx, f: s->file)) + ": cmse " + type + " symbol '" +
1335 s->getName() + "' cannot be an absolute symbol")
1336 .str();
1337 return std::nullopt;
1338 };
1339 for (auto [sym, type] :
1340 {std::make_pair(x&: acleSeSym, y: "special"), std::make_pair(x&: sym, y: "entry")})
1341 if (auto err = check(sym, type))
1342 return *err;
1343 return "";
1344}
1345
1346// Look for [__acle_se_<sym>, <sym>] pairs, as specified in the Cortex-M
1347// Security Extensions specification.
1348// 1) <sym> : A standard function name.
1349// 2) __acle_se_<sym> : A special symbol that prefixes the standard function
1350// name with __acle_se_.
1351// Both these symbols are Thumb function symbols with external linkage.
1352// <sym> may be redefined in .gnu.sgstubs.
1353void elf::processArmCmseSymbols(Ctx &ctx) {
1354 if (!ctx.arg.cmseImplib)
1355 return;
1356 // Only symbols with external linkage end up in ctx.symtab, so no need to do
1357 // linkage checks. Only check symbol type.
1358 for (Symbol *acleSeSym : ctx.symtab->getSymbols()) {
1359 if (!acleSeSym->getName().starts_with(Prefix: ACLESESYM_PREFIX))
1360 continue;
1361 // If input object build attributes do not support CMSE, error and disable
1362 // further scanning for <sym>, __acle_se_<sym> pairs.
1363 if (!ctx.arg.armCMSESupport) {
1364 Err(ctx) << "CMSE is only supported by ARMv8-M architecture or later";
1365 ctx.arg.cmseImplib = false;
1366 break;
1367 }
1368
1369 // Try to find the associated symbol definition.
1370 // Symbol must have external linkage.
1371 StringRef name = acleSeSym->getName().substr(Start: std::strlen(s: ACLESESYM_PREFIX));
1372 Symbol *sym = ctx.symtab->find(name);
1373 if (!sym) {
1374 Err(ctx) << acleSeSym->file << ": cmse special symbol '"
1375 << acleSeSym->getName()
1376 << "' detected, but no associated entry function definition '"
1377 << name << "' with external linkage found";
1378 continue;
1379 }
1380
1381 std::string errMsg = checkCmseSymAttributes(ctx, acleSeSym, sym);
1382 if (!errMsg.empty()) {
1383 Err(ctx) << errMsg;
1384 continue;
1385 }
1386
1387 // <sym> may be redefined later in the link in .gnu.sgstubs
1388 ctx.symtab->cmseSymMap[name] = {.acleSeSym: acleSeSym, .sym: sym};
1389 }
1390
1391 // If this is an Arm CMSE secure app, replace references to entry symbol <sym>
1392 // with its corresponding special symbol __acle_se_<sym>.
1393 parallelForEach(R&: ctx.objectFiles, Fn: [&](InputFile *file) {
1394 MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
1395 for (Symbol *&sym : syms) {
1396 StringRef symName = sym->getName();
1397 auto it = ctx.symtab->cmseSymMap.find(Key: symName);
1398 if (it != ctx.symtab->cmseSymMap.end())
1399 sym = it->second.acleSeSym;
1400 }
1401 });
1402}
1403
1404ArmCmseSGSection::ArmCmseSGSection(Ctx &ctx)
1405 : SyntheticSection(ctx, ".gnu.sgstubs", SHT_PROGBITS,
1406 SHF_ALLOC | SHF_EXECINSTR,
1407 /*addralign=*/32) {
1408 entsize = ACLESESYM_SIZE;
1409 // The range of addresses used in the CMSE import library should be fixed.
1410 for (auto &[_, sym] : ctx.symtab->cmseImportLib) {
1411 if (impLibMaxAddr <= sym->value)
1412 impLibMaxAddr = sym->value + sym->size;
1413 }
1414 if (ctx.symtab->cmseSymMap.empty())
1415 return;
1416 addMappingSymbol();
1417 for (auto &[_, entryFunc] : ctx.symtab->cmseSymMap)
1418 addSGVeneer(sym: cast<Defined>(Val: entryFunc.acleSeSym),
1419 ext_sym: cast<Defined>(Val: entryFunc.sym));
1420 for (auto &[_, sym] : ctx.symtab->cmseImportLib) {
1421 if (!ctx.symtab->inCMSEOutImpLib.contains(Key: sym->getName()))
1422 Warn(ctx)
1423 << "entry function '" << sym->getName()
1424 << "' from CMSE import library is not present in secure application";
1425 }
1426
1427 if (!ctx.symtab->cmseImportLib.empty() && ctx.arg.cmseOutputLib.empty()) {
1428 for (auto &[_, entryFunc] : ctx.symtab->cmseSymMap) {
1429 Symbol *sym = entryFunc.sym;
1430 if (!ctx.symtab->inCMSEOutImpLib.contains(Key: sym->getName()))
1431 Warn(ctx) << "new entry function '" << sym->getName()
1432 << "' introduced but no output import library specified";
1433 }
1434 }
1435}
1436
1437void ArmCmseSGSection::addSGVeneer(Symbol *acleSeSym, Symbol *sym) {
1438 entries.emplace_back(Args&: acleSeSym, Args&: sym);
1439 if (ctx.symtab->cmseImportLib.contains(Key: sym->getName()))
1440 ctx.symtab->inCMSEOutImpLib[sym->getName()] = true;
1441 // Symbol addresses different, nothing to do.
1442 if (acleSeSym->file != sym->file ||
1443 cast<Defined>(Val&: *acleSeSym).value != cast<Defined>(Val&: *sym).value)
1444 return;
1445 // Only secure symbols with values equal to that of it's non-secure
1446 // counterpart needs to be in the .gnu.sgstubs section.
1447 std::unique_ptr<ArmCmseSGVeneer> ss;
1448 auto it = ctx.symtab->cmseImportLib.find(Key: sym->getName());
1449 if (it != ctx.symtab->cmseImportLib.end()) {
1450 Defined *impSym = it->second;
1451 ss = std::make_unique<ArmCmseSGVeneer>(args&: sym, args&: acleSeSym, args&: impSym->value);
1452 } else {
1453 ss = std::make_unique<ArmCmseSGVeneer>(args&: sym, args&: acleSeSym);
1454 ++newEntries;
1455 }
1456 sgVeneers.emplace_back(Args: std::move(ss));
1457}
1458
1459void ArmCmseSGSection::writeTo(uint8_t *buf) {
1460 for (std::unique_ptr<ArmCmseSGVeneer> &s : sgVeneers) {
1461 uint8_t *p = buf + s->offset;
1462 write16(ctx, p: p + 0, v: 0xe97f); // SG
1463 write16(ctx, p: p + 2, v: 0xe97f);
1464 write16(ctx, p: p + 4, v: 0xf000); // B.W S
1465 write16(ctx, p: p + 6, v: 0xb000);
1466 ctx.target->relocateNoSym(loc: p + 4, type: R_ARM_THM_JUMP24,
1467 val: s->acleSeSym->getVA(ctx) -
1468 (getVA() + s->offset + s->size));
1469 }
1470}
1471
1472void ArmCmseSGSection::addMappingSymbol() {
1473 addSyntheticLocal(ctx, name: "$t", type: STT_NOTYPE, /*off=*/value: 0, /*size=*/0, section&: *this);
1474}
1475
1476size_t ArmCmseSGSection::getSize() const {
1477 if (sgVeneers.empty())
1478 return (impLibMaxAddr ? impLibMaxAddr - getVA() : 0) + newEntries * entsize;
1479
1480 return entries.size() * entsize;
1481}
1482
1483void ArmCmseSGSection::finalizeContents() {
1484 if (sgVeneers.empty())
1485 return;
1486
1487 auto it =
1488 std::stable_partition(first: sgVeneers.begin(), last: sgVeneers.end(),
1489 pred: [](auto &i) { return i->getAddr().has_value(); });
1490 std::sort(first: sgVeneers.begin(), last: it, comp: [](auto &a, auto &b) {
1491 return a->getAddr().value() < b->getAddr().value();
1492 });
1493 // This is the partition of the veneers with fixed addresses.
1494 uint64_t addr = (*sgVeneers.begin())->getAddr().has_value()
1495 ? (*sgVeneers.begin())->getAddr().value()
1496 : getVA();
1497 // Check if the start address of '.gnu.sgstubs' correspond to the
1498 // linker-synthesized veneer with the lowest address.
1499 if ((getVA() & ~1) != (addr & ~1)) {
1500 Err(ctx)
1501 << "start address of '.gnu.sgstubs' is different from previous link";
1502 return;
1503 }
1504
1505 for (auto [i, s] : enumerate(First&: sgVeneers)) {
1506 s->offset = i * s->size;
1507 Defined(ctx, file, StringRef(), s->sym->binding, s->sym->stOther,
1508 s->sym->type, s->offset | 1, s->size, this)
1509 .overwrite(sym&: *s->sym);
1510 }
1511}
1512
1513// Write the CMSE import library to disk.
1514// The CMSE import library is a relocatable object with only a symbol table.
1515// The symbols are copies of the (absolute) symbols of the secure gateways
1516// in the executable output by this link.
1517// See ArmĀ® v8-M Security Extensions: Requirements on Development Tools
1518// https://developer.arm.com/documentation/ecm0359818/latest
1519template <typename ELFT> void elf::writeARMCmseImportLib(Ctx &ctx) {
1520 auto shstrtab =
1521 std::make_unique<StringTableSection>(args&: ctx, args: ".shstrtab", /*dynamic=*/args: false);
1522 auto strtab =
1523 std::make_unique<StringTableSection>(args&: ctx, args: ".strtab", /*dynamic=*/args: false);
1524 auto impSymTab = std::make_unique<SymbolTableSection<ELFT>>(ctx, *strtab);
1525
1526 SmallVector<std::pair<std::unique_ptr<OutputSection>, SyntheticSection *>, 0>
1527 osIsPairs;
1528 osIsPairs.emplace_back(
1529 Args: std::make_unique<OutputSection>(args&: ctx, args&: strtab->name, args: 0, args: 0), Args: strtab.get());
1530 osIsPairs.emplace_back(
1531 std::make_unique<OutputSection>(ctx, impSymTab->name, 0, 0),
1532 impSymTab.get());
1533 osIsPairs.emplace_back(
1534 Args: std::make_unique<OutputSection>(args&: ctx, args&: shstrtab->name, args: 0, args: 0),
1535 Args: shstrtab.get());
1536
1537 llvm::sort(ctx.symtab->cmseSymMap, [&](const auto &a, const auto &b) {
1538 return a.second.sym->getVA(ctx) < b.second.sym->getVA(ctx);
1539 });
1540 // Copy the secure gateway entry symbols to the import library symbol table.
1541 for (auto &p : ctx.symtab->cmseSymMap) {
1542 Defined *d = cast<Defined>(Val: p.second.sym);
1543 impSymTab->addSymbol(makeDefined(
1544 args&: ctx, args&: ctx.internalFile, args: d->getName(), args: d->computeBinding(ctx),
1545 /*stOther=*/args: 0, args: STT_FUNC, args: d->getVA(ctx), args: d->getSize(), args: nullptr));
1546 }
1547
1548 size_t idx = 0;
1549 uint64_t off = sizeof(typename ELFT::Ehdr);
1550 for (auto &[osec, isec] : osIsPairs) {
1551 osec->sectionIndex = ++idx;
1552 osec->recordSection(isec);
1553 osec->finalizeInputSections();
1554 osec->shName = shstrtab->addString(s: osec->name);
1555 osec->size = isec->getSize();
1556 isec->finalizeContents();
1557 osec->offset = alignToPowerOf2(Value: off, Align: osec->addralign);
1558 off = osec->offset + osec->size;
1559 }
1560
1561 const uint64_t sectionHeaderOff = alignToPowerOf2(Value: off, Align: ctx.arg.wordsize);
1562 const auto shnum = osIsPairs.size() + 1;
1563 const uint64_t fileSize =
1564 sectionHeaderOff + shnum * sizeof(typename ELFT::Shdr);
1565 const unsigned flags =
1566 ctx.arg.mmapOutputFile ? (unsigned)FileOutputBuffer::F_mmap : 0;
1567 unlinkAsync(path: ctx.arg.cmseOutputLib);
1568 Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
1569 FileOutputBuffer::create(FilePath: ctx.arg.cmseOutputLib, Size: fileSize, Flags: flags);
1570 if (!bufferOrErr) {
1571 Err(ctx) << "failed to open " << ctx.arg.cmseOutputLib << ": "
1572 << bufferOrErr.takeError();
1573 return;
1574 }
1575
1576 // Write the ELF Header
1577 std::unique_ptr<FileOutputBuffer> &buffer = *bufferOrErr;
1578 uint8_t *const buf = buffer->getBufferStart();
1579 memcpy(dest: buf, src: "\177ELF", n: 4);
1580 auto *eHdr = reinterpret_cast<typename ELFT::Ehdr *>(buf);
1581 eHdr->e_type = ET_REL;
1582 eHdr->e_entry = 0;
1583 eHdr->e_shoff = sectionHeaderOff;
1584 eHdr->e_ident[EI_CLASS] = ELFCLASS32;
1585 eHdr->e_ident[EI_DATA] = ctx.arg.isLE ? ELFDATA2LSB : ELFDATA2MSB;
1586 eHdr->e_ident[EI_VERSION] = EV_CURRENT;
1587 eHdr->e_ident[EI_OSABI] = ctx.arg.osabi;
1588 eHdr->e_ident[EI_ABIVERSION] = 0;
1589 eHdr->e_machine = EM_ARM;
1590 eHdr->e_version = EV_CURRENT;
1591 eHdr->e_flags = ctx.arg.eflags;
1592 eHdr->e_ehsize = sizeof(typename ELFT::Ehdr);
1593 eHdr->e_phnum = 0;
1594 eHdr->e_shentsize = sizeof(typename ELFT::Shdr);
1595 eHdr->e_phoff = 0;
1596 eHdr->e_phentsize = 0;
1597 eHdr->e_shnum = shnum;
1598 eHdr->e_shstrndx = shstrtab->getParent()->sectionIndex;
1599
1600 // Write the section header table.
1601 auto *sHdrs = reinterpret_cast<typename ELFT::Shdr *>(buf + eHdr->e_shoff);
1602 for (auto &[osec, _] : osIsPairs)
1603 osec->template writeHeaderTo<ELFT>(++sHdrs);
1604
1605 // Write section contents to a mmap'ed file.
1606 {
1607 parallel::TaskGroup tg;
1608 for (auto &[osec, _] : osIsPairs)
1609 osec->template writeTo<ELFT>(ctx, buf + osec->offset, tg);
1610 }
1611
1612 if (auto e = buffer->commit())
1613 Err(ctx) << "failed to write output '" << buffer->getPath()
1614 << "': " << std::move(e);
1615}
1616
1617void elf::setARMTargetInfo(Ctx &ctx) { ctx.target.reset(p: new ARM(ctx)); }
1618
1619template void elf::writeARMCmseImportLib<ELF32LE>(Ctx &);
1620template void elf::writeARMCmseImportLib<ELF32BE>(Ctx &);
1621template void elf::writeARMCmseImportLib<ELF64LE>(Ctx &);
1622template void elf::writeARMCmseImportLib<ELF64BE>(Ctx &);
1623
1624template void ObjFile<ELF32LE>::importCmseSymbols();
1625template void ObjFile<ELF32BE>::importCmseSymbols();
1626template void ObjFile<ELF64LE>::importCmseSymbols();
1627template void ObjFile<ELF64BE>::importCmseSymbols();
1628