10b57cec5SDimitry Andric //===- llvm/CodeGen/TargetLoweringObjectFileImpl.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/CodeGen/TargetLoweringObjectFileImpl.h" 150b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 170b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 190b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h" 200b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 210b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 220b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 23fe6060f1SDimitry Andric #include "llvm/BinaryFormat/Wasm.h" 24e8d8bef9SDimitry Andric #include "llvm/CodeGen/BasicBlockSectionUtils.h" 255ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 265ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 290b57cec5SDimitry Andric #include "llvm/IR/Comdat.h" 300b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 310b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 320b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 335ffd83dbSDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 345ffd83dbSDimitry Andric #include "llvm/IR/DiagnosticPrinter.h" 350b57cec5SDimitry Andric #include "llvm/IR/Function.h" 360b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h" 370b57cec5SDimitry Andric #include "llvm/IR/GlobalObject.h" 380b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 390b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 400b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 410b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 420b57cec5SDimitry Andric #include "llvm/IR/Module.h" 43e8d8bef9SDimitry Andric #include "llvm/IR/PseudoProbe.h" 440b57cec5SDimitry Andric #include "llvm/IR/Type.h" 450b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 460b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 470b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 480b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 490b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h" 50fe6060f1SDimitry Andric #include "llvm/MC/MCSectionGOFF.h" 510b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h" 520b57cec5SDimitry Andric #include "llvm/MC/MCSectionWasm.h" 538bcb0991SDimitry Andric #include "llvm/MC/MCSectionXCOFF.h" 540b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 550b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 560b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 570b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 580b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h" 590b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProf.h" 60bdd1243dSDimitry Andric #include "llvm/Support/Base64.h" 610b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 620b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 630b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 645ffd83dbSDimitry Andric #include "llvm/Support/Format.h" 650b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 660b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 67fe013be4SDimitry Andric #include "llvm/TargetParser/Triple.h" 680b57cec5SDimitry Andric #include <cassert> 690b57cec5SDimitry Andric #include <string> 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric using namespace llvm; 720b57cec5SDimitry Andric using namespace dwarf; 730b57cec5SDimitry Andric 74fe013be4SDimitry Andric static cl::opt<bool> JumpTableInFunctionSection( 75fe013be4SDimitry Andric "jumptable-in-function-section", cl::Hidden, cl::init(false), 76fe013be4SDimitry Andric cl::desc("Putting Jump Table in function section")); 77fe013be4SDimitry Andric 780b57cec5SDimitry Andric static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, 790b57cec5SDimitry Andric StringRef &Section) { 800b57cec5SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; 810b57cec5SDimitry Andric M.getModuleFlagsMetadata(ModuleFlags); 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric for (const auto &MFE: ModuleFlags) { 840b57cec5SDimitry Andric // Ignore flags with 'Require' behaviour. 850b57cec5SDimitry Andric if (MFE.Behavior == Module::Require) 860b57cec5SDimitry Andric continue; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric StringRef Key = MFE.Key->getString(); 890b57cec5SDimitry Andric if (Key == "Objective-C Image Info Version") { 900b57cec5SDimitry Andric Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 910b57cec5SDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 920b57cec5SDimitry Andric Key == "Objective-C GC Only" || 930b57cec5SDimitry Andric Key == "Objective-C Is Simulated" || 940b57cec5SDimitry Andric Key == "Objective-C Class Properties" || 950b57cec5SDimitry Andric Key == "Objective-C Image Swift Version") { 960b57cec5SDimitry Andric Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 970b57cec5SDimitry Andric } else if (Key == "Objective-C Image Info Section") { 980b57cec5SDimitry Andric Section = cast<MDString>(MFE.Val)->getString(); 990b57cec5SDimitry Andric } 1005ffd83dbSDimitry Andric // Backend generates L_OBJC_IMAGE_INFO from Swift ABI version + major + minor + 1015ffd83dbSDimitry Andric // "Objective-C Garbage Collection". 1025ffd83dbSDimitry Andric else if (Key == "Swift ABI Version") { 1035ffd83dbSDimitry Andric Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 8; 1045ffd83dbSDimitry Andric } else if (Key == "Swift Major Version") { 1055ffd83dbSDimitry Andric Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 24; 1065ffd83dbSDimitry Andric } else if (Key == "Swift Minor Version") { 1075ffd83dbSDimitry Andric Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 16; 1085ffd83dbSDimitry Andric } 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1130b57cec5SDimitry Andric // ELF 1140b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1150b57cec5SDimitry Andric 11604eeddc0SDimitry Andric TargetLoweringObjectFileELF::TargetLoweringObjectFileELF() { 117e8d8bef9SDimitry Andric SupportDSOLocalEquivalentLowering = true; 118e8d8bef9SDimitry Andric } 119e8d8bef9SDimitry Andric 1200b57cec5SDimitry Andric void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, 1210b57cec5SDimitry Andric const TargetMachine &TgtM) { 1220b57cec5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TgtM); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric CodeModel::Model CM = TgtM.getCodeModel(); 1255ffd83dbSDimitry Andric InitializeELF(TgtM.Options.UseInitArray); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric switch (TgtM.getTargetTriple().getArch()) { 1280b57cec5SDimitry Andric case Triple::arm: 1290b57cec5SDimitry Andric case Triple::armeb: 1300b57cec5SDimitry Andric case Triple::thumb: 1310b57cec5SDimitry Andric case Triple::thumbeb: 1320b57cec5SDimitry Andric if (Ctx.getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM) 1330b57cec5SDimitry Andric break; 1340b57cec5SDimitry Andric // Fallthrough if not using EHABI 135bdd1243dSDimitry Andric [[fallthrough]]; 1360b57cec5SDimitry Andric case Triple::ppc: 137e8d8bef9SDimitry Andric case Triple::ppcle: 1380b57cec5SDimitry Andric case Triple::x86: 1390b57cec5SDimitry Andric PersonalityEncoding = isPositionIndependent() 1400b57cec5SDimitry Andric ? dwarf::DW_EH_PE_indirect | 1410b57cec5SDimitry Andric dwarf::DW_EH_PE_pcrel | 1420b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4 1430b57cec5SDimitry Andric : dwarf::DW_EH_PE_absptr; 1440b57cec5SDimitry Andric LSDAEncoding = isPositionIndependent() 1450b57cec5SDimitry Andric ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 1460b57cec5SDimitry Andric : dwarf::DW_EH_PE_absptr; 1470b57cec5SDimitry Andric TTypeEncoding = isPositionIndependent() 1480b57cec5SDimitry Andric ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 1490b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4 1500b57cec5SDimitry Andric : dwarf::DW_EH_PE_absptr; 1510b57cec5SDimitry Andric break; 1520b57cec5SDimitry Andric case Triple::x86_64: 1530b57cec5SDimitry Andric if (isPositionIndependent()) { 1540b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 1550b57cec5SDimitry Andric ((CM == CodeModel::Small || CM == CodeModel::Medium) 1560b57cec5SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); 1570b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | 1580b57cec5SDimitry Andric (CM == CodeModel::Small 1590b57cec5SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); 1600b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 1610b57cec5SDimitry Andric ((CM == CodeModel::Small || CM == CodeModel::Medium) 162fe6060f1SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); 1630b57cec5SDimitry Andric } else { 1640b57cec5SDimitry Andric PersonalityEncoding = 1650b57cec5SDimitry Andric (CM == CodeModel::Small || CM == CodeModel::Medium) 1660b57cec5SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; 1670b57cec5SDimitry Andric LSDAEncoding = (CM == CodeModel::Small) 1680b57cec5SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; 1690b57cec5SDimitry Andric TTypeEncoding = (CM == CodeModel::Small) 1700b57cec5SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric break; 1730b57cec5SDimitry Andric case Triple::hexagon: 1740b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 1750b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 1760b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 1770b57cec5SDimitry Andric if (isPositionIndependent()) { 1780b57cec5SDimitry Andric PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; 1790b57cec5SDimitry Andric LSDAEncoding |= dwarf::DW_EH_PE_pcrel; 1800b57cec5SDimitry Andric TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric break; 1830b57cec5SDimitry Andric case Triple::aarch64: 1840b57cec5SDimitry Andric case Triple::aarch64_be: 1858bcb0991SDimitry Andric case Triple::aarch64_32: 1860b57cec5SDimitry Andric // The small model guarantees static code/data size < 4GB, but not where it 1870b57cec5SDimitry Andric // will be in memory. Most of these could end up >2GB away so even a signed 1880b57cec5SDimitry Andric // pc-relative 32-bit address is insufficient, theoretically. 189fe013be4SDimitry Andric // 190fe013be4SDimitry Andric // Use DW_EH_PE_indirect even for -fno-pic to avoid copy relocations. 191fe013be4SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | 192fe013be4SDimitry Andric (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32 193fe013be4SDimitry Andric ? dwarf::DW_EH_PE_sdata4 194fe013be4SDimitry Andric : dwarf::DW_EH_PE_sdata8); 195fe013be4SDimitry Andric PersonalityEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect; 196fe013be4SDimitry Andric TTypeEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect; 1970b57cec5SDimitry Andric break; 1980b57cec5SDimitry Andric case Triple::lanai: 1990b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 2000b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 2010b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 2020b57cec5SDimitry Andric break; 2030b57cec5SDimitry Andric case Triple::mips: 2040b57cec5SDimitry Andric case Triple::mipsel: 2050b57cec5SDimitry Andric case Triple::mips64: 2060b57cec5SDimitry Andric case Triple::mips64el: 2070b57cec5SDimitry Andric // MIPS uses indirect pointer to refer personality functions and types, so 2080b57cec5SDimitry Andric // that the eh_frame section can be read-only. DW.ref.personality will be 2090b57cec5SDimitry Andric // generated for relocation. 2100b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect; 2110b57cec5SDimitry Andric // FIXME: The N64 ABI probably ought to use DW_EH_PE_sdata8 but we can't 2120b57cec5SDimitry Andric // identify N64 from just a triple. 2130b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2140b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2150b57cec5SDimitry Andric // We don't support PC-relative LSDA references in GAS so we use the default 2160b57cec5SDimitry Andric // DW_EH_PE_absptr for those. 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric // FreeBSD must be explicit about the data size and using pcrel since it's 2190b57cec5SDimitry Andric // assembler/linker won't do the automatic conversion that the Linux tools 2200b57cec5SDimitry Andric // do. 2210b57cec5SDimitry Andric if (TgtM.getTargetTriple().isOSFreeBSD()) { 2220b57cec5SDimitry Andric PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2230b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric break; 2260b57cec5SDimitry Andric case Triple::ppc64: 2270b57cec5SDimitry Andric case Triple::ppc64le: 2280b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2290b57cec5SDimitry Andric dwarf::DW_EH_PE_udata8; 2300b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; 2310b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2320b57cec5SDimitry Andric dwarf::DW_EH_PE_udata8; 2330b57cec5SDimitry Andric break; 2340b57cec5SDimitry Andric case Triple::sparcel: 2350b57cec5SDimitry Andric case Triple::sparc: 2360b57cec5SDimitry Andric if (isPositionIndependent()) { 2370b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2380b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2390b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2400b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2410b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2420b57cec5SDimitry Andric } else { 2430b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 2440b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 2450b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric CallSiteEncoding = dwarf::DW_EH_PE_udata4; 2480b57cec5SDimitry Andric break; 2490b57cec5SDimitry Andric case Triple::riscv32: 2500b57cec5SDimitry Andric case Triple::riscv64: 2510b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2520b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2530b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2540b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2550b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2560b57cec5SDimitry Andric CallSiteEncoding = dwarf::DW_EH_PE_udata4; 2570b57cec5SDimitry Andric break; 2580b57cec5SDimitry Andric case Triple::sparcv9: 2590b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2600b57cec5SDimitry Andric if (isPositionIndependent()) { 2610b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2620b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2630b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2640b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2650b57cec5SDimitry Andric } else { 2660b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 2670b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric break; 2700b57cec5SDimitry Andric case Triple::systemz: 2710b57cec5SDimitry Andric // All currently-defined code models guarantee that 4-byte PC-relative 2720b57cec5SDimitry Andric // values will be in range. 2730b57cec5SDimitry Andric if (isPositionIndependent()) { 2740b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2750b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2760b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2770b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2780b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2790b57cec5SDimitry Andric } else { 2800b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 2810b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 2820b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric break; 285bdd1243dSDimitry Andric case Triple::loongarch32: 286bdd1243dSDimitry Andric case Triple::loongarch64: 287bdd1243dSDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 288bdd1243dSDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 289bdd1243dSDimitry Andric dwarf::DW_EH_PE_sdata4; 290bdd1243dSDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 291bdd1243dSDimitry Andric dwarf::DW_EH_PE_sdata4; 292bdd1243dSDimitry Andric break; 2930b57cec5SDimitry Andric default: 2940b57cec5SDimitry Andric break; 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 298fe6060f1SDimitry Andric void TargetLoweringObjectFileELF::getModuleMetadata(Module &M) { 299fe6060f1SDimitry Andric SmallVector<GlobalValue *, 4> Vec; 300fe6060f1SDimitry Andric collectUsedGlobalVariables(M, Vec, false); 301fe6060f1SDimitry Andric for (GlobalValue *GV : Vec) 302fe6060f1SDimitry Andric if (auto *GO = dyn_cast<GlobalObject>(GV)) 303fe6060f1SDimitry Andric Used.insert(GO); 304fe6060f1SDimitry Andric } 305fe6060f1SDimitry Andric 3060b57cec5SDimitry Andric void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, 3070b57cec5SDimitry Andric Module &M) const { 3080b57cec5SDimitry Andric auto &C = getContext(); 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 3110b57cec5SDimitry Andric auto *S = C.getELFSection(".linker-options", ELF::SHT_LLVM_LINKER_OPTIONS, 3120b57cec5SDimitry Andric ELF::SHF_EXCLUDE); 3130b57cec5SDimitry Andric 31481ad6265SDimitry Andric Streamer.switchSection(S); 3150b57cec5SDimitry Andric 316480093f4SDimitry Andric for (const auto *Operand : LinkerOptions->operands()) { 3170b57cec5SDimitry Andric if (cast<MDNode>(Operand)->getNumOperands() != 2) 3180b57cec5SDimitry Andric report_fatal_error("invalid llvm.linker.options"); 3190b57cec5SDimitry Andric for (const auto &Option : cast<MDNode>(Operand)->operands()) { 3205ffd83dbSDimitry Andric Streamer.emitBytes(cast<MDString>(Option)->getString()); 3215ffd83dbSDimitry Andric Streamer.emitInt8(0); 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) { 3270b57cec5SDimitry Andric auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES, 328fe6060f1SDimitry Andric ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); 3290b57cec5SDimitry Andric 33081ad6265SDimitry Andric Streamer.switchSection(S); 3310b57cec5SDimitry Andric 332480093f4SDimitry Andric for (const auto *Operand : DependentLibraries->operands()) { 3335ffd83dbSDimitry Andric Streamer.emitBytes( 3340b57cec5SDimitry Andric cast<MDString>(cast<MDNode>(Operand)->getOperand(0))->getString()); 3355ffd83dbSDimitry Andric Streamer.emitInt8(0); 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 339e8d8bef9SDimitry Andric if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) { 340e8d8bef9SDimitry Andric // Emit a descriptor for every function including functions that have an 341e8d8bef9SDimitry Andric // available external linkage. We may not want this for imported functions 342e8d8bef9SDimitry Andric // that has code in another thinLTO module but we don't have a good way to 343e8d8bef9SDimitry Andric // tell them apart from inline functions defined in header files. Therefore 344e8d8bef9SDimitry Andric // we put each descriptor in a separate comdat section and rely on the 345e8d8bef9SDimitry Andric // linker to deduplicate. 346e8d8bef9SDimitry Andric for (const auto *Operand : FuncInfo->operands()) { 347e8d8bef9SDimitry Andric const auto *MD = cast<MDNode>(Operand); 348e8d8bef9SDimitry Andric auto *GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0)); 349e8d8bef9SDimitry Andric auto *Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1)); 350e8d8bef9SDimitry Andric auto *Name = cast<MDString>(MD->getOperand(2)); 351e8d8bef9SDimitry Andric auto *S = C.getObjectFileInfo()->getPseudoProbeDescSection( 352e8d8bef9SDimitry Andric TM->getFunctionSections() ? Name->getString() : StringRef()); 353e8d8bef9SDimitry Andric 35481ad6265SDimitry Andric Streamer.switchSection(S); 355e8d8bef9SDimitry Andric Streamer.emitInt64(GUID->getZExtValue()); 356e8d8bef9SDimitry Andric Streamer.emitInt64(Hash->getZExtValue()); 357e8d8bef9SDimitry Andric Streamer.emitULEB128IntValue(Name->getString().size()); 358e8d8bef9SDimitry Andric Streamer.emitBytes(Name->getString()); 359e8d8bef9SDimitry Andric } 360e8d8bef9SDimitry Andric } 361e8d8bef9SDimitry Andric 362bdd1243dSDimitry Andric if (NamedMDNode *LLVMStats = M.getNamedMetadata("llvm.stats")) { 363bdd1243dSDimitry Andric // Emit the metadata for llvm statistics into .llvm_stats section, which is 364bdd1243dSDimitry Andric // formatted as a list of key/value pair, the value is base64 encoded. 365bdd1243dSDimitry Andric auto *S = C.getObjectFileInfo()->getLLVMStatsSection(); 366bdd1243dSDimitry Andric Streamer.switchSection(S); 367bdd1243dSDimitry Andric for (const auto *Operand : LLVMStats->operands()) { 368bdd1243dSDimitry Andric const auto *MD = cast<MDNode>(Operand); 369bdd1243dSDimitry Andric assert(MD->getNumOperands() % 2 == 0 && 370bdd1243dSDimitry Andric ("Operand num should be even for a list of key/value pair")); 371bdd1243dSDimitry Andric for (size_t I = 0; I < MD->getNumOperands(); I += 2) { 372bdd1243dSDimitry Andric // Encode the key string size. 373bdd1243dSDimitry Andric auto *Key = cast<MDString>(MD->getOperand(I)); 374bdd1243dSDimitry Andric Streamer.emitULEB128IntValue(Key->getString().size()); 375bdd1243dSDimitry Andric Streamer.emitBytes(Key->getString()); 376bdd1243dSDimitry Andric // Encode the value into a Base64 string. 377bdd1243dSDimitry Andric std::string Value = encodeBase64( 378bdd1243dSDimitry Andric Twine(mdconst::dyn_extract<ConstantInt>(MD->getOperand(I + 1)) 379bdd1243dSDimitry Andric ->getZExtValue()) 380bdd1243dSDimitry Andric .str()); 381bdd1243dSDimitry Andric Streamer.emitULEB128IntValue(Value.size()); 382bdd1243dSDimitry Andric Streamer.emitBytes(Value); 383bdd1243dSDimitry Andric } 384bdd1243dSDimitry Andric } 385bdd1243dSDimitry Andric } 386bdd1243dSDimitry Andric 3870b57cec5SDimitry Andric unsigned Version = 0; 3880b57cec5SDimitry Andric unsigned Flags = 0; 3890b57cec5SDimitry Andric StringRef Section; 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 3920b57cec5SDimitry Andric if (!Section.empty()) { 3930b57cec5SDimitry Andric auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 39481ad6265SDimitry Andric Streamer.switchSection(S); 3955ffd83dbSDimitry Andric Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 3965ffd83dbSDimitry Andric Streamer.emitInt32(Version); 3975ffd83dbSDimitry Andric Streamer.emitInt32(Flags); 39881ad6265SDimitry Andric Streamer.addBlankLine(); 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 401e8d8bef9SDimitry Andric emitCGProfileMetadata(Streamer, M); 4020b57cec5SDimitry Andric } 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( 4050b57cec5SDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 4060b57cec5SDimitry Andric MachineModuleInfo *MMI) const { 4070b57cec5SDimitry Andric unsigned Encoding = getPersonalityEncoding(); 4080b57cec5SDimitry Andric if ((Encoding & 0x80) == DW_EH_PE_indirect) 4090b57cec5SDimitry Andric return getContext().getOrCreateSymbol(StringRef("DW.ref.") + 4100b57cec5SDimitry Andric TM.getSymbol(GV)->getName()); 4110b57cec5SDimitry Andric if ((Encoding & 0x70) == DW_EH_PE_absptr) 4120b57cec5SDimitry Andric return TM.getSymbol(GV); 4130b57cec5SDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!"); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue( 4170b57cec5SDimitry Andric MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { 4180b57cec5SDimitry Andric SmallString<64> NameData("DW.ref."); 4190b57cec5SDimitry Andric NameData += Sym->getName(); 4200b57cec5SDimitry Andric MCSymbolELF *Label = 4210b57cec5SDimitry Andric cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); 4225ffd83dbSDimitry Andric Streamer.emitSymbolAttribute(Label, MCSA_Hidden); 4235ffd83dbSDimitry Andric Streamer.emitSymbolAttribute(Label, MCSA_Weak); 4240b57cec5SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; 4250b57cec5SDimitry Andric MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), 4260b57cec5SDimitry Andric ELF::SHT_PROGBITS, Flags, 0); 4270b57cec5SDimitry Andric unsigned Size = DL.getPointerSize(); 42881ad6265SDimitry Andric Streamer.switchSection(Sec); 429bdd1243dSDimitry Andric Streamer.emitValueToAlignment(DL.getPointerABIAlignment(0)); 4305ffd83dbSDimitry Andric Streamer.emitSymbolAttribute(Label, MCSA_ELF_TypeObject); 4310b57cec5SDimitry Andric const MCExpr *E = MCConstantExpr::create(Size, getContext()); 4320b57cec5SDimitry Andric Streamer.emitELFSize(Label, E); 4335ffd83dbSDimitry Andric Streamer.emitLabel(Label); 4340b57cec5SDimitry Andric 4355ffd83dbSDimitry Andric Streamer.emitSymbolValue(Sym, Size); 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( 4390b57cec5SDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 4400b57cec5SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 4410b57cec5SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 4420b57cec5SDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM); 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric // Add information about the stub reference to ELFMMI so that the stub 4470b57cec5SDimitry Andric // gets emitted by the asmprinter. 4480b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); 4490b57cec5SDimitry Andric if (!StubSym.getPointer()) { 4500b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 4510b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 4520b57cec5SDimitry Andric } 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric return TargetLoweringObjectFile:: 4550b57cec5SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 4560b57cec5SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 4600b57cec5SDimitry Andric MMI, Streamer); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) { 4640b57cec5SDimitry Andric // N.B.: The defaults used in here are not the same ones used in MC. 4650b57cec5SDimitry Andric // We follow gcc, MC follows gas. For example, given ".section .eh_frame", 4660b57cec5SDimitry Andric // both gas and MC will produce a section with no flags. Given 4670b57cec5SDimitry Andric // section(".eh_frame") gcc will produce: 4680b57cec5SDimitry Andric // 4690b57cec5SDimitry Andric // .section .eh_frame,"a",@progbits 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF, 4725ffd83dbSDimitry Andric /*AddSegmentInfo=*/false) || 4735ffd83dbSDimitry Andric Name == getInstrProfSectionName(IPSK_covfun, Triple::ELF, 474e8d8bef9SDimitry Andric /*AddSegmentInfo=*/false) || 475c9157d92SDimitry Andric Name == getInstrProfSectionName(IPSK_covdata, Triple::ELF, 476c9157d92SDimitry Andric /*AddSegmentInfo=*/false) || 477c9157d92SDimitry Andric Name == getInstrProfSectionName(IPSK_covname, Triple::ELF, 478c9157d92SDimitry Andric /*AddSegmentInfo=*/false) || 479e8d8bef9SDimitry Andric Name == ".llvmbc" || Name == ".llvmcmd") 4800b57cec5SDimitry Andric return SectionKind::getMetadata(); 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric if (Name.empty() || Name[0] != '.') return K; 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric // Default implementation based on some magic section names. 485c9157d92SDimitry Andric if (Name == ".bss" || Name.starts_with(".bss.") || 486c9157d92SDimitry Andric Name.starts_with(".gnu.linkonce.b.") || 487c9157d92SDimitry Andric Name.starts_with(".llvm.linkonce.b.") || Name == ".sbss" || 488c9157d92SDimitry Andric Name.starts_with(".sbss.") || Name.starts_with(".gnu.linkonce.sb.") || 489c9157d92SDimitry Andric Name.starts_with(".llvm.linkonce.sb.")) 4900b57cec5SDimitry Andric return SectionKind::getBSS(); 4910b57cec5SDimitry Andric 492c9157d92SDimitry Andric if (Name == ".tdata" || Name.starts_with(".tdata.") || 493c9157d92SDimitry Andric Name.starts_with(".gnu.linkonce.td.") || 494c9157d92SDimitry Andric Name.starts_with(".llvm.linkonce.td.")) 4950b57cec5SDimitry Andric return SectionKind::getThreadData(); 4960b57cec5SDimitry Andric 497c9157d92SDimitry Andric if (Name == ".tbss" || Name.starts_with(".tbss.") || 498c9157d92SDimitry Andric Name.starts_with(".gnu.linkonce.tb.") || 499c9157d92SDimitry Andric Name.starts_with(".llvm.linkonce.tb.")) 5000b57cec5SDimitry Andric return SectionKind::getThreadBSS(); 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric return K; 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric 50504eeddc0SDimitry Andric static bool hasPrefix(StringRef SectionName, StringRef Prefix) { 50604eeddc0SDimitry Andric return SectionName.consume_front(Prefix) && 50704eeddc0SDimitry Andric (SectionName.empty() || SectionName[0] == '.'); 50804eeddc0SDimitry Andric } 50904eeddc0SDimitry Andric 5100b57cec5SDimitry Andric static unsigned getELFSectionType(StringRef Name, SectionKind K) { 5110b57cec5SDimitry Andric // Use SHT_NOTE for section whose name starts with ".note" to allow 5120b57cec5SDimitry Andric // emitting ELF notes from C variable declaration. 5130b57cec5SDimitry Andric // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609 514c9157d92SDimitry Andric if (Name.starts_with(".note")) 5150b57cec5SDimitry Andric return ELF::SHT_NOTE; 5160b57cec5SDimitry Andric 51704eeddc0SDimitry Andric if (hasPrefix(Name, ".init_array")) 5180b57cec5SDimitry Andric return ELF::SHT_INIT_ARRAY; 5190b57cec5SDimitry Andric 52004eeddc0SDimitry Andric if (hasPrefix(Name, ".fini_array")) 5210b57cec5SDimitry Andric return ELF::SHT_FINI_ARRAY; 5220b57cec5SDimitry Andric 52304eeddc0SDimitry Andric if (hasPrefix(Name, ".preinit_array")) 5240b57cec5SDimitry Andric return ELF::SHT_PREINIT_ARRAY; 5250b57cec5SDimitry Andric 526753f127fSDimitry Andric if (hasPrefix(Name, ".llvm.offloading")) 527753f127fSDimitry Andric return ELF::SHT_LLVM_OFFLOADING; 528753f127fSDimitry Andric 5290b57cec5SDimitry Andric if (K.isBSS() || K.isThreadBSS()) 5300b57cec5SDimitry Andric return ELF::SHT_NOBITS; 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric return ELF::SHT_PROGBITS; 5330b57cec5SDimitry Andric } 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) { 5360b57cec5SDimitry Andric unsigned Flags = 0; 5370b57cec5SDimitry Andric 53881ad6265SDimitry Andric if (!K.isMetadata() && !K.isExclude()) 5390b57cec5SDimitry Andric Flags |= ELF::SHF_ALLOC; 5400b57cec5SDimitry Andric 54181ad6265SDimitry Andric if (K.isExclude()) 54281ad6265SDimitry Andric Flags |= ELF::SHF_EXCLUDE; 54381ad6265SDimitry Andric 5440b57cec5SDimitry Andric if (K.isText()) 5450b57cec5SDimitry Andric Flags |= ELF::SHF_EXECINSTR; 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric if (K.isExecuteOnly()) 5480b57cec5SDimitry Andric Flags |= ELF::SHF_ARM_PURECODE; 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric if (K.isWriteable()) 5510b57cec5SDimitry Andric Flags |= ELF::SHF_WRITE; 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric if (K.isThreadLocal()) 5540b57cec5SDimitry Andric Flags |= ELF::SHF_TLS; 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric if (K.isMergeableCString() || K.isMergeableConst()) 5570b57cec5SDimitry Andric Flags |= ELF::SHF_MERGE; 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric if (K.isMergeableCString()) 5600b57cec5SDimitry Andric Flags |= ELF::SHF_STRINGS; 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric return Flags; 5630b57cec5SDimitry Andric } 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) { 5660b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 5670b57cec5SDimitry Andric if (!C) 5680b57cec5SDimitry Andric return nullptr; 5690b57cec5SDimitry Andric 570fe6060f1SDimitry Andric if (C->getSelectionKind() != Comdat::Any && 571fe6060f1SDimitry Andric C->getSelectionKind() != Comdat::NoDeduplicate) 572fe6060f1SDimitry Andric report_fatal_error("ELF COMDATs only support SelectionKind::Any and " 573fe6060f1SDimitry Andric "SelectionKind::NoDeduplicate, '" + 5740b57cec5SDimitry Andric C->getName() + "' cannot be lowered."); 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andric return C; 5770b57cec5SDimitry Andric } 5780b57cec5SDimitry Andric 5795ffd83dbSDimitry Andric static const MCSymbolELF *getLinkedToSymbol(const GlobalObject *GO, 5800b57cec5SDimitry Andric const TargetMachine &TM) { 5810b57cec5SDimitry Andric MDNode *MD = GO->getMetadata(LLVMContext::MD_associated); 5820b57cec5SDimitry Andric if (!MD) 5830b57cec5SDimitry Andric return nullptr; 5840b57cec5SDimitry Andric 585fe013be4SDimitry Andric auto *VM = cast<ValueAsMetadata>(MD->getOperand(0).get()); 5868bcb0991SDimitry Andric auto *OtherGV = dyn_cast<GlobalValue>(VM->getValue()); 5878bcb0991SDimitry Andric return OtherGV ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGV)) : nullptr; 5880b57cec5SDimitry Andric } 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric static unsigned getEntrySizeForKind(SectionKind Kind) { 5910b57cec5SDimitry Andric if (Kind.isMergeable1ByteCString()) 5920b57cec5SDimitry Andric return 1; 5930b57cec5SDimitry Andric else if (Kind.isMergeable2ByteCString()) 5940b57cec5SDimitry Andric return 2; 5950b57cec5SDimitry Andric else if (Kind.isMergeable4ByteCString()) 5960b57cec5SDimitry Andric return 4; 5970b57cec5SDimitry Andric else if (Kind.isMergeableConst4()) 5980b57cec5SDimitry Andric return 4; 5990b57cec5SDimitry Andric else if (Kind.isMergeableConst8()) 6000b57cec5SDimitry Andric return 8; 6010b57cec5SDimitry Andric else if (Kind.isMergeableConst16()) 6020b57cec5SDimitry Andric return 16; 6030b57cec5SDimitry Andric else if (Kind.isMergeableConst32()) 6040b57cec5SDimitry Andric return 32; 6050b57cec5SDimitry Andric else { 6060b57cec5SDimitry Andric // We shouldn't have mergeable C strings or mergeable constants that we 6070b57cec5SDimitry Andric // didn't handle above. 6080b57cec5SDimitry Andric assert(!Kind.isMergeableCString() && "unknown string width"); 6090b57cec5SDimitry Andric assert(!Kind.isMergeableConst() && "unknown data width"); 6100b57cec5SDimitry Andric return 0; 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric } 6130b57cec5SDimitry Andric 6145ffd83dbSDimitry Andric /// Return the section prefix name used by options FunctionsSections and 6155ffd83dbSDimitry Andric /// DataSections. 616fe013be4SDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind, bool IsLarge) { 6175ffd83dbSDimitry Andric if (Kind.isText()) 618c9157d92SDimitry Andric return IsLarge ? ".ltext" : ".text"; 6195ffd83dbSDimitry Andric if (Kind.isReadOnly()) 620fe013be4SDimitry Andric return IsLarge ? ".lrodata" : ".rodata"; 6215ffd83dbSDimitry Andric if (Kind.isBSS()) 622fe013be4SDimitry Andric return IsLarge ? ".lbss" : ".bss"; 6235ffd83dbSDimitry Andric if (Kind.isThreadData()) 6245ffd83dbSDimitry Andric return ".tdata"; 6255ffd83dbSDimitry Andric if (Kind.isThreadBSS()) 6265ffd83dbSDimitry Andric return ".tbss"; 6275ffd83dbSDimitry Andric if (Kind.isData()) 628fe013be4SDimitry Andric return IsLarge ? ".ldata" : ".data"; 6295ffd83dbSDimitry Andric if (Kind.isReadOnlyWithRel()) 630fe013be4SDimitry Andric return IsLarge ? ".ldata.rel.ro" : ".data.rel.ro"; 6315ffd83dbSDimitry Andric llvm_unreachable("Unknown section kind"); 6325ffd83dbSDimitry Andric } 6335ffd83dbSDimitry Andric 6345ffd83dbSDimitry Andric static SmallString<128> 6355ffd83dbSDimitry Andric getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind, 6365ffd83dbSDimitry Andric Mangler &Mang, const TargetMachine &TM, 6375ffd83dbSDimitry Andric unsigned EntrySize, bool UniqueSectionName) { 6385ffd83dbSDimitry Andric SmallString<128> Name; 6395ffd83dbSDimitry Andric if (Kind.isMergeableCString()) { 6405ffd83dbSDimitry Andric // We also need alignment here. 6415ffd83dbSDimitry Andric // FIXME: this is getting the alignment of the character, not the 6425ffd83dbSDimitry Andric // alignment of the global! 6435ffd83dbSDimitry Andric Align Alignment = GO->getParent()->getDataLayout().getPreferredAlign( 6445ffd83dbSDimitry Andric cast<GlobalVariable>(GO)); 6455ffd83dbSDimitry Andric 6465ffd83dbSDimitry Andric std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; 6475ffd83dbSDimitry Andric Name = SizeSpec + utostr(Alignment.value()); 6485ffd83dbSDimitry Andric } else if (Kind.isMergeableConst()) { 6495ffd83dbSDimitry Andric Name = ".rodata.cst"; 6505ffd83dbSDimitry Andric Name += utostr(EntrySize); 6515ffd83dbSDimitry Andric } else { 652c9157d92SDimitry Andric Name = getSectionPrefixForGlobal(Kind, TM.isLargeGlobalValue(GO)); 6535ffd83dbSDimitry Andric } 6545ffd83dbSDimitry Andric 6555ffd83dbSDimitry Andric bool HasPrefix = false; 6565ffd83dbSDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 657bdd1243dSDimitry Andric if (std::optional<StringRef> Prefix = F->getSectionPrefix()) { 658e8d8bef9SDimitry Andric raw_svector_ostream(Name) << '.' << *Prefix; 6595ffd83dbSDimitry Andric HasPrefix = true; 6605ffd83dbSDimitry Andric } 6615ffd83dbSDimitry Andric } 6625ffd83dbSDimitry Andric 6635ffd83dbSDimitry Andric if (UniqueSectionName) { 6645ffd83dbSDimitry Andric Name.push_back('.'); 6655ffd83dbSDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, /*MayAlwaysUsePrivate*/true); 6665ffd83dbSDimitry Andric } else if (HasPrefix) 667fe6060f1SDimitry Andric // For distinguishing between .text.${text-section-prefix}. (with trailing 668fe6060f1SDimitry Andric // dot) and .text.${function-name} 6695ffd83dbSDimitry Andric Name.push_back('.'); 6705ffd83dbSDimitry Andric return Name; 6715ffd83dbSDimitry Andric } 6725ffd83dbSDimitry Andric 6735ffd83dbSDimitry Andric namespace { 6745ffd83dbSDimitry Andric class LoweringDiagnosticInfo : public DiagnosticInfo { 6755ffd83dbSDimitry Andric const Twine &Msg; 6765ffd83dbSDimitry Andric 6775ffd83dbSDimitry Andric public: 6785ffd83dbSDimitry Andric LoweringDiagnosticInfo(const Twine &DiagMsg, 6795ffd83dbSDimitry Andric DiagnosticSeverity Severity = DS_Error) 6805ffd83dbSDimitry Andric : DiagnosticInfo(DK_Lowering, Severity), Msg(DiagMsg) {} 6815ffd83dbSDimitry Andric void print(DiagnosticPrinter &DP) const override { DP << Msg; } 6825ffd83dbSDimitry Andric }; 6835ffd83dbSDimitry Andric } 6845ffd83dbSDimitry Andric 685fe6060f1SDimitry Andric /// Calculate an appropriate unique ID for a section, and update Flags, 686fe6060f1SDimitry Andric /// EntrySize and NextUniqueID where appropriate. 687fe6060f1SDimitry Andric static unsigned 688fe6060f1SDimitry Andric calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName, 689fe6060f1SDimitry Andric SectionKind Kind, const TargetMachine &TM, 690fe6060f1SDimitry Andric MCContext &Ctx, Mangler &Mang, unsigned &Flags, 691fe6060f1SDimitry Andric unsigned &EntrySize, unsigned &NextUniqueID, 692fe6060f1SDimitry Andric const bool Retain, const bool ForceUnique) { 693fe6060f1SDimitry Andric // Increment uniqueID if we are forced to emit a unique section. 694fe6060f1SDimitry Andric // This works perfectly fine with section attribute or pragma section as the 695fe6060f1SDimitry Andric // sections with the same name are grouped together by the assembler. 696fe6060f1SDimitry Andric if (ForceUnique) 697fe6060f1SDimitry Andric return NextUniqueID++; 698fe6060f1SDimitry Andric 699fe6060f1SDimitry Andric // A section can have at most one associated section. Put each global with 700fe6060f1SDimitry Andric // MD_associated in a unique section. 701fe6060f1SDimitry Andric const bool Associated = GO->getMetadata(LLVMContext::MD_associated); 702fe6060f1SDimitry Andric if (Associated) { 703fe6060f1SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 704fe6060f1SDimitry Andric return NextUniqueID++; 705fe6060f1SDimitry Andric } 706fe6060f1SDimitry Andric 707fe6060f1SDimitry Andric if (Retain) { 70881ad6265SDimitry Andric if (TM.getTargetTriple().isOSSolaris()) 70981ad6265SDimitry Andric Flags |= ELF::SHF_SUNW_NODISCARD; 71081ad6265SDimitry Andric else if (Ctx.getAsmInfo()->useIntegratedAssembler() || 71181ad6265SDimitry Andric Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) 712fe6060f1SDimitry Andric Flags |= ELF::SHF_GNU_RETAIN; 713fe6060f1SDimitry Andric return NextUniqueID++; 714fe6060f1SDimitry Andric } 715fe6060f1SDimitry Andric 716fe6060f1SDimitry Andric // If two symbols with differing sizes end up in the same mergeable section 717fe6060f1SDimitry Andric // that section can be assigned an incorrect entry size. To avoid this we 718fe6060f1SDimitry Andric // usually put symbols of the same size into distinct mergeable sections with 719fe6060f1SDimitry Andric // the same name. Doing so relies on the ",unique ," assembly feature. This 720fe6060f1SDimitry Andric // feature is not avalible until bintuils version 2.35 721fe6060f1SDimitry Andric // (https://sourceware.org/bugzilla/show_bug.cgi?id=25380). 722fe6060f1SDimitry Andric const bool SupportsUnique = Ctx.getAsmInfo()->useIntegratedAssembler() || 723fe6060f1SDimitry Andric Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35); 724fe6060f1SDimitry Andric if (!SupportsUnique) { 725fe6060f1SDimitry Andric Flags &= ~ELF::SHF_MERGE; 726fe6060f1SDimitry Andric EntrySize = 0; 727fe6060f1SDimitry Andric return MCContext::GenericSectionID; 728fe6060f1SDimitry Andric } 729fe6060f1SDimitry Andric 730fe6060f1SDimitry Andric const bool SymbolMergeable = Flags & ELF::SHF_MERGE; 731fe6060f1SDimitry Andric const bool SeenSectionNameBefore = 732fe6060f1SDimitry Andric Ctx.isELFGenericMergeableSection(SectionName); 733fe6060f1SDimitry Andric // If this is the first ocurrence of this section name, treat it as the 734fe6060f1SDimitry Andric // generic section 735fe6060f1SDimitry Andric if (!SymbolMergeable && !SeenSectionNameBefore) 736fe6060f1SDimitry Andric return MCContext::GenericSectionID; 737fe6060f1SDimitry Andric 738fe6060f1SDimitry Andric // Symbols must be placed into sections with compatible entry sizes. Generate 739fe6060f1SDimitry Andric // unique sections for symbols that have not been assigned to compatible 740fe6060f1SDimitry Andric // sections. 741fe6060f1SDimitry Andric const auto PreviousID = 742fe6060f1SDimitry Andric Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize); 743fe6060f1SDimitry Andric if (PreviousID) 744fe6060f1SDimitry Andric return *PreviousID; 745fe6060f1SDimitry Andric 746fe6060f1SDimitry Andric // If the user has specified the same section name as would be created 747fe6060f1SDimitry Andric // implicitly for this symbol e.g. .rodata.str1.1, then we don't need 748fe6060f1SDimitry Andric // to unique the section as the entry size for this symbol will be 749fe6060f1SDimitry Andric // compatible with implicitly created sections. 750fe6060f1SDimitry Andric SmallString<128> ImplicitSectionNameStem = 751fe6060f1SDimitry Andric getELFSectionNameForGlobal(GO, Kind, Mang, TM, EntrySize, false); 752fe6060f1SDimitry Andric if (SymbolMergeable && 753fe6060f1SDimitry Andric Ctx.isELFImplicitMergeableSectionNamePrefix(SectionName) && 754c9157d92SDimitry Andric SectionName.starts_with(ImplicitSectionNameStem)) 755fe6060f1SDimitry Andric return MCContext::GenericSectionID; 756fe6060f1SDimitry Andric 757fe6060f1SDimitry Andric // We have seen this section name before, but with different flags or entity 758fe6060f1SDimitry Andric // size. Create a new unique ID. 759fe6060f1SDimitry Andric return NextUniqueID++; 760fe6060f1SDimitry Andric } 761fe6060f1SDimitry Andric 762c9157d92SDimitry Andric static std::tuple<StringRef, bool, unsigned> 763c9157d92SDimitry Andric getGlobalObjectInfo(const GlobalObject *GO, const TargetMachine &TM) { 764c9157d92SDimitry Andric StringRef Group = ""; 765c9157d92SDimitry Andric bool IsComdat = false; 766c9157d92SDimitry Andric unsigned Flags = 0; 767c9157d92SDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 768c9157d92SDimitry Andric Flags |= ELF::SHF_GROUP; 769c9157d92SDimitry Andric Group = C->getName(); 770c9157d92SDimitry Andric IsComdat = C->getSelectionKind() == Comdat::Any; 771c9157d92SDimitry Andric } 772c9157d92SDimitry Andric if (TM.isLargeGlobalValue(GO)) 773c9157d92SDimitry Andric Flags |= ELF::SHF_X86_64_LARGE; 774c9157d92SDimitry Andric return {Group, IsComdat, Flags}; 775c9157d92SDimitry Andric } 776c9157d92SDimitry Andric 777fe6060f1SDimitry Andric static MCSection *selectExplicitSectionGlobal( 778fe6060f1SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM, 779fe6060f1SDimitry Andric MCContext &Ctx, Mangler &Mang, unsigned &NextUniqueID, 780fe6060f1SDimitry Andric bool Retain, bool ForceUnique) { 7810b57cec5SDimitry Andric StringRef SectionName = GO->getSection(); 7820b57cec5SDimitry Andric 7830b57cec5SDimitry Andric // Check if '#pragma clang section' name is applicable. 7840b57cec5SDimitry Andric // Note that pragma directive overrides -ffunction-section, -fdata-section 7850b57cec5SDimitry Andric // and so section name is exactly as user specified and not uniqued. 7860b57cec5SDimitry Andric const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); 7870b57cec5SDimitry Andric if (GV && GV->hasImplicitSection()) { 7880b57cec5SDimitry Andric auto Attrs = GV->getAttributes(); 7890b57cec5SDimitry Andric if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { 7900b57cec5SDimitry Andric SectionName = Attrs.getAttribute("bss-section").getValueAsString(); 7910b57cec5SDimitry Andric } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { 7920b57cec5SDimitry Andric SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); 7938bcb0991SDimitry Andric } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) { 7948bcb0991SDimitry Andric SectionName = Attrs.getAttribute("relro-section").getValueAsString(); 7950b57cec5SDimitry Andric } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { 7960b57cec5SDimitry Andric SectionName = Attrs.getAttribute("data-section").getValueAsString(); 7970b57cec5SDimitry Andric } 7980b57cec5SDimitry Andric } 7990b57cec5SDimitry Andric const Function *F = dyn_cast<Function>(GO); 8000b57cec5SDimitry Andric if (F && F->hasFnAttribute("implicit-section-name")) { 8010b57cec5SDimitry Andric SectionName = F->getFnAttribute("implicit-section-name").getValueAsString(); 8020b57cec5SDimitry Andric } 8030b57cec5SDimitry Andric 8040b57cec5SDimitry Andric // Infer section flags from the section name if we can. 8050b57cec5SDimitry Andric Kind = getELFKindForNamedSection(SectionName, Kind); 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 808c9157d92SDimitry Andric auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM); 809c9157d92SDimitry Andric Flags |= ExtraFlags; 8100b57cec5SDimitry Andric 8115ffd83dbSDimitry Andric unsigned EntrySize = getEntrySizeForKind(Kind); 812fe6060f1SDimitry Andric const unsigned UniqueID = calcUniqueIDUpdateFlagsAndSize( 813fe6060f1SDimitry Andric GO, SectionName, Kind, TM, Ctx, Mang, Flags, EntrySize, NextUniqueID, 814fe6060f1SDimitry Andric Retain, ForceUnique); 8155ffd83dbSDimitry Andric 8165ffd83dbSDimitry Andric const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); 817fe6060f1SDimitry Andric MCSectionELF *Section = Ctx.getELFSection( 818fe6060f1SDimitry Andric SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize, 819fe6060f1SDimitry Andric Group, IsComdat, UniqueID, LinkedToSym); 8200b57cec5SDimitry Andric // Make sure that we did not get some other section with incompatible sh_link. 8210b57cec5SDimitry Andric // This should not be possible due to UniqueID code above. 8225ffd83dbSDimitry Andric assert(Section->getLinkedToSymbol() == LinkedToSym && 8230b57cec5SDimitry Andric "Associated symbol mismatch between sections"); 8245ffd83dbSDimitry Andric 825fe6060f1SDimitry Andric if (!(Ctx.getAsmInfo()->useIntegratedAssembler() || 826fe6060f1SDimitry Andric Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35))) { 827e8d8bef9SDimitry Andric // If we are using GNU as before 2.35, then this symbol might have 8285ffd83dbSDimitry Andric // been placed in an incompatible mergeable section. Emit an error if this 8295ffd83dbSDimitry Andric // is the case to avoid creating broken output. 8305ffd83dbSDimitry Andric if ((Section->getFlags() & ELF::SHF_MERGE) && 8315ffd83dbSDimitry Andric (Section->getEntrySize() != getEntrySizeForKind(Kind))) 8325ffd83dbSDimitry Andric GO->getContext().diagnose(LoweringDiagnosticInfo( 8335ffd83dbSDimitry Andric "Symbol '" + GO->getName() + "' from module '" + 8345ffd83dbSDimitry Andric (GO->getParent() ? GO->getParent()->getSourceFileName() : "unknown") + 8355ffd83dbSDimitry Andric "' required a section with entry-size=" + 8365ffd83dbSDimitry Andric Twine(getEntrySizeForKind(Kind)) + " but was placed in section '" + 8375ffd83dbSDimitry Andric SectionName + "' with entry-size=" + Twine(Section->getEntrySize()) + 8385ffd83dbSDimitry Andric ": Explicit assignment by pragma or attribute of an incompatible " 8395ffd83dbSDimitry Andric "symbol to this section?")); 8400b57cec5SDimitry Andric } 8410b57cec5SDimitry Andric 8425ffd83dbSDimitry Andric return Section; 8430b57cec5SDimitry Andric } 8440b57cec5SDimitry Andric 845fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( 846fe6060f1SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 847fe6060f1SDimitry Andric return selectExplicitSectionGlobal(GO, Kind, TM, getContext(), getMangler(), 848fe6060f1SDimitry Andric NextUniqueID, Used.count(GO), 849fe6060f1SDimitry Andric /* ForceUnique = */false); 850fe6060f1SDimitry Andric } 851fe6060f1SDimitry Andric 8520b57cec5SDimitry Andric static MCSectionELF *selectELFSectionForGlobal( 8530b57cec5SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 8540b57cec5SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, 8550b57cec5SDimitry Andric unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { 8560b57cec5SDimitry Andric 857c9157d92SDimitry Andric auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM); 858c9157d92SDimitry Andric Flags |= ExtraFlags; 8590b57cec5SDimitry Andric 8600b57cec5SDimitry Andric // Get the section entry size based on the kind. 8610b57cec5SDimitry Andric unsigned EntrySize = getEntrySizeForKind(Kind); 8620b57cec5SDimitry Andric 8635ffd83dbSDimitry Andric bool UniqueSectionName = false; 8640b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 8650b57cec5SDimitry Andric if (EmitUniqueSection) { 8660b57cec5SDimitry Andric if (TM.getUniqueSectionNames()) { 8675ffd83dbSDimitry Andric UniqueSectionName = true; 8680b57cec5SDimitry Andric } else { 8690b57cec5SDimitry Andric UniqueID = *NextUniqueID; 8700b57cec5SDimitry Andric (*NextUniqueID)++; 8710b57cec5SDimitry Andric } 8720b57cec5SDimitry Andric } 8735ffd83dbSDimitry Andric SmallString<128> Name = getELFSectionNameForGlobal( 8745ffd83dbSDimitry Andric GO, Kind, Mang, TM, EntrySize, UniqueSectionName); 8755ffd83dbSDimitry Andric 8760b57cec5SDimitry Andric // Use 0 as the unique ID for execute-only text. 8770b57cec5SDimitry Andric if (Kind.isExecuteOnly()) 8780b57cec5SDimitry Andric UniqueID = 0; 8790b57cec5SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 880fe6060f1SDimitry Andric EntrySize, Group, IsComdat, UniqueID, 881fe6060f1SDimitry Andric AssociatedSymbol); 882fe6060f1SDimitry Andric } 883fe6060f1SDimitry Andric 884fe6060f1SDimitry Andric static MCSection *selectELFSectionForGlobal( 885fe6060f1SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 886fe6060f1SDimitry Andric const TargetMachine &TM, bool Retain, bool EmitUniqueSection, 887fe6060f1SDimitry Andric unsigned Flags, unsigned *NextUniqueID) { 888fe6060f1SDimitry Andric const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); 889fe6060f1SDimitry Andric if (LinkedToSym) { 890fe6060f1SDimitry Andric EmitUniqueSection = true; 891fe6060f1SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 892fe6060f1SDimitry Andric } 89381ad6265SDimitry Andric if (Retain) { 89481ad6265SDimitry Andric if (TM.getTargetTriple().isOSSolaris()) { 89581ad6265SDimitry Andric EmitUniqueSection = true; 89681ad6265SDimitry Andric Flags |= ELF::SHF_SUNW_NODISCARD; 89781ad6265SDimitry Andric } else if (Ctx.getAsmInfo()->useIntegratedAssembler() || 89881ad6265SDimitry Andric Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) { 899fe6060f1SDimitry Andric EmitUniqueSection = true; 900fe6060f1SDimitry Andric Flags |= ELF::SHF_GNU_RETAIN; 901fe6060f1SDimitry Andric } 90281ad6265SDimitry Andric } 903fe6060f1SDimitry Andric 904fe6060f1SDimitry Andric MCSectionELF *Section = selectELFSectionForGlobal( 905fe6060f1SDimitry Andric Ctx, GO, Kind, Mang, TM, EmitUniqueSection, Flags, 906fe6060f1SDimitry Andric NextUniqueID, LinkedToSym); 907fe6060f1SDimitry Andric assert(Section->getLinkedToSymbol() == LinkedToSym); 908fe6060f1SDimitry Andric return Section; 9090b57cec5SDimitry Andric } 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( 9120b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 9130b57cec5SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 9160b57cec5SDimitry Andric // global value to a uniqued section specifically for it. 9170b57cec5SDimitry Andric bool EmitUniqueSection = false; 9180b57cec5SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { 9190b57cec5SDimitry Andric if (Kind.isText()) 9200b57cec5SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 9210b57cec5SDimitry Andric else 9220b57cec5SDimitry Andric EmitUniqueSection = TM.getDataSections(); 9230b57cec5SDimitry Andric } 9240b57cec5SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 925fe6060f1SDimitry Andric return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 926fe6060f1SDimitry Andric Used.count(GO), EmitUniqueSection, Flags, 927fe6060f1SDimitry Andric &NextUniqueID); 9280b57cec5SDimitry Andric } 9290b57cec5SDimitry Andric 930fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction( 931fe6060f1SDimitry Andric const Function &F, const TargetMachine &TM) const { 932fe6060f1SDimitry Andric SectionKind Kind = SectionKind::getText(); 933fe6060f1SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 934fe6060f1SDimitry Andric // If the function's section names is pre-determined via pragma or a 935fe6060f1SDimitry Andric // section attribute, call selectExplicitSectionGlobal. 936fe6060f1SDimitry Andric if (F.hasSection() || F.hasFnAttribute("implicit-section-name")) 937fe6060f1SDimitry Andric return selectExplicitSectionGlobal( 938fe6060f1SDimitry Andric &F, Kind, TM, getContext(), getMangler(), NextUniqueID, 939fe6060f1SDimitry Andric Used.count(&F), /* ForceUnique = */true); 940fe6060f1SDimitry Andric else 941fe6060f1SDimitry Andric return selectELFSectionForGlobal( 942fe6060f1SDimitry Andric getContext(), &F, Kind, getMangler(), TM, Used.count(&F), 943fe6060f1SDimitry Andric /*EmitUniqueSection=*/true, Flags, &NextUniqueID); 9440b57cec5SDimitry Andric } 9450b57cec5SDimitry Andric 9460b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( 9470b57cec5SDimitry Andric const Function &F, const TargetMachine &TM) const { 9480b57cec5SDimitry Andric // If the function can be removed, produce a unique section so that 9490b57cec5SDimitry Andric // the table doesn't prevent the removal. 9500b57cec5SDimitry Andric const Comdat *C = F.getComdat(); 9510b57cec5SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 9520b57cec5SDimitry Andric if (!EmitUniqueSection) 9530b57cec5SDimitry Andric return ReadOnlySection; 9540b57cec5SDimitry Andric 9550b57cec5SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), 9560b57cec5SDimitry Andric getMangler(), TM, EmitUniqueSection, 9570b57cec5SDimitry Andric ELF::SHF_ALLOC, &NextUniqueID, 9580b57cec5SDimitry Andric /* AssociatedSymbol */ nullptr); 9590b57cec5SDimitry Andric } 9600b57cec5SDimitry Andric 961fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForLSDA( 962fe6060f1SDimitry Andric const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { 963e8d8bef9SDimitry Andric // If neither COMDAT nor function sections, use the monolithic LSDA section. 964e8d8bef9SDimitry Andric // Re-use this path if LSDASection is null as in the Arm EHABI. 965e8d8bef9SDimitry Andric if (!LSDASection || (!F.hasComdat() && !TM.getFunctionSections())) 966e8d8bef9SDimitry Andric return LSDASection; 967e8d8bef9SDimitry Andric 968e8d8bef9SDimitry Andric const auto *LSDA = cast<MCSectionELF>(LSDASection); 969e8d8bef9SDimitry Andric unsigned Flags = LSDA->getFlags(); 970fe6060f1SDimitry Andric const MCSymbolELF *LinkedToSym = nullptr; 971e8d8bef9SDimitry Andric StringRef Group; 972fe6060f1SDimitry Andric bool IsComdat = false; 973fe6060f1SDimitry Andric if (const Comdat *C = getELFComdat(&F)) { 974e8d8bef9SDimitry Andric Flags |= ELF::SHF_GROUP; 975fe6060f1SDimitry Andric Group = C->getName(); 976fe6060f1SDimitry Andric IsComdat = C->getSelectionKind() == Comdat::Any; 977fe6060f1SDimitry Andric } 978fe6060f1SDimitry Andric // Use SHF_LINK_ORDER to facilitate --gc-sections if we can use GNU ld>=2.36 979fe6060f1SDimitry Andric // or LLD, which support mixed SHF_LINK_ORDER & non-SHF_LINK_ORDER. 980fe6060f1SDimitry Andric if (TM.getFunctionSections() && 981fe6060f1SDimitry Andric (getContext().getAsmInfo()->useIntegratedAssembler() && 982fe6060f1SDimitry Andric getContext().getAsmInfo()->binutilsIsAtLeast(2, 36))) { 983fe6060f1SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 984fe6060f1SDimitry Andric LinkedToSym = cast<MCSymbolELF>(&FnSym); 985e8d8bef9SDimitry Andric } 986e8d8bef9SDimitry Andric 987e8d8bef9SDimitry Andric // Append the function name as the suffix like GCC, assuming 988e8d8bef9SDimitry Andric // -funique-section-names applies to .gcc_except_table sections. 989fe6060f1SDimitry Andric return getContext().getELFSection( 990fe6060f1SDimitry Andric (TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName() 991fe6060f1SDimitry Andric : LSDA->getName()), 992fe6060f1SDimitry Andric LSDA->getType(), Flags, 0, Group, IsComdat, MCSection::NonUniqueID, 993fe6060f1SDimitry Andric LinkedToSym); 994e8d8bef9SDimitry Andric } 995e8d8bef9SDimitry Andric 9960b57cec5SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( 9970b57cec5SDimitry Andric bool UsesLabelDifference, const Function &F) const { 9980b57cec5SDimitry Andric // We can always create relative relocations, so use another section 9990b57cec5SDimitry Andric // that can be marked non-executable. 10000b57cec5SDimitry Andric return false; 10010b57cec5SDimitry Andric } 10020b57cec5SDimitry Andric 10030b57cec5SDimitry Andric /// Given a mergeable constant with the specified size and relocation 10040b57cec5SDimitry Andric /// information, return a section that it should be placed in. 10050b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant( 10060b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 10075ffd83dbSDimitry Andric Align &Alignment) const { 10080b57cec5SDimitry Andric if (Kind.isMergeableConst4() && MergeableConst4Section) 10090b57cec5SDimitry Andric return MergeableConst4Section; 10100b57cec5SDimitry Andric if (Kind.isMergeableConst8() && MergeableConst8Section) 10110b57cec5SDimitry Andric return MergeableConst8Section; 10120b57cec5SDimitry Andric if (Kind.isMergeableConst16() && MergeableConst16Section) 10130b57cec5SDimitry Andric return MergeableConst16Section; 10140b57cec5SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section) 10150b57cec5SDimitry Andric return MergeableConst32Section; 10160b57cec5SDimitry Andric if (Kind.isReadOnly()) 10170b57cec5SDimitry Andric return ReadOnlySection; 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 10200b57cec5SDimitry Andric return DataRelROSection; 10210b57cec5SDimitry Andric } 10220b57cec5SDimitry Andric 10235ffd83dbSDimitry Andric /// Returns a unique section for the given machine basic block. 10245ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock( 10255ffd83dbSDimitry Andric const Function &F, const MachineBasicBlock &MBB, 10265ffd83dbSDimitry Andric const TargetMachine &TM) const { 10275ffd83dbSDimitry Andric assert(MBB.isBeginSection() && "Basic block does not start a section!"); 10285ffd83dbSDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 10295ffd83dbSDimitry Andric 1030e8d8bef9SDimitry Andric // For cold sections use the .text.split. prefix along with the parent 10315ffd83dbSDimitry Andric // function name. All cold blocks for the same function go to the same 10325ffd83dbSDimitry Andric // section. Similarly all exception blocks are grouped by symbol name 10335ffd83dbSDimitry Andric // under the .text.eh prefix. For regular sections, we either use a unique 10345ffd83dbSDimitry Andric // name, or a unique ID for the section. 10355ffd83dbSDimitry Andric SmallString<128> Name; 1036c9157d92SDimitry Andric StringRef FunctionSectionName = MBB.getParent()->getSection()->getName(); 1037c9157d92SDimitry Andric if (FunctionSectionName.equals(".text") || 1038c9157d92SDimitry Andric FunctionSectionName.starts_with(".text.")) { 1039c9157d92SDimitry Andric // Function is in a regular .text section. 1040c9157d92SDimitry Andric StringRef FunctionName = MBB.getParent()->getName(); 10415ffd83dbSDimitry Andric if (MBB.getSectionID() == MBBSectionID::ColdSectionID) { 1042e8d8bef9SDimitry Andric Name += BBSectionsColdTextPrefix; 1043c9157d92SDimitry Andric Name += FunctionName; 10445ffd83dbSDimitry Andric } else if (MBB.getSectionID() == MBBSectionID::ExceptionSectionID) { 10455ffd83dbSDimitry Andric Name += ".text.eh."; 1046c9157d92SDimitry Andric Name += FunctionName; 10475ffd83dbSDimitry Andric } else { 1048c9157d92SDimitry Andric Name += FunctionSectionName; 10495ffd83dbSDimitry Andric if (TM.getUniqueBasicBlockSectionNames()) { 1050c9157d92SDimitry Andric if (!Name.ends_with(".")) 10515ffd83dbSDimitry Andric Name += "."; 10525ffd83dbSDimitry Andric Name += MBB.getSymbol()->getName(); 10535ffd83dbSDimitry Andric } else { 10545ffd83dbSDimitry Andric UniqueID = NextUniqueID++; 10555ffd83dbSDimitry Andric } 10565ffd83dbSDimitry Andric } 1057c9157d92SDimitry Andric } else { 1058c9157d92SDimitry Andric // If the original function has a custom non-dot-text section, then emit 1059c9157d92SDimitry Andric // all basic block sections into that section too, each with a unique id. 1060c9157d92SDimitry Andric Name = FunctionSectionName; 1061c9157d92SDimitry Andric UniqueID = NextUniqueID++; 1062c9157d92SDimitry Andric } 10635ffd83dbSDimitry Andric 10645ffd83dbSDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; 1065e8d8bef9SDimitry Andric std::string GroupName; 10665ffd83dbSDimitry Andric if (F.hasComdat()) { 10675ffd83dbSDimitry Andric Flags |= ELF::SHF_GROUP; 10685ffd83dbSDimitry Andric GroupName = F.getComdat()->getName().str(); 10695ffd83dbSDimitry Andric } 10705ffd83dbSDimitry Andric return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags, 1071fe6060f1SDimitry Andric 0 /* Entry Size */, GroupName, 1072fe6060f1SDimitry Andric F.hasComdat(), UniqueID, nullptr); 10735ffd83dbSDimitry Andric } 10745ffd83dbSDimitry Andric 10750b57cec5SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, 10760b57cec5SDimitry Andric bool IsCtor, unsigned Priority, 10770b57cec5SDimitry Andric const MCSymbol *KeySym) { 10780b57cec5SDimitry Andric std::string Name; 10790b57cec5SDimitry Andric unsigned Type; 10800b57cec5SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; 1081fe6060f1SDimitry Andric StringRef Comdat = KeySym ? KeySym->getName() : ""; 10820b57cec5SDimitry Andric 10830b57cec5SDimitry Andric if (KeySym) 10840b57cec5SDimitry Andric Flags |= ELF::SHF_GROUP; 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andric if (UseInitArray) { 10870b57cec5SDimitry Andric if (IsCtor) { 10880b57cec5SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 10890b57cec5SDimitry Andric Name = ".init_array"; 10900b57cec5SDimitry Andric } else { 10910b57cec5SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 10920b57cec5SDimitry Andric Name = ".fini_array"; 10930b57cec5SDimitry Andric } 10940b57cec5SDimitry Andric if (Priority != 65535) { 10950b57cec5SDimitry Andric Name += '.'; 10960b57cec5SDimitry Andric Name += utostr(Priority); 10970b57cec5SDimitry Andric } 10980b57cec5SDimitry Andric } else { 10990b57cec5SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority 11000b57cec5SDimitry Andric // numbering. 11010b57cec5SDimitry Andric if (IsCtor) 11020b57cec5SDimitry Andric Name = ".ctors"; 11030b57cec5SDimitry Andric else 11040b57cec5SDimitry Andric Name = ".dtors"; 11050b57cec5SDimitry Andric if (Priority != 65535) 11060b57cec5SDimitry Andric raw_string_ostream(Name) << format(".%05u", 65535 - Priority); 11070b57cec5SDimitry Andric Type = ELF::SHT_PROGBITS; 11080b57cec5SDimitry Andric } 11090b57cec5SDimitry Andric 1110fe6060f1SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, Comdat, /*IsComdat=*/true); 11110b57cec5SDimitry Andric } 11120b57cec5SDimitry Andric 11130b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 11140b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 11150b57cec5SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 11160b57cec5SDimitry Andric KeySym); 11170b57cec5SDimitry Andric } 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 11200b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 11210b57cec5SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 11220b57cec5SDimitry Andric KeySym); 11230b57cec5SDimitry Andric } 11240b57cec5SDimitry Andric 11250b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 11260b57cec5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 11270b57cec5SDimitry Andric const TargetMachine &TM) const { 11280b57cec5SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 11290b57cec5SDimitry Andric // functions. 11300b57cec5SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 11310b57cec5SDimitry Andric return nullptr; 11320b57cec5SDimitry Andric 11334824e7fdSDimitry Andric // Basic correctness checks. 11340b57cec5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 11350b57cec5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 11360b57cec5SDimitry Andric RHS->isThreadLocal()) 11370b57cec5SDimitry Andric return nullptr; 11380b57cec5SDimitry Andric 11390b57cec5SDimitry Andric return MCBinaryExpr::createSub( 11400b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, 11410b57cec5SDimitry Andric getContext()), 11420b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 11430b57cec5SDimitry Andric } 11440b57cec5SDimitry Andric 1145e8d8bef9SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent( 1146e8d8bef9SDimitry Andric const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const { 1147e8d8bef9SDimitry Andric assert(supportDSOLocalEquivalentLowering()); 1148e8d8bef9SDimitry Andric 1149e8d8bef9SDimitry Andric const auto *GV = Equiv->getGlobalValue(); 1150e8d8bef9SDimitry Andric 1151e8d8bef9SDimitry Andric // A PLT entry is not needed for dso_local globals. 1152e8d8bef9SDimitry Andric if (GV->isDSOLocal() || GV->isImplicitDSOLocal()) 1153e8d8bef9SDimitry Andric return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext()); 1154e8d8bef9SDimitry Andric 1155e8d8bef9SDimitry Andric return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeVariantKind, 1156e8d8bef9SDimitry Andric getContext()); 1157e8d8bef9SDimitry Andric } 1158e8d8bef9SDimitry Andric 11590b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const { 11600b57cec5SDimitry Andric // Use ".GCC.command.line" since this feature is to support clang's 11610b57cec5SDimitry Andric // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the 11620b57cec5SDimitry Andric // same name. 11630b57cec5SDimitry Andric return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS, 1164fe6060f1SDimitry Andric ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); 11650b57cec5SDimitry Andric } 11660b57cec5SDimitry Andric 11670b57cec5SDimitry Andric void 11680b57cec5SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 11690b57cec5SDimitry Andric UseInitArray = UseInitArray_; 11700b57cec5SDimitry Andric MCContext &Ctx = getContext(); 11710b57cec5SDimitry Andric if (!UseInitArray) { 11720b57cec5SDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, 11730b57cec5SDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 11740b57cec5SDimitry Andric 11750b57cec5SDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, 11760b57cec5SDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 11770b57cec5SDimitry Andric return; 11780b57cec5SDimitry Andric } 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, 11810b57cec5SDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 11820b57cec5SDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, 11830b57cec5SDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 11840b57cec5SDimitry Andric } 11850b57cec5SDimitry Andric 11860b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11870b57cec5SDimitry Andric // MachO 11880b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11890b57cec5SDimitry Andric 119004eeddc0SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() { 11910b57cec5SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 11920b57cec5SDimitry Andric } 11930b57cec5SDimitry Andric 11940b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, 11950b57cec5SDimitry Andric const TargetMachine &TM) { 11960b57cec5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 11970b57cec5SDimitry Andric if (TM.getRelocationModel() == Reloc::Static) { 11980b57cec5SDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, 11990b57cec5SDimitry Andric SectionKind::getData()); 12000b57cec5SDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, 12010b57cec5SDimitry Andric SectionKind::getData()); 12020b57cec5SDimitry Andric } else { 12030b57cec5SDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", 12040b57cec5SDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 12050b57cec5SDimitry Andric SectionKind::getData()); 12060b57cec5SDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", 12070b57cec5SDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 12080b57cec5SDimitry Andric SectionKind::getData()); 12090b57cec5SDimitry Andric } 12100b57cec5SDimitry Andric 12110b57cec5SDimitry Andric PersonalityEncoding = 12120b57cec5SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 12130b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel; 12140b57cec5SDimitry Andric TTypeEncoding = 12150b57cec5SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric 121881ad6265SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getStaticDtorSection( 121981ad6265SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 122081ad6265SDimitry Andric return StaticDtorSection; 1221fe013be4SDimitry Andric // In userspace, we lower global destructors via atexit(), but kernel/kext 1222fe013be4SDimitry Andric // environments do not provide this function so we still need to support the 1223fe013be4SDimitry Andric // legacy way here. 1224fe013be4SDimitry Andric // See the -disable-atexit-based-global-dtor-lowering CodeGen flag for more 1225fe013be4SDimitry Andric // context. 122681ad6265SDimitry Andric } 122781ad6265SDimitry Andric 12280b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, 12290b57cec5SDimitry Andric Module &M) const { 12300b57cec5SDimitry Andric // Emit the linker options if present. 12310b57cec5SDimitry Andric if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 1232480093f4SDimitry Andric for (const auto *Option : LinkerOptions->operands()) { 12330b57cec5SDimitry Andric SmallVector<std::string, 4> StrOptions; 12340b57cec5SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 12355ffd83dbSDimitry Andric StrOptions.push_back(std::string(cast<MDString>(Piece)->getString())); 12365ffd83dbSDimitry Andric Streamer.emitLinkerOptions(StrOptions); 12370b57cec5SDimitry Andric } 12380b57cec5SDimitry Andric } 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andric unsigned VersionVal = 0; 12410b57cec5SDimitry Andric unsigned ImageInfoFlags = 0; 12420b57cec5SDimitry Andric StringRef SectionVal; 12430b57cec5SDimitry Andric 12440b57cec5SDimitry Andric GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal); 124504eeddc0SDimitry Andric emitCGProfileMetadata(Streamer, M); 12460b57cec5SDimitry Andric 12470b57cec5SDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 12480b57cec5SDimitry Andric if (SectionVal.empty()) 12490b57cec5SDimitry Andric return; 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric StringRef Segment, Section; 12520b57cec5SDimitry Andric unsigned TAA = 0, StubSize = 0; 12530b57cec5SDimitry Andric bool TAAParsed; 1254fe6060f1SDimitry Andric if (Error E = MCSectionMachO::ParseSectionSpecifier( 1255fe6060f1SDimitry Andric SectionVal, Segment, Section, TAA, TAAParsed, StubSize)) { 12560b57cec5SDimitry Andric // If invalid, report the error with report_fatal_error. 1257fe6060f1SDimitry Andric report_fatal_error("Invalid section specifier '" + Section + 1258fe6060f1SDimitry Andric "': " + toString(std::move(E)) + "."); 1259fe6060f1SDimitry Andric } 12600b57cec5SDimitry Andric 12610b57cec5SDimitry Andric // Get the section. 12620b57cec5SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 12630b57cec5SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 126481ad6265SDimitry Andric Streamer.switchSection(S); 12655ffd83dbSDimitry Andric Streamer.emitLabel(getContext(). 12660b57cec5SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 12675ffd83dbSDimitry Andric Streamer.emitInt32(VersionVal); 12685ffd83dbSDimitry Andric Streamer.emitInt32(ImageInfoFlags); 126981ad6265SDimitry Andric Streamer.addBlankLine(); 12700b57cec5SDimitry Andric } 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 12730b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 12740b57cec5SDimitry Andric if (!C) 12750b57cec5SDimitry Andric return; 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 12780b57cec5SDimitry Andric "' cannot be lowered."); 12790b57cec5SDimitry Andric } 12800b57cec5SDimitry Andric 12810b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 12820b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1283fe6060f1SDimitry Andric 1284fe6060f1SDimitry Andric StringRef SectionName = GO->getSection(); 1285fe6060f1SDimitry Andric 1286fe013be4SDimitry Andric const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); 1287fe013be4SDimitry Andric if (GV && GV->hasImplicitSection()) { 1288fe013be4SDimitry Andric auto Attrs = GV->getAttributes(); 1289fe013be4SDimitry Andric if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { 1290fe013be4SDimitry Andric SectionName = Attrs.getAttribute("bss-section").getValueAsString(); 1291fe013be4SDimitry Andric } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { 1292fe013be4SDimitry Andric SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); 1293fe013be4SDimitry Andric } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) { 1294fe013be4SDimitry Andric SectionName = Attrs.getAttribute("relro-section").getValueAsString(); 1295fe013be4SDimitry Andric } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { 1296fe013be4SDimitry Andric SectionName = Attrs.getAttribute("data-section").getValueAsString(); 1297fe013be4SDimitry Andric } 1298fe013be4SDimitry Andric } 1299fe013be4SDimitry Andric 1300fe6060f1SDimitry Andric const Function *F = dyn_cast<Function>(GO); 1301fe6060f1SDimitry Andric if (F && F->hasFnAttribute("implicit-section-name")) { 1302fe6060f1SDimitry Andric SectionName = F->getFnAttribute("implicit-section-name").getValueAsString(); 1303fe6060f1SDimitry Andric } 1304fe6060f1SDimitry Andric 13050b57cec5SDimitry Andric // Parse the section specifier and create it if valid. 13060b57cec5SDimitry Andric StringRef Segment, Section; 13070b57cec5SDimitry Andric unsigned TAA = 0, StubSize = 0; 13080b57cec5SDimitry Andric bool TAAParsed; 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric checkMachOComdat(GO); 13110b57cec5SDimitry Andric 1312fe6060f1SDimitry Andric if (Error E = MCSectionMachO::ParseSectionSpecifier( 1313fe6060f1SDimitry Andric SectionName, Segment, Section, TAA, TAAParsed, StubSize)) { 13140b57cec5SDimitry Andric // If invalid, report the error with report_fatal_error. 13150b57cec5SDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 13160b57cec5SDimitry Andric "' has an invalid section specifier '" + 1317fe6060f1SDimitry Andric GO->getSection() + "': " + toString(std::move(E)) + "."); 13180b57cec5SDimitry Andric } 13190b57cec5SDimitry Andric 13200b57cec5SDimitry Andric // Get the section. 13210b57cec5SDimitry Andric MCSectionMachO *S = 13220b57cec5SDimitry Andric getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 13230b57cec5SDimitry Andric 13240b57cec5SDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 13250b57cec5SDimitry Andric // use the value returned by getMachOSection() as a default. 13260b57cec5SDimitry Andric if (!TAAParsed) 13270b57cec5SDimitry Andric TAA = S->getTypeAndAttributes(); 13280b57cec5SDimitry Andric 13290b57cec5SDimitry Andric // Okay, now that we got the section, verify that the TAA & StubSize agree. 13300b57cec5SDimitry Andric // If the user declared multiple globals with different section flags, we need 13310b57cec5SDimitry Andric // to reject it here. 13320b57cec5SDimitry Andric if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 13330b57cec5SDimitry Andric // If invalid, report the error with report_fatal_error. 13340b57cec5SDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 13350b57cec5SDimitry Andric "' section type or attributes does not match previous" 13360b57cec5SDimitry Andric " section specifier"); 13370b57cec5SDimitry Andric } 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andric return S; 13400b57cec5SDimitry Andric } 13410b57cec5SDimitry Andric 13420b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 13430b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 13440b57cec5SDimitry Andric checkMachOComdat(GO); 13450b57cec5SDimitry Andric 13460b57cec5SDimitry Andric // Handle thread local data. 13470b57cec5SDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 13480b57cec5SDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 13490b57cec5SDimitry Andric 13500b57cec5SDimitry Andric if (Kind.isText()) 13510b57cec5SDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection; 13520b57cec5SDimitry Andric 13530b57cec5SDimitry Andric // If this is weak/linkonce, put this in a coalescable section, either in text 13540b57cec5SDimitry Andric // or data depending on if it is writable. 13550b57cec5SDimitry Andric if (GO->isWeakForLinker()) { 13560b57cec5SDimitry Andric if (Kind.isReadOnly()) 13570b57cec5SDimitry Andric return ConstTextCoalSection; 13580b57cec5SDimitry Andric if (Kind.isReadOnlyWithRel()) 13590b57cec5SDimitry Andric return ConstDataCoalSection; 13600b57cec5SDimitry Andric return DataCoalSection; 13610b57cec5SDimitry Andric } 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andric // FIXME: Alignment check should be handled by section classifier. 13640b57cec5SDimitry Andric if (Kind.isMergeable1ByteCString() && 13655ffd83dbSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlign( 13665ffd83dbSDimitry Andric cast<GlobalVariable>(GO)) < Align(32)) 13670b57cec5SDimitry Andric return CStringSection; 13680b57cec5SDimitry Andric 13690b57cec5SDimitry Andric // Do not put 16-bit arrays in the UString section if they have an 13700b57cec5SDimitry Andric // externally visible label, this runs into issues with certain linker 13710b57cec5SDimitry Andric // versions. 13720b57cec5SDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() && 13735ffd83dbSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlign( 13745ffd83dbSDimitry Andric cast<GlobalVariable>(GO)) < Align(32)) 13750b57cec5SDimitry Andric return UStringSection; 13760b57cec5SDimitry Andric 13770b57cec5SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 13780b57cec5SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 13790b57cec5SDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) { 13800b57cec5SDimitry Andric if (Kind.isMergeableConst4()) 13810b57cec5SDimitry Andric return FourByteConstantSection; 13820b57cec5SDimitry Andric if (Kind.isMergeableConst8()) 13830b57cec5SDimitry Andric return EightByteConstantSection; 13840b57cec5SDimitry Andric if (Kind.isMergeableConst16()) 13850b57cec5SDimitry Andric return SixteenByteConstantSection; 13860b57cec5SDimitry Andric } 13870b57cec5SDimitry Andric 13880b57cec5SDimitry Andric // Otherwise, if it is readonly, but not something we can specially optimize, 13890b57cec5SDimitry Andric // just drop it in .const. 13900b57cec5SDimitry Andric if (Kind.isReadOnly()) 13910b57cec5SDimitry Andric return ReadOnlySection; 13920b57cec5SDimitry Andric 13930b57cec5SDimitry Andric // If this is marked const, put it into a const section. But if the dynamic 13940b57cec5SDimitry Andric // linker needs to write to it, put it in the data segment. 13950b57cec5SDimitry Andric if (Kind.isReadOnlyWithRel()) 13960b57cec5SDimitry Andric return ConstDataSection; 13970b57cec5SDimitry Andric 13980b57cec5SDimitry Andric // Put zero initialized globals with strong external linkage in the 13990b57cec5SDimitry Andric // DATA, __common section with the .zerofill directive. 14000b57cec5SDimitry Andric if (Kind.isBSSExtern()) 14010b57cec5SDimitry Andric return DataCommonSection; 14020b57cec5SDimitry Andric 14030b57cec5SDimitry Andric // Put zero initialized globals with local linkage in __DATA,__bss directive 14040b57cec5SDimitry Andric // with the .zerofill directive (aka .lcomm). 14050b57cec5SDimitry Andric if (Kind.isBSSLocal()) 14060b57cec5SDimitry Andric return DataBSSSection; 14070b57cec5SDimitry Andric 14080b57cec5SDimitry Andric // Otherwise, just drop the variable in the normal data section. 14090b57cec5SDimitry Andric return DataSection; 14100b57cec5SDimitry Andric } 14110b57cec5SDimitry Andric 14120b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 14130b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 14145ffd83dbSDimitry Andric Align &Alignment) const { 14150b57cec5SDimitry Andric // If this constant requires a relocation, we have to put it in the data 14160b57cec5SDimitry Andric // segment, not in the text segment. 14170b57cec5SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 14180b57cec5SDimitry Andric return ConstDataSection; 14190b57cec5SDimitry Andric 14200b57cec5SDimitry Andric if (Kind.isMergeableConst4()) 14210b57cec5SDimitry Andric return FourByteConstantSection; 14220b57cec5SDimitry Andric if (Kind.isMergeableConst8()) 14230b57cec5SDimitry Andric return EightByteConstantSection; 14240b57cec5SDimitry Andric if (Kind.isMergeableConst16()) 14250b57cec5SDimitry Andric return SixteenByteConstantSection; 14260b57cec5SDimitry Andric return ReadOnlySection; // .const 14270b57cec5SDimitry Andric } 14280b57cec5SDimitry Andric 1429fe013be4SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForCommandLines() const { 1430fe013be4SDimitry Andric return getContext().getMachOSection("__TEXT", "__command_line", 0, 1431fe013be4SDimitry Andric SectionKind::getReadOnly()); 1432fe013be4SDimitry Andric } 1433fe013be4SDimitry Andric 14340b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 14350b57cec5SDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 14360b57cec5SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 14370b57cec5SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 14380b57cec5SDimitry Andric 14390b57cec5SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 14400b57cec5SDimitry Andric MachineModuleInfoMachO &MachOMMI = 14410b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 14420b57cec5SDimitry Andric 14430b57cec5SDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 14440b57cec5SDimitry Andric 14450b57cec5SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 14460b57cec5SDimitry Andric // gets emitted by the asmprinter. 14470b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 14480b57cec5SDimitry Andric if (!StubSym.getPointer()) { 14490b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 14500b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 14510b57cec5SDimitry Andric } 14520b57cec5SDimitry Andric 14530b57cec5SDimitry Andric return TargetLoweringObjectFile:: 14540b57cec5SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 14550b57cec5SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 14560b57cec5SDimitry Andric } 14570b57cec5SDimitry Andric 14580b57cec5SDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 14590b57cec5SDimitry Andric MMI, Streamer); 14600b57cec5SDimitry Andric } 14610b57cec5SDimitry Andric 14620b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 14630b57cec5SDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 14640b57cec5SDimitry Andric MachineModuleInfo *MMI) const { 14650b57cec5SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 14660b57cec5SDimitry Andric MachineModuleInfoMachO &MachOMMI = 14670b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 14680b57cec5SDimitry Andric 14690b57cec5SDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 14700b57cec5SDimitry Andric 14710b57cec5SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 14720b57cec5SDimitry Andric // gets emitted by the asmprinter. 14730b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 14740b57cec5SDimitry Andric if (!StubSym.getPointer()) { 14750b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 14760b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 14770b57cec5SDimitry Andric } 14780b57cec5SDimitry Andric 14790b57cec5SDimitry Andric return SSym; 14800b57cec5SDimitry Andric } 14810b57cec5SDimitry Andric 14820b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 14838bcb0991SDimitry Andric const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, 14848bcb0991SDimitry Andric int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { 14850b57cec5SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 14860b57cec5SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 14870b57cec5SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 14880b57cec5SDimitry Andric // computation of deltas to final external symbols. Example: 14890b57cec5SDimitry Andric // 14900b57cec5SDimitry Andric // _extgotequiv: 14910b57cec5SDimitry Andric // .long _extfoo 14920b57cec5SDimitry Andric // 14930b57cec5SDimitry Andric // _delta: 14940b57cec5SDimitry Andric // .long _extgotequiv-_delta 14950b57cec5SDimitry Andric // 14960b57cec5SDimitry Andric // is transformed to: 14970b57cec5SDimitry Andric // 14980b57cec5SDimitry Andric // _delta: 14990b57cec5SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 15000b57cec5SDimitry Andric // 15010b57cec5SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 15020b57cec5SDimitry Andric // L_extfoo$non_lazy_ptr: 15030b57cec5SDimitry Andric // .indirect_symbol _extfoo 15040b57cec5SDimitry Andric // .long 0 15050b57cec5SDimitry Andric // 15060b57cec5SDimitry Andric // The indirect symbol table (and sections of non_lazy_symbol_pointers type) 15070b57cec5SDimitry Andric // may point to both local (same translation unit) and global (other 15080b57cec5SDimitry Andric // translation units) symbols. Example: 15090b57cec5SDimitry Andric // 15100b57cec5SDimitry Andric // .section __DATA,__pointers,non_lazy_symbol_pointers 15110b57cec5SDimitry Andric // L1: 15120b57cec5SDimitry Andric // .indirect_symbol _myGlobal 15130b57cec5SDimitry Andric // .long 0 15140b57cec5SDimitry Andric // L2: 15150b57cec5SDimitry Andric // .indirect_symbol _myLocal 15160b57cec5SDimitry Andric // .long _myLocal 15170b57cec5SDimitry Andric // 15180b57cec5SDimitry Andric // If the symbol is local, instead of the symbol's index, the assembler 15190b57cec5SDimitry Andric // places the constant INDIRECT_SYMBOL_LOCAL into the indirect symbol table. 15200b57cec5SDimitry Andric // Then the linker will notice the constant in the table and will look at the 15210b57cec5SDimitry Andric // content of the symbol. 15220b57cec5SDimitry Andric MachineModuleInfoMachO &MachOMMI = 15230b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 15240b57cec5SDimitry Andric MCContext &Ctx = getContext(); 15250b57cec5SDimitry Andric 15260b57cec5SDimitry Andric // The offset must consider the original displacement from the base symbol 15270b57cec5SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 15280b57cec5SDimitry Andric Offset = -MV.getConstant(); 15290b57cec5SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 15300b57cec5SDimitry Andric 15310b57cec5SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 15320b57cec5SDimitry Andric // non_lazy_ptr stubs. 15330b57cec5SDimitry Andric SmallString<128> Name; 15340b57cec5SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 15350b57cec5SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 15360b57cec5SDimitry Andric Name += Sym->getName(); 15370b57cec5SDimitry Andric Name += Suffix; 15380b57cec5SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 15390b57cec5SDimitry Andric 15400b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 15418bcb0991SDimitry Andric 15428bcb0991SDimitry Andric if (!StubSym.getPointer()) 15430b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym), 15448bcb0991SDimitry Andric !GV->hasLocalLinkage()); 15450b57cec5SDimitry Andric 15460b57cec5SDimitry Andric const MCExpr *BSymExpr = 15470b57cec5SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 15480b57cec5SDimitry Andric const MCExpr *LHS = 15490b57cec5SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 15500b57cec5SDimitry Andric 15510b57cec5SDimitry Andric if (!Offset) 15520b57cec5SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 15530b57cec5SDimitry Andric 15540b57cec5SDimitry Andric const MCExpr *RHS = 15550b57cec5SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 15560b57cec5SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 15570b57cec5SDimitry Andric } 15580b57cec5SDimitry Andric 15590b57cec5SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 15600b57cec5SDimitry Andric const MCSection &Section) { 15610b57cec5SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section)) 15620b57cec5SDimitry Andric return true; 15630b57cec5SDimitry Andric 1564fe6060f1SDimitry Andric // FIXME: we should be able to use private labels for sections that can't be 1565fe6060f1SDimitry Andric // dead-stripped (there's no issue with blocking atomization there), but `ld 1566fe6060f1SDimitry Andric // -r` sometimes drops the no_dead_strip attribute from sections so for safety 1567fe6060f1SDimitry Andric // we don't allow it. 15680b57cec5SDimitry Andric return false; 15690b57cec5SDimitry Andric } 15700b57cec5SDimitry Andric 15710b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 15720b57cec5SDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 15730b57cec5SDimitry Andric const TargetMachine &TM) const { 15740b57cec5SDimitry Andric bool CannotUsePrivateLabel = true; 1575349cc55cSDimitry Andric if (auto *GO = GV->getAliaseeObject()) { 15760b57cec5SDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); 15770b57cec5SDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); 15780b57cec5SDimitry Andric CannotUsePrivateLabel = 15790b57cec5SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 15800b57cec5SDimitry Andric } 15810b57cec5SDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 15820b57cec5SDimitry Andric } 15830b57cec5SDimitry Andric 15840b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 15850b57cec5SDimitry Andric // COFF 15860b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 15870b57cec5SDimitry Andric 15880b57cec5SDimitry Andric static unsigned 15890b57cec5SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 15900b57cec5SDimitry Andric unsigned Flags = 0; 15910b57cec5SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 15920b57cec5SDimitry Andric 15930b57cec5SDimitry Andric if (K.isMetadata()) 15940b57cec5SDimitry Andric Flags |= 15950b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_DISCARDABLE; 159681ad6265SDimitry Andric else if (K.isExclude()) 159781ad6265SDimitry Andric Flags |= 159881ad6265SDimitry Andric COFF::IMAGE_SCN_LNK_REMOVE | COFF::IMAGE_SCN_MEM_DISCARDABLE; 15990b57cec5SDimitry Andric else if (K.isText()) 16000b57cec5SDimitry Andric Flags |= 16010b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_EXECUTE | 16020b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 16030b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 16040b57cec5SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 16050b57cec5SDimitry Andric else if (K.isBSS()) 16060b57cec5SDimitry Andric Flags |= 16070b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 16080b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 16090b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 16100b57cec5SDimitry Andric else if (K.isThreadLocal()) 16110b57cec5SDimitry Andric Flags |= 16120b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 16130b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 16140b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 16150b57cec5SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 16160b57cec5SDimitry Andric Flags |= 16170b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 16180b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ; 16190b57cec5SDimitry Andric else if (K.isWriteable()) 16200b57cec5SDimitry Andric Flags |= 16210b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 16220b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 16230b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 16240b57cec5SDimitry Andric 16250b57cec5SDimitry Andric return Flags; 16260b57cec5SDimitry Andric } 16270b57cec5SDimitry Andric 16280b57cec5SDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 16290b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 16300b57cec5SDimitry Andric assert(C && "expected GV to have a Comdat!"); 16310b57cec5SDimitry Andric 16320b57cec5SDimitry Andric StringRef ComdatGVName = C->getName(); 16330b57cec5SDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 16340b57cec5SDimitry Andric if (!ComdatGV) 16350b57cec5SDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 16360b57cec5SDimitry Andric "' does not exist."); 16370b57cec5SDimitry Andric 16380b57cec5SDimitry Andric if (ComdatGV->getComdat() != C) 16390b57cec5SDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 16400b57cec5SDimitry Andric "' is not a key for its COMDAT."); 16410b57cec5SDimitry Andric 16420b57cec5SDimitry Andric return ComdatGV; 16430b57cec5SDimitry Andric } 16440b57cec5SDimitry Andric 16450b57cec5SDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 16460b57cec5SDimitry Andric if (const Comdat *C = GV->getComdat()) { 16470b57cec5SDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 16480b57cec5SDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 1649349cc55cSDimitry Andric ComdatKey = GA->getAliaseeObject(); 16500b57cec5SDimitry Andric if (ComdatKey == GV) { 16510b57cec5SDimitry Andric switch (C->getSelectionKind()) { 16520b57cec5SDimitry Andric case Comdat::Any: 16530b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 16540b57cec5SDimitry Andric case Comdat::ExactMatch: 16550b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 16560b57cec5SDimitry Andric case Comdat::Largest: 16570b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 1658fe6060f1SDimitry Andric case Comdat::NoDeduplicate: 16590b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 16600b57cec5SDimitry Andric case Comdat::SameSize: 16610b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 16620b57cec5SDimitry Andric } 16630b57cec5SDimitry Andric } else { 16640b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 16650b57cec5SDimitry Andric } 16660b57cec5SDimitry Andric } 16670b57cec5SDimitry Andric return 0; 16680b57cec5SDimitry Andric } 16690b57cec5SDimitry Andric 16700b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 16710b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 16720b57cec5SDimitry Andric int Selection = 0; 16730b57cec5SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 16740b57cec5SDimitry Andric StringRef Name = GO->getSection(); 16750b57cec5SDimitry Andric StringRef COMDATSymName = ""; 16760b57cec5SDimitry Andric if (GO->hasComdat()) { 16770b57cec5SDimitry Andric Selection = getSelectionForCOFF(GO); 16780b57cec5SDimitry Andric const GlobalValue *ComdatGV; 16790b57cec5SDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 16800b57cec5SDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 16810b57cec5SDimitry Andric else 16820b57cec5SDimitry Andric ComdatGV = GO; 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 16850b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 16860b57cec5SDimitry Andric COMDATSymName = Sym->getName(); 16870b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 16880b57cec5SDimitry Andric } else { 16890b57cec5SDimitry Andric Selection = 0; 16900b57cec5SDimitry Andric } 16910b57cec5SDimitry Andric } 16920b57cec5SDimitry Andric 16930b57cec5SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 16940b57cec5SDimitry Andric Selection); 16950b57cec5SDimitry Andric } 16960b57cec5SDimitry Andric 16970b57cec5SDimitry Andric static StringRef getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 16980b57cec5SDimitry Andric if (Kind.isText()) 16990b57cec5SDimitry Andric return ".text"; 17000b57cec5SDimitry Andric if (Kind.isBSS()) 17010b57cec5SDimitry Andric return ".bss"; 17020b57cec5SDimitry Andric if (Kind.isThreadLocal()) 17030b57cec5SDimitry Andric return ".tls$"; 17040b57cec5SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 17050b57cec5SDimitry Andric return ".rdata"; 17060b57cec5SDimitry Andric return ".data"; 17070b57cec5SDimitry Andric } 17080b57cec5SDimitry Andric 17090b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 17100b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 17110b57cec5SDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 17120b57cec5SDimitry Andric // uniqued section specifically for it. 17130b57cec5SDimitry Andric bool EmitUniquedSection; 17140b57cec5SDimitry Andric if (Kind.isText()) 17150b57cec5SDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 17160b57cec5SDimitry Andric else 17170b57cec5SDimitry Andric EmitUniquedSection = TM.getDataSections(); 17180b57cec5SDimitry Andric 17190b57cec5SDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) { 17200b57cec5SDimitry Andric SmallString<256> Name = getCOFFSectionNameForUniqueGlobal(Kind); 17210b57cec5SDimitry Andric 17220b57cec5SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 17230b57cec5SDimitry Andric 17240b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 17250b57cec5SDimitry Andric int Selection = getSelectionForCOFF(GO); 17260b57cec5SDimitry Andric if (!Selection) 17270b57cec5SDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 17280b57cec5SDimitry Andric const GlobalValue *ComdatGV; 17290b57cec5SDimitry Andric if (GO->hasComdat()) 17300b57cec5SDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 17310b57cec5SDimitry Andric else 17320b57cec5SDimitry Andric ComdatGV = GO; 17330b57cec5SDimitry Andric 17340b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 17350b57cec5SDimitry Andric if (EmitUniquedSection) 17360b57cec5SDimitry Andric UniqueID = NextUniqueID++; 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 17390b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 17400b57cec5SDimitry Andric StringRef COMDATSymName = Sym->getName(); 17410b57cec5SDimitry Andric 1742e8d8bef9SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) 1743bdd1243dSDimitry Andric if (std::optional<StringRef> Prefix = F->getSectionPrefix()) 1744e8d8bef9SDimitry Andric raw_svector_ostream(Name) << '$' << *Prefix; 1745e8d8bef9SDimitry Andric 17460b57cec5SDimitry Andric // Append "$symbol" to the section name *before* IR-level mangling is 17470b57cec5SDimitry Andric // applied when targetting mingw. This is what GCC does, and the ld.bfd 17480b57cec5SDimitry Andric // COFF linker will not properly handle comdats otherwise. 1749fe6060f1SDimitry Andric if (getContext().getTargetTriple().isWindowsGNUEnvironment()) 17500b57cec5SDimitry Andric raw_svector_ostream(Name) << '$' << ComdatGV->getName(); 17510b57cec5SDimitry Andric 17520b57cec5SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, 17530b57cec5SDimitry Andric COMDATSymName, Selection, UniqueID); 17540b57cec5SDimitry Andric } else { 17550b57cec5SDimitry Andric SmallString<256> TmpData; 17560b57cec5SDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); 17570b57cec5SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, 17580b57cec5SDimitry Andric Selection, UniqueID); 17590b57cec5SDimitry Andric } 17600b57cec5SDimitry Andric } 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andric if (Kind.isText()) 17630b57cec5SDimitry Andric return TextSection; 17640b57cec5SDimitry Andric 17650b57cec5SDimitry Andric if (Kind.isThreadLocal()) 17660b57cec5SDimitry Andric return TLSDataSection; 17670b57cec5SDimitry Andric 17680b57cec5SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 17690b57cec5SDimitry Andric return ReadOnlySection; 17700b57cec5SDimitry Andric 17710b57cec5SDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 17720b57cec5SDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 17730b57cec5SDimitry Andric // entry but not a section. 17740b57cec5SDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 17750b57cec5SDimitry Andric return BSSSection; 17760b57cec5SDimitry Andric 17770b57cec5SDimitry Andric return DataSection; 17780b57cec5SDimitry Andric } 17790b57cec5SDimitry Andric 17800b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 17810b57cec5SDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 17820b57cec5SDimitry Andric const TargetMachine &TM) const { 17830b57cec5SDimitry Andric bool CannotUsePrivateLabel = false; 17840b57cec5SDimitry Andric if (GV->hasPrivateLinkage() && 17850b57cec5SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 17860b57cec5SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 17870b57cec5SDimitry Andric CannotUsePrivateLabel = true; 17880b57cec5SDimitry Andric 17890b57cec5SDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 17900b57cec5SDimitry Andric } 17910b57cec5SDimitry Andric 17920b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 17930b57cec5SDimitry Andric const Function &F, const TargetMachine &TM) const { 17940b57cec5SDimitry Andric // If the function can be removed, produce a unique section so that 17950b57cec5SDimitry Andric // the table doesn't prevent the removal. 17960b57cec5SDimitry Andric const Comdat *C = F.getComdat(); 17970b57cec5SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 17980b57cec5SDimitry Andric if (!EmitUniqueSection) 17990b57cec5SDimitry Andric return ReadOnlySection; 18000b57cec5SDimitry Andric 18010b57cec5SDimitry Andric // FIXME: we should produce a symbol for F instead. 18020b57cec5SDimitry Andric if (F.hasPrivateLinkage()) 18030b57cec5SDimitry Andric return ReadOnlySection; 18040b57cec5SDimitry Andric 18050b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(&F); 18060b57cec5SDimitry Andric StringRef COMDATSymName = Sym->getName(); 18070b57cec5SDimitry Andric 18080b57cec5SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 18090b57cec5SDimitry Andric StringRef SecName = getCOFFSectionNameForUniqueGlobal(Kind); 18100b57cec5SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 18110b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 18120b57cec5SDimitry Andric unsigned UniqueID = NextUniqueID++; 18130b57cec5SDimitry Andric 18140b57cec5SDimitry Andric return getContext().getCOFFSection( 18150b57cec5SDimitry Andric SecName, Characteristics, Kind, COMDATSymName, 18160b57cec5SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 18170b57cec5SDimitry Andric } 18180b57cec5SDimitry Andric 1819fe013be4SDimitry Andric bool TargetLoweringObjectFileCOFF::shouldPutJumpTableInFunctionSection( 1820fe013be4SDimitry Andric bool UsesLabelDifference, const Function &F) const { 1821fe013be4SDimitry Andric if (TM->getTargetTriple().getArch() == Triple::x86_64) { 1822fe013be4SDimitry Andric if (!JumpTableInFunctionSection) { 1823fe013be4SDimitry Andric // We can always create relative relocations, so use another section 1824fe013be4SDimitry Andric // that can be marked non-executable. 1825fe013be4SDimitry Andric return false; 1826fe013be4SDimitry Andric } 1827fe013be4SDimitry Andric } 1828fe013be4SDimitry Andric return TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( 1829fe013be4SDimitry Andric UsesLabelDifference, F); 1830fe013be4SDimitry Andric } 1831fe013be4SDimitry Andric 18320b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, 18330b57cec5SDimitry Andric Module &M) const { 1834e8d8bef9SDimitry Andric emitLinkerDirectives(Streamer, M); 1835e8d8bef9SDimitry Andric 1836e8d8bef9SDimitry Andric unsigned Version = 0; 1837e8d8bef9SDimitry Andric unsigned Flags = 0; 1838e8d8bef9SDimitry Andric StringRef Section; 1839e8d8bef9SDimitry Andric 1840e8d8bef9SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 1841e8d8bef9SDimitry Andric if (!Section.empty()) { 1842e8d8bef9SDimitry Andric auto &C = getContext(); 1843e8d8bef9SDimitry Andric auto *S = C.getCOFFSection(Section, 1844e8d8bef9SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1845e8d8bef9SDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1846e8d8bef9SDimitry Andric SectionKind::getReadOnly()); 184781ad6265SDimitry Andric Streamer.switchSection(S); 1848e8d8bef9SDimitry Andric Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 1849e8d8bef9SDimitry Andric Streamer.emitInt32(Version); 1850e8d8bef9SDimitry Andric Streamer.emitInt32(Flags); 185181ad6265SDimitry Andric Streamer.addBlankLine(); 1852e8d8bef9SDimitry Andric } 1853e8d8bef9SDimitry Andric 1854e8d8bef9SDimitry Andric emitCGProfileMetadata(Streamer, M); 1855e8d8bef9SDimitry Andric } 1856e8d8bef9SDimitry Andric 1857e8d8bef9SDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerDirectives( 1858e8d8bef9SDimitry Andric MCStreamer &Streamer, Module &M) const { 18590b57cec5SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 18600b57cec5SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 18610b57cec5SDimitry Andric // spec, this section is a space-separated string containing flags for 18620b57cec5SDimitry Andric // linker. 18630b57cec5SDimitry Andric MCSection *Sec = getDrectveSection(); 186481ad6265SDimitry Andric Streamer.switchSection(Sec); 1865480093f4SDimitry Andric for (const auto *Option : LinkerOptions->operands()) { 18660b57cec5SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 18670b57cec5SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 18680b57cec5SDimitry Andric std::string Directive(" "); 18695ffd83dbSDimitry Andric Directive.append(std::string(cast<MDString>(Piece)->getString())); 18705ffd83dbSDimitry Andric Streamer.emitBytes(Directive); 18710b57cec5SDimitry Andric } 18720b57cec5SDimitry Andric } 18730b57cec5SDimitry Andric } 18740b57cec5SDimitry Andric 1875e8d8bef9SDimitry Andric // Emit /EXPORT: flags for each exported global as necessary. 1876e8d8bef9SDimitry Andric std::string Flags; 1877e8d8bef9SDimitry Andric for (const GlobalValue &GV : M.global_values()) { 1878e8d8bef9SDimitry Andric raw_string_ostream OS(Flags); 1879fe6060f1SDimitry Andric emitLinkerFlagsForGlobalCOFF(OS, &GV, getContext().getTargetTriple(), 1880fe6060f1SDimitry Andric getMangler()); 1881e8d8bef9SDimitry Andric OS.flush(); 1882e8d8bef9SDimitry Andric if (!Flags.empty()) { 188381ad6265SDimitry Andric Streamer.switchSection(getDrectveSection()); 1884e8d8bef9SDimitry Andric Streamer.emitBytes(Flags); 1885e8d8bef9SDimitry Andric } 1886e8d8bef9SDimitry Andric Flags.clear(); 1887e8d8bef9SDimitry Andric } 18880b57cec5SDimitry Andric 1889e8d8bef9SDimitry Andric // Emit /INCLUDE: flags for each used global as necessary. 1890e8d8bef9SDimitry Andric if (const auto *LU = M.getNamedGlobal("llvm.used")) { 1891e8d8bef9SDimitry Andric assert(LU->hasInitializer() && "expected llvm.used to have an initializer"); 1892e8d8bef9SDimitry Andric assert(isa<ArrayType>(LU->getValueType()) && 1893e8d8bef9SDimitry Andric "expected llvm.used to be an array type"); 1894e8d8bef9SDimitry Andric if (const auto *A = cast<ConstantArray>(LU->getInitializer())) { 1895e8d8bef9SDimitry Andric for (const Value *Op : A->operands()) { 1896e8d8bef9SDimitry Andric const auto *GV = cast<GlobalValue>(Op->stripPointerCasts()); 1897e8d8bef9SDimitry Andric // Global symbols with internal or private linkage are not visible to 1898e8d8bef9SDimitry Andric // the linker, and thus would cause an error when the linker tried to 1899e8d8bef9SDimitry Andric // preserve the symbol due to the `/include:` directive. 1900e8d8bef9SDimitry Andric if (GV->hasLocalLinkage()) 1901e8d8bef9SDimitry Andric continue; 19020b57cec5SDimitry Andric 1903e8d8bef9SDimitry Andric raw_string_ostream OS(Flags); 1904fe6060f1SDimitry Andric emitLinkerFlagsForUsedCOFF(OS, GV, getContext().getTargetTriple(), 1905fe6060f1SDimitry Andric getMangler()); 1906e8d8bef9SDimitry Andric OS.flush(); 1907e8d8bef9SDimitry Andric 1908e8d8bef9SDimitry Andric if (!Flags.empty()) { 190981ad6265SDimitry Andric Streamer.switchSection(getDrectveSection()); 1910e8d8bef9SDimitry Andric Streamer.emitBytes(Flags); 1911e8d8bef9SDimitry Andric } 1912e8d8bef9SDimitry Andric Flags.clear(); 1913e8d8bef9SDimitry Andric } 1914e8d8bef9SDimitry Andric } 1915e8d8bef9SDimitry Andric } 19160b57cec5SDimitry Andric } 19170b57cec5SDimitry Andric 19180b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, 19190b57cec5SDimitry Andric const TargetMachine &TM) { 19200b57cec5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 1921e8d8bef9SDimitry Andric this->TM = &TM; 19220b57cec5SDimitry Andric const Triple &T = TM.getTargetTriple(); 19230b57cec5SDimitry Andric if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 19240b57cec5SDimitry Andric StaticCtorSection = 19250b57cec5SDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 19260b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ, 19270b57cec5SDimitry Andric SectionKind::getReadOnly()); 19280b57cec5SDimitry Andric StaticDtorSection = 19290b57cec5SDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 19300b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ, 19310b57cec5SDimitry Andric SectionKind::getReadOnly()); 19320b57cec5SDimitry Andric } else { 19330b57cec5SDimitry Andric StaticCtorSection = Ctx.getCOFFSection( 19340b57cec5SDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 19350b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 19360b57cec5SDimitry Andric SectionKind::getData()); 19370b57cec5SDimitry Andric StaticDtorSection = Ctx.getCOFFSection( 19380b57cec5SDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 19390b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 19400b57cec5SDimitry Andric SectionKind::getData()); 19410b57cec5SDimitry Andric } 19420b57cec5SDimitry Andric } 19430b57cec5SDimitry Andric 19440b57cec5SDimitry Andric static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx, 19450b57cec5SDimitry Andric const Triple &T, bool IsCtor, 19460b57cec5SDimitry Andric unsigned Priority, 19470b57cec5SDimitry Andric const MCSymbol *KeySym, 19480b57cec5SDimitry Andric MCSectionCOFF *Default) { 19490b57cec5SDimitry Andric if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 19500b57cec5SDimitry Andric // If the priority is the default, use .CRT$XCU, possibly associative. 19510b57cec5SDimitry Andric if (Priority == 65535) 19520b57cec5SDimitry Andric return Ctx.getAssociativeCOFFSection(Default, KeySym, 0); 19530b57cec5SDimitry Andric 19540b57cec5SDimitry Andric // Otherwise, we need to compute a new section name. Low priorities should 19550b57cec5SDimitry Andric // run earlier. The linker will sort sections ASCII-betically, and we need a 19560b57cec5SDimitry Andric // string that sorts between .CRT$XCA and .CRT$XCU. In the general case, we 19570b57cec5SDimitry Andric // make a name like ".CRT$XCT12345", since that runs before .CRT$XCU. Really 19580b57cec5SDimitry Andric // low priorities need to sort before 'L', since the CRT uses that 1959bdd1243dSDimitry Andric // internally, so we use ".CRT$XCA00001" for them. We have a contract with 1960bdd1243dSDimitry Andric // the frontend that "init_seg(compiler)" corresponds to priority 200 and 1961bdd1243dSDimitry Andric // "init_seg(lib)" corresponds to priority 400, and those respectively use 1962bdd1243dSDimitry Andric // 'C' and 'L' without the priority suffix. Priorities between 200 and 400 1963bdd1243dSDimitry Andric // use 'C' with the priority as a suffix. 19640b57cec5SDimitry Andric SmallString<24> Name; 1965bdd1243dSDimitry Andric char LastLetter = 'T'; 1966bdd1243dSDimitry Andric bool AddPrioritySuffix = Priority != 200 && Priority != 400; 1967bdd1243dSDimitry Andric if (Priority < 200) 1968bdd1243dSDimitry Andric LastLetter = 'A'; 1969bdd1243dSDimitry Andric else if (Priority < 400) 1970bdd1243dSDimitry Andric LastLetter = 'C'; 1971bdd1243dSDimitry Andric else if (Priority == 400) 1972bdd1243dSDimitry Andric LastLetter = 'L'; 19730b57cec5SDimitry Andric raw_svector_ostream OS(Name); 1974bdd1243dSDimitry Andric OS << ".CRT$X" << (IsCtor ? "C" : "T") << LastLetter; 1975bdd1243dSDimitry Andric if (AddPrioritySuffix) 1976bdd1243dSDimitry Andric OS << format("%05u", Priority); 19770b57cec5SDimitry Andric MCSectionCOFF *Sec = Ctx.getCOFFSection( 19780b57cec5SDimitry Andric Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, 19790b57cec5SDimitry Andric SectionKind::getReadOnly()); 19800b57cec5SDimitry Andric return Ctx.getAssociativeCOFFSection(Sec, KeySym, 0); 19810b57cec5SDimitry Andric } 19820b57cec5SDimitry Andric 19830b57cec5SDimitry Andric std::string Name = IsCtor ? ".ctors" : ".dtors"; 19840b57cec5SDimitry Andric if (Priority != 65535) 19850b57cec5SDimitry Andric raw_string_ostream(Name) << format(".%05u", 65535 - Priority); 19860b57cec5SDimitry Andric 19870b57cec5SDimitry Andric return Ctx.getAssociativeCOFFSection( 19880b57cec5SDimitry Andric Ctx.getCOFFSection(Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 19890b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 19900b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE, 19910b57cec5SDimitry Andric SectionKind::getData()), 19920b57cec5SDimitry Andric KeySym, 0); 19930b57cec5SDimitry Andric } 19940b57cec5SDimitry Andric 19950b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 19960b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 1997fe6060f1SDimitry Andric return getCOFFStaticStructorSection( 1998fe6060f1SDimitry Andric getContext(), getContext().getTargetTriple(), true, Priority, KeySym, 19990b57cec5SDimitry Andric cast<MCSectionCOFF>(StaticCtorSection)); 20000b57cec5SDimitry Andric } 20010b57cec5SDimitry Andric 20020b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 20030b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 2004fe6060f1SDimitry Andric return getCOFFStaticStructorSection( 2005fe6060f1SDimitry Andric getContext(), getContext().getTargetTriple(), false, Priority, KeySym, 20060b57cec5SDimitry Andric cast<MCSectionCOFF>(StaticDtorSection)); 20070b57cec5SDimitry Andric } 20080b57cec5SDimitry Andric 20090b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( 20100b57cec5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 20110b57cec5SDimitry Andric const TargetMachine &TM) const { 20120b57cec5SDimitry Andric const Triple &T = TM.getTargetTriple(); 20130b57cec5SDimitry Andric if (T.isOSCygMing()) 20140b57cec5SDimitry Andric return nullptr; 20150b57cec5SDimitry Andric 20160b57cec5SDimitry Andric // Our symbols should exist in address space zero, cowardly no-op if 20170b57cec5SDimitry Andric // otherwise. 20180b57cec5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 20190b57cec5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0) 20200b57cec5SDimitry Andric return nullptr; 20210b57cec5SDimitry Andric 20220b57cec5SDimitry Andric // Both ptrtoint instructions must wrap global objects: 20230b57cec5SDimitry Andric // - Only global variables are eligible for image relative relocations. 20240b57cec5SDimitry Andric // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable. 20250b57cec5SDimitry Andric // We expect __ImageBase to be a global variable without a section, externally 20260b57cec5SDimitry Andric // defined. 20270b57cec5SDimitry Andric // 20280b57cec5SDimitry Andric // It should look something like this: @__ImageBase = external constant i8 20290b57cec5SDimitry Andric if (!isa<GlobalObject>(LHS) || !isa<GlobalVariable>(RHS) || 20300b57cec5SDimitry Andric LHS->isThreadLocal() || RHS->isThreadLocal() || 20310b57cec5SDimitry Andric RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() || 20320b57cec5SDimitry Andric cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection()) 20330b57cec5SDimitry Andric return nullptr; 20340b57cec5SDimitry Andric 20350b57cec5SDimitry Andric return MCSymbolRefExpr::create(TM.getSymbol(LHS), 20360b57cec5SDimitry Andric MCSymbolRefExpr::VK_COFF_IMGREL32, 20370b57cec5SDimitry Andric getContext()); 20380b57cec5SDimitry Andric } 20390b57cec5SDimitry Andric 20400b57cec5SDimitry Andric static std::string APIntToHexString(const APInt &AI) { 20410b57cec5SDimitry Andric unsigned Width = (AI.getBitWidth() / 8) * 2; 2042fe6060f1SDimitry Andric std::string HexString = toString(AI, 16, /*Signed=*/false); 20435ffd83dbSDimitry Andric llvm::transform(HexString, HexString.begin(), tolower); 20440b57cec5SDimitry Andric unsigned Size = HexString.size(); 20450b57cec5SDimitry Andric assert(Width >= Size && "hex string is too large!"); 20460b57cec5SDimitry Andric HexString.insert(HexString.begin(), Width - Size, '0'); 20470b57cec5SDimitry Andric 20480b57cec5SDimitry Andric return HexString; 20490b57cec5SDimitry Andric } 20500b57cec5SDimitry Andric 20510b57cec5SDimitry Andric static std::string scalarConstantToHexString(const Constant *C) { 20520b57cec5SDimitry Andric Type *Ty = C->getType(); 20530b57cec5SDimitry Andric if (isa<UndefValue>(C)) { 2054349cc55cSDimitry Andric return APIntToHexString(APInt::getZero(Ty->getPrimitiveSizeInBits())); 20550b57cec5SDimitry Andric } else if (const auto *CFP = dyn_cast<ConstantFP>(C)) { 20560b57cec5SDimitry Andric return APIntToHexString(CFP->getValueAPF().bitcastToAPInt()); 20570b57cec5SDimitry Andric } else if (const auto *CI = dyn_cast<ConstantInt>(C)) { 20580b57cec5SDimitry Andric return APIntToHexString(CI->getValue()); 20590b57cec5SDimitry Andric } else { 20600b57cec5SDimitry Andric unsigned NumElements; 20615ffd83dbSDimitry Andric if (auto *VTy = dyn_cast<VectorType>(Ty)) 20625ffd83dbSDimitry Andric NumElements = cast<FixedVectorType>(VTy)->getNumElements(); 20630b57cec5SDimitry Andric else 20640b57cec5SDimitry Andric NumElements = Ty->getArrayNumElements(); 20650b57cec5SDimitry Andric std::string HexString; 20660b57cec5SDimitry Andric for (int I = NumElements - 1, E = -1; I != E; --I) 20670b57cec5SDimitry Andric HexString += scalarConstantToHexString(C->getAggregateElement(I)); 20680b57cec5SDimitry Andric return HexString; 20690b57cec5SDimitry Andric } 20700b57cec5SDimitry Andric } 20710b57cec5SDimitry Andric 20720b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant( 20730b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 20745ffd83dbSDimitry Andric Align &Alignment) const { 20750b57cec5SDimitry Andric if (Kind.isMergeableConst() && C && 20760b57cec5SDimitry Andric getContext().getAsmInfo()->hasCOFFComdatConstants()) { 20770b57cec5SDimitry Andric // This creates comdat sections with the given symbol name, but unless 20780b57cec5SDimitry Andric // AsmPrinter::GetCPISymbol actually makes the symbol global, the symbol 20790b57cec5SDimitry Andric // will be created with a null storage class, which makes GNU binutils 20800b57cec5SDimitry Andric // error out. 20810b57cec5SDimitry Andric const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 20820b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 20830b57cec5SDimitry Andric COFF::IMAGE_SCN_LNK_COMDAT; 20840b57cec5SDimitry Andric std::string COMDATSymName; 20850b57cec5SDimitry Andric if (Kind.isMergeableConst4()) { 20865ffd83dbSDimitry Andric if (Alignment <= 4) { 20870b57cec5SDimitry Andric COMDATSymName = "__real@" + scalarConstantToHexString(C); 20885ffd83dbSDimitry Andric Alignment = Align(4); 20890b57cec5SDimitry Andric } 20900b57cec5SDimitry Andric } else if (Kind.isMergeableConst8()) { 20915ffd83dbSDimitry Andric if (Alignment <= 8) { 20920b57cec5SDimitry Andric COMDATSymName = "__real@" + scalarConstantToHexString(C); 20935ffd83dbSDimitry Andric Alignment = Align(8); 20940b57cec5SDimitry Andric } 20950b57cec5SDimitry Andric } else if (Kind.isMergeableConst16()) { 20960b57cec5SDimitry Andric // FIXME: These may not be appropriate for non-x86 architectures. 20975ffd83dbSDimitry Andric if (Alignment <= 16) { 20980b57cec5SDimitry Andric COMDATSymName = "__xmm@" + scalarConstantToHexString(C); 20995ffd83dbSDimitry Andric Alignment = Align(16); 21000b57cec5SDimitry Andric } 21010b57cec5SDimitry Andric } else if (Kind.isMergeableConst32()) { 21025ffd83dbSDimitry Andric if (Alignment <= 32) { 21030b57cec5SDimitry Andric COMDATSymName = "__ymm@" + scalarConstantToHexString(C); 21045ffd83dbSDimitry Andric Alignment = Align(32); 21050b57cec5SDimitry Andric } 21060b57cec5SDimitry Andric } 21070b57cec5SDimitry Andric 21080b57cec5SDimitry Andric if (!COMDATSymName.empty()) 21090b57cec5SDimitry Andric return getContext().getCOFFSection(".rdata", Characteristics, Kind, 21100b57cec5SDimitry Andric COMDATSymName, 21110b57cec5SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ANY); 21120b57cec5SDimitry Andric } 21130b57cec5SDimitry Andric 21145ffd83dbSDimitry Andric return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, 21155ffd83dbSDimitry Andric Alignment); 21160b57cec5SDimitry Andric } 21170b57cec5SDimitry Andric 21180b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 21190b57cec5SDimitry Andric // Wasm 21200b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 21210b57cec5SDimitry Andric 21220b57cec5SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) { 21230b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 21240b57cec5SDimitry Andric if (!C) 21250b57cec5SDimitry Andric return nullptr; 21260b57cec5SDimitry Andric 21270b57cec5SDimitry Andric if (C->getSelectionKind() != Comdat::Any) 21280b57cec5SDimitry Andric report_fatal_error("WebAssembly COMDATs only support " 21290b57cec5SDimitry Andric "SelectionKind::Any, '" + C->getName() + "' cannot be " 21300b57cec5SDimitry Andric "lowered."); 21310b57cec5SDimitry Andric 21320b57cec5SDimitry Andric return C; 21330b57cec5SDimitry Andric } 21340b57cec5SDimitry Andric 2135fe6060f1SDimitry Andric static unsigned getWasmSectionFlags(SectionKind K) { 2136fe6060f1SDimitry Andric unsigned Flags = 0; 2137fe6060f1SDimitry Andric 2138fe6060f1SDimitry Andric if (K.isThreadLocal()) 2139fe6060f1SDimitry Andric Flags |= wasm::WASM_SEG_FLAG_TLS; 2140fe6060f1SDimitry Andric 2141fe6060f1SDimitry Andric if (K.isMergeableCString()) 2142fe6060f1SDimitry Andric Flags |= wasm::WASM_SEG_FLAG_STRINGS; 2143fe6060f1SDimitry Andric 2144fe6060f1SDimitry Andric // TODO(sbc): Add suport for K.isMergeableConst() 2145fe6060f1SDimitry Andric 2146fe6060f1SDimitry Andric return Flags; 2147fe6060f1SDimitry Andric } 2148fe6060f1SDimitry Andric 21490b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( 21500b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 21510b57cec5SDimitry Andric // We don't support explict section names for functions in the wasm object 21520b57cec5SDimitry Andric // format. Each function has to be in its own unique section. 21530b57cec5SDimitry Andric if (isa<Function>(GO)) { 21540b57cec5SDimitry Andric return SelectSectionForGlobal(GO, Kind, TM); 21550b57cec5SDimitry Andric } 21560b57cec5SDimitry Andric 21570b57cec5SDimitry Andric StringRef Name = GO->getSection(); 21580b57cec5SDimitry Andric 21595ffd83dbSDimitry Andric // Certain data sections we treat as named custom sections rather than 21605ffd83dbSDimitry Andric // segments within the data section. 21615ffd83dbSDimitry Andric // This could be avoided if all data segements (the wasm sense) were 21625ffd83dbSDimitry Andric // represented as their own sections (in the llvm sense). 21635ffd83dbSDimitry Andric // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138 21645ffd83dbSDimitry Andric if (Name == ".llvmcmd" || Name == ".llvmbc") 21655ffd83dbSDimitry Andric Kind = SectionKind::getMetadata(); 21660b57cec5SDimitry Andric 21670b57cec5SDimitry Andric StringRef Group = ""; 21680b57cec5SDimitry Andric if (const Comdat *C = getWasmComdat(GO)) { 21690b57cec5SDimitry Andric Group = C->getName(); 21700b57cec5SDimitry Andric } 21710b57cec5SDimitry Andric 2172fe6060f1SDimitry Andric unsigned Flags = getWasmSectionFlags(Kind); 2173fe6060f1SDimitry Andric MCSectionWasm *Section = getContext().getWasmSection( 2174fe6060f1SDimitry Andric Name, Kind, Flags, Group, MCContext::GenericSectionID); 21750b57cec5SDimitry Andric 21760b57cec5SDimitry Andric return Section; 21770b57cec5SDimitry Andric } 21780b57cec5SDimitry Andric 21790b57cec5SDimitry Andric static MCSectionWasm *selectWasmSectionForGlobal( 21800b57cec5SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 21810b57cec5SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) { 21820b57cec5SDimitry Andric StringRef Group = ""; 21830b57cec5SDimitry Andric if (const Comdat *C = getWasmComdat(GO)) { 21840b57cec5SDimitry Andric Group = C->getName(); 21850b57cec5SDimitry Andric } 21860b57cec5SDimitry Andric 21870b57cec5SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 2188fe013be4SDimitry Andric SmallString<128> Name = getSectionPrefixForGlobal(Kind, /*IsLarge=*/false); 21890b57cec5SDimitry Andric 21900b57cec5SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 21910b57cec5SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 21920b57cec5SDimitry Andric if (OptionalPrefix) 2193e8d8bef9SDimitry Andric raw_svector_ostream(Name) << '.' << *OptionalPrefix; 21940b57cec5SDimitry Andric } 21950b57cec5SDimitry Andric 21960b57cec5SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 21970b57cec5SDimitry Andric Name.push_back('.'); 21980b57cec5SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 21990b57cec5SDimitry Andric } 22000b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 22010b57cec5SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 22020b57cec5SDimitry Andric UniqueID = *NextUniqueID; 22030b57cec5SDimitry Andric (*NextUniqueID)++; 22040b57cec5SDimitry Andric } 22050b57cec5SDimitry Andric 2206fe6060f1SDimitry Andric unsigned Flags = getWasmSectionFlags(Kind); 2207fe6060f1SDimitry Andric return Ctx.getWasmSection(Name, Kind, Flags, Group, UniqueID); 22080b57cec5SDimitry Andric } 22090b57cec5SDimitry Andric 22100b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( 22110b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 22120b57cec5SDimitry Andric 22130b57cec5SDimitry Andric if (Kind.isCommon()) 22140b57cec5SDimitry Andric report_fatal_error("mergable sections not supported yet on wasm"); 22150b57cec5SDimitry Andric 22160b57cec5SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 22170b57cec5SDimitry Andric // global value to a uniqued section specifically for it. 22180b57cec5SDimitry Andric bool EmitUniqueSection = false; 22190b57cec5SDimitry Andric if (Kind.isText()) 22200b57cec5SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 22210b57cec5SDimitry Andric else 22220b57cec5SDimitry Andric EmitUniqueSection = TM.getDataSections(); 22230b57cec5SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 22240b57cec5SDimitry Andric 22250b57cec5SDimitry Andric return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 22260b57cec5SDimitry Andric EmitUniqueSection, &NextUniqueID); 22270b57cec5SDimitry Andric } 22280b57cec5SDimitry Andric 22290b57cec5SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( 22300b57cec5SDimitry Andric bool UsesLabelDifference, const Function &F) const { 22310b57cec5SDimitry Andric // We can always create relative relocations, so use another section 22320b57cec5SDimitry Andric // that can be marked non-executable. 22330b57cec5SDimitry Andric return false; 22340b57cec5SDimitry Andric } 22350b57cec5SDimitry Andric 22360b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( 22370b57cec5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 22380b57cec5SDimitry Andric const TargetMachine &TM) const { 22390b57cec5SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 22400b57cec5SDimitry Andric // functions. 22410b57cec5SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 22420b57cec5SDimitry Andric return nullptr; 22430b57cec5SDimitry Andric 22444824e7fdSDimitry Andric // Basic correctness checks. 22450b57cec5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 22460b57cec5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 22470b57cec5SDimitry Andric RHS->isThreadLocal()) 22480b57cec5SDimitry Andric return nullptr; 22490b57cec5SDimitry Andric 22500b57cec5SDimitry Andric return MCBinaryExpr::createSub( 22510b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, 22520b57cec5SDimitry Andric getContext()), 22530b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 22540b57cec5SDimitry Andric } 22550b57cec5SDimitry Andric 22560b57cec5SDimitry Andric void TargetLoweringObjectFileWasm::InitializeWasm() { 22570b57cec5SDimitry Andric StaticCtorSection = 22580b57cec5SDimitry Andric getContext().getWasmSection(".init_array", SectionKind::getData()); 22590b57cec5SDimitry Andric 22600b57cec5SDimitry Andric // We don't use PersonalityEncoding and LSDAEncoding because we don't emit 22610b57cec5SDimitry Andric // .cfi directives. We use TTypeEncoding to encode typeinfo global variables. 22620b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 22630b57cec5SDimitry Andric } 22640b57cec5SDimitry Andric 22650b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticCtorSection( 22660b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 22670b57cec5SDimitry Andric return Priority == UINT16_MAX ? 22680b57cec5SDimitry Andric StaticCtorSection : 22690b57cec5SDimitry Andric getContext().getWasmSection(".init_array." + utostr(Priority), 22700b57cec5SDimitry Andric SectionKind::getData()); 22710b57cec5SDimitry Andric } 22720b57cec5SDimitry Andric 22730b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection( 22740b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 227581ad6265SDimitry Andric report_fatal_error("@llvm.global_dtors should have been lowered already"); 22760b57cec5SDimitry Andric } 22778bcb0991SDimitry Andric 22788bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 22798bcb0991SDimitry Andric // XCOFF 22808bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 2281e8d8bef9SDimitry Andric bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock( 2282e8d8bef9SDimitry Andric const MachineFunction *MF) { 2283e8d8bef9SDimitry Andric if (!MF->getLandingPads().empty()) 2284e8d8bef9SDimitry Andric return true; 2285e8d8bef9SDimitry Andric 2286e8d8bef9SDimitry Andric const Function &F = MF->getFunction(); 2287e8d8bef9SDimitry Andric if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry()) 2288e8d8bef9SDimitry Andric return false; 2289e8d8bef9SDimitry Andric 2290fe6060f1SDimitry Andric const GlobalValue *Per = 2291fe6060f1SDimitry Andric dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts()); 2292fe6060f1SDimitry Andric assert(Per && "Personality routine is not a GlobalValue type."); 2293e8d8bef9SDimitry Andric if (isNoOpWithoutInvoke(classifyEHPersonality(Per))) 2294e8d8bef9SDimitry Andric return false; 2295e8d8bef9SDimitry Andric 2296e8d8bef9SDimitry Andric return true; 2297e8d8bef9SDimitry Andric } 2298e8d8bef9SDimitry Andric 2299fe6060f1SDimitry Andric bool TargetLoweringObjectFileXCOFF::ShouldSetSSPCanaryBitInTB( 2300fe6060f1SDimitry Andric const MachineFunction *MF) { 2301fe6060f1SDimitry Andric const Function &F = MF->getFunction(); 2302fe6060f1SDimitry Andric if (!F.hasStackProtectorFnAttr()) 2303fe6060f1SDimitry Andric return false; 2304fe6060f1SDimitry Andric // FIXME: check presence of canary word 2305fe6060f1SDimitry Andric // There are cases that the stack protectors are not really inserted even if 2306fe6060f1SDimitry Andric // the attributes are on. 2307fe6060f1SDimitry Andric return true; 2308fe6060f1SDimitry Andric } 2309fe6060f1SDimitry Andric 2310e8d8bef9SDimitry Andric MCSymbol * 2311e8d8bef9SDimitry Andric TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) { 2312c9157d92SDimitry Andric MCSymbol *EHInfoSym = MF->getMMI().getContext().getOrCreateSymbol( 2313e8d8bef9SDimitry Andric "__ehinfo." + Twine(MF->getFunctionNumber())); 2314c9157d92SDimitry Andric cast<MCSymbolXCOFF>(EHInfoSym)->setEHInfo(); 2315c9157d92SDimitry Andric return EHInfoSym; 2316e8d8bef9SDimitry Andric } 2317e8d8bef9SDimitry Andric 23185ffd83dbSDimitry Andric MCSymbol * 23195ffd83dbSDimitry Andric TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV, 23205ffd83dbSDimitry Andric const TargetMachine &TM) const { 23215ffd83dbSDimitry Andric // We always use a qualname symbol for a GV that represents 23225ffd83dbSDimitry Andric // a declaration, a function descriptor, or a common symbol. 2323e8d8bef9SDimitry Andric // If a GV represents a GlobalVariable and -fdata-sections is enabled, we 2324e8d8bef9SDimitry Andric // also return a qualname so that a label symbol could be avoided. 23255ffd83dbSDimitry Andric // It is inherently ambiguous when the GO represents the address of a 23265ffd83dbSDimitry Andric // function, as the GO could either represent a function descriptor or a 23275ffd83dbSDimitry Andric // function entry point. We choose to always return a function descriptor 23285ffd83dbSDimitry Andric // here. 23295ffd83dbSDimitry Andric if (const GlobalObject *GO = dyn_cast<GlobalObject>(GV)) { 2330bdd1243dSDimitry Andric if (GO->isDeclarationForLinker()) 2331bdd1243dSDimitry Andric return cast<MCSectionXCOFF>(getSectionForExternalReference(GO, TM)) 2332bdd1243dSDimitry Andric ->getQualNameSymbol(); 2333bdd1243dSDimitry Andric 2334fe6060f1SDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) 2335fe6060f1SDimitry Andric if (GVar->hasAttribute("toc-data")) 2336fe6060f1SDimitry Andric return cast<MCSectionXCOFF>( 2337fe6060f1SDimitry Andric SectionForGlobal(GVar, SectionKind::getData(), TM)) 2338fe6060f1SDimitry Andric ->getQualNameSymbol(); 2339fe6060f1SDimitry Andric 23405ffd83dbSDimitry Andric SectionKind GOKind = getKindForGlobal(GO, TM); 23415ffd83dbSDimitry Andric if (GOKind.isText()) 23425ffd83dbSDimitry Andric return cast<MCSectionXCOFF>( 23435ffd83dbSDimitry Andric getSectionForFunctionDescriptor(cast<Function>(GO), TM)) 23445ffd83dbSDimitry Andric ->getQualNameSymbol(); 2345fe6060f1SDimitry Andric if ((TM.getDataSections() && !GO->hasSection()) || GO->hasCommonLinkage() || 2346fe6060f1SDimitry Andric GOKind.isBSSLocal() || GOKind.isThreadBSSLocal()) 23475ffd83dbSDimitry Andric return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM)) 23485ffd83dbSDimitry Andric ->getQualNameSymbol(); 23495ffd83dbSDimitry Andric } 23505ffd83dbSDimitry Andric 23515ffd83dbSDimitry Andric // For all other cases, fall back to getSymbol to return the unqualified name. 23525ffd83dbSDimitry Andric return nullptr; 23535ffd83dbSDimitry Andric } 23545ffd83dbSDimitry Andric 23558bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal( 23568bcb0991SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 2357e8d8bef9SDimitry Andric if (!GO->hasSection()) 2358e8d8bef9SDimitry Andric report_fatal_error("#pragma clang section is not yet supported"); 2359e8d8bef9SDimitry Andric 2360e8d8bef9SDimitry Andric StringRef SectionName = GO->getSection(); 2361fe6060f1SDimitry Andric 2362fe6060f1SDimitry Andric // Handle the XCOFF::TD case first, then deal with the rest. 2363fe6060f1SDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO)) 2364fe6060f1SDimitry Andric if (GVar->hasAttribute("toc-data")) 2365fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2366fe6060f1SDimitry Andric SectionName, Kind, 2367fe6060f1SDimitry Andric XCOFF::CsectProperties(/*MappingClass*/ XCOFF::XMC_TD, XCOFF::XTY_SD), 2368fe6060f1SDimitry Andric /* MultiSymbolsAllowed*/ true); 2369fe6060f1SDimitry Andric 2370e8d8bef9SDimitry Andric XCOFF::StorageMappingClass MappingClass; 2371e8d8bef9SDimitry Andric if (Kind.isText()) 2372e8d8bef9SDimitry Andric MappingClass = XCOFF::XMC_PR; 2373fe013be4SDimitry Andric else if (Kind.isData() || Kind.isBSS()) 2374e8d8bef9SDimitry Andric MappingClass = XCOFF::XMC_RW; 2375fe013be4SDimitry Andric else if (Kind.isReadOnlyWithRel()) 2376fe013be4SDimitry Andric MappingClass = 2377fe013be4SDimitry Andric TM.Options.XCOFFReadOnlyPointers ? XCOFF::XMC_RO : XCOFF::XMC_RW; 2378e8d8bef9SDimitry Andric else if (Kind.isReadOnly()) 2379e8d8bef9SDimitry Andric MappingClass = XCOFF::XMC_RO; 2380e8d8bef9SDimitry Andric else 2381e8d8bef9SDimitry Andric report_fatal_error("XCOFF other section types not yet implemented."); 2382e8d8bef9SDimitry Andric 2383fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2384fe6060f1SDimitry Andric SectionName, Kind, XCOFF::CsectProperties(MappingClass, XCOFF::XTY_SD), 2385fe6060f1SDimitry Andric /* MultiSymbolsAllowed*/ true); 23868bcb0991SDimitry Andric } 23878bcb0991SDimitry Andric 23885ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference( 23895ffd83dbSDimitry Andric const GlobalObject *GO, const TargetMachine &TM) const { 23905ffd83dbSDimitry Andric assert(GO->isDeclarationForLinker() && 23915ffd83dbSDimitry Andric "Tried to get ER section for a defined global."); 23925ffd83dbSDimitry Andric 23935ffd83dbSDimitry Andric SmallString<128> Name; 23945ffd83dbSDimitry Andric getNameWithPrefix(Name, GO, TM); 23955ffd83dbSDimitry Andric 2396fe6060f1SDimitry Andric XCOFF::StorageMappingClass SMC = 2397fe6060f1SDimitry Andric isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA; 2398fe6060f1SDimitry Andric if (GO->isThreadLocal()) 2399fe6060f1SDimitry Andric SMC = XCOFF::XMC_UL; 2400fe6060f1SDimitry Andric 2401bdd1243dSDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO)) 2402bdd1243dSDimitry Andric if (GVar->hasAttribute("toc-data")) 2403bdd1243dSDimitry Andric SMC = XCOFF::XMC_TD; 2404bdd1243dSDimitry Andric 24055ffd83dbSDimitry Andric // Externals go into a csect of type ER. 24065ffd83dbSDimitry Andric return getContext().getXCOFFSection( 2407fe6060f1SDimitry Andric Name, SectionKind::getMetadata(), 2408fe6060f1SDimitry Andric XCOFF::CsectProperties(SMC, XCOFF::XTY_ER)); 24095ffd83dbSDimitry Andric } 24105ffd83dbSDimitry Andric 24118bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal( 24128bcb0991SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 2413fe6060f1SDimitry Andric // Handle the XCOFF::TD case first, then deal with the rest. 2414fe6060f1SDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO)) 2415fe6060f1SDimitry Andric if (GVar->hasAttribute("toc-data")) { 24168bcb0991SDimitry Andric SmallString<128> Name; 24178bcb0991SDimitry Andric getNameWithPrefix(Name, GO, TM); 24188bcb0991SDimitry Andric return getContext().getXCOFFSection( 2419fe6060f1SDimitry Andric Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TD, XCOFF::XTY_SD), 2420fe6060f1SDimitry Andric /* MultiSymbolsAllowed*/ true); 2421fe6060f1SDimitry Andric } 2422fe6060f1SDimitry Andric 2423fe6060f1SDimitry Andric // Common symbols go into a csect with matching name which will get mapped 2424fe6060f1SDimitry Andric // into the .bss section. 2425fe6060f1SDimitry Andric // Zero-initialized local TLS symbols go into a csect with matching name which 2426fe6060f1SDimitry Andric // will get mapped into the .tbss section. 2427fe6060f1SDimitry Andric if (Kind.isBSSLocal() || GO->hasCommonLinkage() || Kind.isThreadBSSLocal()) { 2428fe6060f1SDimitry Andric SmallString<128> Name; 2429fe6060f1SDimitry Andric getNameWithPrefix(Name, GO, TM); 2430fe6060f1SDimitry Andric XCOFF::StorageMappingClass SMC = Kind.isBSSLocal() ? XCOFF::XMC_BS 2431fe6060f1SDimitry Andric : Kind.isCommon() ? XCOFF::XMC_RW 2432fe6060f1SDimitry Andric : XCOFF::XMC_UL; 2433fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2434fe6060f1SDimitry Andric Name, Kind, XCOFF::CsectProperties(SMC, XCOFF::XTY_CM)); 24358bcb0991SDimitry Andric } 24368bcb0991SDimitry Andric 2437e8d8bef9SDimitry Andric if (Kind.isText()) { 2438e8d8bef9SDimitry Andric if (TM.getFunctionSections()) { 2439e8d8bef9SDimitry Andric return cast<MCSymbolXCOFF>(getFunctionEntryPointSymbol(GO, TM)) 2440e8d8bef9SDimitry Andric ->getRepresentedCsect(); 2441e8d8bef9SDimitry Andric } 24428bcb0991SDimitry Andric return TextSection; 2443e8d8bef9SDimitry Andric } 24448bcb0991SDimitry Andric 2445fe013be4SDimitry Andric if (TM.Options.XCOFFReadOnlyPointers && Kind.isReadOnlyWithRel()) { 2446fe013be4SDimitry Andric if (!TM.getDataSections()) 2447fe013be4SDimitry Andric report_fatal_error( 2448fe013be4SDimitry Andric "ReadOnlyPointers is supported only if data sections is turned on"); 2449fe013be4SDimitry Andric 2450fe013be4SDimitry Andric SmallString<128> Name; 2451fe013be4SDimitry Andric getNameWithPrefix(Name, GO, TM); 2452fe013be4SDimitry Andric return getContext().getXCOFFSection( 2453fe013be4SDimitry Andric Name, SectionKind::getReadOnly(), 2454fe013be4SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD)); 2455fe013be4SDimitry Andric } 2456fe013be4SDimitry Andric 2457e8d8bef9SDimitry Andric // For BSS kind, zero initialized data must be emitted to the .data section 2458e8d8bef9SDimitry Andric // because external linkage control sections that get mapped to the .bss 2459e8d8bef9SDimitry Andric // section will be linked as tentative defintions, which is only appropriate 2460e8d8bef9SDimitry Andric // for SectionKind::Common. 2461e8d8bef9SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS()) { 2462e8d8bef9SDimitry Andric if (TM.getDataSections()) { 2463e8d8bef9SDimitry Andric SmallString<128> Name; 2464e8d8bef9SDimitry Andric getNameWithPrefix(Name, GO, TM); 2465fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2466fe6060f1SDimitry Andric Name, SectionKind::getData(), 2467fe6060f1SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD)); 2468e8d8bef9SDimitry Andric } 24698bcb0991SDimitry Andric return DataSection; 2470e8d8bef9SDimitry Andric } 24718bcb0991SDimitry Andric 2472e8d8bef9SDimitry Andric if (Kind.isReadOnly()) { 2473e8d8bef9SDimitry Andric if (TM.getDataSections()) { 2474e8d8bef9SDimitry Andric SmallString<128> Name; 2475e8d8bef9SDimitry Andric getNameWithPrefix(Name, GO, TM); 2476fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2477fe6060f1SDimitry Andric Name, SectionKind::getReadOnly(), 2478fe6060f1SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD)); 2479e8d8bef9SDimitry Andric } 2480480093f4SDimitry Andric return ReadOnlySection; 2481e8d8bef9SDimitry Andric } 2482480093f4SDimitry Andric 2483fe6060f1SDimitry Andric // External/weak TLS data and initialized local TLS data are not eligible 2484fe6060f1SDimitry Andric // to be put into common csect. If data sections are enabled, thread 2485fe6060f1SDimitry Andric // data are emitted into separate sections. Otherwise, thread data 2486fe6060f1SDimitry Andric // are emitted into the .tdata section. 2487fe6060f1SDimitry Andric if (Kind.isThreadLocal()) { 2488fe6060f1SDimitry Andric if (TM.getDataSections()) { 2489fe6060f1SDimitry Andric SmallString<128> Name; 2490fe6060f1SDimitry Andric getNameWithPrefix(Name, GO, TM); 2491fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2492fe6060f1SDimitry Andric Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TL, XCOFF::XTY_SD)); 2493fe6060f1SDimitry Andric } 2494fe6060f1SDimitry Andric return TLSDataSection; 2495fe6060f1SDimitry Andric } 2496fe6060f1SDimitry Andric 24978bcb0991SDimitry Andric report_fatal_error("XCOFF other section types not yet implemented."); 24988bcb0991SDimitry Andric } 24998bcb0991SDimitry Andric 2500480093f4SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForJumpTable( 2501480093f4SDimitry Andric const Function &F, const TargetMachine &TM) const { 2502480093f4SDimitry Andric assert (!F.getComdat() && "Comdat not supported on XCOFF."); 2503e8d8bef9SDimitry Andric 2504e8d8bef9SDimitry Andric if (!TM.getFunctionSections()) 2505480093f4SDimitry Andric return ReadOnlySection; 2506e8d8bef9SDimitry Andric 2507e8d8bef9SDimitry Andric // If the function can be removed, produce a unique section so that 2508e8d8bef9SDimitry Andric // the table doesn't prevent the removal. 2509e8d8bef9SDimitry Andric SmallString<128> NameStr(".rodata.jmp.."); 2510e8d8bef9SDimitry Andric getNameWithPrefix(NameStr, &F, TM); 2511fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2512fe6060f1SDimitry Andric NameStr, SectionKind::getReadOnly(), 2513fe6060f1SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD)); 2514480093f4SDimitry Andric } 2515480093f4SDimitry Andric 25168bcb0991SDimitry Andric bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection( 25178bcb0991SDimitry Andric bool UsesLabelDifference, const Function &F) const { 2518480093f4SDimitry Andric return false; 2519480093f4SDimitry Andric } 2520480093f4SDimitry Andric 2521480093f4SDimitry Andric /// Given a mergeable constant with the specified size and relocation 2522480093f4SDimitry Andric /// information, return a section that it should be placed in. 2523480093f4SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForConstant( 2524480093f4SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 25255ffd83dbSDimitry Andric Align &Alignment) const { 2526480093f4SDimitry Andric // TODO: Enable emiting constant pool to unique sections when we support it. 2527349cc55cSDimitry Andric if (Alignment > Align(16)) 2528349cc55cSDimitry Andric report_fatal_error("Alignments greater than 16 not yet supported."); 2529349cc55cSDimitry Andric 2530349cc55cSDimitry Andric if (Alignment == Align(8)) { 2531349cc55cSDimitry Andric assert(ReadOnly8Section && "Section should always be initialized."); 2532349cc55cSDimitry Andric return ReadOnly8Section; 2533349cc55cSDimitry Andric } 2534349cc55cSDimitry Andric 2535349cc55cSDimitry Andric if (Alignment == Align(16)) { 2536349cc55cSDimitry Andric assert(ReadOnly16Section && "Section should always be initialized."); 2537349cc55cSDimitry Andric return ReadOnly16Section; 2538349cc55cSDimitry Andric } 2539349cc55cSDimitry Andric 2540480093f4SDimitry Andric return ReadOnlySection; 25418bcb0991SDimitry Andric } 25428bcb0991SDimitry Andric 25438bcb0991SDimitry Andric void TargetLoweringObjectFileXCOFF::Initialize(MCContext &Ctx, 25448bcb0991SDimitry Andric const TargetMachine &TgtM) { 25458bcb0991SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TgtM); 2546e8d8bef9SDimitry Andric TTypeEncoding = 2547e8d8bef9SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel | 2548e8d8bef9SDimitry Andric (TgtM.getTargetTriple().isArch32Bit() ? dwarf::DW_EH_PE_sdata4 2549e8d8bef9SDimitry Andric : dwarf::DW_EH_PE_sdata8); 25508bcb0991SDimitry Andric PersonalityEncoding = 0; 25518bcb0991SDimitry Andric LSDAEncoding = 0; 2552e8d8bef9SDimitry Andric CallSiteEncoding = dwarf::DW_EH_PE_udata4; 2553bdd1243dSDimitry Andric 2554bdd1243dSDimitry Andric // AIX debug for thread local location is not ready. And for integrated as 2555bdd1243dSDimitry Andric // mode, the relocatable address for the thread local variable will cause 2556bdd1243dSDimitry Andric // linker error. So disable the location attribute generation for thread local 2557bdd1243dSDimitry Andric // variables for now. 2558bdd1243dSDimitry Andric // FIXME: when TLS debug on AIX is ready, remove this setting. 2559bdd1243dSDimitry Andric SupportDebugThreadLocalLocation = false; 25608bcb0991SDimitry Andric } 25618bcb0991SDimitry Andric 25628bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getStaticCtorSection( 25638bcb0991SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 2564e8d8bef9SDimitry Andric report_fatal_error("no static constructor section on AIX"); 25658bcb0991SDimitry Andric } 25668bcb0991SDimitry Andric 25678bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getStaticDtorSection( 25688bcb0991SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 2569e8d8bef9SDimitry Andric report_fatal_error("no static destructor section on AIX"); 25708bcb0991SDimitry Andric } 25718bcb0991SDimitry Andric 25728bcb0991SDimitry Andric const MCExpr *TargetLoweringObjectFileXCOFF::lowerRelativeReference( 25738bcb0991SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 25748bcb0991SDimitry Andric const TargetMachine &TM) const { 2575349cc55cSDimitry Andric /* Not implemented yet, but don't crash, return nullptr. */ 2576349cc55cSDimitry Andric return nullptr; 25778bcb0991SDimitry Andric } 25788bcb0991SDimitry Andric 2579e8d8bef9SDimitry Andric XCOFF::StorageClass 2580e8d8bef9SDimitry Andric TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) { 2581e8d8bef9SDimitry Andric assert(!isa<GlobalIFunc>(GV) && "GlobalIFunc is not supported on AIX."); 2582e8d8bef9SDimitry Andric 2583e8d8bef9SDimitry Andric switch (GV->getLinkage()) { 25848bcb0991SDimitry Andric case GlobalValue::InternalLinkage: 2585480093f4SDimitry Andric case GlobalValue::PrivateLinkage: 25868bcb0991SDimitry Andric return XCOFF::C_HIDEXT; 25878bcb0991SDimitry Andric case GlobalValue::ExternalLinkage: 25888bcb0991SDimitry Andric case GlobalValue::CommonLinkage: 25895ffd83dbSDimitry Andric case GlobalValue::AvailableExternallyLinkage: 25908bcb0991SDimitry Andric return XCOFF::C_EXT; 25918bcb0991SDimitry Andric case GlobalValue::ExternalWeakLinkage: 25925ffd83dbSDimitry Andric case GlobalValue::LinkOnceAnyLinkage: 25935ffd83dbSDimitry Andric case GlobalValue::LinkOnceODRLinkage: 25945ffd83dbSDimitry Andric case GlobalValue::WeakAnyLinkage: 25955ffd83dbSDimitry Andric case GlobalValue::WeakODRLinkage: 25968bcb0991SDimitry Andric return XCOFF::C_WEAKEXT; 25975ffd83dbSDimitry Andric case GlobalValue::AppendingLinkage: 25988bcb0991SDimitry Andric report_fatal_error( 25995ffd83dbSDimitry Andric "There is no mapping that implements AppendingLinkage for XCOFF."); 26008bcb0991SDimitry Andric } 26015ffd83dbSDimitry Andric llvm_unreachable("Unknown linkage type!"); 26025ffd83dbSDimitry Andric } 26035ffd83dbSDimitry Andric 26045ffd83dbSDimitry Andric MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol( 2605e8d8bef9SDimitry Andric const GlobalValue *Func, const TargetMachine &TM) const { 2606349cc55cSDimitry Andric assert((isa<Function>(Func) || 2607e8d8bef9SDimitry Andric (isa<GlobalAlias>(Func) && 2608349cc55cSDimitry Andric isa_and_nonnull<Function>( 2609349cc55cSDimitry Andric cast<GlobalAlias>(Func)->getAliaseeObject()))) && 2610e8d8bef9SDimitry Andric "Func must be a function or an alias which has a function as base " 2611e8d8bef9SDimitry Andric "object."); 2612e8d8bef9SDimitry Andric 26135ffd83dbSDimitry Andric SmallString<128> NameStr; 26145ffd83dbSDimitry Andric NameStr.push_back('.'); 2615e8d8bef9SDimitry Andric getNameWithPrefix(NameStr, Func, TM); 2616e8d8bef9SDimitry Andric 2617e8d8bef9SDimitry Andric // When -function-sections is enabled and explicit section is not specified, 2618e8d8bef9SDimitry Andric // it's not necessary to emit function entry point label any more. We will use 2619e8d8bef9SDimitry Andric // function entry point csect instead. And for function delcarations, the 2620e8d8bef9SDimitry Andric // undefined symbols gets treated as csect with XTY_ER property. 2621e8d8bef9SDimitry Andric if (((TM.getFunctionSections() && !Func->hasSection()) || 2622271697daSDimitry Andric Func->isDeclarationForLinker()) && 2623e8d8bef9SDimitry Andric isa<Function>(Func)) { 2624e8d8bef9SDimitry Andric return getContext() 2625fe6060f1SDimitry Andric .getXCOFFSection( 2626fe6060f1SDimitry Andric NameStr, SectionKind::getText(), 2627271697daSDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_PR, Func->isDeclarationForLinker() 2628fe6060f1SDimitry Andric ? XCOFF::XTY_ER 2629fe6060f1SDimitry Andric : XCOFF::XTY_SD)) 2630e8d8bef9SDimitry Andric ->getQualNameSymbol(); 2631e8d8bef9SDimitry Andric } 2632e8d8bef9SDimitry Andric 26335ffd83dbSDimitry Andric return getContext().getOrCreateSymbol(NameStr); 26345ffd83dbSDimitry Andric } 26355ffd83dbSDimitry Andric 26365ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForFunctionDescriptor( 26375ffd83dbSDimitry Andric const Function *F, const TargetMachine &TM) const { 26385ffd83dbSDimitry Andric SmallString<128> NameStr; 26395ffd83dbSDimitry Andric getNameWithPrefix(NameStr, F, TM); 2640fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2641fe6060f1SDimitry Andric NameStr, SectionKind::getData(), 2642fe6060f1SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_DS, XCOFF::XTY_SD)); 26435ffd83dbSDimitry Andric } 26445ffd83dbSDimitry Andric 26455ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry( 2646e8d8bef9SDimitry Andric const MCSymbol *Sym, const TargetMachine &TM) const { 2647e8d8bef9SDimitry Andric // Use TE storage-mapping class when large code model is enabled so that 2648c9157d92SDimitry Andric // the chance of needing -bbigtoc is decreased. Also, the toc-entry for 2649c9157d92SDimitry Andric // EH info is never referenced directly using instructions so it can be 2650c9157d92SDimitry Andric // allocated with TE storage-mapping class. 26515ffd83dbSDimitry Andric return getContext().getXCOFFSection( 2652fe6060f1SDimitry Andric cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(), SectionKind::getData(), 2653c9157d92SDimitry Andric XCOFF::CsectProperties((TM.getCodeModel() == CodeModel::Large || 2654c9157d92SDimitry Andric cast<MCSymbolXCOFF>(Sym)->isEHInfo()) 2655c9157d92SDimitry Andric ? XCOFF::XMC_TE 2656c9157d92SDimitry Andric : XCOFF::XMC_TC, 2657fe6060f1SDimitry Andric XCOFF::XTY_SD)); 2658fe6060f1SDimitry Andric } 2659fe6060f1SDimitry Andric 266081ad6265SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA( 266181ad6265SDimitry Andric const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { 266281ad6265SDimitry Andric auto *LSDA = cast<MCSectionXCOFF>(LSDASection); 266381ad6265SDimitry Andric if (TM.getFunctionSections()) { 266481ad6265SDimitry Andric // If option -ffunction-sections is on, append the function name to the 266581ad6265SDimitry Andric // name of the LSDA csect so that each function has its own LSDA csect. 266681ad6265SDimitry Andric // This helps the linker to garbage-collect EH info of unused functions. 266781ad6265SDimitry Andric SmallString<128> NameStr = LSDA->getName(); 266881ad6265SDimitry Andric raw_svector_ostream(NameStr) << '.' << F.getName(); 266981ad6265SDimitry Andric LSDA = getContext().getXCOFFSection(NameStr, LSDA->getKind(), 267081ad6265SDimitry Andric LSDA->getCsectProp()); 267181ad6265SDimitry Andric } 267281ad6265SDimitry Andric return LSDA; 267381ad6265SDimitry Andric } 2674fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 2675fe6060f1SDimitry Andric // GOFF 2676fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 267781ad6265SDimitry Andric TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default; 2678fe6060f1SDimitry Andric 2679fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( 2680fe6060f1SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 2681fe6060f1SDimitry Andric return SelectSectionForGlobal(GO, Kind, TM); 2682fe6060f1SDimitry Andric } 2683fe6060f1SDimitry Andric 2684*e710425bSDimitry Andric MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA( 2685*e710425bSDimitry Andric const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { 2686*e710425bSDimitry Andric std::string Name = ".gcc_exception_table." + F.getName().str(); 2687*e710425bSDimitry Andric return getContext().getGOFFSection(Name, SectionKind::getData(), nullptr, 2688*e710425bSDimitry Andric nullptr); 2689*e710425bSDimitry Andric } 2690*e710425bSDimitry Andric 2691fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( 2692fe6060f1SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 2693fe6060f1SDimitry Andric auto *Symbol = TM.getSymbol(GO); 2694fe6060f1SDimitry Andric if (Kind.isBSS()) 269581ad6265SDimitry Andric return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(), 269681ad6265SDimitry Andric nullptr, nullptr); 2697fe6060f1SDimitry Andric 2698fe6060f1SDimitry Andric return getContext().getObjectFileInfo()->getTextSection(); 26998bcb0991SDimitry Andric } 2700