xref: /llvm-project-15.0.7/lld/ELF/Arch/ARM.cpp (revision ad38fbff)
1 //===- ARM.cpp ------------------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "Error.h"
11 #include "InputFiles.h"
12 #include "Symbols.h"
13 #include "SyntheticSections.h"
14 #include "Target.h"
15 #include "Thunks.h"
16 #include "llvm/Object/ELF.h"
17 #include "llvm/Support/Endian.h"
18 
19 using namespace llvm;
20 using namespace llvm::support::endian;
21 using namespace llvm::ELF;
22 using namespace lld;
23 using namespace lld::elf;
24 
25 namespace {
26 class ARM final : public TargetInfo {
27 public:
28   ARM();
29   RelExpr getRelExpr(RelType Type, const SymbolBody &S,
30                      const uint8_t *Loc) const override;
31   bool isPicRel(RelType Type) const override;
32   RelType getDynRel(RelType Type) const override;
33   int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
34   void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
35   void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const override;
36   void writePltHeader(uint8_t *Buf) const override;
37   void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
38                 int32_t Index, unsigned RelOff) const override;
39   void addPltSymbols(InputSectionBase *IS, uint64_t Off) const override;
40   void addPltHeaderSymbols(InputSectionBase *ISD) const override;
41   bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
42                   const SymbolBody &S) const override;
43   bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
44   void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
45 };
46 } // namespace
47 
48 ARM::ARM() {
49   CopyRel = R_ARM_COPY;
50   RelativeRel = R_ARM_RELATIVE;
51   IRelativeRel = R_ARM_IRELATIVE;
52   GotRel = R_ARM_GLOB_DAT;
53   PltRel = R_ARM_JUMP_SLOT;
54   TlsGotRel = R_ARM_TLS_TPOFF32;
55   TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
56   TlsOffsetRel = R_ARM_TLS_DTPOFF32;
57   GotEntrySize = 4;
58   GotPltEntrySize = 4;
59   PltEntrySize = 16;
60   PltHeaderSize = 20;
61   TrapInstr = 0xd4d4d4d4;
62   // ARM uses Variant 1 TLS
63   TcbSize = 8;
64   NeedsThunks = true;
65 }
66 
67 RelExpr ARM::getRelExpr(RelType Type, const SymbolBody &S,
68                         const uint8_t *Loc) const {
69   switch (Type) {
70   case R_ARM_THM_JUMP11:
71     return R_PC;
72   case R_ARM_CALL:
73   case R_ARM_JUMP24:
74   case R_ARM_PC24:
75   case R_ARM_PLT32:
76   case R_ARM_PREL31:
77   case R_ARM_THM_JUMP19:
78   case R_ARM_THM_JUMP24:
79   case R_ARM_THM_CALL:
80     return R_PLT_PC;
81   case R_ARM_GOTOFF32:
82     // (S + A) - GOT_ORG
83     return R_GOTREL;
84   case R_ARM_GOT_BREL:
85     // GOT(S) + A - GOT_ORG
86     return R_GOT_OFF;
87   case R_ARM_GOT_PREL:
88   case R_ARM_TLS_IE32:
89     // GOT(S) + A - P
90     return R_GOT_PC;
91   case R_ARM_SBREL32:
92     return R_ARM_SBREL;
93   case R_ARM_TARGET1:
94     return Config->Target1Rel ? R_PC : R_ABS;
95   case R_ARM_TARGET2:
96     if (Config->Target2 == Target2Policy::Rel)
97       return R_PC;
98     if (Config->Target2 == Target2Policy::Abs)
99       return R_ABS;
100     return R_GOT_PC;
101   case R_ARM_TLS_GD32:
102     return R_TLSGD_PC;
103   case R_ARM_TLS_LDM32:
104     return R_TLSLD_PC;
105   case R_ARM_BASE_PREL:
106     // B(S) + A - P
107     // FIXME: currently B(S) assumed to be .got, this may not hold for all
108     // platforms.
109     return R_GOTONLY_PC;
110   case R_ARM_MOVW_PREL_NC:
111   case R_ARM_MOVT_PREL:
112   case R_ARM_REL32:
113   case R_ARM_THM_MOVW_PREL_NC:
114   case R_ARM_THM_MOVT_PREL:
115     return R_PC;
116   case R_ARM_NONE:
117     return R_NONE;
118   case R_ARM_TLS_LE32:
119     return R_TLS;
120   default:
121     return R_ABS;
122   }
123 }
124 
125 bool ARM::isPicRel(RelType Type) const {
126   return (Type == R_ARM_TARGET1 && !Config->Target1Rel) ||
127          (Type == R_ARM_ABS32);
128 }
129 
130 RelType ARM::getDynRel(RelType Type) const {
131   if (Type == R_ARM_TARGET1 && !Config->Target1Rel)
132     return R_ARM_ABS32;
133   if (Type == R_ARM_ABS32)
134     return Type;
135   // Keep it going with a dummy value so that we can find more reloc errors.
136   return R_ARM_ABS32;
137 }
138 
139 void ARM::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
140   write32le(Buf, InX::Plt->getVA());
141 }
142 
143 void ARM::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const {
144   // An ARM entry is the address of the ifunc resolver function.
145   write32le(Buf, S.getVA());
146 }
147 
148 void ARM::writePltHeader(uint8_t *Buf) const {
149   const uint8_t PltData[] = {
150       0x04, 0xe0, 0x2d, 0xe5, //     str lr, [sp,#-4]!
151       0x04, 0xe0, 0x9f, 0xe5, //     ldr lr, L2
152       0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr
153       0x08, 0xf0, 0xbe, 0xe5, //     ldr pc, [lr, #8]
154       0x00, 0x00, 0x00, 0x00, // L2: .word   &(.got.plt) - L1 - 8
155   };
156   memcpy(Buf, PltData, sizeof(PltData));
157   uint64_t GotPlt = InX::GotPlt->getVA();
158   uint64_t L1 = InX::Plt->getVA() + 8;
159   write32le(Buf + 16, GotPlt - L1 - 8);
160 }
161 
162 void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const {
163   auto *IS = cast<InputSection>(ISD);
164   addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
165   addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
166 }
167 
168 void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
169                    uint64_t PltEntryAddr, int32_t Index,
170                    unsigned RelOff) const {
171   // FIXME: Using simple code sequence with simple relocations.
172   // There is a more optimal sequence but it requires support for the group
173   // relocations. See ELF for the ARM Architecture Appendix A.3
174   const uint8_t PltData[] = {
175       0x04, 0xc0, 0x9f, 0xe5, //     ldr ip, L2
176       0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
177       0x00, 0xf0, 0x9c, 0xe5, //     ldr pc, [ip]
178       0x00, 0x00, 0x00, 0x00, // L2: .word   Offset(&(.plt.got) - L1 - 8
179   };
180   memcpy(Buf, PltData, sizeof(PltData));
181   uint64_t L1 = PltEntryAddr + 4;
182   write32le(Buf + 12, GotPltEntryAddr - L1 - 8);
183 }
184 
185 void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const {
186   auto *IS = cast<InputSection>(ISD);
187   addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
188   addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
189 }
190 
191 bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
192                      const SymbolBody &S) const {
193   // If S is an undefined weak symbol in an executable we don't need a Thunk.
194   // In a DSO calls to undefined symbols, including weak ones get PLT entries
195   // which may need a thunk.
196   if (S.isUndefWeak() && !Config->Shared)
197     return false;
198   // A state change from ARM to Thumb and vice versa must go through an
199   // interworking thunk if the relocation type is not R_ARM_CALL or
200   // R_ARM_THM_CALL.
201   switch (Type) {
202   case R_ARM_PC24:
203   case R_ARM_PLT32:
204   case R_ARM_JUMP24:
205     // Source is ARM, all PLT entries are ARM so no interworking required.
206     // Otherwise we need to interwork if Symbol has bit 0 set (Thumb).
207     if (Expr == R_PC && ((S.getVA() & 1) == 1))
208       return true;
209     break;
210   case R_ARM_THM_JUMP19:
211   case R_ARM_THM_JUMP24:
212     // Source is Thumb, all PLT entries are ARM so interworking is required.
213     // Otherwise we need to interwork if Symbol has bit 0 clear (ARM).
214     if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0))
215       return true;
216     break;
217   }
218   return false;
219 }
220 
221 bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
222   uint64_t Range;
223   uint64_t InstrSize;
224 
225   switch (Type) {
226   case R_ARM_PC24:
227   case R_ARM_PLT32:
228   case R_ARM_JUMP24:
229   case R_ARM_CALL:
230     Range = 0x2000000;
231     InstrSize = 4;
232     break;
233   case R_ARM_THM_JUMP19:
234     Range = 0x100000;
235     InstrSize = 2;
236     break;
237   case R_ARM_THM_JUMP24:
238   case R_ARM_THM_CALL:
239     Range = 0x1000000;
240     InstrSize = 2;
241     break;
242   default:
243     return true;
244   }
245   // PC at Src is 2 instructions ahead, immediate of branch is signed
246   if (Src > Dst)
247     Range -= 2 * InstrSize;
248   else
249     Range += InstrSize;
250 
251   if ((Dst & 0x1) == 0)
252     // Destination is ARM, if ARM caller then Src is already 4-byte aligned.
253     // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
254     // destination will be 4 byte aligned.
255     Src &= ~0x3;
256   else
257     // Bit 0 == 1 denotes Thumb state, it is not part of the range
258     Dst &= ~0x1;
259 
260   uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src;
261   return Distance <= Range;
262 }
263 
264 void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
265   switch (Type) {
266   case R_ARM_ABS32:
267   case R_ARM_BASE_PREL:
268   case R_ARM_GLOB_DAT:
269   case R_ARM_GOTOFF32:
270   case R_ARM_GOT_BREL:
271   case R_ARM_GOT_PREL:
272   case R_ARM_REL32:
273   case R_ARM_RELATIVE:
274   case R_ARM_SBREL32:
275   case R_ARM_TARGET1:
276   case R_ARM_TARGET2:
277   case R_ARM_TLS_GD32:
278   case R_ARM_TLS_IE32:
279   case R_ARM_TLS_LDM32:
280   case R_ARM_TLS_LDO32:
281   case R_ARM_TLS_LE32:
282   case R_ARM_TLS_TPOFF32:
283   case R_ARM_TLS_DTPOFF32:
284     write32le(Loc, Val);
285     break;
286   case R_ARM_TLS_DTPMOD32:
287     write32le(Loc, 1);
288     break;
289   case R_ARM_PREL31:
290     checkInt<31>(Loc, Val, Type);
291     write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000));
292     break;
293   case R_ARM_CALL:
294     // R_ARM_CALL is used for BL and BLX instructions, depending on the
295     // value of bit 0 of Val, we must select a BL or BLX instruction
296     if (Val & 1) {
297       // If bit 0 of Val is 1 the target is Thumb, we must select a BLX.
298       // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
299       checkInt<26>(Loc, Val, Type);
300       write32le(Loc, 0xfa000000 |                    // opcode
301                          ((Val & 2) << 23) |         // H
302                          ((Val >> 2) & 0x00ffffff)); // imm24
303       break;
304     }
305     if ((read32le(Loc) & 0xfe000000) == 0xfa000000)
306       // BLX (always unconditional) instruction to an ARM Target, select an
307       // unconditional BL.
308       write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff));
309     // fall through as BL encoding is shared with B
310     LLVM_FALLTHROUGH;
311   case R_ARM_JUMP24:
312   case R_ARM_PC24:
313   case R_ARM_PLT32:
314     checkInt<26>(Loc, Val, Type);
315     write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff));
316     break;
317   case R_ARM_THM_JUMP11:
318     checkInt<12>(Loc, Val, Type);
319     write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff));
320     break;
321   case R_ARM_THM_JUMP19:
322     // Encoding T3: Val = S:J2:J1:imm6:imm11:0
323     checkInt<21>(Loc, Val, Type);
324     write16le(Loc,
325               (read16le(Loc) & 0xfbc0) |   // opcode cond
326                   ((Val >> 10) & 0x0400) | // S
327                   ((Val >> 12) & 0x003f)); // imm6
328     write16le(Loc + 2,
329               0x8000 |                    // opcode
330                   ((Val >> 8) & 0x0800) | // J2
331                   ((Val >> 5) & 0x2000) | // J1
332                   ((Val >> 1) & 0x07ff)); // imm11
333     break;
334   case R_ARM_THM_CALL:
335     // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the
336     // value of bit 0 of Val, we must select a BL or BLX instruction
337     if ((Val & 1) == 0) {
338       // Ensure BLX destination is 4-byte aligned. As BLX instruction may
339       // only be two byte aligned. This must be done before overflow check
340       Val = alignTo(Val, 4);
341     }
342     // Bit 12 is 0 for BLX, 1 for BL
343     write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
344     // Fall through as rest of encoding is the same as B.W
345     LLVM_FALLTHROUGH;
346   case R_ARM_THM_JUMP24:
347     // Encoding B  T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
348     // FIXME: Use of I1 and I2 require v6T2ops
349     checkInt<25>(Loc, Val, Type);
350     write16le(Loc,
351               0xf000 |                     // opcode
352                   ((Val >> 14) & 0x0400) | // S
353                   ((Val >> 12) & 0x03ff)); // imm10
354     write16le(Loc + 2,
355               (read16le(Loc + 2) & 0xd000) |                  // opcode
356                   (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1
357                   (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2
358                   ((Val >> 1) & 0x07ff));                     // imm11
359     break;
360   case R_ARM_MOVW_ABS_NC:
361   case R_ARM_MOVW_PREL_NC:
362     write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) |
363                        (Val & 0x0fff));
364     break;
365   case R_ARM_MOVT_ABS:
366   case R_ARM_MOVT_PREL:
367     checkInt<32>(Loc, Val, Type);
368     write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
369                        (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
370     break;
371   case R_ARM_THM_MOVT_ABS:
372   case R_ARM_THM_MOVT_PREL:
373     // Encoding T1: A = imm4:i:imm3:imm8
374     checkInt<32>(Loc, Val, Type);
375     write16le(Loc,
376               0xf2c0 |                     // opcode
377                   ((Val >> 17) & 0x0400) | // i
378                   ((Val >> 28) & 0x000f)); // imm4
379     write16le(Loc + 2,
380               (read16le(Loc + 2) & 0x8f00) | // opcode
381                   ((Val >> 12) & 0x7000) |   // imm3
382                   ((Val >> 16) & 0x00ff));   // imm8
383     break;
384   case R_ARM_THM_MOVW_ABS_NC:
385   case R_ARM_THM_MOVW_PREL_NC:
386     // Encoding T3: A = imm4:i:imm3:imm8
387     write16le(Loc,
388               0xf240 |                     // opcode
389                   ((Val >> 1) & 0x0400) |  // i
390                   ((Val >> 12) & 0x000f)); // imm4
391     write16le(Loc + 2,
392               (read16le(Loc + 2) & 0x8f00) | // opcode
393                   ((Val << 4) & 0x7000) |    // imm3
394                   (Val & 0x00ff));           // imm8
395     break;
396   default:
397     error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
398   }
399 }
400 
401 int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
402   switch (Type) {
403   default:
404     return 0;
405   case R_ARM_ABS32:
406   case R_ARM_BASE_PREL:
407   case R_ARM_GOTOFF32:
408   case R_ARM_GOT_BREL:
409   case R_ARM_GOT_PREL:
410   case R_ARM_REL32:
411   case R_ARM_TARGET1:
412   case R_ARM_TARGET2:
413   case R_ARM_TLS_GD32:
414   case R_ARM_TLS_LDM32:
415   case R_ARM_TLS_LDO32:
416   case R_ARM_TLS_IE32:
417   case R_ARM_TLS_LE32:
418     return SignExtend64<32>(read32le(Buf));
419   case R_ARM_PREL31:
420     return SignExtend64<31>(read32le(Buf));
421   case R_ARM_CALL:
422   case R_ARM_JUMP24:
423   case R_ARM_PC24:
424   case R_ARM_PLT32:
425     return SignExtend64<26>(read32le(Buf) << 2);
426   case R_ARM_THM_JUMP11:
427     return SignExtend64<12>(read16le(Buf) << 1);
428   case R_ARM_THM_JUMP19: {
429     // Encoding T3: A = S:J2:J1:imm10:imm6:0
430     uint16_t Hi = read16le(Buf);
431     uint16_t Lo = read16le(Buf + 2);
432     return SignExtend64<20>(((Hi & 0x0400) << 10) | // S
433                             ((Lo & 0x0800) << 8) |  // J2
434                             ((Lo & 0x2000) << 5) |  // J1
435                             ((Hi & 0x003f) << 12) | // imm6
436                             ((Lo & 0x07ff) << 1));  // imm11:0
437   }
438   case R_ARM_THM_CALL:
439   case R_ARM_THM_JUMP24: {
440     // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
441     // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
442     // FIXME: I1 and I2 require v6T2ops
443     uint16_t Hi = read16le(Buf);
444     uint16_t Lo = read16le(Buf + 2);
445     return SignExtend64<24>(((Hi & 0x0400) << 14) |                    // S
446                             (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1
447                             (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2
448                             ((Hi & 0x003ff) << 12) |                   // imm0
449                             ((Lo & 0x007ff) << 1)); // imm11:0
450   }
451   // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
452   // MOVT is in the range -32768 <= A < 32768
453   case R_ARM_MOVW_ABS_NC:
454   case R_ARM_MOVT_ABS:
455   case R_ARM_MOVW_PREL_NC:
456   case R_ARM_MOVT_PREL: {
457     uint64_t Val = read32le(Buf) & 0x000f0fff;
458     return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff));
459   }
460   case R_ARM_THM_MOVW_ABS_NC:
461   case R_ARM_THM_MOVT_ABS:
462   case R_ARM_THM_MOVW_PREL_NC:
463   case R_ARM_THM_MOVT_PREL: {
464     // Encoding T3: A = imm4:i:imm3:imm8
465     uint16_t Hi = read16le(Buf);
466     uint16_t Lo = read16le(Buf + 2);
467     return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4
468                             ((Hi & 0x0400) << 1) |  // i
469                             ((Lo & 0x7000) >> 4) |  // imm3
470                             (Lo & 0x00ff));         // imm8
471   }
472   }
473 }
474 
475 TargetInfo *elf::getARMTargetInfo() {
476   static ARM Target;
477   return &Target;
478 }
479