Lines Matching +full:loc +full:- +full:code
1 //===- LoongArch.cpp ------------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
37 const uint8_t *loc) const override;
39 void relocate(uint8_t *loc, const Relocation &rel,
75 // produces a PC-relative intermediate value with the lowest 12 bits zeroed (the
80 // Here a "page" is in fact just another way to refer to the 12-bit range
95 // (lu32i.d and lu52i.d). Compensate all the sign-extensions is a bit in getLoongArchPageDelta()
103 pcalau12i_pc = pc - 8; in getLoongArchPageDelta()
109 pcalau12i_pc = pc - 12; in getLoongArchPageDelta()
115 uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pcalau12i_pc); in getLoongArchPageDelta()
117 result += 0x1000 - 0x1'0000'0000; in getLoongArchPageDelta()
131 return begin == 63 ? v >> end : (v & ((1ULL << (begin + 1)) - 1)) >> end; in extractBits()
162 static void handleUleb128(uint8_t *loc, uint64_t val) { in handleUleb128() argument
166 uint64_t orig = decodeULEB128(loc, &count, nullptr, &error); in handleUleb128()
168 errorOrWarn(getErrorLocation(loc) + "extra space for uleb128"); in handleUleb128()
169 uint64_t mask = count < maxcount ? (1ULL << 7 * count) - 1 : -1ULL; in handleUleb128()
170 encodeULEB128((orig + val) & mask, loc, count); in handleUleb128()
179 // kernel implementation, and 64KiB is the biggest non-huge page size in LoongArch()
191 if (config->is64) { in LoongArch()
216 if (config->is64) in getEFlags()
217 return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader().e_flags; in getEFlags()
218 return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader().e_flags; in getEFlags()
222 for (const auto *sec : f->getSections()) in inputFileHasCode()
223 if (sec && sec->flags & SHF_EXECINSTR) in inputFileHasCode()
230 // If there are only binary input files (from -b binary), use a in calcEFlags()
238 // Do not enforce ABI compatibility if the input file does not contain code. in calcEFlags()
239 // This is useful for allowing linkage with data-only object files produced in calcEFlags()
244 // Take the first non-zero e_flags as the reference. in calcEFlags()
264 // binary-compatible with the upstream i.e. new-world ecosystem, it's not in calcEFlags()
267 // There are briefly some new-world systems with object ABI v0 binaries too. in calcEFlags()
297 return config->is64 ? read64le(buf) : read32le(buf); in getImplicitAddend()
310 if (config->is64) in writeGotPlt()
311 write64le(buf, in.plt->getVA()); in writeGotPlt()
313 write32le(buf, in.plt->getVA()); in writeGotPlt()
317 if (config->writeAddends) { in writeIgotPlt()
318 if (config->is64) in writeIgotPlt()
328 // PC-relative addressing (because `pcaddu12i` is the same as RISCV `auipc`), in writePltHeader()
329 // in contrast to the AArch64-like page-offset scheme with `pcalau12i` that in writePltHeader()
330 // is used everywhere else involving PC-relative operations in the LoongArch in writePltHeader()
339 // addi.[wd] $t1, $t1, -pltHeaderSize-12 ; t1 = &.plt[i] - &.plt[0] in writePltHeader()
341 // srli.[wd] $t1, $t1, (is64?1:2) ; t1 = &.got.plt[i] - &.got.plt[0] in writePltHeader()
344 uint32_t offset = in.gotPlt->getVA() - in.plt->getVA(); in writePltHeader()
345 uint32_t sub = config->is64 ? SUB_D : SUB_W; in writePltHeader()
346 uint32_t ld = config->is64 ? LD_D : LD_W; in writePltHeader()
347 uint32_t addi = config->is64 ? ADDI_D : ADDI_W; in writePltHeader()
348 uint32_t srli = config->is64 ? SRLI_D : SRLI_W; in writePltHeader()
352 write32le(buf + 12, insn(addi, R_T1, R_T1, lo12(-target->pltHeaderSize - 12))); in writePltHeader()
354 write32le(buf + 20, insn(srli, R_T1, R_T1, config->is64 ? 1 : 2)); in writePltHeader()
355 write32le(buf + 24, insn(ld, R_T0, R_T0, config->wordsize)); in writePltHeader()
368 uint32_t offset = sym.getGotPltVA() - pltEntryAddr; in writePlt()
371 insn(config->is64 ? LD_D : LD_W, R_T3, R_T3, lo12(offset))); in writePlt()
377 return type == target->symbolicRel ? type in getDynRel()
382 const uint8_t *loc) const { in getRelExpr()
403 // [2]: https://github.com/loongson/la-abi-specs/pull/3 in getRelExpr()
404 return isJirl(read32le(loc)) ? R_PLT : R_ABS; in getRelExpr()
430 // the RelExpr to avoid code duplication. in getRelExpr()
468 // (e.g. as outlined in https://github.com/loongson/la-abi-specs/pull/3). in getRelExpr()
473 // allow for such inter-pass state. in getRelExpr()
476 // BFD: assuming every R_LARCH_PCALA_HI20 is potentially PLT-needing, only in getRelExpr()
498 return config->relax ? R_RELAX_HINT : R_NONE; in getRelExpr()
523 // - psABI v1 relocs that need a stateful stack machine to work, and not in getRelExpr()
525 // - relocs that are not used anywhere (R_LARCH_{ADD,SUB}_24 [1], and the in getRelExpr()
526 // two GNU vtable-related relocs). in getRelExpr()
528 …// [1]: https://web.archive.org/web/20230709064026/https://github.com/loongson/LoongArch-Documenta… in getRelExpr()
530 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) + in getRelExpr()
550 void LoongArch::relocate(uint8_t *loc, const Relocation &rel, in relocate() argument
554 checkInt(loc, val, 32, rel); in relocate()
558 write32le(loc, val); in relocate()
563 write64le(loc, val); in relocate()
571 checkInt(loc, val, 22, rel); in relocate()
572 checkAlignment(loc, val, 4, rel); in relocate()
573 write32le(loc, setJ20(read32le(loc), val >> 2)); in relocate()
577 checkInt(loc, val, 18, rel); in relocate()
578 checkAlignment(loc, val, 4, rel); in relocate()
579 write32le(loc, setK16(read32le(loc), val >> 2)); in relocate()
583 checkInt(loc, val, 23, rel); in relocate()
584 checkAlignment(loc, val, 4, rel); in relocate()
585 write32le(loc, setD5k16(read32le(loc), val >> 2)); in relocate()
589 checkInt(loc, val, 28, rel); in relocate()
590 checkAlignment(loc, val, 4, rel); in relocate()
591 write32le(loc, setD10k16(read32le(loc), val >> 2)); in relocate()
597 // immediate fields, the relocation range is [-128G - 0x20000, +128G - in relocate()
598 // 0x20000) (of course must be 4-byte aligned). in relocate()
600 reportRangeError(loc, rel, Twine(val), llvm::minIntN(38) - 0x20000, in relocate()
601 llvm::maxIntN(38) - 0x20000); in relocate()
602 checkAlignment(loc, val, 4, rel); in relocate()
606 // Despite the name, the lower part is actually 18 bits with 4-byte aligned. in relocate()
608 write32le(loc, setJ20(read32le(loc), hi20)); in relocate()
609 write32le(loc + 4, setK16(read32le(loc + 4), lo16)); in relocate()
621 if (isJirl(read32le(loc))) { in relocate()
622 checkAlignment(loc, val, 4, rel); in relocate()
624 write32le(loc, setK16(read32le(loc), val >> 2)); in relocate()
637 write32le(loc, setK12(read32le(loc), extractBits(val, 11, 0))); in relocate()
654 write32le(loc, setJ20(read32le(loc), extractBits(val, 31, 12))); in relocate()
657 write32le(loc, setJ20(read32le(loc), extractBits(val + 0x800, 31, 12))); in relocate()
670 write32le(loc, setJ20(read32le(loc), extractBits(val, 51, 32))); in relocate()
683 write32le(loc, setK12(read32le(loc), extractBits(val, 63, 52))); in relocate()
687 *loc = (*loc & 0xc0) | ((*loc + val) & 0x3f); in relocate()
690 *loc += val; in relocate()
693 write16le(loc, read16le(loc) + val); in relocate()
696 write32le(loc, read32le(loc) + val); in relocate()
699 write64le(loc, read64le(loc) + val); in relocate()
702 handleUleb128(loc, val); in relocate()
705 *loc = (*loc & 0xc0) | ((*loc - val) & 0x3f); in relocate()
708 *loc -= val; in relocate()
711 write16le(loc, read16le(loc) - val); in relocate()
714 write32le(loc, read32le(loc) - val); in relocate()
717 write64le(loc, read64le(loc) - val); in relocate()
720 handleUleb128(loc, -val); in relocate()
725 // no-op in relocate()
735 write32le(loc + 4, val); in relocate()
738 write64le(loc + 8, val); in relocate()
757 const uint64_t loc = secAddr + r.offset - delta; in relax() local
762 r.sym->isUndefined() ? Log2_64(r.addend) + 1 : r.addend; in relax()
763 const uint64_t allBytes = (1ULL << (addend & 0xff)) - 4; in relax()
766 const uint64_t off = loc & (align - 1); in relax()
767 const uint64_t curBytes = off == 0 ? 0 : align - off; in relax()
773 remove = allBytes - curBytes; in relax()
776 errorOrWarn(getErrorLocation((const uint8_t *)loc) + in relax()
791 sa[0].d->size = sa[0].offset - delta - sa[0].d->value; in relax()
793 sa[0].d->value = sa[0].offset - delta; in relax()
804 a.d->size = a.offset - delta - a.d->value; in relax()
806 a.d->value = a.offset - delta; in relax()
816 // the absence of a linker script. For call and load/store R_LARCH_RELAX, code
818 // relaxation. Code shrinkage may increase displacement to a call/load/store
823 if (config->relocatable) in relaxOnce()
832 if (!(osec->flags & SHF_EXECINSTR)) in relaxOnce()
844 if (!(osec->flags & SHF_EXECINSTR)) in finalizeRelax()
847 RelaxAux &aux = *sec->relaxAux; in finalizeRelax()
851 MutableArrayRef<Relocation> rels = sec->relocs(); in finalizeRelax()
852 ArrayRef<uint8_t> old = sec->content(); in finalizeRelax()
853 size_t newSize = old.size() - aux.relocDeltas[rels.size() - 1]; in finalizeRelax()
857 sec->content_ = p; in finalizeRelax()
858 sec->size = newSize; in finalizeRelax()
859 sec->bytesDropped = 0; in finalizeRelax()
864 uint32_t remove = aux.relocDeltas[i] - delta; in finalizeRelax()
871 uint64_t size = r.offset - offset; in finalizeRelax()
876 memcpy(p, old.data() + offset, old.size() - offset); in finalizeRelax()
885 rels[i].offset -= delta; in finalizeRelax()
889 delta = aux.relocDeltas[i - 1]; in finalizeRelax()