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