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 | uint64_t 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 (uint64_t 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( |
145 | MCStreamer &Streamer, const DataLayout &, const MCSymbol *Sym, |
146 | const MachineModuleInfo *MMI) const {} |
147 | |
148 | void TargetLoweringObjectFile::emitCGProfileMetadata(MCStreamer &Streamer, |
149 | Module &M) const { |
150 | MCContext &C = getContext(); |
151 | SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; |
152 | M.getModuleFlagsMetadata(Flags&: ModuleFlags); |
153 | |
154 | MDNode *CFGProfile = nullptr; |
155 | |
156 | for (const auto &MFE : ModuleFlags) { |
157 | StringRef Key = MFE.Key->getString(); |
158 | if (Key == "CG Profile" ) { |
159 | CFGProfile = cast<MDNode>(Val: MFE.Val); |
160 | break; |
161 | } |
162 | } |
163 | |
164 | if (!CFGProfile) |
165 | return; |
166 | |
167 | auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * { |
168 | if (!MDO) |
169 | return nullptr; |
170 | auto *V = cast<ValueAsMetadata>(Val: MDO); |
171 | const Function *F = cast<Function>(Val: V->getValue()->stripPointerCasts()); |
172 | if (F->hasDLLImportStorageClass()) |
173 | return nullptr; |
174 | return TM->getSymbol(GV: F); |
175 | }; |
176 | |
177 | for (const auto &Edge : CFGProfile->operands()) { |
178 | MDNode *E = cast<MDNode>(Val: Edge); |
179 | const MCSymbol *From = GetSym(E->getOperand(I: 0)); |
180 | const MCSymbol *To = GetSym(E->getOperand(I: 1)); |
181 | // Skip null functions. This can happen if functions are dead stripped after |
182 | // the CGProfile pass has been run. |
183 | if (!From || !To) |
184 | continue; |
185 | uint64_t Count = cast<ConstantAsMetadata>(Val: E->getOperand(I: 2)) |
186 | ->getValue() |
187 | ->getUniqueInteger() |
188 | .getZExtValue(); |
189 | Streamer.emitCGProfileEntry(From: MCSymbolRefExpr::create(Symbol: From, Ctx&: C), |
190 | To: MCSymbolRefExpr::create(Symbol: To, Ctx&: C), Count); |
191 | } |
192 | } |
193 | |
194 | /// getKindForGlobal - This is a top-level target-independent classifier for |
195 | /// a global object. Given a global variable and information from the TM, this |
196 | /// function classifies the global in a target independent manner. This function |
197 | /// may be overridden by the target implementation. |
198 | SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO, |
199 | const TargetMachine &TM){ |
200 | assert(!GO->isDeclarationForLinker() && |
201 | "Can only be used for global definitions" ); |
202 | |
203 | // Functions are classified as text sections. |
204 | if (isa<Function>(Val: GO)) |
205 | return SectionKind::getText(); |
206 | |
207 | // Basic blocks are classified as text sections. |
208 | if (isa<BasicBlock>(Val: GO)) |
209 | return SectionKind::getText(); |
210 | |
211 | // Global variables require more detailed analysis. |
212 | const auto *GVar = cast<GlobalVariable>(Val: GO); |
213 | |
214 | // Handle thread-local data first. |
215 | if (GVar->isThreadLocal()) { |
216 | if (isSuitableForBSS(GV: GVar) && !TM.Options.NoZerosInBSS) { |
217 | // Zero-initialized TLS variables with local linkage always get classified |
218 | // as ThreadBSSLocal. |
219 | if (GVar->hasLocalLinkage()) { |
220 | return SectionKind::getThreadBSSLocal(); |
221 | } |
222 | return SectionKind::getThreadBSS(); |
223 | } |
224 | return SectionKind::getThreadData(); |
225 | } |
226 | |
227 | // Variables with common linkage always get classified as common. |
228 | if (GVar->hasCommonLinkage()) |
229 | return SectionKind::getCommon(); |
230 | |
231 | // Most non-mergeable zero data can be put in the BSS section unless otherwise |
232 | // specified. |
233 | if (isSuitableForBSS(GV: GVar) && !TM.Options.NoZerosInBSS) { |
234 | if (GVar->hasLocalLinkage()) |
235 | return SectionKind::getBSSLocal(); |
236 | else if (GVar->hasExternalLinkage()) |
237 | return SectionKind::getBSSExtern(); |
238 | return SectionKind::getBSS(); |
239 | } |
240 | |
241 | // Global variables with '!exclude' should get the exclude section kind if |
242 | // they have an explicit section and no other metadata. |
243 | if (GVar->hasSection()) |
244 | if (MDNode *MD = GVar->getMetadata(KindID: LLVMContext::MD_exclude)) |
245 | if (!MD->getNumOperands()) |
246 | return SectionKind::getExclude(); |
247 | |
248 | // If the global is marked constant, we can put it into a mergable section, |
249 | // a mergable string section, or general .data if it contains relocations. |
250 | if (GVar->isConstant()) { |
251 | // If the initializer for the global contains something that requires a |
252 | // relocation, then we may have to drop this into a writable data section |
253 | // even though it is marked const. |
254 | const Constant *C = GVar->getInitializer(); |
255 | if (!C->needsRelocation()) { |
256 | // If the global is required to have a unique address, it can't be put |
257 | // into a mergable section: just drop it into the general read-only |
258 | // section instead. |
259 | if (!GVar->hasGlobalUnnamedAddr()) |
260 | return SectionKind::getReadOnly(); |
261 | |
262 | // If initializer is a null-terminated string, put it in a "cstring" |
263 | // section of the right width. |
264 | if (ArrayType *ATy = dyn_cast<ArrayType>(Val: C->getType())) { |
265 | if (IntegerType *ITy = |
266 | dyn_cast<IntegerType>(Val: ATy->getElementType())) { |
267 | if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 || |
268 | ITy->getBitWidth() == 32) && |
269 | IsNullTerminatedString(C)) { |
270 | if (ITy->getBitWidth() == 8) |
271 | return SectionKind::getMergeable1ByteCString(); |
272 | if (ITy->getBitWidth() == 16) |
273 | return SectionKind::getMergeable2ByteCString(); |
274 | |
275 | assert(ITy->getBitWidth() == 32 && "Unknown width" ); |
276 | return SectionKind::getMergeable4ByteCString(); |
277 | } |
278 | } |
279 | } |
280 | |
281 | // Otherwise, just drop it into a mergable constant section. If we have |
282 | // a section for this size, use it, otherwise use the arbitrary sized |
283 | // mergable section. |
284 | switch ( |
285 | GVar->getDataLayout().getTypeAllocSize(Ty: C->getType())) { |
286 | case 4: return SectionKind::getMergeableConst4(); |
287 | case 8: return SectionKind::getMergeableConst8(); |
288 | case 16: return SectionKind::getMergeableConst16(); |
289 | case 32: return SectionKind::getMergeableConst32(); |
290 | default: |
291 | return SectionKind::getReadOnly(); |
292 | } |
293 | |
294 | } else { |
295 | // In static, ROPI and RWPI relocation models, the linker will resolve |
296 | // all addresses, so the relocation entries will actually be constants by |
297 | // the time the app starts up. However, we can't put this into a |
298 | // mergable section, because the linker doesn't take relocations into |
299 | // consideration when it tries to merge entries in the section. |
300 | Reloc::Model ReloModel = TM.getRelocationModel(); |
301 | if (ReloModel == Reloc::Static || ReloModel == Reloc::ROPI || |
302 | ReloModel == Reloc::RWPI || ReloModel == Reloc::ROPI_RWPI || |
303 | !C->needsDynamicRelocation()) |
304 | return SectionKind::getReadOnly(); |
305 | |
306 | // Otherwise, the dynamic linker needs to fix it up, put it in the |
307 | // writable data.rel section. |
308 | return SectionKind::getReadOnlyWithRel(); |
309 | } |
310 | } |
311 | |
312 | // Okay, this isn't a constant. |
313 | return SectionKind::getData(); |
314 | } |
315 | |
316 | /// This method computes the appropriate section to emit the specified global |
317 | /// variable or function definition. This should not be passed external (or |
318 | /// available externally) globals. |
319 | MCSection *TargetLoweringObjectFile::SectionForGlobal( |
320 | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
321 | // Select section name. |
322 | if (GO->hasSection()) |
323 | return getExplicitSectionGlobal(GO, Kind, TM); |
324 | |
325 | if (auto *GVar = dyn_cast<GlobalVariable>(Val: GO)) { |
326 | auto Attrs = GVar->getAttributes(); |
327 | if ((Attrs.hasAttribute(Kind: "bss-section" ) && Kind.isBSS()) || |
328 | (Attrs.hasAttribute(Kind: "data-section" ) && Kind.isData()) || |
329 | (Attrs.hasAttribute(Kind: "relro-section" ) && Kind.isReadOnlyWithRel()) || |
330 | (Attrs.hasAttribute(Kind: "rodata-section" ) && Kind.isReadOnly())) { |
331 | return getExplicitSectionGlobal(GO, Kind, TM); |
332 | } |
333 | } |
334 | |
335 | // Use default section depending on the 'type' of global |
336 | return SelectSectionForGlobal(GO, Kind, TM); |
337 | } |
338 | |
339 | /// This method computes the appropriate section to emit the specified global |
340 | /// variable or function definition. This should not be passed external (or |
341 | /// available externally) globals. |
342 | MCSection * |
343 | TargetLoweringObjectFile::SectionForGlobal(const GlobalObject *GO, |
344 | const TargetMachine &TM) const { |
345 | return SectionForGlobal(GO, Kind: getKindForGlobal(GO, TM), TM); |
346 | } |
347 | |
348 | MCSection *TargetLoweringObjectFile::getSectionForJumpTable( |
349 | const Function &F, const TargetMachine &TM) const { |
350 | return getSectionForJumpTable(F, TM, /*JTE=*/nullptr); |
351 | } |
352 | |
353 | MCSection *TargetLoweringObjectFile::getSectionForJumpTable( |
354 | const Function &F, const TargetMachine &TM, |
355 | const MachineJumpTableEntry *JTE) const { |
356 | Align Alignment(1); |
357 | return getSectionForConstant(DL: F.getDataLayout(), |
358 | Kind: SectionKind::getReadOnly(), /*C=*/nullptr, |
359 | Alignment); |
360 | } |
361 | |
362 | bool TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( |
363 | bool UsesLabelDifference, const Function &F) const { |
364 | // In PIC mode, we need to emit the jump table to the same section as the |
365 | // function body itself, otherwise the label differences won't make sense. |
366 | // FIXME: Need a better predicate for this: what about custom entries? |
367 | if (UsesLabelDifference) |
368 | return true; |
369 | |
370 | // We should also do if the section name is NULL or function is declared |
371 | // in discardable section |
372 | // FIXME: this isn't the right predicate, should be based on the MCSection |
373 | // for the function. |
374 | return F.isWeakForLinker(); |
375 | } |
376 | |
377 | /// Given a mergable constant with the specified size and relocation |
378 | /// information, return a section that it should be placed in. |
379 | MCSection *TargetLoweringObjectFile::getSectionForConstant( |
380 | const DataLayout &DL, SectionKind Kind, const Constant *C, |
381 | Align &Alignment) const { |
382 | if (Kind.isReadOnly() && ReadOnlySection != nullptr) |
383 | return ReadOnlySection; |
384 | |
385 | return DataSection; |
386 | } |
387 | |
388 | MCSection *TargetLoweringObjectFile::getSectionForConstant( |
389 | const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment, |
390 | StringRef SectionPrefix) const { |
391 | // Fallback to `getSectionForConstant` without `SectionPrefix` parameter if it |
392 | // is empty. |
393 | if (SectionPrefix.empty()) |
394 | return getSectionForConstant(DL, Kind, C, Alignment); |
395 | report_fatal_error( |
396 | reason: "TargetLoweringObjectFile::getSectionForConstant that " |
397 | "accepts SectionPrefix is not implemented for the object file format" ); |
398 | } |
399 | |
400 | MCSection *TargetLoweringObjectFile::getSectionForMachineBasicBlock( |
401 | const Function &F, const MachineBasicBlock &MBB, |
402 | const TargetMachine &TM) const { |
403 | return nullptr; |
404 | } |
405 | |
406 | MCSection *TargetLoweringObjectFile::getUniqueSectionForFunction( |
407 | const Function &F, const TargetMachine &TM) const { |
408 | return nullptr; |
409 | } |
410 | |
411 | /// getTTypeGlobalReference - Return an MCExpr to use for a |
412 | /// reference to the specified global variable from exception |
413 | /// handling information. |
414 | const MCExpr *TargetLoweringObjectFile::getTTypeGlobalReference( |
415 | const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, |
416 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
417 | const MCSymbolRefExpr *Ref = |
418 | MCSymbolRefExpr::create(Symbol: TM.getSymbol(GV), Ctx&: getContext()); |
419 | |
420 | return getTTypeReference(Sym: Ref, Encoding, Streamer); |
421 | } |
422 | |
423 | const MCExpr *TargetLoweringObjectFile:: |
424 | getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, |
425 | MCStreamer &Streamer) const { |
426 | switch (Encoding & 0x70) { |
427 | default: |
428 | report_fatal_error(reason: "We do not support this DWARF encoding yet!" ); |
429 | case dwarf::DW_EH_PE_absptr: |
430 | // Do nothing special |
431 | return Sym; |
432 | case dwarf::DW_EH_PE_pcrel: { |
433 | // Emit a label to the streamer for the current position. This gives us |
434 | // .-foo addressing. |
435 | MCSymbol *PCSym = getContext().createTempSymbol(); |
436 | Streamer.emitLabel(Symbol: PCSym); |
437 | const MCExpr *PC = MCSymbolRefExpr::create(Symbol: PCSym, Ctx&: getContext()); |
438 | return MCBinaryExpr::createSub(LHS: Sym, RHS: PC, Ctx&: getContext()); |
439 | } |
440 | } |
441 | } |
442 | |
443 | const MCExpr *TargetLoweringObjectFile::getDebugThreadLocalSymbol(const MCSymbol *Sym) const { |
444 | // FIXME: It's not clear what, if any, default this should have - perhaps a |
445 | // null return could mean 'no location' & we should just do that here. |
446 | return MCSymbolRefExpr::create(Symbol: Sym, Ctx&: getContext()); |
447 | } |
448 | |
449 | void TargetLoweringObjectFile::getNameWithPrefix( |
450 | SmallVectorImpl<char> &OutName, const GlobalValue *GV, |
451 | const TargetMachine &TM) const { |
452 | Mang->getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/false); |
453 | } |
454 | |