10b57cec5SDimitry Andric //===- Target.cpp ---------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Machine-specific things, such as applying relocations, creation of 100b57cec5SDimitry Andric // GOT or PLT entries, etc., are handled in this file. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric // Refer the ELF spec for the single letter variables, S, A or P, used 130b57cec5SDimitry Andric // in this file. 140b57cec5SDimitry Andric // 150b57cec5SDimitry Andric // Some functions defined in this file has "relaxTls" as part of their names. 160b57cec5SDimitry Andric // They do peephole optimization for TLS variables by rewriting instructions. 170b57cec5SDimitry Andric // They are not part of the ABI but optional optimization, so you can skip 180b57cec5SDimitry Andric // them if you are not interested in how TLS variables are optimized. 190b57cec5SDimitry Andric // See the following paper for the details. 200b57cec5SDimitry Andric // 210b57cec5SDimitry Andric // Ulrich Drepper, ELF Handling For Thread-Local Storage 220b57cec5SDimitry Andric // http://www.akkadia.org/drepper/tls.pdf 230b57cec5SDimitry Andric // 240b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric #include "Target.h" 270b57cec5SDimitry Andric #include "InputFiles.h" 280b57cec5SDimitry Andric #include "OutputSections.h" 290b57cec5SDimitry Andric #include "SymbolTable.h" 300b57cec5SDimitry Andric #include "Symbols.h" 31480093f4SDimitry Andric #include "SyntheticSections.h" 320b57cec5SDimitry Andric #include "lld/Common/ErrorHandler.h" 330b57cec5SDimitry Andric #include "llvm/Object/ELF.h" 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric using namespace llvm; 360b57cec5SDimitry Andric using namespace llvm::object; 370b57cec5SDimitry Andric using namespace llvm::ELF; 385ffd83dbSDimitry Andric using namespace lld; 395ffd83dbSDimitry Andric using namespace lld::elf; 400b57cec5SDimitry Andric 415ffd83dbSDimitry Andric const TargetInfo *elf::target; 425ffd83dbSDimitry Andric 435ffd83dbSDimitry Andric std::string lld::toString(RelType type) { 440b57cec5SDimitry Andric StringRef s = getELFRelocationTypeName(elf::config->emachine, type); 450b57cec5SDimitry Andric if (s == "Unknown") 460b57cec5SDimitry Andric return ("Unknown (" + Twine(type) + ")").str(); 475ffd83dbSDimitry Andric return std::string(s); 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric 505ffd83dbSDimitry Andric TargetInfo *elf::getTarget() { 510b57cec5SDimitry Andric switch (config->emachine) { 520b57cec5SDimitry Andric case EM_386: 530b57cec5SDimitry Andric case EM_IAMCU: 540b57cec5SDimitry Andric return getX86TargetInfo(); 550b57cec5SDimitry Andric case EM_AARCH64: 560b57cec5SDimitry Andric return getAArch64TargetInfo(); 570b57cec5SDimitry Andric case EM_AMDGPU: 580b57cec5SDimitry Andric return getAMDGPUTargetInfo(); 590b57cec5SDimitry Andric case EM_ARM: 600b57cec5SDimitry Andric return getARMTargetInfo(); 610b57cec5SDimitry Andric case EM_AVR: 620b57cec5SDimitry Andric return getAVRTargetInfo(); 630b57cec5SDimitry Andric case EM_HEXAGON: 640b57cec5SDimitry Andric return getHexagonTargetInfo(); 6506c3fb27SDimitry Andric case EM_LOONGARCH: 6606c3fb27SDimitry Andric return getLoongArchTargetInfo(); 670b57cec5SDimitry Andric case EM_MIPS: 680b57cec5SDimitry Andric switch (config->ekind) { 690b57cec5SDimitry Andric case ELF32LEKind: 700b57cec5SDimitry Andric return getMipsTargetInfo<ELF32LE>(); 710b57cec5SDimitry Andric case ELF32BEKind: 720b57cec5SDimitry Andric return getMipsTargetInfo<ELF32BE>(); 730b57cec5SDimitry Andric case ELF64LEKind: 740b57cec5SDimitry Andric return getMipsTargetInfo<ELF64LE>(); 750b57cec5SDimitry Andric case ELF64BEKind: 760b57cec5SDimitry Andric return getMipsTargetInfo<ELF64BE>(); 770b57cec5SDimitry Andric default: 780b57cec5SDimitry Andric llvm_unreachable("unsupported MIPS target"); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric case EM_MSP430: 810b57cec5SDimitry Andric return getMSP430TargetInfo(); 820b57cec5SDimitry Andric case EM_PPC: 830b57cec5SDimitry Andric return getPPCTargetInfo(); 840b57cec5SDimitry Andric case EM_PPC64: 850b57cec5SDimitry Andric return getPPC64TargetInfo(); 860b57cec5SDimitry Andric case EM_RISCV: 870b57cec5SDimitry Andric return getRISCVTargetInfo(); 880b57cec5SDimitry Andric case EM_SPARCV9: 890b57cec5SDimitry Andric return getSPARCV9TargetInfo(); 900b57cec5SDimitry Andric case EM_X86_64: 910b57cec5SDimitry Andric return getX86_64TargetInfo(); 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric llvm_unreachable("unknown target machine"); 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric 961fd87a68SDimitry Andric ErrorPlace elf::getErrorPlace(const uint8_t *loc) { 97480093f4SDimitry Andric assert(loc != nullptr); 98bdd1243dSDimitry Andric for (InputSectionBase *d : ctx.inputSections) { 99bdd1243dSDimitry Andric auto *isec = dyn_cast<InputSection>(d); 100bdd1243dSDimitry Andric if (!isec || !isec->getParent() || (isec->type & SHT_NOBITS)) 1010b57cec5SDimitry Andric continue; 1020b57cec5SDimitry Andric 103480093f4SDimitry Andric const uint8_t *isecLoc = 104480093f4SDimitry Andric Out::bufferStart 105480093f4SDimitry Andric ? (Out::bufferStart + isec->getParent()->offset + isec->outSecOff) 106bdd1243dSDimitry Andric : isec->contentMaybeDecompress().data(); 107480093f4SDimitry Andric if (isecLoc == nullptr) { 108480093f4SDimitry Andric assert(isa<SyntheticSection>(isec) && "No data but not synthetic?"); 109480093f4SDimitry Andric continue; 110480093f4SDimitry Andric } 111349cc55cSDimitry Andric if (isecLoc <= loc && loc < isecLoc + isec->getSize()) { 11204eeddc0SDimitry Andric std::string objLoc = isec->getLocation(loc - isecLoc); 113349cc55cSDimitry Andric // Return object file location and source file location. 114349cc55cSDimitry Andric // TODO: Refactor getSrcMsg not to take a variable. 115349cc55cSDimitry Andric Undefined dummy(nullptr, "", STB_LOCAL, 0, 0); 116349cc55cSDimitry Andric return {isec, objLoc + ": ", 117349cc55cSDimitry Andric isec->file ? isec->getSrcMsg(dummy, loc - isecLoc) : ""}; 118349cc55cSDimitry Andric } 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric return {}; 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric TargetInfo::~TargetInfo() {} 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const { 126fe6060f1SDimitry Andric internalLinkerError(getErrorLocation(buf), 127fe6060f1SDimitry Andric "cannot read addend for relocation " + toString(type)); 1280b57cec5SDimitry Andric return 0; 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file, 134480093f4SDimitry Andric uint64_t branchAddr, const Symbol &s, 135480093f4SDimitry Andric int64_t a) const { 1360b57cec5SDimitry Andric return false; 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end, 1400b57cec5SDimitry Andric uint8_t stOther) const { 1410b57cec5SDimitry Andric llvm_unreachable("Target doesn't support split stacks."); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const { 1450b57cec5SDimitry Andric return true; 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric 148e8d8bef9SDimitry Andric RelExpr TargetInfo::adjustTlsExpr(RelType type, RelExpr expr) const { 1490b57cec5SDimitry Andric return expr; 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 152e8d8bef9SDimitry Andric RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend, 153e8d8bef9SDimitry Andric const uint8_t *data) const { 154e8d8bef9SDimitry Andric return R_GOT_PC; 155e8d8bef9SDimitry Andric } 156e8d8bef9SDimitry Andric 157bdd1243dSDimitry Andric void TargetInfo::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const { 158bdd1243dSDimitry Andric const unsigned bits = config->is64 ? 64 : 32; 159bdd1243dSDimitry Andric uint64_t secAddr = sec.getOutputSection()->addr; 160bdd1243dSDimitry Andric if (auto *s = dyn_cast<InputSection>(&sec)) 161bdd1243dSDimitry Andric secAddr += s->outSecOff; 162*5f757f3fSDimitry Andric else if (auto *ehIn = dyn_cast<EhInputSection>(&sec)) 163*5f757f3fSDimitry Andric secAddr += ehIn->getParent()->outSecOff; 164bdd1243dSDimitry Andric for (const Relocation &rel : sec.relocs()) { 165bdd1243dSDimitry Andric uint8_t *loc = buf + rel.offset; 166bdd1243dSDimitry Andric const uint64_t val = SignExtend64( 167bdd1243dSDimitry Andric sec.getRelocTargetVA(sec.file, rel.type, rel.addend, 168bdd1243dSDimitry Andric secAddr + rel.offset, *rel.sym, rel.expr), 169bdd1243dSDimitry Andric bits); 170bdd1243dSDimitry Andric if (rel.expr != R_RELAX_HINT) 171bdd1243dSDimitry Andric relocate(loc, rel, val); 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric uint64_t TargetInfo::getImageBase() const { 176349cc55cSDimitry Andric // Use --image-base if set. Fall back to the target default if not. 1770b57cec5SDimitry Andric if (config->imageBase) 1780b57cec5SDimitry Andric return *config->imageBase; 1790b57cec5SDimitry Andric return config->isPic ? 0 : defaultImageBase; 1800b57cec5SDimitry Andric } 181