xref: /freebsd/contrib/llvm-project/lld/ELF/Target.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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     }
1090b57cec5SDimitry Andric     if (isecLoc <= loc && loc < isecLoc + isec->getSize())
1100b57cec5SDimitry Andric       return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
1110b57cec5SDimitry Andric   }
1120b57cec5SDimitry Andric   return {};
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
1155ffd83dbSDimitry Andric ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
1160b57cec5SDimitry Andric   switch (config->ekind) {
1170b57cec5SDimitry Andric   case ELF32LEKind:
1180b57cec5SDimitry Andric     return getErrPlace<ELF32LE>(loc);
1190b57cec5SDimitry Andric   case ELF32BEKind:
1200b57cec5SDimitry Andric     return getErrPlace<ELF32BE>(loc);
1210b57cec5SDimitry Andric   case ELF64LEKind:
1220b57cec5SDimitry Andric     return getErrPlace<ELF64LE>(loc);
1230b57cec5SDimitry Andric   case ELF64BEKind:
1240b57cec5SDimitry Andric     return getErrPlace<ELF64BE>(loc);
1250b57cec5SDimitry Andric   default:
1260b57cec5SDimitry Andric     llvm_unreachable("unknown ELF type");
1270b57cec5SDimitry Andric   }
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric TargetInfo::~TargetInfo() {}
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
1330b57cec5SDimitry Andric   return 0;
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
139480093f4SDimitry Andric                             uint64_t branchAddr, const Symbol &s,
140480093f4SDimitry Andric                             int64_t a) const {
1410b57cec5SDimitry Andric   return false;
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
1450b57cec5SDimitry Andric                                                   uint8_t stOther) const {
1460b57cec5SDimitry Andric   llvm_unreachable("Target doesn't support split stacks.");
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
1500b57cec5SDimitry Andric   return true;
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric 
153*e8d8bef9SDimitry Andric RelExpr TargetInfo::adjustTlsExpr(RelType type, RelExpr expr) const {
1540b57cec5SDimitry Andric   return expr;
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
157*e8d8bef9SDimitry Andric RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend,
158*e8d8bef9SDimitry Andric                                     const uint8_t *data) const {
159*e8d8bef9SDimitry Andric   return R_GOT_PC;
160*e8d8bef9SDimitry Andric }
161*e8d8bef9SDimitry Andric 
1625ffd83dbSDimitry Andric void TargetInfo::relaxGot(uint8_t *loc, const Relocation &rel,
1630b57cec5SDimitry Andric                           uint64_t val) const {
1640b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric 
1675ffd83dbSDimitry Andric void TargetInfo::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
1680b57cec5SDimitry Andric                                 uint64_t val) const {
1690b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
1725ffd83dbSDimitry Andric void TargetInfo::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
1730b57cec5SDimitry Andric                                 uint64_t val) const {
1740b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric 
1775ffd83dbSDimitry Andric void TargetInfo::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
1785ffd83dbSDimitry Andric                                 uint64_t val) const {
1795ffd83dbSDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1805ffd83dbSDimitry Andric }
1815ffd83dbSDimitry Andric 
1825ffd83dbSDimitry Andric void TargetInfo::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
1830b57cec5SDimitry Andric                                 uint64_t val) const {
1840b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric uint64_t TargetInfo::getImageBase() const {
1880b57cec5SDimitry Andric   // Use -image-base if set. Fall back to the target default if not.
1890b57cec5SDimitry Andric   if (config->imageBase)
1900b57cec5SDimitry Andric     return *config->imageBase;
1910b57cec5SDimitry Andric   return config->isPic ? 0 : defaultImageBase;
1920b57cec5SDimitry Andric }
193