10b57cec5SDimitry Andric //===-- llvm/Target/TargetLoweringObjectFile.cpp - Object File Info -------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements classes used to handle lowerings specific to common 100b57cec5SDimitry Andric // object file formats. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 150b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 160b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 170b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 180b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 190b57cec5SDimitry Andric #include "llvm/IR/Function.h" 200b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 210b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 225ffd83dbSDimitry Andric #include "llvm/IR/Module.h" 23e8d8bef9SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 260b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 275ffd83dbSDimitry Andric #include "llvm/MC/SectionKind.h" 280b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 290b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 300b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 310b57cec5SDimitry Andric using namespace llvm; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 340b57cec5SDimitry Andric // Generic Code 350b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric /// Initialize - this method must be called before any actual lowering is 380b57cec5SDimitry Andric /// done. This specifies the current context for codegen, and gives the 390b57cec5SDimitry Andric /// lowering implementations a chance to set up their default sections. 400b57cec5SDimitry Andric void TargetLoweringObjectFile::Initialize(MCContext &ctx, 410b57cec5SDimitry Andric const TargetMachine &TM) { 420b57cec5SDimitry Andric // `Initialize` can be called more than once. 430b57cec5SDimitry Andric delete Mang; 440b57cec5SDimitry Andric Mang = new Mangler(); 45fe6060f1SDimitry Andric initMCObjectFileInfo(ctx, TM.isPositionIndependent(), 460b57cec5SDimitry Andric TM.getCodeModel() == CodeModel::Large); 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric // Reset various EH DWARF encodings. 490b57cec5SDimitry Andric PersonalityEncoding = LSDAEncoding = TTypeEncoding = dwarf::DW_EH_PE_absptr; 500b57cec5SDimitry Andric CallSiteEncoding = dwarf::DW_EH_PE_uleb128; 51e8d8bef9SDimitry Andric 52e8d8bef9SDimitry Andric this->TM = &TM; 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric TargetLoweringObjectFile::~TargetLoweringObjectFile() { 560b57cec5SDimitry Andric delete Mang; 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 59e8d8bef9SDimitry Andric unsigned TargetLoweringObjectFile::getCallSiteEncoding() const { 60e8d8bef9SDimitry Andric // If target does not have LEB128 directives, we would need the 61e8d8bef9SDimitry Andric // call site encoding to be udata4 so that the alternative path 62e8d8bef9SDimitry Andric // for not having LEB128 directives could work. 63e8d8bef9SDimitry Andric if (!getContext().getAsmInfo()->hasLEB128Directives()) 64e8d8bef9SDimitry Andric return dwarf::DW_EH_PE_udata4; 65e8d8bef9SDimitry Andric return CallSiteEncoding; 66e8d8bef9SDimitry Andric } 67e8d8bef9SDimitry Andric 680b57cec5SDimitry Andric static bool isNullOrUndef(const Constant *C) { 690b57cec5SDimitry Andric // Check that the constant isn't all zeros or undefs. 700b57cec5SDimitry Andric if (C->isNullValue() || isa<UndefValue>(C)) 710b57cec5SDimitry Andric return true; 720b57cec5SDimitry Andric if (!isa<ConstantAggregate>(C)) 730b57cec5SDimitry Andric return false; 74bdd1243dSDimitry Andric for (const auto *Operand : C->operand_values()) { 750b57cec5SDimitry Andric if (!isNullOrUndef(cast<Constant>(Operand))) 760b57cec5SDimitry Andric return false; 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric return true; 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric static bool isSuitableForBSS(const GlobalVariable *GV) { 820b57cec5SDimitry Andric const Constant *C = GV->getInitializer(); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric // Must have zero initializer. 850b57cec5SDimitry Andric if (!isNullOrUndef(C)) 860b57cec5SDimitry Andric return false; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric // Leave constant zeros in readonly constant sections, so they can be shared. 890b57cec5SDimitry Andric if (GV->isConstant()) 900b57cec5SDimitry Andric return false; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric // If the global has an explicit section specified, don't put it in BSS. 930b57cec5SDimitry Andric if (GV->hasSection()) 940b57cec5SDimitry Andric return false; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric // Otherwise, put it in BSS! 970b57cec5SDimitry Andric return true; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric /// IsNullTerminatedString - Return true if the specified constant (which is 1010b57cec5SDimitry Andric /// known to have a type that is an array of 1/2/4 byte elements) ends with a 1020b57cec5SDimitry Andric /// nul value and contains no other nuls in it. Note that this is more general 1030b57cec5SDimitry Andric /// than ConstantDataSequential::isString because we allow 2 & 4 byte strings. 1040b57cec5SDimitry Andric static bool IsNullTerminatedString(const Constant *C) { 1050b57cec5SDimitry Andric // First check: is we have constant array terminated with zero 1060b57cec5SDimitry Andric if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(C)) { 1070b57cec5SDimitry Andric unsigned NumElts = CDS->getNumElements(); 1080b57cec5SDimitry Andric assert(NumElts != 0 && "Can't have an empty CDS"); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric if (CDS->getElementAsInteger(NumElts-1) != 0) 1110b57cec5SDimitry Andric return false; // Not null terminated. 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric // Verify that the null doesn't occur anywhere else in the string. 1140b57cec5SDimitry Andric for (unsigned i = 0; i != NumElts-1; ++i) 1150b57cec5SDimitry Andric if (CDS->getElementAsInteger(i) == 0) 1160b57cec5SDimitry Andric return false; 1170b57cec5SDimitry Andric return true; 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric // Another possibility: [1 x i8] zeroinitializer 1210b57cec5SDimitry Andric if (isa<ConstantAggregateZero>(C)) 1220b57cec5SDimitry Andric return cast<ArrayType>(C->getType())->getNumElements() == 1; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric return false; 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFile::getSymbolWithGlobalValueBase( 1280b57cec5SDimitry Andric const GlobalValue *GV, StringRef Suffix, const TargetMachine &TM) const { 1290b57cec5SDimitry Andric assert(!Suffix.empty()); 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric SmallString<60> NameStr; 132*0fca6ea1SDimitry Andric NameStr += GV->getDataLayout().getPrivateGlobalPrefix(); 1330b57cec5SDimitry Andric TM.getNameWithPrefix(NameStr, GV, *Mang); 1340b57cec5SDimitry Andric NameStr.append(Suffix.begin(), Suffix.end()); 1355ffd83dbSDimitry Andric return getContext().getOrCreateSymbol(NameStr); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFile::getCFIPersonalitySymbol( 1390b57cec5SDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 1400b57cec5SDimitry Andric MachineModuleInfo *MMI) const { 1410b57cec5SDimitry Andric return TM.getSymbol(GV); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer, 1450b57cec5SDimitry Andric const DataLayout &, 1460b57cec5SDimitry Andric const MCSymbol *Sym) const { 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 149e8d8bef9SDimitry Andric void TargetLoweringObjectFile::emitCGProfileMetadata(MCStreamer &Streamer, 150e8d8bef9SDimitry Andric Module &M) const { 151e8d8bef9SDimitry Andric MCContext &C = getContext(); 152e8d8bef9SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; 153e8d8bef9SDimitry Andric M.getModuleFlagsMetadata(ModuleFlags); 154e8d8bef9SDimitry Andric 155e8d8bef9SDimitry Andric MDNode *CFGProfile = nullptr; 156e8d8bef9SDimitry Andric 157e8d8bef9SDimitry Andric for (const auto &MFE : ModuleFlags) { 158e8d8bef9SDimitry Andric StringRef Key = MFE.Key->getString(); 159e8d8bef9SDimitry Andric if (Key == "CG Profile") { 160e8d8bef9SDimitry Andric CFGProfile = cast<MDNode>(MFE.Val); 161e8d8bef9SDimitry Andric break; 162e8d8bef9SDimitry Andric } 163e8d8bef9SDimitry Andric } 164e8d8bef9SDimitry Andric 165e8d8bef9SDimitry Andric if (!CFGProfile) 166e8d8bef9SDimitry Andric return; 167e8d8bef9SDimitry Andric 168e8d8bef9SDimitry Andric auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * { 169e8d8bef9SDimitry Andric if (!MDO) 170e8d8bef9SDimitry Andric return nullptr; 171e8d8bef9SDimitry Andric auto *V = cast<ValueAsMetadata>(MDO); 172e8d8bef9SDimitry Andric const Function *F = cast<Function>(V->getValue()->stripPointerCasts()); 173e8d8bef9SDimitry Andric if (F->hasDLLImportStorageClass()) 174e8d8bef9SDimitry Andric return nullptr; 175e8d8bef9SDimitry Andric return TM->getSymbol(F); 176e8d8bef9SDimitry Andric }; 177e8d8bef9SDimitry Andric 178e8d8bef9SDimitry Andric for (const auto &Edge : CFGProfile->operands()) { 179e8d8bef9SDimitry Andric MDNode *E = cast<MDNode>(Edge); 180e8d8bef9SDimitry Andric const MCSymbol *From = GetSym(E->getOperand(0)); 181e8d8bef9SDimitry Andric const MCSymbol *To = GetSym(E->getOperand(1)); 182e8d8bef9SDimitry Andric // Skip null functions. This can happen if functions are dead stripped after 183e8d8bef9SDimitry Andric // the CGProfile pass has been run. 184e8d8bef9SDimitry Andric if (!From || !To) 185e8d8bef9SDimitry Andric continue; 186e8d8bef9SDimitry Andric uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2)) 187e8d8bef9SDimitry Andric ->getValue() 188e8d8bef9SDimitry Andric ->getUniqueInteger() 189e8d8bef9SDimitry Andric .getZExtValue(); 190e8d8bef9SDimitry Andric Streamer.emitCGProfileEntry( 191e8d8bef9SDimitry Andric MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C), 192e8d8bef9SDimitry Andric MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count); 193e8d8bef9SDimitry Andric } 194e8d8bef9SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric /// getKindForGlobal - This is a top-level target-independent classifier for 1970b57cec5SDimitry Andric /// a global object. Given a global variable and information from the TM, this 1980b57cec5SDimitry Andric /// function classifies the global in a target independent manner. This function 1990b57cec5SDimitry Andric /// may be overridden by the target implementation. 2000b57cec5SDimitry Andric SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO, 2010b57cec5SDimitry Andric const TargetMachine &TM){ 2025ffd83dbSDimitry Andric assert(!GO->isDeclarationForLinker() && 2030b57cec5SDimitry Andric "Can only be used for global definitions"); 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric // Functions are classified as text sections. 2060b57cec5SDimitry Andric if (isa<Function>(GO)) 2070b57cec5SDimitry Andric return SectionKind::getText(); 2080b57cec5SDimitry Andric 2095ffd83dbSDimitry Andric // Basic blocks are classified as text sections. 2105ffd83dbSDimitry Andric if (isa<BasicBlock>(GO)) 2115ffd83dbSDimitry Andric return SectionKind::getText(); 2125ffd83dbSDimitry Andric 2130b57cec5SDimitry Andric // Global variables require more detailed analysis. 2140b57cec5SDimitry Andric const auto *GVar = cast<GlobalVariable>(GO); 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric // Handle thread-local data first. 2170b57cec5SDimitry Andric if (GVar->isThreadLocal()) { 218fe6060f1SDimitry Andric if (isSuitableForBSS(GVar) && !TM.Options.NoZerosInBSS) { 219fe6060f1SDimitry Andric // Zero-initialized TLS variables with local linkage always get classified 220fe6060f1SDimitry Andric // as ThreadBSSLocal. 221fe6060f1SDimitry Andric if (GVar->hasLocalLinkage()) { 222fe6060f1SDimitry Andric return SectionKind::getThreadBSSLocal(); 223fe6060f1SDimitry Andric } 2240b57cec5SDimitry Andric return SectionKind::getThreadBSS(); 225fe6060f1SDimitry Andric } 2260b57cec5SDimitry Andric return SectionKind::getThreadData(); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric // Variables with common linkage always get classified as common. 2300b57cec5SDimitry Andric if (GVar->hasCommonLinkage()) 2310b57cec5SDimitry Andric return SectionKind::getCommon(); 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric // Most non-mergeable zero data can be put in the BSS section unless otherwise 2340b57cec5SDimitry Andric // specified. 2350b57cec5SDimitry Andric if (isSuitableForBSS(GVar) && !TM.Options.NoZerosInBSS) { 2360b57cec5SDimitry Andric if (GVar->hasLocalLinkage()) 2370b57cec5SDimitry Andric return SectionKind::getBSSLocal(); 2380b57cec5SDimitry Andric else if (GVar->hasExternalLinkage()) 2390b57cec5SDimitry Andric return SectionKind::getBSSExtern(); 2400b57cec5SDimitry Andric return SectionKind::getBSS(); 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 243753f127fSDimitry Andric // Global variables with '!exclude' should get the exclude section kind if 244753f127fSDimitry Andric // they have an explicit section and no other metadata. 245753f127fSDimitry Andric if (GVar->hasSection()) 246753f127fSDimitry Andric if (MDNode *MD = GVar->getMetadata(LLVMContext::MD_exclude)) 247753f127fSDimitry Andric if (!MD->getNumOperands()) 248753f127fSDimitry Andric return SectionKind::getExclude(); 249753f127fSDimitry Andric 2500b57cec5SDimitry Andric // If the global is marked constant, we can put it into a mergable section, 2510b57cec5SDimitry Andric // a mergable string section, or general .data if it contains relocations. 2520b57cec5SDimitry Andric if (GVar->isConstant()) { 2530b57cec5SDimitry Andric // If the initializer for the global contains something that requires a 2540b57cec5SDimitry Andric // relocation, then we may have to drop this into a writable data section 2550b57cec5SDimitry Andric // even though it is marked const. 2560b57cec5SDimitry Andric const Constant *C = GVar->getInitializer(); 2570b57cec5SDimitry Andric if (!C->needsRelocation()) { 2580b57cec5SDimitry Andric // If the global is required to have a unique address, it can't be put 2590b57cec5SDimitry Andric // into a mergable section: just drop it into the general read-only 2600b57cec5SDimitry Andric // section instead. 2610b57cec5SDimitry Andric if (!GVar->hasGlobalUnnamedAddr()) 2620b57cec5SDimitry Andric return SectionKind::getReadOnly(); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric // If initializer is a null-terminated string, put it in a "cstring" 2650b57cec5SDimitry Andric // section of the right width. 2660b57cec5SDimitry Andric if (ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) { 2670b57cec5SDimitry Andric if (IntegerType *ITy = 2680b57cec5SDimitry Andric dyn_cast<IntegerType>(ATy->getElementType())) { 2690b57cec5SDimitry Andric if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 || 2700b57cec5SDimitry Andric ITy->getBitWidth() == 32) && 2710b57cec5SDimitry Andric IsNullTerminatedString(C)) { 2720b57cec5SDimitry Andric if (ITy->getBitWidth() == 8) 2730b57cec5SDimitry Andric return SectionKind::getMergeable1ByteCString(); 2740b57cec5SDimitry Andric if (ITy->getBitWidth() == 16) 2750b57cec5SDimitry Andric return SectionKind::getMergeable2ByteCString(); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric assert(ITy->getBitWidth() == 32 && "Unknown width"); 2780b57cec5SDimitry Andric return SectionKind::getMergeable4ByteCString(); 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric } 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric // Otherwise, just drop it into a mergable constant section. If we have 2840b57cec5SDimitry Andric // a section for this size, use it, otherwise use the arbitrary sized 2850b57cec5SDimitry Andric // mergable section. 2860b57cec5SDimitry Andric switch ( 287*0fca6ea1SDimitry Andric GVar->getDataLayout().getTypeAllocSize(C->getType())) { 2880b57cec5SDimitry Andric case 4: return SectionKind::getMergeableConst4(); 2890b57cec5SDimitry Andric case 8: return SectionKind::getMergeableConst8(); 2900b57cec5SDimitry Andric case 16: return SectionKind::getMergeableConst16(); 2910b57cec5SDimitry Andric case 32: return SectionKind::getMergeableConst32(); 2920b57cec5SDimitry Andric default: 2930b57cec5SDimitry Andric return SectionKind::getReadOnly(); 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric } else { 2970b57cec5SDimitry Andric // In static, ROPI and RWPI relocation models, the linker will resolve 2980b57cec5SDimitry Andric // all addresses, so the relocation entries will actually be constants by 2990b57cec5SDimitry Andric // the time the app starts up. However, we can't put this into a 3000b57cec5SDimitry Andric // mergable section, because the linker doesn't take relocations into 3010b57cec5SDimitry Andric // consideration when it tries to merge entries in the section. 3020b57cec5SDimitry Andric Reloc::Model ReloModel = TM.getRelocationModel(); 3030b57cec5SDimitry Andric if (ReloModel == Reloc::Static || ReloModel == Reloc::ROPI || 304fe6060f1SDimitry Andric ReloModel == Reloc::RWPI || ReloModel == Reloc::ROPI_RWPI || 305fe6060f1SDimitry Andric !C->needsDynamicRelocation()) 3060b57cec5SDimitry Andric return SectionKind::getReadOnly(); 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric // Otherwise, the dynamic linker needs to fix it up, put it in the 3090b57cec5SDimitry Andric // writable data.rel section. 3100b57cec5SDimitry Andric return SectionKind::getReadOnlyWithRel(); 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric // Okay, this isn't a constant. 3150b57cec5SDimitry Andric return SectionKind::getData(); 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric /// This method computes the appropriate section to emit the specified global 3190b57cec5SDimitry Andric /// variable or function definition. This should not be passed external (or 3200b57cec5SDimitry Andric /// available externally) globals. 3210b57cec5SDimitry Andric MCSection *TargetLoweringObjectFile::SectionForGlobal( 3220b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 3230b57cec5SDimitry Andric // Select section name. 3240b57cec5SDimitry Andric if (GO->hasSection()) 3250b57cec5SDimitry Andric return getExplicitSectionGlobal(GO, Kind, TM); 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric if (auto *GVar = dyn_cast<GlobalVariable>(GO)) { 3280b57cec5SDimitry Andric auto Attrs = GVar->getAttributes(); 3290b57cec5SDimitry Andric if ((Attrs.hasAttribute("bss-section") && Kind.isBSS()) || 3300b57cec5SDimitry Andric (Attrs.hasAttribute("data-section") && Kind.isData()) || 3318bcb0991SDimitry Andric (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) || 3320b57cec5SDimitry Andric (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly())) { 3330b57cec5SDimitry Andric return getExplicitSectionGlobal(GO, Kind, TM); 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric // Use default section depending on the 'type' of global 3380b57cec5SDimitry Andric return SelectSectionForGlobal(GO, Kind, TM); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3415ffd83dbSDimitry Andric /// This method computes the appropriate section to emit the specified global 3425ffd83dbSDimitry Andric /// variable or function definition. This should not be passed external (or 3435ffd83dbSDimitry Andric /// available externally) globals. 3445ffd83dbSDimitry Andric MCSection * 3455ffd83dbSDimitry Andric TargetLoweringObjectFile::SectionForGlobal(const GlobalObject *GO, 3465ffd83dbSDimitry Andric const TargetMachine &TM) const { 3475ffd83dbSDimitry Andric return SectionForGlobal(GO, getKindForGlobal(GO, TM), TM); 3485ffd83dbSDimitry Andric } 3495ffd83dbSDimitry Andric 3500b57cec5SDimitry Andric MCSection *TargetLoweringObjectFile::getSectionForJumpTable( 3510b57cec5SDimitry Andric const Function &F, const TargetMachine &TM) const { 3525ffd83dbSDimitry Andric Align Alignment(1); 353*0fca6ea1SDimitry Andric return getSectionForConstant(F.getDataLayout(), 3540b57cec5SDimitry Andric SectionKind::getReadOnly(), /*C=*/nullptr, 3555ffd83dbSDimitry Andric Alignment); 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric bool TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( 3590b57cec5SDimitry Andric bool UsesLabelDifference, const Function &F) const { 3600b57cec5SDimitry Andric // In PIC mode, we need to emit the jump table to the same section as the 3610b57cec5SDimitry Andric // function body itself, otherwise the label differences won't make sense. 3620b57cec5SDimitry Andric // FIXME: Need a better predicate for this: what about custom entries? 3630b57cec5SDimitry Andric if (UsesLabelDifference) 3640b57cec5SDimitry Andric return true; 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric // We should also do if the section name is NULL or function is declared 3670b57cec5SDimitry Andric // in discardable section 3680b57cec5SDimitry Andric // FIXME: this isn't the right predicate, should be based on the MCSection 3690b57cec5SDimitry Andric // for the function. 3700b57cec5SDimitry Andric return F.isWeakForLinker(); 3710b57cec5SDimitry Andric } 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric /// Given a mergable constant with the specified size and relocation 3740b57cec5SDimitry Andric /// information, return a section that it should be placed in. 3750b57cec5SDimitry Andric MCSection *TargetLoweringObjectFile::getSectionForConstant( 3760b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 3775ffd83dbSDimitry Andric Align &Alignment) const { 3780b57cec5SDimitry Andric if (Kind.isReadOnly() && ReadOnlySection != nullptr) 3790b57cec5SDimitry Andric return ReadOnlySection; 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric return DataSection; 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 3845ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFile::getSectionForMachineBasicBlock( 3855ffd83dbSDimitry Andric const Function &F, const MachineBasicBlock &MBB, 3865ffd83dbSDimitry Andric const TargetMachine &TM) const { 3875ffd83dbSDimitry Andric return nullptr; 3885ffd83dbSDimitry Andric } 3895ffd83dbSDimitry Andric 390fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFile::getUniqueSectionForFunction( 391fe6060f1SDimitry Andric const Function &F, const TargetMachine &TM) const { 392fe6060f1SDimitry Andric return nullptr; 393fe6060f1SDimitry Andric } 394fe6060f1SDimitry Andric 3950b57cec5SDimitry Andric /// getTTypeGlobalReference - Return an MCExpr to use for a 3960b57cec5SDimitry Andric /// reference to the specified global variable from exception 3970b57cec5SDimitry Andric /// handling information. 3980b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFile::getTTypeGlobalReference( 3990b57cec5SDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 4000b57cec5SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 4010b57cec5SDimitry Andric const MCSymbolRefExpr *Ref = 4020b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(GV), getContext()); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric return getTTypeReference(Ref, Encoding, Streamer); 4050b57cec5SDimitry Andric } 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFile:: 4080b57cec5SDimitry Andric getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, 4090b57cec5SDimitry Andric MCStreamer &Streamer) const { 4100b57cec5SDimitry Andric switch (Encoding & 0x70) { 4110b57cec5SDimitry Andric default: 4120b57cec5SDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!"); 4130b57cec5SDimitry Andric case dwarf::DW_EH_PE_absptr: 4140b57cec5SDimitry Andric // Do nothing special 4150b57cec5SDimitry Andric return Sym; 4160b57cec5SDimitry Andric case dwarf::DW_EH_PE_pcrel: { 4170b57cec5SDimitry Andric // Emit a label to the streamer for the current position. This gives us 4180b57cec5SDimitry Andric // .-foo addressing. 4190b57cec5SDimitry Andric MCSymbol *PCSym = getContext().createTempSymbol(); 4205ffd83dbSDimitry Andric Streamer.emitLabel(PCSym); 4210b57cec5SDimitry Andric const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext()); 4220b57cec5SDimitry Andric return MCBinaryExpr::createSub(Sym, PC, getContext()); 4230b57cec5SDimitry Andric } 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFile::getDebugThreadLocalSymbol(const MCSymbol *Sym) const { 4280b57cec5SDimitry Andric // FIXME: It's not clear what, if any, default this should have - perhaps a 4290b57cec5SDimitry Andric // null return could mean 'no location' & we should just do that here. 4305ffd83dbSDimitry Andric return MCSymbolRefExpr::create(Sym, getContext()); 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric void TargetLoweringObjectFile::getNameWithPrefix( 4340b57cec5SDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 4350b57cec5SDimitry Andric const TargetMachine &TM) const { 4360b57cec5SDimitry Andric Mang->getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/false); 4370b57cec5SDimitry Andric } 438