xref: /freebsd/contrib/llvm-project/lld/ELF/Target.cpp (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
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();
650b57cec5SDimitry Andric   case EM_MIPS:
660b57cec5SDimitry Andric     switch (config->ekind) {
670b57cec5SDimitry Andric     case ELF32LEKind:
680b57cec5SDimitry Andric       return getMipsTargetInfo<ELF32LE>();
690b57cec5SDimitry Andric     case ELF32BEKind:
700b57cec5SDimitry Andric       return getMipsTargetInfo<ELF32BE>();
710b57cec5SDimitry Andric     case ELF64LEKind:
720b57cec5SDimitry Andric       return getMipsTargetInfo<ELF64LE>();
730b57cec5SDimitry Andric     case ELF64BEKind:
740b57cec5SDimitry Andric       return getMipsTargetInfo<ELF64BE>();
750b57cec5SDimitry Andric     default:
760b57cec5SDimitry Andric       llvm_unreachable("unsupported MIPS target");
770b57cec5SDimitry Andric     }
780b57cec5SDimitry Andric   case EM_MSP430:
790b57cec5SDimitry Andric     return getMSP430TargetInfo();
800b57cec5SDimitry Andric   case EM_PPC:
810b57cec5SDimitry Andric     return getPPCTargetInfo();
820b57cec5SDimitry Andric   case EM_PPC64:
830b57cec5SDimitry Andric     return getPPC64TargetInfo();
840b57cec5SDimitry Andric   case EM_RISCV:
850b57cec5SDimitry Andric     return getRISCVTargetInfo();
860b57cec5SDimitry Andric   case EM_SPARCV9:
870b57cec5SDimitry Andric     return getSPARCV9TargetInfo();
880b57cec5SDimitry Andric   case EM_X86_64:
890b57cec5SDimitry Andric     return getX86_64TargetInfo();
900b57cec5SDimitry Andric   }
910b57cec5SDimitry Andric   llvm_unreachable("unknown target machine");
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
95480093f4SDimitry Andric   assert(loc != nullptr);
960b57cec5SDimitry Andric   for (InputSectionBase *d : inputSections) {
970b57cec5SDimitry Andric     auto *isec = cast<InputSection>(d);
9855e4f9d5SDimitry Andric     if (!isec->getParent() || (isec->type & SHT_NOBITS))
990b57cec5SDimitry Andric       continue;
1000b57cec5SDimitry Andric 
101480093f4SDimitry Andric     const uint8_t *isecLoc =
102480093f4SDimitry Andric         Out::bufferStart
103480093f4SDimitry Andric             ? (Out::bufferStart + isec->getParent()->offset + isec->outSecOff)
104480093f4SDimitry Andric             : isec->data().data();
105480093f4SDimitry Andric     if (isecLoc == nullptr) {
106480093f4SDimitry Andric       assert(isa<SyntheticSection>(isec) && "No data but not synthetic?");
107480093f4SDimitry Andric       continue;
108480093f4SDimitry Andric     }
109349cc55cSDimitry Andric     if (isecLoc <= loc && loc < isecLoc + isec->getSize()) {
110*04eeddc0SDimitry Andric       std::string objLoc = isec->getLocation(loc - isecLoc);
111349cc55cSDimitry Andric       // Return object file location and source file location.
112349cc55cSDimitry Andric       // TODO: Refactor getSrcMsg not to take a variable.
113349cc55cSDimitry Andric       Undefined dummy(nullptr, "", STB_LOCAL, 0, 0);
114349cc55cSDimitry Andric       return {isec, objLoc + ": ",
115349cc55cSDimitry Andric               isec->file ? isec->getSrcMsg(dummy, loc - isecLoc) : ""};
116349cc55cSDimitry Andric     }
1170b57cec5SDimitry Andric   }
1180b57cec5SDimitry Andric   return {};
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
1215ffd83dbSDimitry Andric ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
1220b57cec5SDimitry Andric   switch (config->ekind) {
1230b57cec5SDimitry Andric   case ELF32LEKind:
1240b57cec5SDimitry Andric     return getErrPlace<ELF32LE>(loc);
1250b57cec5SDimitry Andric   case ELF32BEKind:
1260b57cec5SDimitry Andric     return getErrPlace<ELF32BE>(loc);
1270b57cec5SDimitry Andric   case ELF64LEKind:
1280b57cec5SDimitry Andric     return getErrPlace<ELF64LE>(loc);
1290b57cec5SDimitry Andric   case ELF64BEKind:
1300b57cec5SDimitry Andric     return getErrPlace<ELF64BE>(loc);
1310b57cec5SDimitry Andric   default:
1320b57cec5SDimitry Andric     llvm_unreachable("unknown ELF type");
1330b57cec5SDimitry Andric   }
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric TargetInfo::~TargetInfo() {}
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
139fe6060f1SDimitry Andric   internalLinkerError(getErrorLocation(buf),
140fe6060f1SDimitry Andric                       "cannot read addend for relocation " + toString(type));
1410b57cec5SDimitry Andric   return 0;
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
147480093f4SDimitry Andric                             uint64_t branchAddr, const Symbol &s,
148480093f4SDimitry Andric                             int64_t a) const {
1490b57cec5SDimitry Andric   return false;
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
1530b57cec5SDimitry Andric                                                   uint8_t stOther) const {
1540b57cec5SDimitry Andric   llvm_unreachable("Target doesn't support split stacks.");
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
1580b57cec5SDimitry Andric   return true;
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric 
161e8d8bef9SDimitry Andric RelExpr TargetInfo::adjustTlsExpr(RelType type, RelExpr expr) const {
1620b57cec5SDimitry Andric   return expr;
1630b57cec5SDimitry Andric }
1640b57cec5SDimitry Andric 
165e8d8bef9SDimitry Andric RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend,
166e8d8bef9SDimitry Andric                                     const uint8_t *data) const {
167e8d8bef9SDimitry Andric   return R_GOT_PC;
168e8d8bef9SDimitry Andric }
169e8d8bef9SDimitry Andric 
1705ffd83dbSDimitry Andric void TargetInfo::relaxGot(uint8_t *loc, const Relocation &rel,
1710b57cec5SDimitry Andric                           uint64_t val) const {
1720b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
1755ffd83dbSDimitry Andric void TargetInfo::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
1760b57cec5SDimitry Andric                                 uint64_t val) const {
1770b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric 
1805ffd83dbSDimitry Andric void TargetInfo::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
1810b57cec5SDimitry Andric                                 uint64_t val) const {
1820b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric 
1855ffd83dbSDimitry Andric void TargetInfo::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
1865ffd83dbSDimitry Andric                                 uint64_t val) const {
1875ffd83dbSDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1885ffd83dbSDimitry Andric }
1895ffd83dbSDimitry Andric 
1905ffd83dbSDimitry Andric void TargetInfo::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
1910b57cec5SDimitry Andric                                 uint64_t val) const {
1920b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric uint64_t TargetInfo::getImageBase() const {
196349cc55cSDimitry Andric   // Use --image-base if set. Fall back to the target default if not.
1970b57cec5SDimitry Andric   if (config->imageBase)
1980b57cec5SDimitry Andric     return *config->imageBase;
1990b57cec5SDimitry Andric   return config->isPic ? 0 : defaultImageBase;
2000b57cec5SDimitry Andric }
201