1 | //===-- llvm/Target/TargetLoweringObjectFile.cpp - Object File Info -------===// |
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 | // This file implements classes used to handle lowerings specific to common |
10 | // object file formats. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "llvm/Target/TargetLoweringObjectFile.h" |
15 | #include "llvm/BinaryFormat/Dwarf.h" |
16 | #include "llvm/IR/Constants.h" |
17 | #include "llvm/IR/DataLayout.h" |
18 | #include "llvm/IR/DerivedTypes.h" |
19 | #include "llvm/IR/Function.h" |
20 | #include "llvm/IR/GlobalVariable.h" |
21 | #include "llvm/IR/Mangler.h" |
22 | #include "llvm/IR/Module.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/SectionKind.h" |
28 | #include "llvm/Support/ErrorHandling.h" |
29 | #include "llvm/Target/TargetMachine.h" |
30 | #include "llvm/Target/TargetOptions.h" |
31 | using namespace llvm; |
32 | |
33 | //===----------------------------------------------------------------------===// |
34 | // Generic Code |
35 | //===----------------------------------------------------------------------===// |
36 | |
37 | /// Initialize - this method must be called before any actual lowering is |
38 | /// done. This specifies the current context for codegen, and gives the |
39 | /// lowering implementations a chance to set up their default sections. |
40 | void TargetLoweringObjectFile::Initialize(MCContext &ctx, |
41 | const TargetMachine &TM) { |
42 | // `Initialize` can be called more than once. |
43 | delete Mang; |
44 | Mang = new Mangler(); |
45 | initMCObjectFileInfo(MCCtx&: ctx, PIC: TM.isPositionIndependent(), |
46 | LargeCodeModel: TM.getCodeModel() == CodeModel::Large); |
47 | |
48 | // Reset various EH DWARF encodings. |
49 | PersonalityEncoding = LSDAEncoding = TTypeEncoding = dwarf::DW_EH_PE_absptr; |
50 | CallSiteEncoding = dwarf::DW_EH_PE_uleb128; |
51 | |
52 | this->TM = &TM; |
53 | } |
54 | |
55 | TargetLoweringObjectFile::~TargetLoweringObjectFile() { |
56 | delete Mang; |
57 | } |
58 | |
59 | unsigned TargetLoweringObjectFile::getCallSiteEncoding() const { |
60 | // If target does not have LEB128 directives, we would need the |
61 | // call site encoding to be udata4 so that the alternative path |
62 | // for not having LEB128 directives could work. |
63 | if (!getContext().getAsmInfo()->hasLEB128Directives()) |
64 | return dwarf::DW_EH_PE_udata4; |
65 | return CallSiteEncoding; |
66 | } |
67 | |
68 | static bool isNullOrUndef(const Constant *C) { |
69 | // Check that the constant isn't all zeros or undefs. |
70 | if (C->isNullValue() || isa<UndefValue>(Val: C)) |
71 | return true; |
72 | if (!isa<ConstantAggregate>(Val: C)) |
73 | return false; |
74 | for (const auto *Operand : C->operand_values()) { |
75 | if (!isNullOrUndef(C: cast<Constant>(Val: Operand))) |
76 | return false; |
77 | } |
78 | return true; |
79 | } |
80 | |
81 | static bool isSuitableForBSS(const GlobalVariable *GV) { |
82 | const Constant *C = GV->getInitializer(); |
83 | |
84 | // Must have zero initializer. |
85 | if (!isNullOrUndef(C)) |
86 | return false; |
87 | |
88 | // Leave constant zeros in readonly constant sections, so they can be shared. |
89 | if (GV->isConstant()) |
90 | return false; |
91 | |
92 | // If the global has an explicit section specified, don't put it in BSS. |
93 | if (GV->hasSection()) |
94 | return false; |
95 | |
96 | // Otherwise, put it in BSS! |
97 | return true; |
98 | } |
99 | |
100 | /// IsNullTerminatedString - Return true if the specified constant (which is |
101 | /// known to have a type that is an array of 1/2/4 byte elements) ends with a |
102 | /// nul value and contains no other nuls in it. Note that this is more general |
103 | /// than ConstantDataSequential::isString because we allow 2 & 4 byte strings. |
104 | static bool IsNullTerminatedString(const Constant *C) { |
105 | // First check: is we have constant array terminated with zero |
106 | if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(Val: C)) { |
107 | unsigned NumElts = CDS->getNumElements(); |
108 | assert(NumElts != 0 && "Can't have an empty CDS" ); |
109 | |
110 | if (CDS->getElementAsInteger(i: NumElts-1) != 0) |
111 | return false; // Not null terminated. |
112 | |
113 | // Verify that the null doesn't occur anywhere else in the string. |
114 | for (unsigned i = 0; i != NumElts-1; ++i) |
115 | if (CDS->getElementAsInteger(i) == 0) |
116 | return false; |
117 | return true; |
118 | } |
119 | |
120 | // Another possibility: [1 x i8] zeroinitializer |
121 | if (isa<ConstantAggregateZero>(Val: C)) |
122 | return cast<ArrayType>(Val: C->getType())->getNumElements() == 1; |
123 | |
124 | return false; |
125 | } |
126 | |
127 | MCSymbol *TargetLoweringObjectFile::getSymbolWithGlobalValueBase( |
128 | const GlobalValue *GV, StringRef Suffix, const TargetMachine &TM) const { |
129 | assert(!Suffix.empty()); |
130 | |
131 | SmallString<60> NameStr; |
132 | NameStr += GV->getDataLayout().getPrivateGlobalPrefix(); |
133 | TM.getNameWithPrefix(Name&: NameStr, GV, Mang&: *Mang); |
134 | NameStr.append(in_start: Suffix.begin(), in_end: Suffix.end()); |
135 | return getContext().getOrCreateSymbol(Name: NameStr); |
136 | } |
137 | |
138 | MCSymbol *TargetLoweringObjectFile::getCFIPersonalitySymbol( |
139 | const GlobalValue *GV, const TargetMachine &TM, |
140 | MachineModuleInfo *MMI) const { |
141 | return TM.getSymbol(GV); |
142 | } |
143 | |
144 | void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer, |
145 | const DataLayout &, |
146 | const MCSymbol *Sym) const { |
147 | } |
148 | |
149 | void TargetLoweringObjectFile::emitCGProfileMetadata(MCStreamer &Streamer, |
150 | Module &M) const { |
151 | MCContext &C = getContext(); |
152 | SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; |
153 | M.getModuleFlagsMetadata(Flags&: ModuleFlags); |
154 | |
155 | MDNode *CFGProfile = nullptr; |
156 | |
157 | for (const auto &MFE : ModuleFlags) { |
158 | StringRef Key = MFE.Key->getString(); |
159 | if (Key == "CG Profile" ) { |
160 | CFGProfile = cast<MDNode>(Val: MFE.Val); |
161 | break; |
162 | } |
163 | } |
164 | |
165 | if (!CFGProfile) |
166 | return; |
167 | |
168 | auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * { |
169 | if (!MDO) |
170 | return nullptr; |
171 | auto *V = cast<ValueAsMetadata>(Val: MDO); |
172 | const Function *F = cast<Function>(Val: V->getValue()->stripPointerCasts()); |
173 | if (F->hasDLLImportStorageClass()) |
174 | return nullptr; |
175 | return TM->getSymbol(GV: F); |
176 | }; |
177 | |
178 | for (const auto &Edge : CFGProfile->operands()) { |
179 | MDNode *E = cast<MDNode>(Val: Edge); |
180 | const MCSymbol *From = GetSym(E->getOperand(I: 0)); |
181 | const MCSymbol *To = GetSym(E->getOperand(I: 1)); |
182 | // Skip null functions. This can happen if functions are dead stripped after |
183 | // the CGProfile pass has been run. |
184 | if (!From || !To) |
185 | continue; |
186 | uint64_t Count = cast<ConstantAsMetadata>(Val: E->getOperand(I: 2)) |
187 | ->getValue() |
188 | ->getUniqueInteger() |
189 | .getZExtValue(); |
190 | Streamer.emitCGProfileEntry( |
191 | From: MCSymbolRefExpr::create(Symbol: From, Kind: MCSymbolRefExpr::VK_None, Ctx&: C), |
192 | To: MCSymbolRefExpr::create(Symbol: To, Kind: MCSymbolRefExpr::VK_None, Ctx&: C), Count); |
193 | } |
194 | } |
195 | |
196 | /// getKindForGlobal - This is a top-level target-independent classifier for |
197 | /// a global object. Given a global variable and information from the TM, this |
198 | /// function classifies the global in a target independent manner. This function |
199 | /// may be overridden by the target implementation. |
200 | SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO, |
201 | const TargetMachine &TM){ |
202 | assert(!GO->isDeclarationForLinker() && |
203 | "Can only be used for global definitions" ); |
204 | |
205 | // Functions are classified as text sections. |
206 | if (isa<Function>(Val: GO)) |
207 | return SectionKind::getText(); |
208 | |
209 | // Basic blocks are classified as text sections. |
210 | if (isa<BasicBlock>(Val: GO)) |
211 | return SectionKind::getText(); |
212 | |
213 | // Global variables require more detailed analysis. |
214 | const auto *GVar = cast<GlobalVariable>(Val: GO); |
215 | |
216 | // Handle thread-local data first. |
217 | if (GVar->isThreadLocal()) { |
218 | if (isSuitableForBSS(GV: GVar) && !TM.Options.NoZerosInBSS) { |
219 | // Zero-initialized TLS variables with local linkage always get classified |
220 | // as ThreadBSSLocal. |
221 | if (GVar->hasLocalLinkage()) { |
222 | return SectionKind::getThreadBSSLocal(); |
223 | } |
224 | return SectionKind::getThreadBSS(); |
225 | } |
226 | return SectionKind::getThreadData(); |
227 | } |
228 | |
229 | // Variables with common linkage always get classified as common. |
230 | if (GVar->hasCommonLinkage()) |
231 | return SectionKind::getCommon(); |
232 | |
233 | // Most non-mergeable zero data can be put in the BSS section unless otherwise |
234 | // specified. |
235 | if (isSuitableForBSS(GV: GVar) && !TM.Options.NoZerosInBSS) { |
236 | if (GVar->hasLocalLinkage()) |
237 | return SectionKind::getBSSLocal(); |
238 | else if (GVar->hasExternalLinkage()) |
239 | return SectionKind::getBSSExtern(); |
240 | return SectionKind::getBSS(); |
241 | } |
242 | |
243 | // Global variables with '!exclude' should get the exclude section kind if |
244 | // they have an explicit section and no other metadata. |
245 | if (GVar->hasSection()) |
246 | if (MDNode *MD = GVar->getMetadata(KindID: LLVMContext::MD_exclude)) |
247 | if (!MD->getNumOperands()) |
248 | return SectionKind::getExclude(); |
249 | |
250 | // If the global is marked constant, we can put it into a mergable section, |
251 | // a mergable string section, or general .data if it contains relocations. |
252 | if (GVar->isConstant()) { |
253 | // If the initializer for the global contains something that requires a |
254 | // relocation, then we may have to drop this into a writable data section |
255 | // even though it is marked const. |
256 | const Constant *C = GVar->getInitializer(); |
257 | if (!C->needsRelocation()) { |
258 | // If the global is required to have a unique address, it can't be put |
259 | // into a mergable section: just drop it into the general read-only |
260 | // section instead. |
261 | if (!GVar->hasGlobalUnnamedAddr()) |
262 | return SectionKind::getReadOnly(); |
263 | |
264 | // If initializer is a null-terminated string, put it in a "cstring" |
265 | // section of the right width. |
266 | if (ArrayType *ATy = dyn_cast<ArrayType>(Val: C->getType())) { |
267 | if (IntegerType *ITy = |
268 | dyn_cast<IntegerType>(Val: ATy->getElementType())) { |
269 | if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 || |
270 | ITy->getBitWidth() == 32) && |
271 | IsNullTerminatedString(C)) { |
272 | if (ITy->getBitWidth() == 8) |
273 | return SectionKind::getMergeable1ByteCString(); |
274 | if (ITy->getBitWidth() == 16) |
275 | return SectionKind::getMergeable2ByteCString(); |
276 | |
277 | assert(ITy->getBitWidth() == 32 && "Unknown width" ); |
278 | return SectionKind::getMergeable4ByteCString(); |
279 | } |
280 | } |
281 | } |
282 | |
283 | // Otherwise, just drop it into a mergable constant section. If we have |
284 | // a section for this size, use it, otherwise use the arbitrary sized |
285 | // mergable section. |
286 | switch ( |
287 | GVar->getDataLayout().getTypeAllocSize(Ty: C->getType())) { |
288 | case 4: return SectionKind::getMergeableConst4(); |
289 | case 8: return SectionKind::getMergeableConst8(); |
290 | case 16: return SectionKind::getMergeableConst16(); |
291 | case 32: return SectionKind::getMergeableConst32(); |
292 | default: |
293 | return SectionKind::getReadOnly(); |
294 | } |
295 | |
296 | } else { |
297 | // In static, ROPI and RWPI relocation models, the linker will resolve |
298 | // all addresses, so the relocation entries will actually be constants by |
299 | // the time the app starts up. However, we can't put this into a |
300 | // mergable section, because the linker doesn't take relocations into |
301 | // consideration when it tries to merge entries in the section. |
302 | Reloc::Model ReloModel = TM.getRelocationModel(); |
303 | if (ReloModel == Reloc::Static || ReloModel == Reloc::ROPI || |
304 | ReloModel == Reloc::RWPI || ReloModel == Reloc::ROPI_RWPI || |
305 | !C->needsDynamicRelocation()) |
306 | return SectionKind::getReadOnly(); |
307 | |
308 | // Otherwise, the dynamic linker needs to fix it up, put it in the |
309 | // writable data.rel section. |
310 | return SectionKind::getReadOnlyWithRel(); |
311 | } |
312 | } |
313 | |
314 | // Okay, this isn't a constant. |
315 | return SectionKind::getData(); |
316 | } |
317 | |
318 | /// This method computes the appropriate section to emit the specified global |
319 | /// variable or function definition. This should not be passed external (or |
320 | /// available externally) globals. |
321 | MCSection *TargetLoweringObjectFile::SectionForGlobal( |
322 | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
323 | // Select section name. |
324 | if (GO->hasSection()) |
325 | return getExplicitSectionGlobal(GO, Kind, TM); |
326 | |
327 | if (auto *GVar = dyn_cast<GlobalVariable>(Val: GO)) { |
328 | auto Attrs = GVar->getAttributes(); |
329 | if ((Attrs.hasAttribute(Kind: "bss-section" ) && Kind.isBSS()) || |
330 | (Attrs.hasAttribute(Kind: "data-section" ) && Kind.isData()) || |
331 | (Attrs.hasAttribute(Kind: "relro-section" ) && Kind.isReadOnlyWithRel()) || |
332 | (Attrs.hasAttribute(Kind: "rodata-section" ) && Kind.isReadOnly())) { |
333 | return getExplicitSectionGlobal(GO, Kind, TM); |
334 | } |
335 | } |
336 | |
337 | // Use default section depending on the 'type' of global |
338 | return SelectSectionForGlobal(GO, Kind, TM); |
339 | } |
340 | |
341 | /// This method computes the appropriate section to emit the specified global |
342 | /// variable or function definition. This should not be passed external (or |
343 | /// available externally) globals. |
344 | MCSection * |
345 | TargetLoweringObjectFile::SectionForGlobal(const GlobalObject *GO, |
346 | const TargetMachine &TM) const { |
347 | return SectionForGlobal(GO, Kind: getKindForGlobal(GO, TM), TM); |
348 | } |
349 | |
350 | MCSection *TargetLoweringObjectFile::getSectionForJumpTable( |
351 | const Function &F, const TargetMachine &TM) const { |
352 | Align Alignment(1); |
353 | return getSectionForConstant(DL: F.getDataLayout(), |
354 | Kind: SectionKind::getReadOnly(), /*C=*/nullptr, |
355 | Alignment); |
356 | } |
357 | |
358 | bool TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( |
359 | bool UsesLabelDifference, const Function &F) const { |
360 | // In PIC mode, we need to emit the jump table to the same section as the |
361 | // function body itself, otherwise the label differences won't make sense. |
362 | // FIXME: Need a better predicate for this: what about custom entries? |
363 | if (UsesLabelDifference) |
364 | return true; |
365 | |
366 | // We should also do if the section name is NULL or function is declared |
367 | // in discardable section |
368 | // FIXME: this isn't the right predicate, should be based on the MCSection |
369 | // for the function. |
370 | return F.isWeakForLinker(); |
371 | } |
372 | |
373 | /// Given a mergable constant with the specified size and relocation |
374 | /// information, return a section that it should be placed in. |
375 | MCSection *TargetLoweringObjectFile::getSectionForConstant( |
376 | const DataLayout &DL, SectionKind Kind, const Constant *C, |
377 | Align &Alignment) const { |
378 | if (Kind.isReadOnly() && ReadOnlySection != nullptr) |
379 | return ReadOnlySection; |
380 | |
381 | return DataSection; |
382 | } |
383 | |
384 | MCSection *TargetLoweringObjectFile::getSectionForMachineBasicBlock( |
385 | const Function &F, const MachineBasicBlock &MBB, |
386 | const TargetMachine &TM) const { |
387 | return nullptr; |
388 | } |
389 | |
390 | MCSection *TargetLoweringObjectFile::getUniqueSectionForFunction( |
391 | const Function &F, const TargetMachine &TM) const { |
392 | return nullptr; |
393 | } |
394 | |
395 | /// getTTypeGlobalReference - Return an MCExpr to use for a |
396 | /// reference to the specified global variable from exception |
397 | /// handling information. |
398 | const MCExpr *TargetLoweringObjectFile::getTTypeGlobalReference( |
399 | const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, |
400 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
401 | const MCSymbolRefExpr *Ref = |
402 | MCSymbolRefExpr::create(Symbol: TM.getSymbol(GV), Ctx&: getContext()); |
403 | |
404 | return getTTypeReference(Sym: Ref, Encoding, Streamer); |
405 | } |
406 | |
407 | const MCExpr *TargetLoweringObjectFile:: |
408 | getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, |
409 | MCStreamer &Streamer) const { |
410 | switch (Encoding & 0x70) { |
411 | default: |
412 | report_fatal_error(reason: "We do not support this DWARF encoding yet!" ); |
413 | case dwarf::DW_EH_PE_absptr: |
414 | // Do nothing special |
415 | return Sym; |
416 | case dwarf::DW_EH_PE_pcrel: { |
417 | // Emit a label to the streamer for the current position. This gives us |
418 | // .-foo addressing. |
419 | MCSymbol *PCSym = getContext().createTempSymbol(); |
420 | Streamer.emitLabel(Symbol: PCSym); |
421 | const MCExpr *PC = MCSymbolRefExpr::create(Symbol: PCSym, Ctx&: getContext()); |
422 | return MCBinaryExpr::createSub(LHS: Sym, RHS: PC, Ctx&: getContext()); |
423 | } |
424 | } |
425 | } |
426 | |
427 | const MCExpr *TargetLoweringObjectFile::getDebugThreadLocalSymbol(const MCSymbol *Sym) const { |
428 | // FIXME: It's not clear what, if any, default this should have - perhaps a |
429 | // null return could mean 'no location' & we should just do that here. |
430 | return MCSymbolRefExpr::create(Symbol: Sym, Ctx&: getContext()); |
431 | } |
432 | |
433 | void TargetLoweringObjectFile::getNameWithPrefix( |
434 | SmallVectorImpl<char> &OutName, const GlobalValue *GV, |
435 | const TargetMachine &TM) const { |
436 | Mang->getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/false); |
437 | } |
438 | |