/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/TargetLoweringObjectFile.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- llvm/Target/TargetLoweringObjectFile.cpp - Object File Info -------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file implements classes used to handle lowerings specific to common |
11 | | // object file formats. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "llvm/Target/TargetLoweringObjectFile.h" |
16 | | #include "llvm/BinaryFormat/Dwarf.h" |
17 | | #include "llvm/IR/Constants.h" |
18 | | #include "llvm/IR/DataLayout.h" |
19 | | #include "llvm/IR/DerivedTypes.h" |
20 | | #include "llvm/IR/Function.h" |
21 | | #include "llvm/IR/GlobalVariable.h" |
22 | | #include "llvm/IR/Mangler.h" |
23 | | #include "llvm/MC/MCAsmInfo.h" |
24 | | #include "llvm/MC/MCContext.h" |
25 | | #include "llvm/MC/MCExpr.h" |
26 | | #include "llvm/MC/MCStreamer.h" |
27 | | #include "llvm/MC/MCSymbol.h" |
28 | | #include "llvm/Support/ErrorHandling.h" |
29 | | #include "llvm/Support/raw_ostream.h" |
30 | | #include "llvm/Target/TargetLowering.h" |
31 | | #include "llvm/Target/TargetMachine.h" |
32 | | #include "llvm/Target/TargetOptions.h" |
33 | | #include "llvm/Target/TargetSubtargetInfo.h" |
34 | | using namespace llvm; |
35 | | |
36 | | //===----------------------------------------------------------------------===// |
37 | | // Generic Code |
38 | | //===----------------------------------------------------------------------===// |
39 | | |
40 | | /// Initialize - this method must be called before any actual lowering is |
41 | | /// done. This specifies the current context for codegen, and gives the |
42 | | /// lowering implementations a chance to set up their default sections. |
43 | | void TargetLoweringObjectFile::Initialize(MCContext &ctx, |
44 | 33.4k | const TargetMachine &TM) { |
45 | 33.4k | Ctx = &ctx; |
46 | 33.4k | // `Initialize` can be called more than once. |
47 | 33.4k | delete Mang; |
48 | 33.4k | Mang = new Mangler(); |
49 | 33.4k | InitMCObjectFileInfo(TM.getTargetTriple(), TM.isPositionIndependent(), *Ctx, |
50 | 33.4k | TM.getCodeModel() == CodeModel::Large); |
51 | 33.4k | } |
52 | | |
53 | 25.0k | TargetLoweringObjectFile::~TargetLoweringObjectFile() { |
54 | 25.0k | delete Mang; |
55 | 25.0k | } |
56 | | |
57 | 779k | static bool isSuitableForBSS(const GlobalVariable *GV, bool NoZerosInBSS) { |
58 | 779k | const Constant *C = GV->getInitializer(); |
59 | 779k | |
60 | 779k | // Must have zero initializer. |
61 | 779k | if (!C->isNullValue()) |
62 | 709k | return false; |
63 | 69.8k | |
64 | 69.8k | // Leave constant zeros in readonly constant sections, so they can be shared. |
65 | 69.8k | if (69.8k GV->isConstant()69.8k ) |
66 | 1.11k | return false; |
67 | 68.7k | |
68 | 68.7k | // If the global has an explicit section specified, don't put it in BSS. |
69 | 68.7k | if (68.7k GV->hasSection()68.7k ) |
70 | 75 | return false; |
71 | 68.6k | |
72 | 68.6k | // If -nozero-initialized-in-bss is specified, don't ever use BSS. |
73 | 68.6k | if (68.6k NoZerosInBSS68.6k ) |
74 | 0 | return false; |
75 | 68.6k | |
76 | 68.6k | // Otherwise, put it in BSS! |
77 | 68.6k | return true; |
78 | 68.6k | } |
79 | | |
80 | | /// IsNullTerminatedString - Return true if the specified constant (which is |
81 | | /// known to have a type that is an array of 1/2/4 byte elements) ends with a |
82 | | /// nul value and contains no other nuls in it. Note that this is more general |
83 | | /// than ConstantDataSequential::isString because we allow 2 & 4 byte strings. |
84 | 495k | static bool IsNullTerminatedString(const Constant *C) { |
85 | 495k | // First check: is we have constant array terminated with zero |
86 | 495k | if (const ConstantDataSequential *CDS495k = dyn_cast<ConstantDataSequential>(C)) { |
87 | 494k | unsigned NumElts = CDS->getNumElements(); |
88 | 494k | assert(NumElts != 0 && "Can't have an empty CDS"); |
89 | 494k | |
90 | 494k | if (CDS->getElementAsInteger(NumElts-1) != 0) |
91 | 1.18k | return false; // Not null terminated. |
92 | 493k | |
93 | 493k | // Verify that the null doesn't occur anywhere else in the string. |
94 | 17.9M | for (unsigned i = 0; 493k i != NumElts-117.9M ; ++i17.4M ) |
95 | 17.4M | if (17.4M CDS->getElementAsInteger(i) == 017.4M ) |
96 | 348 | return false; |
97 | 493k | return true; |
98 | 966 | } |
99 | 966 | |
100 | 966 | // Another possibility: [1 x i8] zeroinitializer |
101 | 966 | if (966 isa<ConstantAggregateZero>(C)966 ) |
102 | 962 | return cast<ArrayType>(C->getType())->getNumElements() == 1; |
103 | 4 | |
104 | 4 | return false; |
105 | 4 | } |
106 | | |
107 | | MCSymbol *TargetLoweringObjectFile::getSymbolWithGlobalValueBase( |
108 | 2.63k | const GlobalValue *GV, StringRef Suffix, const TargetMachine &TM) const { |
109 | 2.63k | assert(!Suffix.empty()); |
110 | 2.63k | |
111 | 2.63k | SmallString<60> NameStr; |
112 | 2.63k | NameStr += GV->getParent()->getDataLayout().getPrivateGlobalPrefix(); |
113 | 2.63k | TM.getNameWithPrefix(NameStr, GV, *Mang); |
114 | 2.63k | NameStr.append(Suffix.begin(), Suffix.end()); |
115 | 2.63k | return Ctx->getOrCreateSymbol(NameStr); |
116 | 2.63k | } |
117 | | |
118 | | MCSymbol *TargetLoweringObjectFile::getCFIPersonalitySymbol( |
119 | | const GlobalValue *GV, const TargetMachine &TM, |
120 | 153 | MachineModuleInfo *MMI) const { |
121 | 153 | return TM.getSymbol(GV); |
122 | 153 | } |
123 | | |
124 | | void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer, |
125 | | const DataLayout &, |
126 | 387 | const MCSymbol *Sym) const { |
127 | 387 | } |
128 | | |
129 | | |
130 | | /// getKindForGlobal - This is a top-level target-independent classifier for |
131 | | /// a global variable. Given an global variable and information from TM, it |
132 | | /// classifies the global in a variety of ways that make various target |
133 | | /// implementations simpler. The target implementation is free to ignore this |
134 | | /// extra info of course. |
135 | | SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO, |
136 | 1.39M | const TargetMachine &TM){ |
137 | 1.39M | assert(!GO->isDeclaration() && !GO->hasAvailableExternallyLinkage() && |
138 | 1.39M | "Can only be used for global definitions"); |
139 | 1.39M | |
140 | 1.39M | Reloc::Model ReloModel = TM.getRelocationModel(); |
141 | 1.39M | |
142 | 1.39M | // Early exit - functions should be always in text sections. |
143 | 1.39M | const auto *GVar = dyn_cast<GlobalVariable>(GO); |
144 | 1.39M | if (!GVar) |
145 | 595k | return SectionKind::getText(); |
146 | 803k | |
147 | 803k | // Handle thread-local data first. |
148 | 803k | if (803k GVar->isThreadLocal()803k ) { |
149 | 277 | if (isSuitableForBSS(GVar, TM.Options.NoZerosInBSS)) |
150 | 170 | return SectionKind::getThreadBSS(); |
151 | 107 | return SectionKind::getThreadData(); |
152 | 107 | } |
153 | 803k | |
154 | 803k | // Variables with common linkage always get classified as common. |
155 | 803k | if (803k GVar->hasCommonLinkage()803k ) |
156 | 23.9k | return SectionKind::getCommon(); |
157 | 779k | |
158 | 779k | // Variable can be easily put to BSS section. |
159 | 779k | if (779k isSuitableForBSS(GVar, TM.Options.NoZerosInBSS)779k ) { |
160 | 68.4k | if (GVar->hasLocalLinkage()) |
161 | 15.2k | return SectionKind::getBSSLocal(); |
162 | 53.2k | else if (53.2k GVar->hasExternalLinkage()53.2k ) |
163 | 5.81k | return SectionKind::getBSSExtern(); |
164 | 47.3k | return SectionKind::getBSS(); |
165 | 47.3k | } |
166 | 711k | |
167 | 711k | const Constant *C = GVar->getInitializer(); |
168 | 711k | |
169 | 711k | // If the global is marked constant, we can put it into a mergable section, |
170 | 711k | // a mergable string section, or general .data if it contains relocations. |
171 | 711k | if (GVar->isConstant()711k ) { |
172 | 646k | // If the initializer for the global contains something that requires a |
173 | 646k | // relocation, then we may have to drop this into a writable data section |
174 | 646k | // even though it is marked const. |
175 | 646k | if (!C->needsRelocation()646k ) { |
176 | 628k | // If the global is required to have a unique address, it can't be put |
177 | 628k | // into a mergable section: just drop it into the general read-only |
178 | 628k | // section instead. |
179 | 628k | if (!GVar->hasGlobalUnnamedAddr()) |
180 | 131k | return SectionKind::getReadOnly(); |
181 | 496k | |
182 | 496k | // If initializer is a null-terminated string, put it in a "cstring" |
183 | 496k | // section of the right width. |
184 | 496k | if (ArrayType *496k ATy496k = dyn_cast<ArrayType>(C->getType())) { |
185 | 496k | if (IntegerType *ITy = |
186 | 495k | dyn_cast<IntegerType>(ATy->getElementType())) { |
187 | 495k | if ((ITy->getBitWidth() == 8 || 495k ITy->getBitWidth() == 161.65k || |
188 | 1.31k | ITy->getBitWidth() == 32) && |
189 | 495k | IsNullTerminatedString(C)495k ) { |
190 | 493k | if (ITy->getBitWidth() == 8) |
191 | 493k | return SectionKind::getMergeable1ByteCString(); |
192 | 515 | if (515 ITy->getBitWidth() == 16515 ) |
193 | 24 | return SectionKind::getMergeable2ByteCString(); |
194 | 491 | |
195 | 0 | assert(ITy->getBitWidth() == 32 && "Unknown width"); |
196 | 491 | return SectionKind::getMergeable4ByteCString(); |
197 | 491 | } |
198 | 495k | } |
199 | 496k | } |
200 | 2.92k | |
201 | 2.92k | // Otherwise, just drop it into a mergable constant section. If we have |
202 | 2.92k | // a section for this size, use it, otherwise use the arbitrary sized |
203 | 2.92k | // mergable section. |
204 | 2.92k | switch ( |
205 | 2.92k | GVar->getParent()->getDataLayout().getTypeAllocSize(C->getType())) { |
206 | 93 | case 4: return SectionKind::getMergeableConst4(); |
207 | 76 | case 8: return SectionKind::getMergeableConst8(); |
208 | 800 | case 16: return SectionKind::getMergeableConst16(); |
209 | 142 | case 32: return SectionKind::getMergeableConst32(); |
210 | 1.81k | default: |
211 | 1.81k | return SectionKind::getReadOnly(); |
212 | 646k | } |
213 | 646k | |
214 | 18.3k | } else { |
215 | 18.3k | // In static, ROPI and RWPI relocation models, the linker will resolve |
216 | 18.3k | // all addresses, so the relocation entries will actually be constants by |
217 | 18.3k | // the time the app starts up. However, we can't put this into a |
218 | 18.3k | // mergable section, because the linker doesn't take relocations into |
219 | 18.3k | // consideration when it tries to merge entries in the section. |
220 | 18.3k | if (ReloModel == Reloc::Static || 18.3k ReloModel == Reloc::ROPI18.3k || |
221 | 18.3k | ReloModel == Reloc::RWPI18.3k || ReloModel == Reloc::ROPI_RWPI18.3k ) |
222 | 65 | return SectionKind::getReadOnly(); |
223 | 18.3k | |
224 | 18.3k | // Otherwise, the dynamic linker needs to fix it up, put it in the |
225 | 18.3k | // writable data.rel section. |
226 | 18.3k | return SectionKind::getReadOnlyWithRel(); |
227 | 18.3k | } |
228 | 646k | } |
229 | 64.2k | |
230 | 64.2k | // Okay, this isn't a constant. |
231 | 64.2k | return SectionKind::getData(); |
232 | 64.2k | } |
233 | | |
234 | | /// This method computes the appropriate section to emit the specified global |
235 | | /// variable or function definition. This should not be passed external (or |
236 | | /// available externally) globals. |
237 | | MCSection *TargetLoweringObjectFile::SectionForGlobal( |
238 | 1.34M | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
239 | 1.34M | // Select section name. |
240 | 1.34M | if (GO->hasSection()) |
241 | 4.14k | return getExplicitSectionGlobal(GO, Kind, TM); |
242 | 1.34M | |
243 | 1.34M | if (auto *1.34M GVar1.34M = dyn_cast<GlobalVariable>(GO)) { |
244 | 749k | auto Attrs = GVar->getAttributes(); |
245 | 749k | if ((Attrs.hasAttribute("bss-section") && 749k Kind.isBSS()13 ) || |
246 | 749k | (Attrs.hasAttribute("data-section") && 749k Kind.isData()6 ) || |
247 | 749k | (Attrs.hasAttribute("rodata-section") && 749k Kind.isReadOnly()4 )) { |
248 | 13 | return getExplicitSectionGlobal(GO, Kind, TM); |
249 | 13 | } |
250 | 1.34M | } |
251 | 1.34M | |
252 | 1.34M | if (auto *1.34M F1.34M = dyn_cast<Function>(GO)) { |
253 | 595k | if (F->hasFnAttribute("implicit-section-name")) |
254 | 2 | return getExplicitSectionGlobal(GO, Kind, TM); |
255 | 1.34M | } |
256 | 1.34M | |
257 | 1.34M | // Use default section depending on the 'type' of global |
258 | 1.34M | return SelectSectionForGlobal(GO, Kind, TM); |
259 | 1.34M | } |
260 | | |
261 | | MCSection *TargetLoweringObjectFile::getSectionForJumpTable( |
262 | 45 | const Function &F, const TargetMachine &TM) const { |
263 | 45 | unsigned Align = 0; |
264 | 45 | return getSectionForConstant(F.getParent()->getDataLayout(), |
265 | 45 | SectionKind::getReadOnly(), /*C=*/nullptr, |
266 | 45 | Align); |
267 | 45 | } |
268 | | |
269 | | bool TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( |
270 | 4.33k | bool UsesLabelDifference, const Function &F) const { |
271 | 4.33k | // In PIC mode, we need to emit the jump table to the same section as the |
272 | 4.33k | // function body itself, otherwise the label differences won't make sense. |
273 | 4.33k | // FIXME: Need a better predicate for this: what about custom entries? |
274 | 4.33k | if (UsesLabelDifference) |
275 | 4.27k | return true; |
276 | 52 | |
277 | 52 | // We should also do if the section name is NULL or function is declared |
278 | 52 | // in discardable section |
279 | 52 | // FIXME: this isn't the right predicate, should be based on the MCSection |
280 | 52 | // for the function. |
281 | 52 | return F.isWeakForLinker(); |
282 | 52 | } |
283 | | |
284 | | /// Given a mergable constant with the specified size and relocation |
285 | | /// information, return a section that it should be placed in. |
286 | | MCSection *TargetLoweringObjectFile::getSectionForConstant( |
287 | | const DataLayout &DL, SectionKind Kind, const Constant *C, |
288 | 7 | unsigned &Align) const { |
289 | 7 | if (Kind.isReadOnly() && 7 ReadOnlySection != nullptr7 ) |
290 | 7 | return ReadOnlySection; |
291 | 0 |
|
292 | 0 | return DataSection; |
293 | 0 | } |
294 | | |
295 | | /// getTTypeGlobalReference - Return an MCExpr to use for a |
296 | | /// reference to the specified global variable from exception |
297 | | /// handling information. |
298 | | const MCExpr *TargetLoweringObjectFile::getTTypeGlobalReference( |
299 | | const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, |
300 | 22 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
301 | 22 | const MCSymbolRefExpr *Ref = |
302 | 22 | MCSymbolRefExpr::create(TM.getSymbol(GV), getContext()); |
303 | 22 | |
304 | 22 | return getTTypeReference(Ref, Encoding, Streamer); |
305 | 22 | } |
306 | | |
307 | | const MCExpr *TargetLoweringObjectFile:: |
308 | | getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, |
309 | 45 | MCStreamer &Streamer) const { |
310 | 45 | switch (Encoding & 0x70) { |
311 | 0 | default: |
312 | 0 | report_fatal_error("We do not support this DWARF encoding yet!"); |
313 | 22 | case dwarf::DW_EH_PE_absptr: |
314 | 22 | // Do nothing special |
315 | 22 | return Sym; |
316 | 23 | case dwarf::DW_EH_PE_pcrel: { |
317 | 23 | // Emit a label to the streamer for the current position. This gives us |
318 | 23 | // .-foo addressing. |
319 | 23 | MCSymbol *PCSym = getContext().createTempSymbol(); |
320 | 23 | Streamer.EmitLabel(PCSym); |
321 | 23 | const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext()); |
322 | 23 | return MCBinaryExpr::createSub(Sym, PC, getContext()); |
323 | 0 | } |
324 | 0 | } |
325 | 0 | } |
326 | | |
327 | 1 | const MCExpr *TargetLoweringObjectFile::getDebugThreadLocalSymbol(const MCSymbol *Sym) const { |
328 | 1 | // FIXME: It's not clear what, if any, default this should have - perhaps a |
329 | 1 | // null return could mean 'no location' & we should just do that here. |
330 | 1 | return MCSymbolRefExpr::create(Sym, *Ctx); |
331 | 1 | } |
332 | | |
333 | | void TargetLoweringObjectFile::getNameWithPrefix( |
334 | | SmallVectorImpl<char> &OutName, const GlobalValue *GV, |
335 | 2.62k | const TargetMachine &TM) const { |
336 | 2.62k | Mang->getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/false); |
337 | 2.62k | } |