xref: /freebsd/contrib/llvm-project/lld/ELF/Target.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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