| 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 | |