xref: /freebsd/contrib/llvm-project/lld/ELF/Target.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- Target.cpp ---------------------------------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // Machine-specific things, such as applying relocations, creation of
10*0b57cec5SDimitry Andric // GOT or PLT entries, etc., are handled in this file.
11*0b57cec5SDimitry Andric //
12*0b57cec5SDimitry Andric // Refer the ELF spec for the single letter variables, S, A or P, used
13*0b57cec5SDimitry Andric // in this file.
14*0b57cec5SDimitry Andric //
15*0b57cec5SDimitry Andric // Some functions defined in this file has "relaxTls" as part of their names.
16*0b57cec5SDimitry Andric // They do peephole optimization for TLS variables by rewriting instructions.
17*0b57cec5SDimitry Andric // They are not part of the ABI but optional optimization, so you can skip
18*0b57cec5SDimitry Andric // them if you are not interested in how TLS variables are optimized.
19*0b57cec5SDimitry Andric // See the following paper for the details.
20*0b57cec5SDimitry Andric //
21*0b57cec5SDimitry Andric //   Ulrich Drepper, ELF Handling For Thread-Local Storage
22*0b57cec5SDimitry Andric //   http://www.akkadia.org/drepper/tls.pdf
23*0b57cec5SDimitry Andric //
24*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25*0b57cec5SDimitry Andric 
26*0b57cec5SDimitry Andric #include "Target.h"
27*0b57cec5SDimitry Andric #include "InputFiles.h"
28*0b57cec5SDimitry Andric #include "OutputSections.h"
29*0b57cec5SDimitry Andric #include "SymbolTable.h"
30*0b57cec5SDimitry Andric #include "Symbols.h"
31*0b57cec5SDimitry Andric #include "lld/Common/ErrorHandler.h"
32*0b57cec5SDimitry Andric #include "llvm/Object/ELF.h"
33*0b57cec5SDimitry Andric 
34*0b57cec5SDimitry Andric using namespace llvm;
35*0b57cec5SDimitry Andric using namespace llvm::object;
36*0b57cec5SDimitry Andric using namespace llvm::ELF;
37*0b57cec5SDimitry Andric using namespace lld;
38*0b57cec5SDimitry Andric using namespace lld::elf;
39*0b57cec5SDimitry Andric 
40*0b57cec5SDimitry Andric const TargetInfo *elf::target;
41*0b57cec5SDimitry Andric 
42*0b57cec5SDimitry Andric std::string lld::toString(RelType type) {
43*0b57cec5SDimitry Andric   StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
44*0b57cec5SDimitry Andric   if (s == "Unknown")
45*0b57cec5SDimitry Andric     return ("Unknown (" + Twine(type) + ")").str();
46*0b57cec5SDimitry Andric   return s;
47*0b57cec5SDimitry Andric }
48*0b57cec5SDimitry Andric 
49*0b57cec5SDimitry Andric TargetInfo *elf::getTarget() {
50*0b57cec5SDimitry Andric   switch (config->emachine) {
51*0b57cec5SDimitry Andric   case EM_386:
52*0b57cec5SDimitry Andric   case EM_IAMCU:
53*0b57cec5SDimitry Andric     return getX86TargetInfo();
54*0b57cec5SDimitry Andric   case EM_AARCH64:
55*0b57cec5SDimitry Andric     return getAArch64TargetInfo();
56*0b57cec5SDimitry Andric   case EM_AMDGPU:
57*0b57cec5SDimitry Andric     return getAMDGPUTargetInfo();
58*0b57cec5SDimitry Andric   case EM_ARM:
59*0b57cec5SDimitry Andric     return getARMTargetInfo();
60*0b57cec5SDimitry Andric   case EM_AVR:
61*0b57cec5SDimitry Andric     return getAVRTargetInfo();
62*0b57cec5SDimitry Andric   case EM_HEXAGON:
63*0b57cec5SDimitry Andric     return getHexagonTargetInfo();
64*0b57cec5SDimitry Andric   case EM_MIPS:
65*0b57cec5SDimitry Andric     switch (config->ekind) {
66*0b57cec5SDimitry Andric     case ELF32LEKind:
67*0b57cec5SDimitry Andric       return getMipsTargetInfo<ELF32LE>();
68*0b57cec5SDimitry Andric     case ELF32BEKind:
69*0b57cec5SDimitry Andric       return getMipsTargetInfo<ELF32BE>();
70*0b57cec5SDimitry Andric     case ELF64LEKind:
71*0b57cec5SDimitry Andric       return getMipsTargetInfo<ELF64LE>();
72*0b57cec5SDimitry Andric     case ELF64BEKind:
73*0b57cec5SDimitry Andric       return getMipsTargetInfo<ELF64BE>();
74*0b57cec5SDimitry Andric     default:
75*0b57cec5SDimitry Andric       llvm_unreachable("unsupported MIPS target");
76*0b57cec5SDimitry Andric     }
77*0b57cec5SDimitry Andric   case EM_MSP430:
78*0b57cec5SDimitry Andric     return getMSP430TargetInfo();
79*0b57cec5SDimitry Andric   case EM_PPC:
80*0b57cec5SDimitry Andric     return getPPCTargetInfo();
81*0b57cec5SDimitry Andric   case EM_PPC64:
82*0b57cec5SDimitry Andric     return getPPC64TargetInfo();
83*0b57cec5SDimitry Andric   case EM_RISCV:
84*0b57cec5SDimitry Andric     return getRISCVTargetInfo();
85*0b57cec5SDimitry Andric   case EM_SPARCV9:
86*0b57cec5SDimitry Andric     return getSPARCV9TargetInfo();
87*0b57cec5SDimitry Andric   case EM_X86_64:
88*0b57cec5SDimitry Andric     return getX86_64TargetInfo();
89*0b57cec5SDimitry Andric   }
90*0b57cec5SDimitry Andric   llvm_unreachable("unknown target machine");
91*0b57cec5SDimitry Andric }
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
94*0b57cec5SDimitry Andric   for (InputSectionBase *d : inputSections) {
95*0b57cec5SDimitry Andric     auto *isec = cast<InputSection>(d);
96*0b57cec5SDimitry Andric     if (!isec->getParent())
97*0b57cec5SDimitry Andric       continue;
98*0b57cec5SDimitry Andric 
99*0b57cec5SDimitry Andric     uint8_t *isecLoc = Out::bufferStart + isec->getParent()->offset + isec->outSecOff;
100*0b57cec5SDimitry Andric     if (isecLoc <= loc && loc < isecLoc + isec->getSize())
101*0b57cec5SDimitry Andric       return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
102*0b57cec5SDimitry Andric   }
103*0b57cec5SDimitry Andric   return {};
104*0b57cec5SDimitry Andric }
105*0b57cec5SDimitry Andric 
106*0b57cec5SDimitry Andric ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
107*0b57cec5SDimitry Andric   switch (config->ekind) {
108*0b57cec5SDimitry Andric   case ELF32LEKind:
109*0b57cec5SDimitry Andric     return getErrPlace<ELF32LE>(loc);
110*0b57cec5SDimitry Andric   case ELF32BEKind:
111*0b57cec5SDimitry Andric     return getErrPlace<ELF32BE>(loc);
112*0b57cec5SDimitry Andric   case ELF64LEKind:
113*0b57cec5SDimitry Andric     return getErrPlace<ELF64LE>(loc);
114*0b57cec5SDimitry Andric   case ELF64BEKind:
115*0b57cec5SDimitry Andric     return getErrPlace<ELF64BE>(loc);
116*0b57cec5SDimitry Andric   default:
117*0b57cec5SDimitry Andric     llvm_unreachable("unknown ELF type");
118*0b57cec5SDimitry Andric   }
119*0b57cec5SDimitry Andric }
120*0b57cec5SDimitry Andric 
121*0b57cec5SDimitry Andric TargetInfo::~TargetInfo() {}
122*0b57cec5SDimitry Andric 
123*0b57cec5SDimitry Andric int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
124*0b57cec5SDimitry Andric   return 0;
125*0b57cec5SDimitry Andric }
126*0b57cec5SDimitry Andric 
127*0b57cec5SDimitry Andric bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
128*0b57cec5SDimitry Andric 
129*0b57cec5SDimitry Andric bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
130*0b57cec5SDimitry Andric                             uint64_t branchAddr, const Symbol &s) const {
131*0b57cec5SDimitry Andric   return false;
132*0b57cec5SDimitry Andric }
133*0b57cec5SDimitry Andric 
134*0b57cec5SDimitry Andric bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
135*0b57cec5SDimitry Andric                                                   uint8_t stOther) const {
136*0b57cec5SDimitry Andric   llvm_unreachable("Target doesn't support split stacks.");
137*0b57cec5SDimitry Andric }
138*0b57cec5SDimitry Andric 
139*0b57cec5SDimitry Andric bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
140*0b57cec5SDimitry Andric   return true;
141*0b57cec5SDimitry Andric }
142*0b57cec5SDimitry Andric 
143*0b57cec5SDimitry Andric void TargetInfo::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
144*0b57cec5SDimitry Andric   writeGotPlt(buf, s);
145*0b57cec5SDimitry Andric }
146*0b57cec5SDimitry Andric 
147*0b57cec5SDimitry Andric RelExpr TargetInfo::adjustRelaxExpr(RelType type, const uint8_t *data,
148*0b57cec5SDimitry Andric                                     RelExpr expr) const {
149*0b57cec5SDimitry Andric   return expr;
150*0b57cec5SDimitry Andric }
151*0b57cec5SDimitry Andric 
152*0b57cec5SDimitry Andric void TargetInfo::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
153*0b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
154*0b57cec5SDimitry Andric }
155*0b57cec5SDimitry Andric 
156*0b57cec5SDimitry Andric void TargetInfo::relaxTlsGdToLe(uint8_t *loc, RelType type,
157*0b57cec5SDimitry Andric                                 uint64_t val) const {
158*0b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
159*0b57cec5SDimitry Andric }
160*0b57cec5SDimitry Andric 
161*0b57cec5SDimitry Andric void TargetInfo::relaxTlsGdToIe(uint8_t *loc, RelType type,
162*0b57cec5SDimitry Andric                                 uint64_t val) const {
163*0b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
164*0b57cec5SDimitry Andric }
165*0b57cec5SDimitry Andric 
166*0b57cec5SDimitry Andric void TargetInfo::relaxTlsIeToLe(uint8_t *loc, RelType type,
167*0b57cec5SDimitry Andric                                 uint64_t val) const {
168*0b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
169*0b57cec5SDimitry Andric }
170*0b57cec5SDimitry Andric 
171*0b57cec5SDimitry Andric void TargetInfo::relaxTlsLdToLe(uint8_t *loc, RelType type,
172*0b57cec5SDimitry Andric                                 uint64_t val) const {
173*0b57cec5SDimitry Andric   llvm_unreachable("Should not have claimed to be relaxable");
174*0b57cec5SDimitry Andric }
175*0b57cec5SDimitry Andric 
176*0b57cec5SDimitry Andric uint64_t TargetInfo::getImageBase() const {
177*0b57cec5SDimitry Andric   // Use -image-base if set. Fall back to the target default if not.
178*0b57cec5SDimitry Andric   if (config->imageBase)
179*0b57cec5SDimitry Andric     return *config->imageBase;
180*0b57cec5SDimitry Andric   return config->isPic ? 0 : defaultImageBase;
181*0b57cec5SDimitry Andric }
182