xref: /llvm-project-15.0.7/lld/ELF/Target.cpp (revision 8d8fce87)
101205f79SRafael Espindola //===- Target.cpp ---------------------------------------------------------===//
201205f79SRafael Espindola //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
601205f79SRafael Espindola //
701205f79SRafael Espindola //===----------------------------------------------------------------------===//
834f29246SRui Ueyama //
96607227fSRui Ueyama // Machine-specific things, such as applying relocations, creation of
106607227fSRui Ueyama // GOT or PLT entries, etc., are handled in this file.
116607227fSRui Ueyama //
12d08aa5c3SNico Weber // Refer the ELF spec for the single letter variables, S, A or P, used
1322ef956aSRafael Espindola // in this file.
1434f29246SRui Ueyama //
1555274e3fSRui Ueyama // Some functions defined in this file has "relaxTls" as part of their names.
1655274e3fSRui Ueyama // They do peephole optimization for TLS variables by rewriting instructions.
1755274e3fSRui Ueyama // They are not part of the ABI but optional optimization, so you can skip
1855274e3fSRui Ueyama // them if you are not interested in how TLS variables are optimized.
1955274e3fSRui Ueyama // See the following paper for the details.
2055274e3fSRui Ueyama //
2155274e3fSRui Ueyama //   Ulrich Drepper, ELF Handling For Thread-Local Storage
2255274e3fSRui Ueyama //   http://www.akkadia.org/drepper/tls.pdf
2355274e3fSRui Ueyama //
2434f29246SRui Ueyama //===----------------------------------------------------------------------===//
2501205f79SRafael Espindola 
2601205f79SRafael Espindola #include "Target.h"
2713f6da1dSSimon Atanasyan #include "InputFiles.h"
28af21d923SRui Ueyama #include "OutputSections.h"
296e3595d6SRui Ueyama #include "SymbolTable.h"
303ef3a4c9SRafael Espindola #include "Symbols.h"
311444e6e2SAlex Richardson #include "SyntheticSections.h"
32b8a59c8aSBob Haarman #include "lld/Common/ErrorHandler.h"
33c4010885SRafael Espindola #include "llvm/Object/ELF.h"
3401205f79SRafael Espindola 
3501205f79SRafael Espindola using namespace llvm;
36c4010885SRafael Espindola using namespace llvm::object;
3701205f79SRafael Espindola using namespace llvm::ELF;
3807837b8fSFangrui Song using namespace lld;
3907837b8fSFangrui Song using namespace lld::elf;
4021c0a9ceSRui Ueyama 
4107837b8fSFangrui Song const TargetInfo *elf::target;
4207837b8fSFangrui Song 
toString(RelType type)4307837b8fSFangrui Song std::string lld::toString(RelType type) {
443837f427SRui Ueyama   StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
453837f427SRui Ueyama   if (s == "Unknown")
463837f427SRui Ueyama     return ("Unknown (" + Twine(type) + ")").str();
47adcd0268SBenjamin Kramer   return std::string(s);
48ce039266SRui Ueyama }
49ce039266SRui Ueyama 
getTarget()5007837b8fSFangrui Song TargetInfo *elf::getTarget() {
513837f427SRui Ueyama   switch (config->emachine) {
5221c0a9ceSRui Ueyama   case EM_386:
5321c0a9ceSRui Ueyama   case EM_IAMCU:
54e145bc22SRui Ueyama     return getX86TargetInfo();
5521c0a9ceSRui Ueyama   case EM_AARCH64:
56e145bc22SRui Ueyama     return getAArch64TargetInfo();
5721c0a9ceSRui Ueyama   case EM_AMDGPU:
58e145bc22SRui Ueyama     return getAMDGPUTargetInfo();
5921c0a9ceSRui Ueyama   case EM_ARM:
60e145bc22SRui Ueyama     return getARMTargetInfo();
6121c0a9ceSRui Ueyama   case EM_AVR:
62e145bc22SRui Ueyama     return getAVRTargetInfo();
6395b0c2e1SSid Manning   case EM_HEXAGON:
6495b0c2e1SSid Manning     return getHexagonTargetInfo();
6521c0a9ceSRui Ueyama   case EM_MIPS:
663837f427SRui Ueyama     switch (config->ekind) {
6721c0a9ceSRui Ueyama     case ELF32LEKind:
68e145bc22SRui Ueyama       return getMipsTargetInfo<ELF32LE>();
6921c0a9ceSRui Ueyama     case ELF32BEKind:
70e145bc22SRui Ueyama       return getMipsTargetInfo<ELF32BE>();
7121c0a9ceSRui Ueyama     case ELF64LEKind:
72e145bc22SRui Ueyama       return getMipsTargetInfo<ELF64LE>();
7321c0a9ceSRui Ueyama     case ELF64BEKind:
74e145bc22SRui Ueyama       return getMipsTargetInfo<ELF64BE>();
7521c0a9ceSRui Ueyama     default:
76cace50c6SRui Ueyama       llvm_unreachable("unsupported MIPS target");
7721c0a9ceSRui Ueyama     }
7873af3d40SGeorge Rimar   case EM_MSP430:
7973af3d40SGeorge Rimar     return getMSP430TargetInfo();
8021c0a9ceSRui Ueyama   case EM_PPC:
81e145bc22SRui Ueyama     return getPPCTargetInfo();
8221c0a9ceSRui Ueyama   case EM_PPC64:
83e145bc22SRui Ueyama     return getPPC64TargetInfo();
845cd9c6bcSRui Ueyama   case EM_RISCV:
855cd9c6bcSRui Ueyama     return getRISCVTargetInfo();
860cc14835SRui Ueyama   case EM_SPARCV9:
870cc14835SRui Ueyama     return getSPARCV9TargetInfo();
8821c0a9ceSRui Ueyama   case EM_X86_64:
89e145bc22SRui Ueyama     return getX86_64TargetInfo();
9021c0a9ceSRui Ueyama   }
91cace50c6SRui Ueyama   llvm_unreachable("unknown target machine");
9221c0a9ceSRui Ueyama }
93efc23de4SRui Ueyama 
getErrorPlace(const uint8_t * loc)94*8d8fce87SFangrui Song ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
951444e6e2SAlex Richardson   assert(loc != nullptr);
963837f427SRui Ueyama   for (InputSectionBase *d : inputSections) {
973837f427SRui Ueyama     auto *isec = cast<InputSection>(d);
98441410beSAlex Richardson     if (!isec->getParent() || (isec->type & SHT_NOBITS))
996e3595d6SRui Ueyama       continue;
1006e3595d6SRui Ueyama 
1011444e6e2SAlex Richardson     const uint8_t *isecLoc =
1021444e6e2SAlex Richardson         Out::bufferStart
1031444e6e2SAlex Richardson             ? (Out::bufferStart + isec->getParent()->offset + isec->outSecOff)
1041444e6e2SAlex Richardson             : isec->data().data();
1051444e6e2SAlex Richardson     if (isecLoc == nullptr) {
1061444e6e2SAlex Richardson       assert(isa<SyntheticSection>(isec) && "No data but not synthetic?");
1071444e6e2SAlex Richardson       continue;
1081444e6e2SAlex Richardson     }
1092b1e3241SFangrui Song     if (isecLoc <= loc && loc < isecLoc + isec->getSize()) {
1105f404a74SFangrui Song       std::string objLoc = isec->getLocation(loc - isecLoc);
1112b1e3241SFangrui Song       // Return object file location and source file location.
1122b1e3241SFangrui Song       // TODO: Refactor getSrcMsg not to take a variable.
1132b1e3241SFangrui Song       Undefined dummy(nullptr, "", STB_LOCAL, 0, 0);
1142b1e3241SFangrui Song       return {isec, objLoc + ": ",
1152b1e3241SFangrui Song               isec->file ? isec->getSrcMsg(dummy, loc - isecLoc) : ""};
1162b1e3241SFangrui Song     }
1176e3595d6SRui Ueyama   }
11889481f36SGeorge Rimar   return {};
1196e3595d6SRui Ueyama }
1206e3595d6SRui Ueyama 
~TargetInfo()12101205f79SRafael Espindola TargetInfo::~TargetInfo() {}
12201205f79SRafael Espindola 
getImplicitAddend(const uint8_t * buf,RelType type) const1233837f427SRui Ueyama int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
12435c5e564SAlex Richardson   internalLinkerError(getErrorLocation(buf),
12535c5e564SAlex Richardson                       "cannot read addend for relocation " + toString(type));
126da99df36SRafael Espindola   return 0;
127da99df36SRafael Espindola }
128da99df36SRafael Espindola 
usesOnlyLowPageBits(RelType type) const1293837f427SRui Ueyama bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
13048651489SGeorge Rimar 
needsThunk(RelExpr expr,RelType type,const InputFile * file,uint64_t branchAddr,const Symbol & s,int64_t a) const1313837f427SRui Ueyama bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
132bf535ac4SFangrui Song                             uint64_t branchAddr, const Symbol &s,
133bf535ac4SFangrui Song                             int64_t a) const {
1343a52eb00SPeter Smith   return false;
13513f6da1dSSimon Atanasyan }
13613f6da1dSSimon Atanasyan 
adjustPrologueForCrossSplitStack(uint8_t * loc,uint8_t * end,uint8_t stOther) const1373837f427SRui Ueyama bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
1383837f427SRui Ueyama                                                   uint8_t stOther) const {
1394fd84c18SSterling Augustine   llvm_unreachable("Target doesn't support split stacks.");
1404fd84c18SSterling Augustine }
1414fd84c18SSterling Augustine 
inBranchRange(RelType type,uint64_t src,uint64_t dst) const1423837f427SRui Ueyama bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
143a49442f3SPeter Smith   return true;
144a49442f3SPeter Smith }
145a49442f3SPeter Smith 
adjustTlsExpr(RelType type,RelExpr expr) const14650564ca0SFangrui Song RelExpr TargetInfo::adjustTlsExpr(RelType type, RelExpr expr) const {
1473837f427SRui Ueyama   return expr;
1485c33b91bSGeorge Rimar }
1495c33b91bSGeorge Rimar 
adjustGotPcExpr(RelType type,int64_t addend,const uint8_t * data) const150572d1839SFangrui Song RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend,
151572d1839SFangrui Song                                     const uint8_t *data) const {
152572d1839SFangrui Song   return R_GOT_PC;
153572d1839SFangrui Song }
154572d1839SFangrui Song 
relaxGot(uint8_t * loc,const Relocation & rel,uint64_t val) const1551e57038bSFangrui Song void TargetInfo::relaxGot(uint8_t *loc, const Relocation &rel,
1563837f427SRui Ueyama                           uint64_t val) const {
15789cc14fdSRafael Espindola   llvm_unreachable("Should not have claimed to be relaxable");
15889cc14fdSRafael Espindola }
15989cc14fdSRafael Espindola 
relaxTlsGdToLe(uint8_t * loc,const Relocation & rel,uint64_t val) const1601e57038bSFangrui Song void TargetInfo::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
1613837f427SRui Ueyama                                 uint64_t val) const {
16289cc14fdSRafael Espindola   llvm_unreachable("Should not have claimed to be relaxable");
16389cc14fdSRafael Espindola }
16489cc14fdSRafael Espindola 
relaxTlsGdToIe(uint8_t * loc,const Relocation & rel,uint64_t val) const1651e57038bSFangrui Song void TargetInfo::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
1663837f427SRui Ueyama                                 uint64_t val) const {
16789cc14fdSRafael Espindola   llvm_unreachable("Should not have claimed to be relaxable");
16889cc14fdSRafael Espindola }
16989cc14fdSRafael Espindola 
relaxTlsIeToLe(uint8_t * loc,const Relocation & rel,uint64_t val) const1701e57038bSFangrui Song void TargetInfo::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
1711e57038bSFangrui Song                                 uint64_t val) const {
1721e57038bSFangrui Song   llvm_unreachable("Should not have claimed to be relaxable");
1731e57038bSFangrui Song }
1741e57038bSFangrui Song 
relaxTlsLdToLe(uint8_t * loc,const Relocation & rel,uint64_t val) const1751e57038bSFangrui Song void TargetInfo::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
1763837f427SRui Ueyama                                 uint64_t val) const {
17789cc14fdSRafael Espindola   llvm_unreachable("Should not have claimed to be relaxable");
1786713cf8aSGeorge Rimar }
179b5ca92efSJames Henderson 
getImageBase() const180c694633aSRui Ueyama uint64_t TargetInfo::getImageBase() const {
181bf6e259bSFangrui Song   // Use --image-base if set. Fall back to the target default if not.
1823837f427SRui Ueyama   if (config->imageBase)
1833837f427SRui Ueyama     return *config->imageBase;
1843837f427SRui Ueyama   return config->isPic ? 0 : defaultImageBase;
185b5ca92efSJames Henderson }
186