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