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