xref: /freebsd/contrib/llvm-project/lld/ELF/Target.cpp (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
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"
31*480093f4SDimitry 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;
380b57cec5SDimitry Andric 
3985868e8aSDimitry Andric namespace lld {
4085868e8aSDimitry Andric std::string toString(elf::RelType type) {
410b57cec5SDimitry Andric   StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
420b57cec5SDimitry Andric   if (s == "Unknown")
430b57cec5SDimitry Andric     return ("Unknown (" + Twine(type) + ")").str();
440b57cec5SDimitry Andric   return s;
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
4785868e8aSDimitry Andric namespace elf {
4885868e8aSDimitry Andric const TargetInfo *target;
4985868e8aSDimitry Andric 
5085868e8aSDimitry Andric TargetInfo *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) {
95*480093f4SDimitry Andric   assert(loc != nullptr);
960b57cec5SDimitry Andric   for (InputSectionBase *d : inputSections) {
970b57cec5SDimitry Andric     auto *isec = cast<InputSection>(d);
980b57cec5SDimitry Andric     if (!isec->getParent())
990b57cec5SDimitry Andric       continue;
1000b57cec5SDimitry Andric 
101*480093f4SDimitry Andric     const uint8_t *isecLoc =
102*480093f4SDimitry Andric         Out::bufferStart
103*480093f4SDimitry Andric             ? (Out::bufferStart + isec->getParent()->offset + isec->outSecOff)
104*480093f4SDimitry Andric             : isec->data().data();
105*480093f4SDimitry Andric     if (isecLoc == nullptr) {
106*480093f4SDimitry Andric       assert(isa<SyntheticSection>(isec) && "No data but not synthetic?");
107*480093f4SDimitry Andric       continue;
108*480093f4SDimitry 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 
11585868e8aSDimitry Andric ErrorPlace 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,
139*480093f4SDimitry Andric                             uint64_t branchAddr, const Symbol &s,
140*480093f4SDimitry 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 
1530b57cec5SDimitry Andric RelExpr TargetInfo::adjustRelaxExpr(RelType type, const uint8_t *data,
1540b57cec5SDimitry Andric                                     RelExpr expr) const {
1550b57cec5SDimitry Andric   return expr;
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric void TargetInfo::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
1590b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric void TargetInfo::relaxTlsGdToLe(uint8_t *loc, RelType type,
1630b57cec5SDimitry Andric                                 uint64_t val) const {
1640b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric void TargetInfo::relaxTlsGdToIe(uint8_t *loc, RelType type,
1680b57cec5SDimitry Andric                                 uint64_t val) const {
1690b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric void TargetInfo::relaxTlsIeToLe(uint8_t *loc, RelType type,
1730b57cec5SDimitry Andric                                 uint64_t val) const {
1740b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric void TargetInfo::relaxTlsLdToLe(uint8_t *loc, RelType type,
1780b57cec5SDimitry Andric                                 uint64_t val) const {
1790b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
1800b57cec5SDimitry Andric }
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric uint64_t TargetInfo::getImageBase() const {
1830b57cec5SDimitry Andric   // Use -image-base if set. Fall back to the target default if not.
1840b57cec5SDimitry Andric   if (config->imageBase)
1850b57cec5SDimitry Andric     return *config->imageBase;
1860b57cec5SDimitry Andric   return config->isPic ? 0 : defaultImageBase;
1870b57cec5SDimitry Andric }
18885868e8aSDimitry Andric 
18985868e8aSDimitry Andric } // namespace elf
19085868e8aSDimitry Andric } // namespace lld
191