ARM.cpp revision 344779
1254721Semaste//===- ARM.cpp ------------------------------------------------------------===// 2254721Semaste// 3254721Semaste// The LLVM Linker 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "InputFiles.h" 11254721Semaste#include "Symbols.h" 12254721Semaste#include "SyntheticSections.h" 13254721Semaste#include "Target.h" 14254721Semaste#include "Thunks.h" 15254721Semaste#include "lld/Common/ErrorHandler.h" 16254721Semaste#include "llvm/Object/ELF.h" 17254721Semaste#include "llvm/Support/Endian.h" 18254721Semaste 19254721Semasteusing namespace llvm; 20254721Semasteusing namespace llvm::support::endian; 21254721Semasteusing namespace llvm::ELF; 22254721Semasteusing namespace lld; 23254721Semasteusing namespace lld::elf; 24288943Sdim 25254721Semastenamespace { 26254721Semasteclass ARM final : public TargetInfo { 27254721Semastepublic: 28254721Semaste ARM(); 29262528Semaste uint32_t calcEFlags() const override; 30296417Sdim RelExpr getRelExpr(RelType Type, const Symbol &S, 31254721Semaste const uint8_t *Loc) const override; 32254721Semaste RelType getDynRel(RelType Type) const override; 33254721Semaste int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override; 34254721Semaste void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; 35254721Semaste void writeIgotPlt(uint8_t *Buf, const Symbol &S) const override; 36254721Semaste void writePltHeader(uint8_t *Buf) const override; 37254721Semaste void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, 38254721Semaste int32_t Index, unsigned RelOff) const override; 39296417Sdim void addPltSymbols(InputSection &IS, uint64_t Off) const override; 40296417Sdim void addPltHeaderSymbols(InputSection &ISD) const override; 41296417Sdim bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File, 42296417Sdim uint64_t BranchAddr, const Symbol &S) const override; 43296417Sdim uint32_t getThunkSectionSpacing() const override; 44254721Semaste bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override; 45254721Semaste void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; 46254721Semaste}; 47254721Semaste} // namespace 48254721Semaste 49254721SemasteARM::ARM() { 50296417Sdim CopyRel = R_ARM_COPY; 51254721Semaste RelativeRel = R_ARM_RELATIVE; 52296417Sdim IRelativeRel = R_ARM_IRELATIVE; 53254721Semaste GotRel = R_ARM_GLOB_DAT; 54254721Semaste NoneRel = R_ARM_NONE; 55296417Sdim PltRel = R_ARM_JUMP_SLOT; 56254721Semaste TlsGotRel = R_ARM_TLS_TPOFF32; 57254721Semaste TlsModuleIndexRel = R_ARM_TLS_DTPMOD32; 58254721Semaste TlsOffsetRel = R_ARM_TLS_DTPOFF32; 59254721Semaste GotBaseSymInGotPlt = false; 60254721Semaste GotEntrySize = 4; 61296417Sdim GotPltEntrySize = 4; 62296417Sdim PltEntrySize = 16; 63296417Sdim PltHeaderSize = 32; 64296417Sdim TrapInstr = {0xd4, 0xd4, 0xd4, 0xd4}; 65296417Sdim NeedsThunks = true; 66254721Semaste} 67296417Sdim 68296417Sdimuint32_t ARM::calcEFlags() const { 69296417Sdim // The ABIFloatType is used by loaders to detect the floating point calling 70296417Sdim // convention. 71296417Sdim uint32_t ABIFloatType = 0; 72254721Semaste if (Config->ARMVFPArgs == ARMVFPArgKind::Base || 73296417Sdim Config->ARMVFPArgs == ARMVFPArgKind::Default) 74296417Sdim ABIFloatType = EF_ARM_ABI_FLOAT_SOFT; 75296417Sdim else if (Config->ARMVFPArgs == ARMVFPArgKind::VFP) 76296417Sdim ABIFloatType = EF_ARM_ABI_FLOAT_HARD; 77296417Sdim 78296417Sdim // We don't currently use any features incompatible with EF_ARM_EABI_VER5, 79296417Sdim // but we don't have any firm guarantees of conformance. Linux AArch64 80296417Sdim // kernels (as of 2016) require an EABI version to be set. 81296417Sdim return EF_ARM_EABI_VER5 | ABIFloatType; 82296417Sdim} 83296417Sdim 84296417SdimRelExpr ARM::getRelExpr(RelType Type, const Symbol &S, 85296417Sdim const uint8_t *Loc) const { 86296417Sdim switch (Type) { 87296417Sdim case R_ARM_THM_JUMP11: 88296417Sdim return R_PC; 89296417Sdim case R_ARM_CALL: 90296417Sdim case R_ARM_JUMP24: 91296417Sdim case R_ARM_PC24: 92254721Semaste case R_ARM_PLT32: 93296417Sdim case R_ARM_PREL31: 94296417Sdim case R_ARM_THM_JUMP19: 95296417Sdim case R_ARM_THM_JUMP24: 96296417Sdim case R_ARM_THM_CALL: 97296417Sdim return R_PLT_PC; 98296417Sdim case R_ARM_GOTOFF32: 99254721Semaste // (S + A) - GOT_ORG 100254721Semaste return R_GOTREL; 101254721Semaste case R_ARM_GOT_BREL: 102254721Semaste // GOT(S) + A - GOT_ORG 103254721Semaste return R_GOT_OFF; 104254721Semaste case R_ARM_GOT_PREL: 105296417Sdim case R_ARM_TLS_IE32: 106254721Semaste // GOT(S) + A - P 107254721Semaste return R_GOT_PC; 108254721Semaste case R_ARM_SBREL32: 109296417Sdim return R_ARM_SBREL; 110296417Sdim case R_ARM_TARGET1: 111254721Semaste return Config->Target1Rel ? R_PC : R_ABS; 112296417Sdim case R_ARM_TARGET2: 113296417Sdim if (Config->Target2 == Target2Policy::Rel) 114296417Sdim return R_PC; 115254721Semaste if (Config->Target2 == Target2Policy::Abs) 116254721Semaste return R_ABS; 117296417Sdim return R_GOT_PC; 118296417Sdim case R_ARM_TLS_GD32: 119254721Semaste return R_TLSGD_PC; 120254721Semaste case R_ARM_TLS_LDM32: 121254721Semaste return R_TLSLD_PC; 122254721Semaste case R_ARM_BASE_PREL: 123254721Semaste // B(S) + A - P 124254721Semaste // FIXME: currently B(S) assumed to be .got, this may not hold for all 125254721Semaste // platforms. 126254721Semaste return R_GOTONLY_PC; 127296417Sdim case R_ARM_MOVW_PREL_NC: 128296417Sdim case R_ARM_MOVT_PREL: 129254721Semaste case R_ARM_REL32: 130296417Sdim case R_ARM_THM_MOVW_PREL_NC: 131296417Sdim case R_ARM_THM_MOVT_PREL: 132296417Sdim return R_PC; 133254721Semaste case R_ARM_NONE: 134254721Semaste return R_NONE; 135296417Sdim case R_ARM_TLS_LE32: 136296417Sdim return R_TLS; 137296417Sdim case R_ARM_V4BX: 138296417Sdim // V4BX is just a marker to indicate there's a "bx rN" instruction at the 139296417Sdim // given address. It can be used to implement a special linker mode which 140296417Sdim // rewrites ARMv4T inputs to ARMv4. Since we support only ARMv4 input and 141254721Semaste // not ARMv4 output, we can just ignore it. 142254721Semaste return R_HINT; 143254721Semaste default: 144296417Sdim return R_ABS; 145254721Semaste } 146254721Semaste} 147296417Sdim 148254721SemasteRelType ARM::getDynRel(RelType Type) const { 149254721Semaste if ((Type == R_ARM_ABS32) || (Type == R_ARM_TARGET1 && !Config->Target1Rel)) 150254721Semaste return R_ARM_ABS32; 151254721Semaste return R_ARM_NONE; 152254721Semaste} 153296417Sdim 154296417Sdimvoid ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const { 155296417Sdim write32le(Buf, In.Plt->getVA()); 156296417Sdim} 157296417Sdim 158296417Sdimvoid ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const { 159296417Sdim // An ARM entry is the address of the ifunc resolver function. 160296417Sdim write32le(Buf, S.getVA()); 161296417Sdim} 162296417Sdim 163296417Sdim// Long form PLT Header that does not have any restrictions on the displacement 164296417Sdim// of the .plt from the .plt.got. 165296417Sdimstatic void writePltHeaderLong(uint8_t *Buf) { 166296417Sdim const uint8_t PltData[] = { 167296417Sdim 0x04, 0xe0, 0x2d, 0xe5, // str lr, [sp,#-4]! 168296417Sdim 0x04, 0xe0, 0x9f, 0xe5, // ldr lr, L2 169296417Sdim 0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr 170296417Sdim 0x08, 0xf0, 0xbe, 0xe5, // ldr pc, [lr, #8] 171296417Sdim 0x00, 0x00, 0x00, 0x00, // L2: .word &(.got.plt) - L1 - 8 172296417Sdim 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary 173296417Sdim 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary 174296417Sdim 0xd4, 0xd4, 0xd4, 0xd4}; 175296417Sdim memcpy(Buf, PltData, sizeof(PltData)); 176296417Sdim uint64_t GotPlt = In.GotPlt->getVA(); 177296417Sdim uint64_t L1 = In.Plt->getVA() + 8; 178296417Sdim write32le(Buf + 16, GotPlt - L1 - 8); 179296417Sdim} 180296417Sdim 181296417Sdim// The default PLT header requires the .plt.got to be within 128 Mb of the 182296417Sdim// .plt in the positive direction. 183296417Sdimvoid ARM::writePltHeader(uint8_t *Buf) const { 184296417Sdim // Use a similar sequence to that in writePlt(), the difference is the calling 185296417Sdim // conventions mean we use lr instead of ip. The PLT entry is responsible for 186296417Sdim // saving lr on the stack, the dynamic loader is responsible for reloading 187296417Sdim // it. 188296417Sdim const uint32_t PltData[] = { 189296417Sdim 0xe52de004, // L1: str lr, [sp,#-4]! 190296417Sdim 0xe28fe600, // add lr, pc, #0x0NN00000 &(.got.plt - L1 - 4) 191296417Sdim 0xe28eea00, // add lr, lr, #0x000NN000 &(.got.plt - L1 - 4) 192296417Sdim 0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4) 193296417Sdim }; 194296417Sdim 195296417Sdim uint64_t Offset = In.GotPlt->getVA() - In.Plt->getVA() - 4; 196296417Sdim if (!llvm::isUInt<27>(Offset)) { 197296417Sdim // We cannot encode the Offset, use the long form. 198296417Sdim writePltHeaderLong(Buf); 199296417Sdim return; 200296417Sdim } 201296417Sdim write32le(Buf + 0, PltData[0]); 202296417Sdim write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff)); 203296417Sdim write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff)); 204296417Sdim write32le(Buf + 12, PltData[3] | (Offset & 0xfff)); 205296417Sdim memcpy(Buf + 16, TrapInstr.data(), 4); // Pad to 32-byte boundary 206296417Sdim memcpy(Buf + 20, TrapInstr.data(), 4); 207296417Sdim memcpy(Buf + 24, TrapInstr.data(), 4); 208296417Sdim memcpy(Buf + 28, TrapInstr.data(), 4); 209296417Sdim} 210296417Sdim 211296417Sdimvoid ARM::addPltHeaderSymbols(InputSection &IS) const { 212296417Sdim addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS); 213296417Sdim addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS); 214296417Sdim} 215296417Sdim 216296417Sdim// Long form PLT entries that do not have any restrictions on the displacement 217296417Sdim// of the .plt from the .plt.got. 218296417Sdimstatic void writePltLong(uint8_t *Buf, uint64_t GotPltEntryAddr, 219296417Sdim uint64_t PltEntryAddr, int32_t Index, 220296417Sdim unsigned RelOff) { 221296417Sdim const uint8_t PltData[] = { 222296417Sdim 0x04, 0xc0, 0x9f, 0xe5, // ldr ip, L2 223296417Sdim 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc 224296417Sdim 0x00, 0xf0, 0x9c, 0xe5, // ldr pc, [ip] 225296417Sdim 0x00, 0x00, 0x00, 0x00, // L2: .word Offset(&(.plt.got) - L1 - 8 226296417Sdim }; 227296417Sdim memcpy(Buf, PltData, sizeof(PltData)); 228296417Sdim uint64_t L1 = PltEntryAddr + 4; 229296417Sdim write32le(Buf + 12, GotPltEntryAddr - L1 - 8); 230296417Sdim} 231296417Sdim 232296417Sdim// The default PLT entries require the .plt.got to be within 128 Mb of the 233296417Sdim// .plt in the positive direction. 234296417Sdimvoid ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, 235296417Sdim uint64_t PltEntryAddr, int32_t Index, 236296417Sdim unsigned RelOff) const { 237296417Sdim // The PLT entry is similar to the example given in Appendix A of ELF for 238296417Sdim // the Arm Architecture. Instead of using the Group Relocations to find the 239296417Sdim // optimal rotation for the 8-bit immediate used in the add instructions we 240296417Sdim // hard code the most compact rotations for simplicity. This saves a load 241296417Sdim // instruction over the long plt sequences. 242296417Sdim const uint32_t PltData[] = { 243296417Sdim 0xe28fc600, // L1: add ip, pc, #0x0NN00000 Offset(&(.plt.got) - L1 - 8 244296417Sdim 0xe28cca00, // add ip, ip, #0x000NN000 Offset(&(.plt.got) - L1 - 8 245296417Sdim 0xe5bcf000, // ldr pc, [ip, #0x00000NNN] Offset(&(.plt.got) - L1 - 8 246296417Sdim }; 247296417Sdim 248296417Sdim uint64_t Offset = GotPltEntryAddr - PltEntryAddr - 8; 249296417Sdim if (!llvm::isUInt<27>(Offset)) { 250296417Sdim // We cannot encode the Offset, use the long form. 251296417Sdim writePltLong(Buf, GotPltEntryAddr, PltEntryAddr, Index, RelOff); 252296417Sdim return; 253296417Sdim } 254296417Sdim write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff)); 255296417Sdim write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff)); 256296417Sdim write32le(Buf + 8, PltData[2] | (Offset & 0xfff)); 257296417Sdim memcpy(Buf + 12, TrapInstr.data(), 4); // Pad to 16-byte boundary 258296417Sdim} 259296417Sdim 260296417Sdimvoid ARM::addPltSymbols(InputSection &IS, uint64_t Off) const { 261296417Sdim addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS); 262296417Sdim addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS); 263296417Sdim} 264296417Sdim 265296417Sdimbool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, 266296417Sdim uint64_t BranchAddr, const Symbol &S) const { 267296417Sdim // If S is an undefined weak symbol and does not have a PLT entry then it 268296417Sdim // will be resolved as a branch to the next instruction. 269296417Sdim if (S.isUndefWeak() && !S.isInPlt()) 270296417Sdim return false; 271296417Sdim // A state change from ARM to Thumb and vice versa must go through an 272296417Sdim // interworking thunk if the relocation type is not R_ARM_CALL or 273296417Sdim // R_ARM_THM_CALL. 274296417Sdim switch (Type) { 275296417Sdim case R_ARM_PC24: 276296417Sdim case R_ARM_PLT32: 277296417Sdim case R_ARM_JUMP24: 278296417Sdim // Source is ARM, all PLT entries are ARM so no interworking required. 279296417Sdim // Otherwise we need to interwork if Symbol has bit 0 set (Thumb). 280296417Sdim if (Expr == R_PC && ((S.getVA() & 1) == 1)) 281296417Sdim return true; 282296417Sdim LLVM_FALLTHROUGH; 283296417Sdim case R_ARM_CALL: { 284296417Sdim uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA(); 285296417Sdim return !inBranchRange(Type, BranchAddr, Dst); 286296417Sdim } 287296417Sdim case R_ARM_THM_JUMP19: 288296417Sdim case R_ARM_THM_JUMP24: 289296417Sdim // Source is Thumb, all PLT entries are ARM so interworking is required. 290296417Sdim // Otherwise we need to interwork if Symbol has bit 0 clear (ARM). 291296417Sdim if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0)) 292296417Sdim return true; 293296417Sdim LLVM_FALLTHROUGH; 294296417Sdim case R_ARM_THM_CALL: { 295296417Sdim uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA(); 296296417Sdim return !inBranchRange(Type, BranchAddr, Dst); 297296417Sdim } 298296417Sdim } 299296417Sdim return false; 300296417Sdim} 301296417Sdim 302296417Sdimuint32_t ARM::getThunkSectionSpacing() const { 303296417Sdim // The placing of pre-created ThunkSections is controlled by the value 304296417Sdim // ThunkSectionSpacing returned by getThunkSectionSpacing(). The aim is to 305296417Sdim // place the ThunkSection such that all branches from the InputSections 306296417Sdim // prior to the ThunkSection can reach a Thunk placed at the end of the 307296417Sdim // ThunkSection. Graphically: 308296417Sdim // | up to ThunkSectionSpacing .text input sections | 309296417Sdim // | ThunkSection | 310296417Sdim // | up to ThunkSectionSpacing .text input sections | 311296417Sdim // | ThunkSection | 312296417Sdim 313296417Sdim // Pre-created ThunkSections are spaced roughly 16MiB apart on ARMv7. This 314296417Sdim // is to match the most common expected case of a Thumb 2 encoded BL, BLX or 315296417Sdim // B.W: 316296417Sdim // ARM B, BL, BLX range +/- 32MiB 317296417Sdim // Thumb B.W, BL, BLX range +/- 16MiB 318296417Sdim // Thumb B<cc>.W range +/- 1MiB 319296417Sdim // If a branch cannot reach a pre-created ThunkSection a new one will be 320296417Sdim // created so we can handle the rare cases of a Thumb 2 conditional branch. 321296417Sdim // We intentionally use a lower size for ThunkSectionSpacing than the maximum 322296417Sdim // branch range so the end of the ThunkSection is more likely to be within 323296417Sdim // range of the branch instruction that is furthest away. The value we shorten 324296417Sdim // ThunkSectionSpacing by is set conservatively to allow us to create 16,384 325296417Sdim // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to 326296417Sdim // one of the Thunks going out of range. 327296417Sdim 328296417Sdim // On Arm the ThunkSectionSpacing depends on the range of the Thumb Branch 329296417Sdim // range. On earlier Architectures such as ARMv4, ARMv5 and ARMv6 (except 330296417Sdim // ARMv6T2) the range is +/- 4MiB. 331296417Sdim 332296417Sdim return (Config->ARMJ1J2BranchEncoding) ? 0x1000000 - 0x30000 333296417Sdim : 0x400000 - 0x7500; 334296417Sdim} 335296417Sdim 336296417Sdimbool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const { 337296417Sdim uint64_t Range; 338296417Sdim uint64_t InstrSize; 339296417Sdim 340296417Sdim switch (Type) { 341296417Sdim case R_ARM_PC24: 342296417Sdim case R_ARM_PLT32: 343296417Sdim case R_ARM_JUMP24: 344296417Sdim case R_ARM_CALL: 345296417Sdim Range = 0x2000000; 346296417Sdim InstrSize = 4; 347296417Sdim break; 348296417Sdim case R_ARM_THM_JUMP19: 349296417Sdim Range = 0x100000; 350296417Sdim InstrSize = 2; 351296417Sdim break; 352296417Sdim case R_ARM_THM_JUMP24: 353296417Sdim case R_ARM_THM_CALL: 354296417Sdim Range = Config->ARMJ1J2BranchEncoding ? 0x1000000 : 0x400000; 355296417Sdim InstrSize = 2; 356296417Sdim break; 357296417Sdim default: 358296417Sdim return true; 359296417Sdim } 360296417Sdim // PC at Src is 2 instructions ahead, immediate of branch is signed 361296417Sdim if (Src > Dst) 362296417Sdim Range -= 2 * InstrSize; 363296417Sdim else 364296417Sdim Range += InstrSize; 365296417Sdim 366296417Sdim if ((Dst & 0x1) == 0) 367296417Sdim // Destination is ARM, if ARM caller then Src is already 4-byte aligned. 368296417Sdim // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure 369296417Sdim // destination will be 4 byte aligned. 370296417Sdim Src &= ~0x3; 371296417Sdim else 372296417Sdim // Bit 0 == 1 denotes Thumb state, it is not part of the range 373296417Sdim Dst &= ~0x1; 374296417Sdim 375296417Sdim uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src; 376296417Sdim return Distance <= Range; 377296417Sdim} 378296417Sdim 379296417Sdimvoid ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { 380296417Sdim switch (Type) { 381296417Sdim case R_ARM_ABS32: 382296417Sdim case R_ARM_BASE_PREL: 383296417Sdim case R_ARM_GLOB_DAT: 384296417Sdim case R_ARM_GOTOFF32: 385296417Sdim case R_ARM_GOT_BREL: 386296417Sdim case R_ARM_GOT_PREL: 387296417Sdim case R_ARM_REL32: 388296417Sdim case R_ARM_RELATIVE: 389296417Sdim case R_ARM_SBREL32: 390296417Sdim case R_ARM_TARGET1: 391296417Sdim case R_ARM_TARGET2: 392296417Sdim case R_ARM_TLS_GD32: 393296417Sdim case R_ARM_TLS_IE32: 394296417Sdim case R_ARM_TLS_LDM32: 395296417Sdim case R_ARM_TLS_LDO32: 396296417Sdim case R_ARM_TLS_LE32: 397296417Sdim case R_ARM_TLS_TPOFF32: 398296417Sdim case R_ARM_TLS_DTPOFF32: 399296417Sdim write32le(Loc, Val); 400296417Sdim break; 401296417Sdim case R_ARM_TLS_DTPMOD32: 402296417Sdim write32le(Loc, 1); 403296417Sdim break; 404296417Sdim case R_ARM_PREL31: 405296417Sdim checkInt(Loc, Val, 31, Type); 406296417Sdim write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000)); 407296417Sdim break; 408296417Sdim case R_ARM_CALL: 409296417Sdim // R_ARM_CALL is used for BL and BLX instructions, depending on the 410296417Sdim // value of bit 0 of Val, we must select a BL or BLX instruction 411296417Sdim if (Val & 1) { 412296417Sdim // If bit 0 of Val is 1 the target is Thumb, we must select a BLX. 413296417Sdim // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1' 414296417Sdim checkInt(Loc, Val, 26, Type); 415254721Semaste write32le(Loc, 0xfa000000 | // opcode 416296417Sdim ((Val & 2) << 23) | // H 417254721Semaste ((Val >> 2) & 0x00ffffff)); // imm24 418296417Sdim break; 419296417Sdim } 420296417Sdim if ((read32le(Loc) & 0xfe000000) == 0xfa000000) 421296417Sdim // BLX (always unconditional) instruction to an ARM Target, select an 422296417Sdim // unconditional BL. 423296417Sdim write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff)); 424296417Sdim // fall through as BL encoding is shared with B 425296417Sdim LLVM_FALLTHROUGH; 426296417Sdim case R_ARM_JUMP24: 427296417Sdim case R_ARM_PC24: 428296417Sdim case R_ARM_PLT32: 429296417Sdim checkInt(Loc, Val, 26, Type); 430296417Sdim write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff)); 431296417Sdim break; 432296417Sdim case R_ARM_THM_JUMP11: 433296417Sdim checkInt(Loc, Val, 12, Type); 434296417Sdim write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff)); 435296417Sdim break; 436296417Sdim case R_ARM_THM_JUMP19: 437296417Sdim // Encoding T3: Val = S:J2:J1:imm6:imm11:0 438296417Sdim checkInt(Loc, Val, 21, Type); 439296417Sdim write16le(Loc, 440296417Sdim (read16le(Loc) & 0xfbc0) | // opcode cond 441296417Sdim ((Val >> 10) & 0x0400) | // S 442296417Sdim ((Val >> 12) & 0x003f)); // imm6 443296417Sdim write16le(Loc + 2, 444296417Sdim 0x8000 | // opcode 445296417Sdim ((Val >> 8) & 0x0800) | // J2 446296417Sdim ((Val >> 5) & 0x2000) | // J1 447296417Sdim ((Val >> 1) & 0x07ff)); // imm11 448296417Sdim break; 449296417Sdim case R_ARM_THM_CALL: 450296417Sdim // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the 451296417Sdim // value of bit 0 of Val, we must select a BL or BLX instruction 452296417Sdim if ((Val & 1) == 0) { 453296417Sdim // Ensure BLX destination is 4-byte aligned. As BLX instruction may 454296417Sdim // only be two byte aligned. This must be done before overflow check 455296417Sdim Val = alignTo(Val, 4); 456296417Sdim } 457296417Sdim // Bit 12 is 0 for BLX, 1 for BL 458296417Sdim write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12); 459296417Sdim if (!Config->ARMJ1J2BranchEncoding) { 460296417Sdim // Older Arm architectures do not support R_ARM_THM_JUMP24 and have 461296417Sdim // different encoding rules and range due to J1 and J2 always being 1. 462296417Sdim checkInt(Loc, Val, 23, Type); 463296417Sdim write16le(Loc, 464296417Sdim 0xf000 | // opcode 465296417Sdim ((Val >> 12) & 0x07ff)); // imm11 466296417Sdim write16le(Loc + 2, 467296417Sdim (read16le(Loc + 2) & 0xd000) | // opcode 468296417Sdim 0x2800 | // J1 == J2 == 1 469296417Sdim ((Val >> 1) & 0x07ff)); // imm11 470296417Sdim break; 471296417Sdim } 472296417Sdim // Fall through as rest of encoding is the same as B.W 473296417Sdim LLVM_FALLTHROUGH; 474296417Sdim case R_ARM_THM_JUMP24: 475296417Sdim // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0 476296417Sdim checkInt(Loc, Val, 25, Type); 477296417Sdim write16le(Loc, 478296417Sdim 0xf000 | // opcode 479296417Sdim ((Val >> 14) & 0x0400) | // S 480296417Sdim ((Val >> 12) & 0x03ff)); // imm10 481296417Sdim write16le(Loc + 2, 482296417Sdim (read16le(Loc + 2) & 0xd000) | // opcode 483296417Sdim (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1 484296417Sdim (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2 485296417Sdim ((Val >> 1) & 0x07ff)); // imm11 486296417Sdim break; 487296417Sdim case R_ARM_MOVW_ABS_NC: 488296417Sdim case R_ARM_MOVW_PREL_NC: 489296417Sdim write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) | 490296417Sdim (Val & 0x0fff)); 491296417Sdim break; 492296417Sdim case R_ARM_MOVT_ABS: 493296417Sdim case R_ARM_MOVT_PREL: 494296417Sdim write32le(Loc, (read32le(Loc) & ~0x000f0fff) | 495296417Sdim (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff)); 496296417Sdim break; 497296417Sdim case R_ARM_THM_MOVT_ABS: 498296417Sdim case R_ARM_THM_MOVT_PREL: 499296417Sdim // Encoding T1: A = imm4:i:imm3:imm8 500296417Sdim write16le(Loc, 501296417Sdim 0xf2c0 | // opcode 502296417Sdim ((Val >> 17) & 0x0400) | // i 503296417Sdim ((Val >> 28) & 0x000f)); // imm4 504296417Sdim write16le(Loc + 2, 505296417Sdim (read16le(Loc + 2) & 0x8f00) | // opcode 506296417Sdim ((Val >> 12) & 0x7000) | // imm3 507296417Sdim ((Val >> 16) & 0x00ff)); // imm8 508296417Sdim break; 509296417Sdim case R_ARM_THM_MOVW_ABS_NC: 510296417Sdim case R_ARM_THM_MOVW_PREL_NC: 511296417Sdim // Encoding T3: A = imm4:i:imm3:imm8 512296417Sdim write16le(Loc, 513296417Sdim 0xf240 | // opcode 514296417Sdim ((Val >> 1) & 0x0400) | // i 515296417Sdim ((Val >> 12) & 0x000f)); // imm4 516254721Semaste write16le(Loc + 2, 517254721Semaste (read16le(Loc + 2) & 0x8f00) | // opcode 518296417Sdim ((Val << 4) & 0x7000) | // imm3 519296417Sdim (Val & 0x00ff)); // imm8 520296417Sdim break; 521296417Sdim default: 522296417Sdim error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); 523296417Sdim } 524296417Sdim} 525296417Sdim 526296417Sdimint64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const { 527296417Sdim switch (Type) { 528296417Sdim default: 529296417Sdim return 0; 530296417Sdim case R_ARM_ABS32: 531296417Sdim case R_ARM_BASE_PREL: 532296417Sdim case R_ARM_GOTOFF32: 533296417Sdim case R_ARM_GOT_BREL: 534296417Sdim case R_ARM_GOT_PREL: 535296417Sdim case R_ARM_REL32: 536296417Sdim case R_ARM_TARGET1: 537296417Sdim case R_ARM_TARGET2: 538296417Sdim case R_ARM_TLS_GD32: 539296417Sdim case R_ARM_TLS_LDM32: 540296417Sdim case R_ARM_TLS_LDO32: 541296417Sdim case R_ARM_TLS_IE32: 542296417Sdim case R_ARM_TLS_LE32: 543296417Sdim return SignExtend64<32>(read32le(Buf)); 544296417Sdim case R_ARM_PREL31: 545296417Sdim return SignExtend64<31>(read32le(Buf)); 546296417Sdim case R_ARM_CALL: 547296417Sdim case R_ARM_JUMP24: 548296417Sdim case R_ARM_PC24: 549296417Sdim case R_ARM_PLT32: 550296417Sdim return SignExtend64<26>(read32le(Buf) << 2); 551296417Sdim case R_ARM_THM_JUMP11: 552296417Sdim return SignExtend64<12>(read16le(Buf) << 1); 553296417Sdim case R_ARM_THM_JUMP19: { 554296417Sdim // Encoding T3: A = S:J2:J1:imm10:imm6:0 555296417Sdim uint16_t Hi = read16le(Buf); 556296417Sdim uint16_t Lo = read16le(Buf + 2); 557296417Sdim return SignExtend64<20>(((Hi & 0x0400) << 10) | // S 558296417Sdim ((Lo & 0x0800) << 8) | // J2 559296417Sdim ((Lo & 0x2000) << 5) | // J1 560296417Sdim ((Hi & 0x003f) << 12) | // imm6 561296417Sdim ((Lo & 0x07ff) << 1)); // imm11:0 562296417Sdim } 563296417Sdim case R_ARM_THM_CALL: 564296417Sdim if (!Config->ARMJ1J2BranchEncoding) { 565296417Sdim // Older Arm architectures do not support R_ARM_THM_JUMP24 and have 566296417Sdim // different encoding rules and range due to J1 and J2 always being 1. 567296417Sdim uint16_t Hi = read16le(Buf); 568296417Sdim uint16_t Lo = read16le(Buf + 2); 569296417Sdim return SignExtend64<22>(((Hi & 0x7ff) << 12) | // imm11 570296417Sdim ((Lo & 0x7ff) << 1)); // imm11:0 571296417Sdim break; 572296417Sdim } 573296417Sdim LLVM_FALLTHROUGH; 574296417Sdim case R_ARM_THM_JUMP24: { 575296417Sdim // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0 576296417Sdim // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S) 577296417Sdim uint16_t Hi = read16le(Buf); 578296417Sdim uint16_t Lo = read16le(Buf + 2); 579296417Sdim return SignExtend64<24>(((Hi & 0x0400) << 14) | // S 580296417Sdim (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1 581296417Sdim (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2 582296417Sdim ((Hi & 0x003ff) << 12) | // imm0 583296417Sdim ((Lo & 0x007ff) << 1)); // imm11:0 584296417Sdim } 585296417Sdim // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and 586296417Sdim // MOVT is in the range -32768 <= A < 32768 587296417Sdim case R_ARM_MOVW_ABS_NC: 588296417Sdim case R_ARM_MOVT_ABS: 589296417Sdim case R_ARM_MOVW_PREL_NC: 590296417Sdim case R_ARM_MOVT_PREL: { 591296417Sdim uint64_t Val = read32le(Buf) & 0x000f0fff; 592296417Sdim return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff)); 593296417Sdim } 594296417Sdim case R_ARM_THM_MOVW_ABS_NC: 595296417Sdim case R_ARM_THM_MOVT_ABS: 596296417Sdim case R_ARM_THM_MOVW_PREL_NC: 597296417Sdim case R_ARM_THM_MOVT_PREL: { 598296417Sdim // Encoding T3: A = imm4:i:imm3:imm8 599296417Sdim uint16_t Hi = read16le(Buf); 600296417Sdim uint16_t Lo = read16le(Buf + 2); 601296417Sdim return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4 602296417Sdim ((Hi & 0x0400) << 1) | // i 603296417Sdim ((Lo & 0x7000) >> 4) | // imm3 604296417Sdim (Lo & 0x00ff)); // imm8 605296417Sdim } 606296417Sdim } 607296417Sdim} 608296417Sdim 609296417SdimTargetInfo *elf::getARMTargetInfo() { 610296417Sdim static ARM Target; 611296417Sdim return &Target; 612296417Sdim} 613296417Sdim