xref: /freebsd/contrib/llvm-project/lld/ELF/Target.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
toString(RelType type)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 
getTarget()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();
9074626c16SDimitry Andric   case EM_S390:
9174626c16SDimitry Andric     return getSystemZTargetInfo();
920b57cec5SDimitry Andric   case EM_X86_64:
930b57cec5SDimitry Andric     return getX86_64TargetInfo();
94*0fca6ea1SDimitry Andric   default:
95*0fca6ea1SDimitry Andric     fatal("unsupported e_machine value: " + Twine(config->emachine));
960b57cec5SDimitry Andric   }
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric 
getErrorPlace(const uint8_t * loc)991fd87a68SDimitry Andric ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
100480093f4SDimitry Andric   assert(loc != nullptr);
101bdd1243dSDimitry Andric   for (InputSectionBase *d : ctx.inputSections) {
102bdd1243dSDimitry Andric     auto *isec = dyn_cast<InputSection>(d);
103bdd1243dSDimitry Andric     if (!isec || !isec->getParent() || (isec->type & SHT_NOBITS))
1040b57cec5SDimitry Andric       continue;
1050b57cec5SDimitry Andric 
106480093f4SDimitry Andric     const uint8_t *isecLoc =
107480093f4SDimitry Andric         Out::bufferStart
108480093f4SDimitry Andric             ? (Out::bufferStart + isec->getParent()->offset + isec->outSecOff)
109bdd1243dSDimitry Andric             : isec->contentMaybeDecompress().data();
110480093f4SDimitry Andric     if (isecLoc == nullptr) {
111480093f4SDimitry Andric       assert(isa<SyntheticSection>(isec) && "No data but not synthetic?");
112480093f4SDimitry Andric       continue;
113480093f4SDimitry Andric     }
114349cc55cSDimitry Andric     if (isecLoc <= loc && loc < isecLoc + isec->getSize()) {
11504eeddc0SDimitry Andric       std::string objLoc = isec->getLocation(loc - isecLoc);
116349cc55cSDimitry Andric       // Return object file location and source file location.
117349cc55cSDimitry Andric       // TODO: Refactor getSrcMsg not to take a variable.
1187a6dacacSDimitry Andric       Undefined dummy(ctx.internalFile, "", STB_LOCAL, 0, 0);
119349cc55cSDimitry Andric       return {isec, objLoc + ": ",
120349cc55cSDimitry Andric               isec->file ? isec->getSrcMsg(dummy, loc - isecLoc) : ""};
121349cc55cSDimitry Andric     }
1220b57cec5SDimitry Andric   }
1230b57cec5SDimitry Andric   return {};
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric 
~TargetInfo()1260b57cec5SDimitry Andric TargetInfo::~TargetInfo() {}
1270b57cec5SDimitry Andric 
getImplicitAddend(const uint8_t * buf,RelType type) const1280b57cec5SDimitry Andric int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
129fe6060f1SDimitry Andric   internalLinkerError(getErrorLocation(buf),
130fe6060f1SDimitry Andric                       "cannot read addend for relocation " + toString(type));
1310b57cec5SDimitry Andric   return 0;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
usesOnlyLowPageBits(RelType type) const1340b57cec5SDimitry Andric bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
1350b57cec5SDimitry Andric 
needsThunk(RelExpr expr,RelType type,const InputFile * file,uint64_t branchAddr,const Symbol & s,int64_t a) const1360b57cec5SDimitry Andric bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
137480093f4SDimitry Andric                             uint64_t branchAddr, const Symbol &s,
138480093f4SDimitry Andric                             int64_t a) const {
1390b57cec5SDimitry Andric   return false;
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric 
adjustPrologueForCrossSplitStack(uint8_t * loc,uint8_t * end,uint8_t stOther) const1420b57cec5SDimitry Andric bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
1430b57cec5SDimitry Andric                                                   uint8_t stOther) const {
144*0fca6ea1SDimitry Andric   fatal("target doesn't support split stacks");
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
inBranchRange(RelType type,uint64_t src,uint64_t dst) const1470b57cec5SDimitry Andric bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
1480b57cec5SDimitry Andric   return true;
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric 
adjustTlsExpr(RelType type,RelExpr expr) const151e8d8bef9SDimitry Andric RelExpr TargetInfo::adjustTlsExpr(RelType type, RelExpr expr) const {
1520b57cec5SDimitry Andric   return expr;
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric 
adjustGotPcExpr(RelType type,int64_t addend,const uint8_t * data) const155e8d8bef9SDimitry Andric RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend,
156e8d8bef9SDimitry Andric                                     const uint8_t *data) const {
157e8d8bef9SDimitry Andric   return R_GOT_PC;
158e8d8bef9SDimitry Andric }
159e8d8bef9SDimitry Andric 
relocateAlloc(InputSectionBase & sec,uint8_t * buf) const160bdd1243dSDimitry Andric void TargetInfo::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
161bdd1243dSDimitry Andric   const unsigned bits = config->is64 ? 64 : 32;
162bdd1243dSDimitry Andric   uint64_t secAddr = sec.getOutputSection()->addr;
163bdd1243dSDimitry Andric   if (auto *s = dyn_cast<InputSection>(&sec))
164bdd1243dSDimitry Andric     secAddr += s->outSecOff;
1655f757f3fSDimitry Andric   else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
1665f757f3fSDimitry Andric     secAddr += ehIn->getParent()->outSecOff;
167bdd1243dSDimitry Andric   for (const Relocation &rel : sec.relocs()) {
168bdd1243dSDimitry Andric     uint8_t *loc = buf + rel.offset;
169bdd1243dSDimitry Andric     const uint64_t val = SignExtend64(
170bdd1243dSDimitry Andric         sec.getRelocTargetVA(sec.file, rel.type, rel.addend,
171bdd1243dSDimitry Andric                              secAddr + rel.offset, *rel.sym, rel.expr),
172bdd1243dSDimitry Andric         bits);
173bdd1243dSDimitry Andric     if (rel.expr != R_RELAX_HINT)
174bdd1243dSDimitry Andric       relocate(loc, rel, val);
1750b57cec5SDimitry Andric   }
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric 
getImageBase() const1780b57cec5SDimitry Andric uint64_t TargetInfo::getImageBase() const {
179349cc55cSDimitry Andric   // Use --image-base if set. Fall back to the target default if not.
1800b57cec5SDimitry Andric   if (config->imageBase)
1810b57cec5SDimitry Andric     return *config->imageBase;
1820b57cec5SDimitry Andric   return config->isPic ? 0 : defaultImageBase;
1830b57cec5SDimitry Andric }
184