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