Lines Matching +full:bl +full:- +full:data +full:- +full:offset
1 //===- PPC64.cpp ----------------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
30 // The instruction encoding of bits 21-30 from the ISA for the Xform and Dform
157 // pc-relative versions. For the most part, the primary opcode is shared
159 // However, there are some instances where that isn't the case (DS-Form and
160 // DQ-form instructions).
163 OPC_AND_RST = 0xffe00000, // Primary opc (0-5) and R[ST] (6-10).
164 ONLY_RST = 0x3e00000, // [RS]T (6-10).
166 0x8000000003e00000, // S/T (6-10) - The [S/T]X bit moves from 28 to 5.
213 uint64_t tocVA = in.got->getVA(); in getPPC64TocBase()
215 // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000 in getPPC64TocBase()
218 // start of the .toc section with only a single (signed) 16-bit relocation. in getPPC64TocBase()
223 // The offset is encoded into the 3 most significant bits of the st_other in getPPC64GlobalEntryToLocalEntryOffset()
225 // 0 --> Zero offset between the GEP and LEP, and the function does NOT use in getPPC64GlobalEntryToLocalEntryOffset()
228 // 1 --> Zero offset between the GEP and LEP, and r2 should be treated as a in getPPC64GlobalEntryToLocalEntryOffset()
229 // caller-saved register for all callers. in getPPC64GlobalEntryToLocalEntryOffset()
230 // 2-6 --> The binary logarithm of the offset eg: in getPPC64GlobalEntryToLocalEntryOffset()
231 // 2 --> 2^2 = 4 bytes --> 1 instruction. in getPPC64GlobalEntryToLocalEntryOffset()
232 // 6 --> 2^6 = 64 bytes --> 16 instructions. in getPPC64GlobalEntryToLocalEntryOffset()
233 // 7 --> Reserved. in getPPC64GlobalEntryToLocalEntryOffset()
239 // log-base-2(offset). in getPPC64GlobalEntryToLocalEntryOffset()
243 error("reserved value of 7 in the 3 most-significant-bits of st_other"); in getPPC64GlobalEntryToLocalEntryOffset()
248 insn = config->isLE ? insn << 32 | insn >> 32 : insn; in writePrefixedInstruction()
255 if (!sym || sym->isDefined()) in addOptional()
257 sym->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN, in addOptional()
265 // firstInsn+0x200008; ...; ${prefix}31: firstInsn+(31-14)*0x200008; $tail
273 uint32_t *ptr = buf.data(); in writeSequence()
276 if (addOptional(name, 4 * (r - from), defined) && defined.size() == 1) in writeSequence()
277 first = r - from; in writeSequence()
278 write32(ptr++, firstInsn + 0x200008 * (r - from)); in writeSequence()
290 ArrayRef(reinterpret_cast<uint8_t *>(buf.data() + first), in writeSequence()
291 4 * (buf.size() - first)), in writeSequence()
295 sym->section = sec; in writeSequence()
296 sym->value -= 4 * first; in writeSequence()
301 // compatible with GCC. With GCC -Os, when the number of call-saved registers
304 // https://sourceware.org/pipermail/binutils/2002-February/017444.html and
305 // https://sourceware.org/pipermail/binutils/2004-August/036765.html . This is
315 // _restgpr0_14: ld 14, -144(1); _restgpr0_15: ld 15, -136(1); ... in addPPC64SaveRestore()
319 // _restgpr1_14: ld 14, -144(12); _restgpr1_15: ld 15, -136(12); ... in addPPC64SaveRestore()
322 // _savegpr0_14: std 14, -144(1); _savegpr0_15: std 15, -136(1); ... in addPPC64SaveRestore()
325 // _savegpr1_14: std 14, -144(12); _savegpr1_15: std 15, -136(12); ... in addPPC64SaveRestore()
330 // Find the R_PPC64_ADDR64 in .rela.toc with matching offset.
333 getRelaTocSymAndAddend(InputSectionBase *tocSec, uint64_t offset) { in getRelaTocSymAndAddend() argument
335 // r_offset: 0, 8, 16, etc. For a given Offset, Offset / 8 gives us the in getRelaTocSymAndAddend()
339 // R_PPC64_ADDR64, the corresponding r_offset is therefore missing. Offset / 8 in getRelaTocSymAndAddend()
344 tocSec->template relsOrRelas<ELFT>().relas; in getRelaTocSymAndAddend()
347 uint64_t index = std::min<uint64_t>(offset / 8, relas.size() - 1); in getRelaTocSymAndAddend()
349 if (relas[index].r_offset == offset) { in getRelaTocSymAndAddend()
350 Symbol &sym = tocSec->file->getRelocTargetSym(relas[index]); in getRelaTocSymAndAddend()
353 if (relas[index].r_offset < offset || index == 0) in getRelaTocSymAndAddend()
355 --index; in getRelaTocSymAndAddend()
361 // reserve a .toc entry, allocate a local label and generate toc-indirect
371 // If var is defined, non-preemptable and addressable with a 32-bit signed
372 // offset from the toc base, the address of var can be computed by adding an
373 // offset to the toc base, saving a load.
382 assert(config->tocOptimize); in tryRelaxPPC64TocIndirection()
386 // If the symbol is not the .toc section, this isn't a toc-indirection. in tryRelaxPPC64TocIndirection()
388 if (!defSym || !defSym->isSection() || defSym->section->name != ".toc") in tryRelaxPPC64TocIndirection()
393 auto *tocISB = cast<InputSectionBase>(defSym->section); in tryRelaxPPC64TocIndirection()
395 config->isLE ? getRelaTocSymAndAddend<ELF64LE>(tocISB, rel.addend) in tryRelaxPPC64TocIndirection()
398 // Only non-preemptable defined symbols can be relaxed. in tryRelaxPPC64TocIndirection()
399 if (!d || d->isPreemptible) in tryRelaxPPC64TocIndirection()
402 // R_PPC64_ADDR64 should have created a canonical PLT for the non-preemptable in tryRelaxPPC64TocIndirection()
404 assert(!d->isGnuIFunc()); in tryRelaxPPC64TocIndirection()
406 // Two instructions can materialize a 32-bit signed offset from the toc base. in tryRelaxPPC64TocIndirection()
407 uint64_t tocRelative = d->getVA(addend) - getPPC64TocBase(); in tryRelaxPPC64TocIndirection()
419 // macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
442 // Namely `lxv` and `stxv` are the DQ-forms that use it. in isDQFormInstruction()
509 return UINT64_C(-1); in getPCRelativeForm()
545 // to the start of the data and the load/store instruction that has the offset
546 // into the data structure.
564 // instruction when handling a half16 relocation type. On big-endian the buffer
566 // little-endian it is pointing to the start of the word. These 2 helpers are to
569 write32(config->isLE ? loc : loc - 2, insn); in writeFromHalf16()
573 return read32(config->isLE ? loc : loc - 2); in readFromHalf16()
578 return config->isLE ? (fullInstr << 32 | fullInstr >> 32) : fullInstr; in readPrefixedInstruction()
610 // operating system full paging flexibility in the 64-bit address space. in PPC64()
612 // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers in PPC64()
616 write32(trapInstr.data(), 0x7fe00008); in PPC64()
634 if (file->ekind == ELF64BEKind) in getEFlags()
635 return cast<ObjFile<ELF64BE>>(file)->getObj().getHeader().e_flags; in getEFlags()
636 return cast<ObjFile<ELF64LE>>(file)->getObj().getHeader().e_flags; in getEFlags()
663 error("expected a 'ld' for got-indirect to toc-relative relaxing"); in relaxGot()
673 error("expected a 'pld' for got-indirect to pc-relative relaxing"); in relaxGot()
683 // We can only relax this if the R_PPC64_GOT_PCREL34 at this offset can in relaxGot()
693 if (pcRelInsn == UINT64_C(-1)) { in relaxGot()
718 // Reference: 3.7.4.2 of the 64-bit ELF V2 abi supplement. in relaxTlsGdToLe()
723 // bl __tls_get_addr(x@tlsgd) R_PPC64_TLSGD x in relaxTlsGdToLe()
730 // bl __tls_get_addr(x@tlsgd) into nop in relaxTlsGdToLe()
750 // Relax from bl __tls_get_addr@notoc(x@tlsgd) to in relaxTlsGdToLe()
753 // Relax from bl __tls_get_addr(x@tlsgd) in relaxTlsGdToLe()
765 relocateNoSym(loc + 4 + (config->ekind == ELF64BEKind ? 2 : 0), in relaxTlsGdToLe()
768 write32(loc - 1, NOP); in relaxTlsGdToLe()
781 // Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement. in relaxTlsLdToLe()
786 // bl __tls_get_addr(x@tlsgd) R_PPC64_TLSLD x in relaxTlsLdToLe()
793 // bl __tls_get_addr(x@tlsgd) into nop in relaxTlsLdToLe()
810 // Relax from bl __tls_get_addr@notoc(x@tlsld) in relaxTlsLdToLe()
814 // Relax from bl __tls_get_addr(x@tlsld) in relaxTlsLdToLe()
824 write32(loc - 1, NOP); in relaxTlsLdToLe()
844 // Map X-Form instructions to their DS-Form counterparts, if applicable.
846 // DS-Form instructions.
909 // instruction, if we are accessing memory it will use any of the X-form in relaxTlsIeToLe()
912 unsigned offset = (config->ekind == ELF64BEKind) ? 2 : 0; in relaxTlsIeToLe() local
915 write32(loc - offset, NOP); in relaxTlsIeToLe()
919 uint32_t regNo = read32(loc - offset) & 0x03E00000; // bits 6-10 in relaxTlsIeToLe()
920 write32(loc - offset, 0x3C0D0000 | regNo); // addis RegNo, r13 in relaxTlsIeToLe()
937 uint32_t secondaryOp = (read32(loc) & 0x000007FE) >> 1; // bits 21-30 in relaxTlsIeToLe()
940 if (dFormOp == 0) { // Expecting a DS-Form instruction. in relaxTlsIeToLe()
948 relocateNoSym(loc + offset, finalReloc, val); in relaxTlsIeToLe()
950 // If the offset is not 4 byte aligned then we have a PCRel type reloc. in relaxTlsIeToLe()
951 // This version of the relocation is offset by one byte from the in relaxTlsIeToLe()
953 uint32_t tlsInstr = read32(loc - 1); in relaxTlsIeToLe()
957 uint32_t secondaryOp = (tlsInstr & 0x000007FE) >> 1; // bits 21-30 in relaxTlsIeToLe()
963 uint32_t rt = (tlsInstr & 0x03E00000) >> 21; // bits 6-10 in relaxTlsIeToLe()
964 uint32_t ra = (tlsInstr & 0x001F0000) >> 16; // bits 11-15 in relaxTlsIeToLe()
966 write32(loc - 1, NOP); in relaxTlsIeToLe()
969 write32(loc - 1, 0x7C000378 | (rt << 16) | (ra << 21) | (ra << 11)); in relaxTlsIeToLe()
973 if (dFormOp == 0) { // Expecting a DS-Form instruction. in relaxTlsIeToLe()
978 write32(loc - 1, (dFormOp | (tlsInstr & 0x03ff0000))); in relaxTlsIeToLe()
982 "offset from 4 byte aligned"); in relaxTlsIeToLe()
1029 return config->tocOptimize ? R_PPC64_RELAX_TOC : R_GOTREL; in getRelExpr()
1156 // following instruction ('mflr r11'). Here we store the offset from that in writePltHeader()
1158 int64_t gotPltOffset = in.gotPlt->getVA() - (in.plt->getVA() + 8); in writePltHeader()
1164 int32_t offset = pltHeaderSize + sym.getPltIdx() * pltEntrySize; in writePlt() local
1165 // bl __glink_PLTresolve in writePlt()
1166 write32(buf, 0x48000000 | ((-offset) & 0x03FFFFFc)); in writePlt()
1171 writePPC64LoadAndBranch(buf, sym.getGotPltVA() - getPPC64TocBase()); in writeIplt()
1175 // Relocations relative to the toc-base need to be adjusted by the Toc offset. in toAddr16Rel()
1176 uint64_t tocBiasedVal = val - ppc64TocOffset; in toAddr16Rel()
1177 // Relocations relative to dtv[dtpmod] need to be adjusted by the DTP offset. in toAddr16Rel()
1178 uint64_t dtpBiasedVal = val - dynamicThreadPointerOffset; in toAddr16Rel()
1262 // For dynamic thread pointer relative, toc-relative, and got-indirect in relocate()
1285 // DQ-form instructions use bits 28-31 as part of the instruction encoding in relocate()
1286 // DS-form instructions only use bits 30-31. in relocate()
1294 if (config->tocOptimize && shouldTocOptimize && ha(val) == 0) in relocate()
1329 // When the high-adjusted part of a toc relocation evaluates to 0, it is in relocate()
1331 // toc-pointer register r2, as the base register. in relocate()
1332 if (config->tocOptimize && shouldTocOptimize && ha(val) == 0) { in relocate()
1336 "can't toc-optimize an update instruction: 0x" + in relocate()
1345 // DQ-form instructions use bits 28-31 as part of the instruction encoding in relocate()
1346 // DS-form instructions only use bits 30-31. in relocate()
1350 if (config->tocOptimize && shouldTocOptimize && ha(val) == 0) { in relocate()
1351 // When the high-adjusted part of a toc relocation evaluates to 0, it is in relocate()
1356 "Can't toc-optimize an update instruction: 0x" + in relocate()
1393 write64(loc, val - dynamicThreadPointerOffset); in relocate()
1399 val -= dynamicThreadPointerOffset; in relocate()
1431 // If a function is in the Plt it needs to be called with a call-stub. in needsThunk()
1446 // isUndefined() here. A undefined non-weak symbol has been errored. in needsThunk()
1450 // If the offset exceeds the range of the branch type then it will need in needsThunk()
1451 // a range-extending thunk. in needsThunk()
1462 // 0x2000000 = (1 << 24-1) * 4 in getThunkSectionSpacing()
1467 int64_t offset = dst - src; in inBranchRange() local
1469 return isInt<16>(offset); in inBranchRange()
1471 return isInt<26>(offset); in inBranchRange()
1486 config->pcRelOptimize) { in adjustGotPcExpr()
1495 // Reference: 3.7.4.1 of the 64-bit ELF V2 abi supplement.
1500 // bl __tls_get_addr(x@tlsgd) R_PPC64_TLSGD x
1504 // Relaxing to initial-exec entails:
1506 // struct for 'x' to an addis/ld pair that loads an offset from a got-entry.
1508 // 3) Convert the nop following the call to an add of the loaded offset to the
1538 // Relax from bl __tls_get_addr@notoc(x@tlsgd) to in relaxTlsGdToIe()
1541 // Relax from bl __tls_get_addr(x@tlsgd) in relaxTlsGdToIe()
1548 write32(loc, NOP); // bl __tls_get_addr(sym@tlsgd) --> nop in relaxTlsGdToIe()
1549 write32(loc + 4, 0x7c636A14); // nop --> add r3, r3, r13 in relaxTlsGdToIe()
1551 // bl __tls_get_addr(sym@tlsgd) --> add r3, r3, r13 in relaxTlsGdToIe()
1552 write32(loc - 1, 0x7c636a14); in relaxTlsGdToIe()
1564 uint64_t secAddr = sec.getOutputSection()->addr; in relocateAlloc()
1566 secAddr += s->outSecOff; in relocateAlloc()
1568 secAddr += ehIn->getParent()->outSecOff; in relocateAlloc()
1569 uint64_t lastPPCRelaxedRelocOff = -1; in relocateAlloc()
1571 uint8_t *loc = buf + rel.offset; in relocateAlloc()
1574 secAddr + rel.offset, *rel.sym, rel.expr); in relocateAlloc()
1578 // R_PPC64_GOT_PCREL34 in the relocations table at the same offset. in relocateAlloc()
1581 // associated symbol. So save the offset when relaxing R_PPC64_GOT_PCREL34 in relocateAlloc()
1582 // and only relax the other if the saved offset matches. in relocateAlloc()
1584 lastPPCRelaxedRelocOff = rel.offset; in relocateAlloc()
1585 if (rel.type == R_PPC64_PCREL_OPT && rel.offset != lastPPCRelaxedRelocOff) in relocateAlloc()
1608 if (rel.sym->needsTocRestore()) { in relocateAlloc()
1613 if ((rel.offset + 8 > sec.content().size() || in relocateAlloc()
1615 rel.sym->file != sec.file) { in relocateAlloc()
1646 // The prologue for a split-stack function is expected to look roughly
1653 // ld r0,-0x7000-64(r13)
1655 // addis r12, r1, ha(-stack-frame size)
1656 // addi r12, r12, l(-stack-frame size)
1660 // blt- cr7, .Lallocate_more_stack
1662 // -) The allocate_more_stack block might be placed after the split-stack
1663 // prologue and the `blt-` replaced with a `bge+ .Lnormal_func_body`
1665 // -) If either the addis or addi is not needed due to the stack size being
1671 // pair by split-stack-size-adjust.
1672 // addis r12, r1, ha(-stack-frame size - split-stack-adjust-size)
1673 // addi r12, r12, l(-stack-frame size - split-stack-adjust-size)
1677 // of the split-stack prologue will be at the local entry point. in adjustPrologueForCrossSplitStack()
1680 // At the very least we expect to see a load of some split-stack data from the in adjustPrologueForCrossSplitStack()
1683 // instructions it can't be a split-stack prologue. in adjustPrologueForCrossSplitStack()
1687 // First instruction must be `ld r0, -0x7000-64(r13)` in adjustPrologueForCrossSplitStack()
1713 // The register operands of the first instruction should be the stack-pointer in adjustPrologueForCrossSplitStack()
1729 if (stackFrameSize < config->splitStackAdjustSize + INT32_MIN) { in adjustPrologueForCrossSplitStack()
1730 error(getErrorLocation(loc) + "split-stack prologue adjustment overflows"); in adjustPrologueForCrossSplitStack()
1735 stackFrameSize - config->splitStackAdjustSize; in adjustPrologueForCrossSplitStack()