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" 46*0fca6ea1SDimitry Andric #include "llvm/MC/MCAsmInfoDarwin.h" 470b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 480b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 490b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 500b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h" 51fe6060f1SDimitry Andric #include "llvm/MC/MCSectionGOFF.h" 520b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h" 530b57cec5SDimitry Andric #include "llvm/MC/MCSectionWasm.h" 548bcb0991SDimitry Andric #include "llvm/MC/MCSectionXCOFF.h" 550b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 560b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 570b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 580b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 590b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h" 600b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProf.h" 61bdd1243dSDimitry Andric #include "llvm/Support/Base64.h" 620b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 630b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 640b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 655ffd83dbSDimitry Andric #include "llvm/Support/Format.h" 660b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 670b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 6806c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 690b57cec5SDimitry Andric #include <cassert> 700b57cec5SDimitry Andric #include <string> 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric using namespace llvm; 730b57cec5SDimitry Andric using namespace dwarf; 740b57cec5SDimitry Andric 7506c3fb27SDimitry Andric static cl::opt<bool> JumpTableInFunctionSection( 7606c3fb27SDimitry Andric "jumptable-in-function-section", cl::Hidden, cl::init(false), 7706c3fb27SDimitry Andric cl::desc("Putting Jump Table in function section")); 7806c3fb27SDimitry Andric 790b57cec5SDimitry Andric static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, 800b57cec5SDimitry Andric StringRef &Section) { 810b57cec5SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; 820b57cec5SDimitry Andric M.getModuleFlagsMetadata(ModuleFlags); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric for (const auto &MFE: ModuleFlags) { 850b57cec5SDimitry Andric // Ignore flags with 'Require' behaviour. 860b57cec5SDimitry Andric if (MFE.Behavior == Module::Require) 870b57cec5SDimitry Andric continue; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric StringRef Key = MFE.Key->getString(); 900b57cec5SDimitry Andric if (Key == "Objective-C Image Info Version") { 910b57cec5SDimitry Andric Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 920b57cec5SDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 930b57cec5SDimitry Andric Key == "Objective-C GC Only" || 940b57cec5SDimitry Andric Key == "Objective-C Is Simulated" || 950b57cec5SDimitry Andric Key == "Objective-C Class Properties" || 960b57cec5SDimitry Andric Key == "Objective-C Image Swift Version") { 970b57cec5SDimitry Andric Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 980b57cec5SDimitry Andric } else if (Key == "Objective-C Image Info Section") { 990b57cec5SDimitry Andric Section = cast<MDString>(MFE.Val)->getString(); 1000b57cec5SDimitry Andric } 1015ffd83dbSDimitry Andric // Backend generates L_OBJC_IMAGE_INFO from Swift ABI version + major + minor + 1025ffd83dbSDimitry Andric // "Objective-C Garbage Collection". 1035ffd83dbSDimitry Andric else if (Key == "Swift ABI Version") { 1045ffd83dbSDimitry Andric Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 8; 1055ffd83dbSDimitry Andric } else if (Key == "Swift Major Version") { 1065ffd83dbSDimitry Andric Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 24; 1075ffd83dbSDimitry Andric } else if (Key == "Swift Minor Version") { 1085ffd83dbSDimitry Andric Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 16; 1095ffd83dbSDimitry Andric } 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1140b57cec5SDimitry Andric // ELF 1150b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1160b57cec5SDimitry Andric 11704eeddc0SDimitry Andric TargetLoweringObjectFileELF::TargetLoweringObjectFileELF() { 118e8d8bef9SDimitry Andric SupportDSOLocalEquivalentLowering = true; 119e8d8bef9SDimitry Andric } 120e8d8bef9SDimitry Andric 1210b57cec5SDimitry Andric void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, 1220b57cec5SDimitry Andric const TargetMachine &TgtM) { 1230b57cec5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TgtM); 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric CodeModel::Model CM = TgtM.getCodeModel(); 1265ffd83dbSDimitry Andric InitializeELF(TgtM.Options.UseInitArray); 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric switch (TgtM.getTargetTriple().getArch()) { 1290b57cec5SDimitry Andric case Triple::arm: 1300b57cec5SDimitry Andric case Triple::armeb: 1310b57cec5SDimitry Andric case Triple::thumb: 1320b57cec5SDimitry Andric case Triple::thumbeb: 1330b57cec5SDimitry Andric if (Ctx.getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM) 1340b57cec5SDimitry Andric break; 1350b57cec5SDimitry Andric // Fallthrough if not using EHABI 136bdd1243dSDimitry Andric [[fallthrough]]; 1370b57cec5SDimitry Andric case Triple::ppc: 138e8d8bef9SDimitry Andric case Triple::ppcle: 1390b57cec5SDimitry Andric case Triple::x86: 1400b57cec5SDimitry Andric PersonalityEncoding = isPositionIndependent() 1410b57cec5SDimitry Andric ? dwarf::DW_EH_PE_indirect | 1420b57cec5SDimitry Andric dwarf::DW_EH_PE_pcrel | 1430b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4 1440b57cec5SDimitry Andric : dwarf::DW_EH_PE_absptr; 1450b57cec5SDimitry Andric LSDAEncoding = isPositionIndependent() 1460b57cec5SDimitry Andric ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 1470b57cec5SDimitry Andric : dwarf::DW_EH_PE_absptr; 1480b57cec5SDimitry Andric TTypeEncoding = isPositionIndependent() 1490b57cec5SDimitry Andric ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 1500b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4 1510b57cec5SDimitry Andric : dwarf::DW_EH_PE_absptr; 1520b57cec5SDimitry Andric break; 1530b57cec5SDimitry Andric case Triple::x86_64: 1540b57cec5SDimitry Andric if (isPositionIndependent()) { 1550b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 1560b57cec5SDimitry Andric ((CM == CodeModel::Small || CM == CodeModel::Medium) 1570b57cec5SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); 1580b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | 1590b57cec5SDimitry Andric (CM == CodeModel::Small 1600b57cec5SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); 1610b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 1620b57cec5SDimitry Andric ((CM == CodeModel::Small || CM == CodeModel::Medium) 163fe6060f1SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); 1640b57cec5SDimitry Andric } else { 1650b57cec5SDimitry Andric PersonalityEncoding = 1660b57cec5SDimitry Andric (CM == CodeModel::Small || CM == CodeModel::Medium) 1670b57cec5SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; 1680b57cec5SDimitry Andric LSDAEncoding = (CM == CodeModel::Small) 1690b57cec5SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; 1700b57cec5SDimitry Andric TTypeEncoding = (CM == CodeModel::Small) 1710b57cec5SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric break; 1740b57cec5SDimitry Andric case Triple::hexagon: 1750b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 1760b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 1770b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 1780b57cec5SDimitry Andric if (isPositionIndependent()) { 1790b57cec5SDimitry Andric PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; 1800b57cec5SDimitry Andric LSDAEncoding |= dwarf::DW_EH_PE_pcrel; 1810b57cec5SDimitry Andric TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric break; 1840b57cec5SDimitry Andric case Triple::aarch64: 1850b57cec5SDimitry Andric case Triple::aarch64_be: 1868bcb0991SDimitry Andric case Triple::aarch64_32: 1870b57cec5SDimitry Andric // The small model guarantees static code/data size < 4GB, but not where it 1880b57cec5SDimitry Andric // will be in memory. Most of these could end up >2GB away so even a signed 1890b57cec5SDimitry Andric // pc-relative 32-bit address is insufficient, theoretically. 19006c3fb27SDimitry Andric // 19106c3fb27SDimitry Andric // Use DW_EH_PE_indirect even for -fno-pic to avoid copy relocations. 19206c3fb27SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | 19306c3fb27SDimitry Andric (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32 19406c3fb27SDimitry Andric ? dwarf::DW_EH_PE_sdata4 19506c3fb27SDimitry Andric : dwarf::DW_EH_PE_sdata8); 19606c3fb27SDimitry Andric PersonalityEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect; 19706c3fb27SDimitry Andric TTypeEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect; 1980b57cec5SDimitry Andric break; 1990b57cec5SDimitry Andric case Triple::lanai: 2000b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 2010b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 2020b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 2030b57cec5SDimitry Andric break; 2040b57cec5SDimitry Andric case Triple::mips: 2050b57cec5SDimitry Andric case Triple::mipsel: 2060b57cec5SDimitry Andric case Triple::mips64: 2070b57cec5SDimitry Andric case Triple::mips64el: 2080b57cec5SDimitry Andric // MIPS uses indirect pointer to refer personality functions and types, so 2090b57cec5SDimitry Andric // that the eh_frame section can be read-only. DW.ref.personality will be 2100b57cec5SDimitry Andric // generated for relocation. 2110b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect; 2120b57cec5SDimitry Andric // FIXME: The N64 ABI probably ought to use DW_EH_PE_sdata8 but we can't 2130b57cec5SDimitry Andric // identify N64 from just a triple. 2140b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2150b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric // FreeBSD must be explicit about the data size and using pcrel since it's 2180b57cec5SDimitry Andric // assembler/linker won't do the automatic conversion that the Linux tools 2190b57cec5SDimitry Andric // do. 220*0fca6ea1SDimitry Andric if (isPositionIndependent() || TgtM.getTargetTriple().isOSFreeBSD()) { 2210b57cec5SDimitry Andric PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2220b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric break; 2250b57cec5SDimitry Andric case Triple::ppc64: 2260b57cec5SDimitry Andric case Triple::ppc64le: 2270b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2280b57cec5SDimitry Andric dwarf::DW_EH_PE_udata8; 2290b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; 2300b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2310b57cec5SDimitry Andric dwarf::DW_EH_PE_udata8; 2320b57cec5SDimitry Andric break; 2330b57cec5SDimitry Andric case Triple::sparcel: 2340b57cec5SDimitry Andric case Triple::sparc: 2350b57cec5SDimitry Andric if (isPositionIndependent()) { 2360b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2370b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2380b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2390b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2400b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2410b57cec5SDimitry Andric } else { 2420b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 2430b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 2440b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric CallSiteEncoding = dwarf::DW_EH_PE_udata4; 2470b57cec5SDimitry Andric break; 2480b57cec5SDimitry Andric case Triple::riscv32: 2490b57cec5SDimitry Andric case Triple::riscv64: 2500b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2510b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2520b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2530b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2540b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2550b57cec5SDimitry Andric CallSiteEncoding = dwarf::DW_EH_PE_udata4; 2560b57cec5SDimitry Andric break; 2570b57cec5SDimitry Andric case Triple::sparcv9: 2580b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2590b57cec5SDimitry Andric if (isPositionIndependent()) { 2600b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2610b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2620b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2630b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2640b57cec5SDimitry Andric } else { 2650b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 2660b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric break; 2690b57cec5SDimitry Andric case Triple::systemz: 2700b57cec5SDimitry Andric // All currently-defined code models guarantee that 4-byte PC-relative 2710b57cec5SDimitry Andric // values will be in range. 2720b57cec5SDimitry Andric if (isPositionIndependent()) { 2730b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2740b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2750b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 2760b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 2770b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 2780b57cec5SDimitry Andric } else { 2790b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 2800b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 2810b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric break; 284bdd1243dSDimitry Andric case Triple::loongarch32: 285bdd1243dSDimitry Andric case Triple::loongarch64: 286bdd1243dSDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 287bdd1243dSDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 288bdd1243dSDimitry Andric dwarf::DW_EH_PE_sdata4; 289bdd1243dSDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 290bdd1243dSDimitry Andric dwarf::DW_EH_PE_sdata4; 291bdd1243dSDimitry Andric break; 2920b57cec5SDimitry Andric default: 2930b57cec5SDimitry Andric break; 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric 297fe6060f1SDimitry Andric void TargetLoweringObjectFileELF::getModuleMetadata(Module &M) { 298fe6060f1SDimitry Andric SmallVector<GlobalValue *, 4> Vec; 299fe6060f1SDimitry Andric collectUsedGlobalVariables(M, Vec, false); 300fe6060f1SDimitry Andric for (GlobalValue *GV : Vec) 301fe6060f1SDimitry Andric if (auto *GO = dyn_cast<GlobalObject>(GV)) 302fe6060f1SDimitry Andric Used.insert(GO); 303fe6060f1SDimitry Andric } 304fe6060f1SDimitry Andric 3050b57cec5SDimitry Andric void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, 3060b57cec5SDimitry Andric Module &M) const { 3070b57cec5SDimitry Andric auto &C = getContext(); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 3100b57cec5SDimitry Andric auto *S = C.getELFSection(".linker-options", ELF::SHT_LLVM_LINKER_OPTIONS, 3110b57cec5SDimitry Andric ELF::SHF_EXCLUDE); 3120b57cec5SDimitry Andric 31381ad6265SDimitry Andric Streamer.switchSection(S); 3140b57cec5SDimitry Andric 315480093f4SDimitry Andric for (const auto *Operand : LinkerOptions->operands()) { 3160b57cec5SDimitry Andric if (cast<MDNode>(Operand)->getNumOperands() != 2) 3170b57cec5SDimitry Andric report_fatal_error("invalid llvm.linker.options"); 3180b57cec5SDimitry Andric for (const auto &Option : cast<MDNode>(Operand)->operands()) { 3195ffd83dbSDimitry Andric Streamer.emitBytes(cast<MDString>(Option)->getString()); 3205ffd83dbSDimitry Andric Streamer.emitInt8(0); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) { 3260b57cec5SDimitry Andric auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES, 327fe6060f1SDimitry Andric ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); 3280b57cec5SDimitry Andric 32981ad6265SDimitry Andric Streamer.switchSection(S); 3300b57cec5SDimitry Andric 331480093f4SDimitry Andric for (const auto *Operand : DependentLibraries->operands()) { 3325ffd83dbSDimitry Andric Streamer.emitBytes( 3330b57cec5SDimitry Andric cast<MDString>(cast<MDNode>(Operand)->getOperand(0))->getString()); 3345ffd83dbSDimitry Andric Streamer.emitInt8(0); 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 338e8d8bef9SDimitry Andric if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) { 339e8d8bef9SDimitry Andric // Emit a descriptor for every function including functions that have an 340e8d8bef9SDimitry Andric // available external linkage. We may not want this for imported functions 341e8d8bef9SDimitry Andric // that has code in another thinLTO module but we don't have a good way to 342e8d8bef9SDimitry Andric // tell them apart from inline functions defined in header files. Therefore 343e8d8bef9SDimitry Andric // we put each descriptor in a separate comdat section and rely on the 344e8d8bef9SDimitry Andric // linker to deduplicate. 345e8d8bef9SDimitry Andric for (const auto *Operand : FuncInfo->operands()) { 346e8d8bef9SDimitry Andric const auto *MD = cast<MDNode>(Operand); 347e8d8bef9SDimitry Andric auto *GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0)); 348e8d8bef9SDimitry Andric auto *Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1)); 349e8d8bef9SDimitry Andric auto *Name = cast<MDString>(MD->getOperand(2)); 350e8d8bef9SDimitry Andric auto *S = C.getObjectFileInfo()->getPseudoProbeDescSection( 351e8d8bef9SDimitry Andric TM->getFunctionSections() ? Name->getString() : StringRef()); 352e8d8bef9SDimitry Andric 35381ad6265SDimitry Andric Streamer.switchSection(S); 354e8d8bef9SDimitry Andric Streamer.emitInt64(GUID->getZExtValue()); 355e8d8bef9SDimitry Andric Streamer.emitInt64(Hash->getZExtValue()); 356e8d8bef9SDimitry Andric Streamer.emitULEB128IntValue(Name->getString().size()); 357e8d8bef9SDimitry Andric Streamer.emitBytes(Name->getString()); 358e8d8bef9SDimitry Andric } 359e8d8bef9SDimitry Andric } 360e8d8bef9SDimitry Andric 361bdd1243dSDimitry Andric if (NamedMDNode *LLVMStats = M.getNamedMetadata("llvm.stats")) { 362bdd1243dSDimitry Andric // Emit the metadata for llvm statistics into .llvm_stats section, which is 363bdd1243dSDimitry Andric // formatted as a list of key/value pair, the value is base64 encoded. 364bdd1243dSDimitry Andric auto *S = C.getObjectFileInfo()->getLLVMStatsSection(); 365bdd1243dSDimitry Andric Streamer.switchSection(S); 366bdd1243dSDimitry Andric for (const auto *Operand : LLVMStats->operands()) { 367bdd1243dSDimitry Andric const auto *MD = cast<MDNode>(Operand); 368bdd1243dSDimitry Andric assert(MD->getNumOperands() % 2 == 0 && 369bdd1243dSDimitry Andric ("Operand num should be even for a list of key/value pair")); 370bdd1243dSDimitry Andric for (size_t I = 0; I < MD->getNumOperands(); I += 2) { 371bdd1243dSDimitry Andric // Encode the key string size. 372bdd1243dSDimitry Andric auto *Key = cast<MDString>(MD->getOperand(I)); 373bdd1243dSDimitry Andric Streamer.emitULEB128IntValue(Key->getString().size()); 374bdd1243dSDimitry Andric Streamer.emitBytes(Key->getString()); 375bdd1243dSDimitry Andric // Encode the value into a Base64 string. 376bdd1243dSDimitry Andric std::string Value = encodeBase64( 377bdd1243dSDimitry Andric Twine(mdconst::dyn_extract<ConstantInt>(MD->getOperand(I + 1)) 378bdd1243dSDimitry Andric ->getZExtValue()) 379bdd1243dSDimitry Andric .str()); 380bdd1243dSDimitry Andric Streamer.emitULEB128IntValue(Value.size()); 381bdd1243dSDimitry Andric Streamer.emitBytes(Value); 382bdd1243dSDimitry Andric } 383bdd1243dSDimitry Andric } 384bdd1243dSDimitry Andric } 385bdd1243dSDimitry Andric 3860b57cec5SDimitry Andric unsigned Version = 0; 3870b57cec5SDimitry Andric unsigned Flags = 0; 3880b57cec5SDimitry Andric StringRef Section; 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 3910b57cec5SDimitry Andric if (!Section.empty()) { 3920b57cec5SDimitry Andric auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 39381ad6265SDimitry Andric Streamer.switchSection(S); 3945ffd83dbSDimitry Andric Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 3955ffd83dbSDimitry Andric Streamer.emitInt32(Version); 3965ffd83dbSDimitry Andric Streamer.emitInt32(Flags); 39781ad6265SDimitry Andric Streamer.addBlankLine(); 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric 400e8d8bef9SDimitry Andric emitCGProfileMetadata(Streamer, M); 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( 4040b57cec5SDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 4050b57cec5SDimitry Andric MachineModuleInfo *MMI) const { 4060b57cec5SDimitry Andric unsigned Encoding = getPersonalityEncoding(); 4070b57cec5SDimitry Andric if ((Encoding & 0x80) == DW_EH_PE_indirect) 4080b57cec5SDimitry Andric return getContext().getOrCreateSymbol(StringRef("DW.ref.") + 4090b57cec5SDimitry Andric TM.getSymbol(GV)->getName()); 4100b57cec5SDimitry Andric if ((Encoding & 0x70) == DW_EH_PE_absptr) 4110b57cec5SDimitry Andric return TM.getSymbol(GV); 4120b57cec5SDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!"); 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue( 4160b57cec5SDimitry Andric MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { 4170b57cec5SDimitry Andric SmallString<64> NameData("DW.ref."); 4180b57cec5SDimitry Andric NameData += Sym->getName(); 4190b57cec5SDimitry Andric MCSymbolELF *Label = 4200b57cec5SDimitry Andric cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); 4215ffd83dbSDimitry Andric Streamer.emitSymbolAttribute(Label, MCSA_Hidden); 4225ffd83dbSDimitry Andric Streamer.emitSymbolAttribute(Label, MCSA_Weak); 4230b57cec5SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; 4240b57cec5SDimitry Andric MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), 4250b57cec5SDimitry Andric ELF::SHT_PROGBITS, Flags, 0); 4260b57cec5SDimitry Andric unsigned Size = DL.getPointerSize(); 42781ad6265SDimitry Andric Streamer.switchSection(Sec); 428bdd1243dSDimitry Andric Streamer.emitValueToAlignment(DL.getPointerABIAlignment(0)); 4295ffd83dbSDimitry Andric Streamer.emitSymbolAttribute(Label, MCSA_ELF_TypeObject); 4300b57cec5SDimitry Andric const MCExpr *E = MCConstantExpr::create(Size, getContext()); 4310b57cec5SDimitry Andric Streamer.emitELFSize(Label, E); 4325ffd83dbSDimitry Andric Streamer.emitLabel(Label); 4330b57cec5SDimitry Andric 4345ffd83dbSDimitry Andric Streamer.emitSymbolValue(Sym, Size); 4350b57cec5SDimitry Andric } 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( 4380b57cec5SDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 4390b57cec5SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 4400b57cec5SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 4410b57cec5SDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM); 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric // Add information about the stub reference to ELFMMI so that the stub 4460b57cec5SDimitry Andric // gets emitted by the asmprinter. 4470b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); 4480b57cec5SDimitry Andric if (!StubSym.getPointer()) { 4490b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 4500b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric return TargetLoweringObjectFile:: 4540b57cec5SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 4550b57cec5SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 4590b57cec5SDimitry Andric MMI, Streamer); 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) { 4630b57cec5SDimitry Andric // N.B.: The defaults used in here are not the same ones used in MC. 4640b57cec5SDimitry Andric // We follow gcc, MC follows gas. For example, given ".section .eh_frame", 4650b57cec5SDimitry Andric // both gas and MC will produce a section with no flags. Given 4660b57cec5SDimitry Andric // section(".eh_frame") gcc will produce: 4670b57cec5SDimitry Andric // 4680b57cec5SDimitry Andric // .section .eh_frame,"a",@progbits 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF, 4715ffd83dbSDimitry Andric /*AddSegmentInfo=*/false) || 4725ffd83dbSDimitry Andric Name == getInstrProfSectionName(IPSK_covfun, Triple::ELF, 473e8d8bef9SDimitry Andric /*AddSegmentInfo=*/false) || 4745f757f3fSDimitry Andric Name == getInstrProfSectionName(IPSK_covdata, Triple::ELF, 4755f757f3fSDimitry Andric /*AddSegmentInfo=*/false) || 4765f757f3fSDimitry Andric Name == getInstrProfSectionName(IPSK_covname, Triple::ELF, 4775f757f3fSDimitry Andric /*AddSegmentInfo=*/false) || 478e8d8bef9SDimitry Andric Name == ".llvmbc" || Name == ".llvmcmd") 4790b57cec5SDimitry Andric return SectionKind::getMetadata(); 4800b57cec5SDimitry Andric 481*0fca6ea1SDimitry Andric if (!Name.starts_with(".")) return K; 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric // Default implementation based on some magic section names. 4845f757f3fSDimitry Andric if (Name == ".bss" || Name.starts_with(".bss.") || 4855f757f3fSDimitry Andric Name.starts_with(".gnu.linkonce.b.") || 4865f757f3fSDimitry Andric Name.starts_with(".llvm.linkonce.b.") || Name == ".sbss" || 4875f757f3fSDimitry Andric Name.starts_with(".sbss.") || Name.starts_with(".gnu.linkonce.sb.") || 4885f757f3fSDimitry Andric Name.starts_with(".llvm.linkonce.sb.")) 4890b57cec5SDimitry Andric return SectionKind::getBSS(); 4900b57cec5SDimitry Andric 4915f757f3fSDimitry Andric if (Name == ".tdata" || Name.starts_with(".tdata.") || 4925f757f3fSDimitry Andric Name.starts_with(".gnu.linkonce.td.") || 4935f757f3fSDimitry Andric Name.starts_with(".llvm.linkonce.td.")) 4940b57cec5SDimitry Andric return SectionKind::getThreadData(); 4950b57cec5SDimitry Andric 4965f757f3fSDimitry Andric if (Name == ".tbss" || Name.starts_with(".tbss.") || 4975f757f3fSDimitry Andric Name.starts_with(".gnu.linkonce.tb.") || 4985f757f3fSDimitry Andric Name.starts_with(".llvm.linkonce.tb.")) 4990b57cec5SDimitry Andric return SectionKind::getThreadBSS(); 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric return K; 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric 50404eeddc0SDimitry Andric static bool hasPrefix(StringRef SectionName, StringRef Prefix) { 50504eeddc0SDimitry Andric return SectionName.consume_front(Prefix) && 50604eeddc0SDimitry Andric (SectionName.empty() || SectionName[0] == '.'); 50704eeddc0SDimitry Andric } 50804eeddc0SDimitry Andric 5090b57cec5SDimitry Andric static unsigned getELFSectionType(StringRef Name, SectionKind K) { 5100b57cec5SDimitry Andric // Use SHT_NOTE for section whose name starts with ".note" to allow 5110b57cec5SDimitry Andric // emitting ELF notes from C variable declaration. 5120b57cec5SDimitry Andric // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609 5135f757f3fSDimitry Andric if (Name.starts_with(".note")) 5140b57cec5SDimitry Andric return ELF::SHT_NOTE; 5150b57cec5SDimitry Andric 51604eeddc0SDimitry Andric if (hasPrefix(Name, ".init_array")) 5170b57cec5SDimitry Andric return ELF::SHT_INIT_ARRAY; 5180b57cec5SDimitry Andric 51904eeddc0SDimitry Andric if (hasPrefix(Name, ".fini_array")) 5200b57cec5SDimitry Andric return ELF::SHT_FINI_ARRAY; 5210b57cec5SDimitry Andric 52204eeddc0SDimitry Andric if (hasPrefix(Name, ".preinit_array")) 5230b57cec5SDimitry Andric return ELF::SHT_PREINIT_ARRAY; 5240b57cec5SDimitry Andric 525753f127fSDimitry Andric if (hasPrefix(Name, ".llvm.offloading")) 526753f127fSDimitry Andric return ELF::SHT_LLVM_OFFLOADING; 527*0fca6ea1SDimitry Andric if (Name == ".llvm.lto") 528*0fca6ea1SDimitry Andric return ELF::SHT_LLVM_LTO; 529753f127fSDimitry Andric 5300b57cec5SDimitry Andric if (K.isBSS() || K.isThreadBSS()) 5310b57cec5SDimitry Andric return ELF::SHT_NOBITS; 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric return ELF::SHT_PROGBITS; 5340b57cec5SDimitry Andric } 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) { 5370b57cec5SDimitry Andric unsigned Flags = 0; 5380b57cec5SDimitry Andric 53981ad6265SDimitry Andric if (!K.isMetadata() && !K.isExclude()) 5400b57cec5SDimitry Andric Flags |= ELF::SHF_ALLOC; 5410b57cec5SDimitry Andric 54281ad6265SDimitry Andric if (K.isExclude()) 54381ad6265SDimitry Andric Flags |= ELF::SHF_EXCLUDE; 54481ad6265SDimitry Andric 5450b57cec5SDimitry Andric if (K.isText()) 5460b57cec5SDimitry Andric Flags |= ELF::SHF_EXECINSTR; 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric if (K.isExecuteOnly()) 5490b57cec5SDimitry Andric Flags |= ELF::SHF_ARM_PURECODE; 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric if (K.isWriteable()) 5520b57cec5SDimitry Andric Flags |= ELF::SHF_WRITE; 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric if (K.isThreadLocal()) 5550b57cec5SDimitry Andric Flags |= ELF::SHF_TLS; 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric if (K.isMergeableCString() || K.isMergeableConst()) 5580b57cec5SDimitry Andric Flags |= ELF::SHF_MERGE; 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric if (K.isMergeableCString()) 5610b57cec5SDimitry Andric Flags |= ELF::SHF_STRINGS; 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric return Flags; 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) { 5670b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 5680b57cec5SDimitry Andric if (!C) 5690b57cec5SDimitry Andric return nullptr; 5700b57cec5SDimitry Andric 571fe6060f1SDimitry Andric if (C->getSelectionKind() != Comdat::Any && 572fe6060f1SDimitry Andric C->getSelectionKind() != Comdat::NoDeduplicate) 573fe6060f1SDimitry Andric report_fatal_error("ELF COMDATs only support SelectionKind::Any and " 574fe6060f1SDimitry Andric "SelectionKind::NoDeduplicate, '" + 5750b57cec5SDimitry Andric C->getName() + "' cannot be lowered."); 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric return C; 5780b57cec5SDimitry Andric } 5790b57cec5SDimitry Andric 5805ffd83dbSDimitry Andric static const MCSymbolELF *getLinkedToSymbol(const GlobalObject *GO, 5810b57cec5SDimitry Andric const TargetMachine &TM) { 5820b57cec5SDimitry Andric MDNode *MD = GO->getMetadata(LLVMContext::MD_associated); 5830b57cec5SDimitry Andric if (!MD) 5840b57cec5SDimitry Andric return nullptr; 5850b57cec5SDimitry Andric 58606c3fb27SDimitry Andric auto *VM = cast<ValueAsMetadata>(MD->getOperand(0).get()); 5878bcb0991SDimitry Andric auto *OtherGV = dyn_cast<GlobalValue>(VM->getValue()); 5888bcb0991SDimitry Andric return OtherGV ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGV)) : nullptr; 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric static unsigned getEntrySizeForKind(SectionKind Kind) { 5920b57cec5SDimitry Andric if (Kind.isMergeable1ByteCString()) 5930b57cec5SDimitry Andric return 1; 5940b57cec5SDimitry Andric else if (Kind.isMergeable2ByteCString()) 5950b57cec5SDimitry Andric return 2; 5960b57cec5SDimitry Andric else if (Kind.isMergeable4ByteCString()) 5970b57cec5SDimitry Andric return 4; 5980b57cec5SDimitry Andric else if (Kind.isMergeableConst4()) 5990b57cec5SDimitry Andric return 4; 6000b57cec5SDimitry Andric else if (Kind.isMergeableConst8()) 6010b57cec5SDimitry Andric return 8; 6020b57cec5SDimitry Andric else if (Kind.isMergeableConst16()) 6030b57cec5SDimitry Andric return 16; 6040b57cec5SDimitry Andric else if (Kind.isMergeableConst32()) 6050b57cec5SDimitry Andric return 32; 6060b57cec5SDimitry Andric else { 6070b57cec5SDimitry Andric // We shouldn't have mergeable C strings or mergeable constants that we 6080b57cec5SDimitry Andric // didn't handle above. 6090b57cec5SDimitry Andric assert(!Kind.isMergeableCString() && "unknown string width"); 6100b57cec5SDimitry Andric assert(!Kind.isMergeableConst() && "unknown data width"); 6110b57cec5SDimitry Andric return 0; 6120b57cec5SDimitry Andric } 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 6155ffd83dbSDimitry Andric /// Return the section prefix name used by options FunctionsSections and 6165ffd83dbSDimitry Andric /// DataSections. 61706c3fb27SDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind, bool IsLarge) { 6185ffd83dbSDimitry Andric if (Kind.isText()) 6195f757f3fSDimitry Andric return IsLarge ? ".ltext" : ".text"; 6205ffd83dbSDimitry Andric if (Kind.isReadOnly()) 62106c3fb27SDimitry Andric return IsLarge ? ".lrodata" : ".rodata"; 6225ffd83dbSDimitry Andric if (Kind.isBSS()) 62306c3fb27SDimitry Andric return IsLarge ? ".lbss" : ".bss"; 6245ffd83dbSDimitry Andric if (Kind.isThreadData()) 6255ffd83dbSDimitry Andric return ".tdata"; 6265ffd83dbSDimitry Andric if (Kind.isThreadBSS()) 6275ffd83dbSDimitry Andric return ".tbss"; 6285ffd83dbSDimitry Andric if (Kind.isData()) 62906c3fb27SDimitry Andric return IsLarge ? ".ldata" : ".data"; 6305ffd83dbSDimitry Andric if (Kind.isReadOnlyWithRel()) 63106c3fb27SDimitry Andric return IsLarge ? ".ldata.rel.ro" : ".data.rel.ro"; 6325ffd83dbSDimitry Andric llvm_unreachable("Unknown section kind"); 6335ffd83dbSDimitry Andric } 6345ffd83dbSDimitry Andric 6355ffd83dbSDimitry Andric static SmallString<128> 6365ffd83dbSDimitry Andric getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind, 6375ffd83dbSDimitry Andric Mangler &Mang, const TargetMachine &TM, 6385ffd83dbSDimitry Andric unsigned EntrySize, bool UniqueSectionName) { 639*0fca6ea1SDimitry Andric SmallString<128> Name = 640*0fca6ea1SDimitry Andric getSectionPrefixForGlobal(Kind, TM.isLargeGlobalValue(GO)); 6415ffd83dbSDimitry Andric if (Kind.isMergeableCString()) { 6425ffd83dbSDimitry Andric // We also need alignment here. 6435ffd83dbSDimitry Andric // FIXME: this is getting the alignment of the character, not the 6445ffd83dbSDimitry Andric // alignment of the global! 645*0fca6ea1SDimitry Andric Align Alignment = GO->getDataLayout().getPreferredAlign( 6465ffd83dbSDimitry Andric cast<GlobalVariable>(GO)); 6475ffd83dbSDimitry Andric 648*0fca6ea1SDimitry Andric Name += ".str"; 6495ffd83dbSDimitry Andric Name += utostr(EntrySize); 650*0fca6ea1SDimitry Andric Name += "."; 651*0fca6ea1SDimitry Andric Name += utostr(Alignment.value()); 652*0fca6ea1SDimitry Andric } else if (Kind.isMergeableConst()) { 653*0fca6ea1SDimitry Andric Name += ".cst"; 654*0fca6ea1SDimitry Andric Name += utostr(EntrySize); 6555ffd83dbSDimitry Andric } 6565ffd83dbSDimitry Andric 6575ffd83dbSDimitry Andric bool HasPrefix = false; 6585ffd83dbSDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 659bdd1243dSDimitry Andric if (std::optional<StringRef> Prefix = F->getSectionPrefix()) { 660e8d8bef9SDimitry Andric raw_svector_ostream(Name) << '.' << *Prefix; 6615ffd83dbSDimitry Andric HasPrefix = true; 6625ffd83dbSDimitry Andric } 6635ffd83dbSDimitry Andric } 6645ffd83dbSDimitry Andric 6655ffd83dbSDimitry Andric if (UniqueSectionName) { 6665ffd83dbSDimitry Andric Name.push_back('.'); 6675ffd83dbSDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, /*MayAlwaysUsePrivate*/true); 6685ffd83dbSDimitry Andric } else if (HasPrefix) 669fe6060f1SDimitry Andric // For distinguishing between .text.${text-section-prefix}. (with trailing 670fe6060f1SDimitry Andric // dot) and .text.${function-name} 6715ffd83dbSDimitry Andric Name.push_back('.'); 6725ffd83dbSDimitry Andric return Name; 6735ffd83dbSDimitry Andric } 6745ffd83dbSDimitry Andric 6755ffd83dbSDimitry Andric namespace { 6765ffd83dbSDimitry Andric class LoweringDiagnosticInfo : public DiagnosticInfo { 6775ffd83dbSDimitry Andric const Twine &Msg; 6785ffd83dbSDimitry Andric 6795ffd83dbSDimitry Andric public: 6805ffd83dbSDimitry Andric LoweringDiagnosticInfo(const Twine &DiagMsg, 6815ffd83dbSDimitry Andric DiagnosticSeverity Severity = DS_Error) 6825ffd83dbSDimitry Andric : DiagnosticInfo(DK_Lowering, Severity), Msg(DiagMsg) {} 6835ffd83dbSDimitry Andric void print(DiagnosticPrinter &DP) const override { DP << Msg; } 6845ffd83dbSDimitry Andric }; 6855ffd83dbSDimitry Andric } 6865ffd83dbSDimitry Andric 687fe6060f1SDimitry Andric /// Calculate an appropriate unique ID for a section, and update Flags, 688fe6060f1SDimitry Andric /// EntrySize and NextUniqueID where appropriate. 689fe6060f1SDimitry Andric static unsigned 690fe6060f1SDimitry Andric calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName, 691fe6060f1SDimitry Andric SectionKind Kind, const TargetMachine &TM, 692fe6060f1SDimitry Andric MCContext &Ctx, Mangler &Mang, unsigned &Flags, 693fe6060f1SDimitry Andric unsigned &EntrySize, unsigned &NextUniqueID, 694fe6060f1SDimitry Andric const bool Retain, const bool ForceUnique) { 695fe6060f1SDimitry Andric // Increment uniqueID if we are forced to emit a unique section. 696fe6060f1SDimitry Andric // This works perfectly fine with section attribute or pragma section as the 697fe6060f1SDimitry Andric // sections with the same name are grouped together by the assembler. 698fe6060f1SDimitry Andric if (ForceUnique) 699fe6060f1SDimitry Andric return NextUniqueID++; 700fe6060f1SDimitry Andric 701fe6060f1SDimitry Andric // A section can have at most one associated section. Put each global with 702fe6060f1SDimitry Andric // MD_associated in a unique section. 703fe6060f1SDimitry Andric const bool Associated = GO->getMetadata(LLVMContext::MD_associated); 704fe6060f1SDimitry Andric if (Associated) { 705fe6060f1SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 706fe6060f1SDimitry Andric return NextUniqueID++; 707fe6060f1SDimitry Andric } 708fe6060f1SDimitry Andric 709fe6060f1SDimitry Andric if (Retain) { 71081ad6265SDimitry Andric if (TM.getTargetTriple().isOSSolaris()) 71181ad6265SDimitry Andric Flags |= ELF::SHF_SUNW_NODISCARD; 71281ad6265SDimitry Andric else if (Ctx.getAsmInfo()->useIntegratedAssembler() || 71381ad6265SDimitry Andric Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) 714fe6060f1SDimitry Andric Flags |= ELF::SHF_GNU_RETAIN; 715fe6060f1SDimitry Andric return NextUniqueID++; 716fe6060f1SDimitry Andric } 717fe6060f1SDimitry Andric 718fe6060f1SDimitry Andric // If two symbols with differing sizes end up in the same mergeable section 719fe6060f1SDimitry Andric // that section can be assigned an incorrect entry size. To avoid this we 720fe6060f1SDimitry Andric // usually put symbols of the same size into distinct mergeable sections with 721fe6060f1SDimitry Andric // the same name. Doing so relies on the ",unique ," assembly feature. This 722fe6060f1SDimitry Andric // feature is not avalible until bintuils version 2.35 723fe6060f1SDimitry Andric // (https://sourceware.org/bugzilla/show_bug.cgi?id=25380). 724fe6060f1SDimitry Andric const bool SupportsUnique = Ctx.getAsmInfo()->useIntegratedAssembler() || 725fe6060f1SDimitry Andric Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35); 726fe6060f1SDimitry Andric if (!SupportsUnique) { 727fe6060f1SDimitry Andric Flags &= ~ELF::SHF_MERGE; 728fe6060f1SDimitry Andric EntrySize = 0; 729fe6060f1SDimitry Andric return MCContext::GenericSectionID; 730fe6060f1SDimitry Andric } 731fe6060f1SDimitry Andric 732fe6060f1SDimitry Andric const bool SymbolMergeable = Flags & ELF::SHF_MERGE; 733fe6060f1SDimitry Andric const bool SeenSectionNameBefore = 734fe6060f1SDimitry Andric Ctx.isELFGenericMergeableSection(SectionName); 735fe6060f1SDimitry Andric // If this is the first ocurrence of this section name, treat it as the 736fe6060f1SDimitry Andric // generic section 737*0fca6ea1SDimitry Andric if (!SymbolMergeable && !SeenSectionNameBefore) { 738*0fca6ea1SDimitry Andric if (TM.getSeparateNamedSections()) 739*0fca6ea1SDimitry Andric return NextUniqueID++; 740*0fca6ea1SDimitry Andric else 741fe6060f1SDimitry Andric return MCContext::GenericSectionID; 742*0fca6ea1SDimitry Andric } 743fe6060f1SDimitry Andric 744fe6060f1SDimitry Andric // Symbols must be placed into sections with compatible entry sizes. Generate 745fe6060f1SDimitry Andric // unique sections for symbols that have not been assigned to compatible 746fe6060f1SDimitry Andric // sections. 747fe6060f1SDimitry Andric const auto PreviousID = 748fe6060f1SDimitry Andric Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize); 749*0fca6ea1SDimitry Andric if (PreviousID && (!TM.getSeparateNamedSections() || 750*0fca6ea1SDimitry Andric *PreviousID == MCContext::GenericSectionID)) 751fe6060f1SDimitry Andric return *PreviousID; 752fe6060f1SDimitry Andric 753fe6060f1SDimitry Andric // If the user has specified the same section name as would be created 754fe6060f1SDimitry Andric // implicitly for this symbol e.g. .rodata.str1.1, then we don't need 755fe6060f1SDimitry Andric // to unique the section as the entry size for this symbol will be 756fe6060f1SDimitry Andric // compatible with implicitly created sections. 757fe6060f1SDimitry Andric SmallString<128> ImplicitSectionNameStem = 758fe6060f1SDimitry Andric getELFSectionNameForGlobal(GO, Kind, Mang, TM, EntrySize, false); 759fe6060f1SDimitry Andric if (SymbolMergeable && 760fe6060f1SDimitry Andric Ctx.isELFImplicitMergeableSectionNamePrefix(SectionName) && 7615f757f3fSDimitry Andric SectionName.starts_with(ImplicitSectionNameStem)) 762fe6060f1SDimitry Andric return MCContext::GenericSectionID; 763fe6060f1SDimitry Andric 764fe6060f1SDimitry Andric // We have seen this section name before, but with different flags or entity 765fe6060f1SDimitry Andric // size. Create a new unique ID. 766fe6060f1SDimitry Andric return NextUniqueID++; 767fe6060f1SDimitry Andric } 768fe6060f1SDimitry Andric 7695f757f3fSDimitry Andric static std::tuple<StringRef, bool, unsigned> 7705f757f3fSDimitry Andric getGlobalObjectInfo(const GlobalObject *GO, const TargetMachine &TM) { 7715f757f3fSDimitry Andric StringRef Group = ""; 7725f757f3fSDimitry Andric bool IsComdat = false; 7735f757f3fSDimitry Andric unsigned Flags = 0; 7745f757f3fSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 7755f757f3fSDimitry Andric Flags |= ELF::SHF_GROUP; 7765f757f3fSDimitry Andric Group = C->getName(); 7775f757f3fSDimitry Andric IsComdat = C->getSelectionKind() == Comdat::Any; 7785f757f3fSDimitry Andric } 7795f757f3fSDimitry Andric if (TM.isLargeGlobalValue(GO)) 7805f757f3fSDimitry Andric Flags |= ELF::SHF_X86_64_LARGE; 7815f757f3fSDimitry Andric return {Group, IsComdat, Flags}; 7825f757f3fSDimitry Andric } 7835f757f3fSDimitry Andric 784fe6060f1SDimitry Andric static MCSection *selectExplicitSectionGlobal( 785fe6060f1SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM, 786fe6060f1SDimitry Andric MCContext &Ctx, Mangler &Mang, unsigned &NextUniqueID, 787fe6060f1SDimitry Andric bool Retain, bool ForceUnique) { 7880b57cec5SDimitry Andric StringRef SectionName = GO->getSection(); 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric // Check if '#pragma clang section' name is applicable. 7910b57cec5SDimitry Andric // Note that pragma directive overrides -ffunction-section, -fdata-section 7920b57cec5SDimitry Andric // and so section name is exactly as user specified and not uniqued. 7930b57cec5SDimitry Andric const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); 7940b57cec5SDimitry Andric if (GV && GV->hasImplicitSection()) { 7950b57cec5SDimitry Andric auto Attrs = GV->getAttributes(); 7960b57cec5SDimitry Andric if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { 7970b57cec5SDimitry Andric SectionName = Attrs.getAttribute("bss-section").getValueAsString(); 7980b57cec5SDimitry Andric } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { 7990b57cec5SDimitry Andric SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); 8008bcb0991SDimitry Andric } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) { 8018bcb0991SDimitry Andric SectionName = Attrs.getAttribute("relro-section").getValueAsString(); 8020b57cec5SDimitry Andric } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { 8030b57cec5SDimitry Andric SectionName = Attrs.getAttribute("data-section").getValueAsString(); 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric } 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric // Infer section flags from the section name if we can. 8080b57cec5SDimitry Andric Kind = getELFKindForNamedSection(SectionName, Kind); 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 8115f757f3fSDimitry Andric auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM); 8125f757f3fSDimitry Andric Flags |= ExtraFlags; 8130b57cec5SDimitry Andric 8145ffd83dbSDimitry Andric unsigned EntrySize = getEntrySizeForKind(Kind); 815fe6060f1SDimitry Andric const unsigned UniqueID = calcUniqueIDUpdateFlagsAndSize( 816fe6060f1SDimitry Andric GO, SectionName, Kind, TM, Ctx, Mang, Flags, EntrySize, NextUniqueID, 817fe6060f1SDimitry Andric Retain, ForceUnique); 8185ffd83dbSDimitry Andric 8195ffd83dbSDimitry Andric const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); 820fe6060f1SDimitry Andric MCSectionELF *Section = Ctx.getELFSection( 821fe6060f1SDimitry Andric SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize, 822fe6060f1SDimitry Andric Group, IsComdat, UniqueID, LinkedToSym); 8230b57cec5SDimitry Andric // Make sure that we did not get some other section with incompatible sh_link. 8240b57cec5SDimitry Andric // This should not be possible due to UniqueID code above. 8255ffd83dbSDimitry Andric assert(Section->getLinkedToSymbol() == LinkedToSym && 8260b57cec5SDimitry Andric "Associated symbol mismatch between sections"); 8275ffd83dbSDimitry Andric 828fe6060f1SDimitry Andric if (!(Ctx.getAsmInfo()->useIntegratedAssembler() || 829fe6060f1SDimitry Andric Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35))) { 830e8d8bef9SDimitry Andric // If we are using GNU as before 2.35, then this symbol might have 8315ffd83dbSDimitry Andric // been placed in an incompatible mergeable section. Emit an error if this 8325ffd83dbSDimitry Andric // is the case to avoid creating broken output. 8335ffd83dbSDimitry Andric if ((Section->getFlags() & ELF::SHF_MERGE) && 8345ffd83dbSDimitry Andric (Section->getEntrySize() != getEntrySizeForKind(Kind))) 8355ffd83dbSDimitry Andric GO->getContext().diagnose(LoweringDiagnosticInfo( 8365ffd83dbSDimitry Andric "Symbol '" + GO->getName() + "' from module '" + 8375ffd83dbSDimitry Andric (GO->getParent() ? GO->getParent()->getSourceFileName() : "unknown") + 8385ffd83dbSDimitry Andric "' required a section with entry-size=" + 8395ffd83dbSDimitry Andric Twine(getEntrySizeForKind(Kind)) + " but was placed in section '" + 8405ffd83dbSDimitry Andric SectionName + "' with entry-size=" + Twine(Section->getEntrySize()) + 8415ffd83dbSDimitry Andric ": Explicit assignment by pragma or attribute of an incompatible " 8425ffd83dbSDimitry Andric "symbol to this section?")); 8430b57cec5SDimitry Andric } 8440b57cec5SDimitry Andric 8455ffd83dbSDimitry Andric return Section; 8460b57cec5SDimitry Andric } 8470b57cec5SDimitry Andric 848fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( 849fe6060f1SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 850fe6060f1SDimitry Andric return selectExplicitSectionGlobal(GO, Kind, TM, getContext(), getMangler(), 851fe6060f1SDimitry Andric NextUniqueID, Used.count(GO), 852fe6060f1SDimitry Andric /* ForceUnique = */false); 853fe6060f1SDimitry Andric } 854fe6060f1SDimitry Andric 8550b57cec5SDimitry Andric static MCSectionELF *selectELFSectionForGlobal( 8560b57cec5SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 8570b57cec5SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, 8580b57cec5SDimitry Andric unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { 8590b57cec5SDimitry Andric 8605f757f3fSDimitry Andric auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM); 8615f757f3fSDimitry Andric Flags |= ExtraFlags; 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric // Get the section entry size based on the kind. 8640b57cec5SDimitry Andric unsigned EntrySize = getEntrySizeForKind(Kind); 8650b57cec5SDimitry Andric 8665ffd83dbSDimitry Andric bool UniqueSectionName = false; 8670b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 8680b57cec5SDimitry Andric if (EmitUniqueSection) { 8690b57cec5SDimitry Andric if (TM.getUniqueSectionNames()) { 8705ffd83dbSDimitry Andric UniqueSectionName = true; 8710b57cec5SDimitry Andric } else { 8720b57cec5SDimitry Andric UniqueID = *NextUniqueID; 8730b57cec5SDimitry Andric (*NextUniqueID)++; 8740b57cec5SDimitry Andric } 8750b57cec5SDimitry Andric } 8765ffd83dbSDimitry Andric SmallString<128> Name = getELFSectionNameForGlobal( 8775ffd83dbSDimitry Andric GO, Kind, Mang, TM, EntrySize, UniqueSectionName); 8785ffd83dbSDimitry Andric 8790b57cec5SDimitry Andric // Use 0 as the unique ID for execute-only text. 8800b57cec5SDimitry Andric if (Kind.isExecuteOnly()) 8810b57cec5SDimitry Andric UniqueID = 0; 8820b57cec5SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 883fe6060f1SDimitry Andric EntrySize, Group, IsComdat, UniqueID, 884fe6060f1SDimitry Andric AssociatedSymbol); 885fe6060f1SDimitry Andric } 886fe6060f1SDimitry Andric 887fe6060f1SDimitry Andric static MCSection *selectELFSectionForGlobal( 888fe6060f1SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 889fe6060f1SDimitry Andric const TargetMachine &TM, bool Retain, bool EmitUniqueSection, 890fe6060f1SDimitry Andric unsigned Flags, unsigned *NextUniqueID) { 891fe6060f1SDimitry Andric const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); 892fe6060f1SDimitry Andric if (LinkedToSym) { 893fe6060f1SDimitry Andric EmitUniqueSection = true; 894fe6060f1SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 895fe6060f1SDimitry Andric } 89681ad6265SDimitry Andric if (Retain) { 89781ad6265SDimitry Andric if (TM.getTargetTriple().isOSSolaris()) { 89881ad6265SDimitry Andric EmitUniqueSection = true; 89981ad6265SDimitry Andric Flags |= ELF::SHF_SUNW_NODISCARD; 90081ad6265SDimitry Andric } else if (Ctx.getAsmInfo()->useIntegratedAssembler() || 90181ad6265SDimitry Andric Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) { 902fe6060f1SDimitry Andric EmitUniqueSection = true; 903fe6060f1SDimitry Andric Flags |= ELF::SHF_GNU_RETAIN; 904fe6060f1SDimitry Andric } 90581ad6265SDimitry Andric } 906fe6060f1SDimitry Andric 907fe6060f1SDimitry Andric MCSectionELF *Section = selectELFSectionForGlobal( 908fe6060f1SDimitry Andric Ctx, GO, Kind, Mang, TM, EmitUniqueSection, Flags, 909fe6060f1SDimitry Andric NextUniqueID, LinkedToSym); 910fe6060f1SDimitry Andric assert(Section->getLinkedToSymbol() == LinkedToSym); 911fe6060f1SDimitry Andric return Section; 9120b57cec5SDimitry Andric } 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( 9150b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 9160b57cec5SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 9190b57cec5SDimitry Andric // global value to a uniqued section specifically for it. 9200b57cec5SDimitry Andric bool EmitUniqueSection = false; 9210b57cec5SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { 9220b57cec5SDimitry Andric if (Kind.isText()) 9230b57cec5SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 9240b57cec5SDimitry Andric else 9250b57cec5SDimitry Andric EmitUniqueSection = TM.getDataSections(); 9260b57cec5SDimitry Andric } 9270b57cec5SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 928fe6060f1SDimitry Andric return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 929fe6060f1SDimitry Andric Used.count(GO), EmitUniqueSection, Flags, 930fe6060f1SDimitry Andric &NextUniqueID); 9310b57cec5SDimitry Andric } 9320b57cec5SDimitry Andric 933fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction( 934fe6060f1SDimitry Andric const Function &F, const TargetMachine &TM) const { 935fe6060f1SDimitry Andric SectionKind Kind = SectionKind::getText(); 936fe6060f1SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 937fe6060f1SDimitry Andric // If the function's section names is pre-determined via pragma or a 938fe6060f1SDimitry Andric // section attribute, call selectExplicitSectionGlobal. 939*0fca6ea1SDimitry Andric if (F.hasSection()) 940fe6060f1SDimitry Andric return selectExplicitSectionGlobal( 941fe6060f1SDimitry Andric &F, Kind, TM, getContext(), getMangler(), NextUniqueID, 942fe6060f1SDimitry Andric Used.count(&F), /* ForceUnique = */true); 943fe6060f1SDimitry Andric else 944fe6060f1SDimitry Andric return selectELFSectionForGlobal( 945fe6060f1SDimitry Andric getContext(), &F, Kind, getMangler(), TM, Used.count(&F), 946fe6060f1SDimitry Andric /*EmitUniqueSection=*/true, Flags, &NextUniqueID); 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( 9500b57cec5SDimitry Andric const Function &F, const TargetMachine &TM) const { 9510b57cec5SDimitry Andric // If the function can be removed, produce a unique section so that 9520b57cec5SDimitry Andric // the table doesn't prevent the removal. 9530b57cec5SDimitry Andric const Comdat *C = F.getComdat(); 9540b57cec5SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 9550b57cec5SDimitry Andric if (!EmitUniqueSection) 9560b57cec5SDimitry Andric return ReadOnlySection; 9570b57cec5SDimitry Andric 9580b57cec5SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), 9590b57cec5SDimitry Andric getMangler(), TM, EmitUniqueSection, 9600b57cec5SDimitry Andric ELF::SHF_ALLOC, &NextUniqueID, 9610b57cec5SDimitry Andric /* AssociatedSymbol */ nullptr); 9620b57cec5SDimitry Andric } 9630b57cec5SDimitry Andric 964fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForLSDA( 965fe6060f1SDimitry Andric const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { 966e8d8bef9SDimitry Andric // If neither COMDAT nor function sections, use the monolithic LSDA section. 967e8d8bef9SDimitry Andric // Re-use this path if LSDASection is null as in the Arm EHABI. 968e8d8bef9SDimitry Andric if (!LSDASection || (!F.hasComdat() && !TM.getFunctionSections())) 969e8d8bef9SDimitry Andric return LSDASection; 970e8d8bef9SDimitry Andric 971e8d8bef9SDimitry Andric const auto *LSDA = cast<MCSectionELF>(LSDASection); 972e8d8bef9SDimitry Andric unsigned Flags = LSDA->getFlags(); 973fe6060f1SDimitry Andric const MCSymbolELF *LinkedToSym = nullptr; 974e8d8bef9SDimitry Andric StringRef Group; 975fe6060f1SDimitry Andric bool IsComdat = false; 976fe6060f1SDimitry Andric if (const Comdat *C = getELFComdat(&F)) { 977e8d8bef9SDimitry Andric Flags |= ELF::SHF_GROUP; 978fe6060f1SDimitry Andric Group = C->getName(); 979fe6060f1SDimitry Andric IsComdat = C->getSelectionKind() == Comdat::Any; 980fe6060f1SDimitry Andric } 981fe6060f1SDimitry Andric // Use SHF_LINK_ORDER to facilitate --gc-sections if we can use GNU ld>=2.36 982fe6060f1SDimitry Andric // or LLD, which support mixed SHF_LINK_ORDER & non-SHF_LINK_ORDER. 983fe6060f1SDimitry Andric if (TM.getFunctionSections() && 984fe6060f1SDimitry Andric (getContext().getAsmInfo()->useIntegratedAssembler() && 985fe6060f1SDimitry Andric getContext().getAsmInfo()->binutilsIsAtLeast(2, 36))) { 986fe6060f1SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 987fe6060f1SDimitry Andric LinkedToSym = cast<MCSymbolELF>(&FnSym); 988e8d8bef9SDimitry Andric } 989e8d8bef9SDimitry Andric 990e8d8bef9SDimitry Andric // Append the function name as the suffix like GCC, assuming 991e8d8bef9SDimitry Andric // -funique-section-names applies to .gcc_except_table sections. 992fe6060f1SDimitry Andric return getContext().getELFSection( 993fe6060f1SDimitry Andric (TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName() 994fe6060f1SDimitry Andric : LSDA->getName()), 995fe6060f1SDimitry Andric LSDA->getType(), Flags, 0, Group, IsComdat, MCSection::NonUniqueID, 996fe6060f1SDimitry Andric LinkedToSym); 997e8d8bef9SDimitry Andric } 998e8d8bef9SDimitry Andric 9990b57cec5SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( 10000b57cec5SDimitry Andric bool UsesLabelDifference, const Function &F) const { 10010b57cec5SDimitry Andric // We can always create relative relocations, so use another section 10020b57cec5SDimitry Andric // that can be marked non-executable. 10030b57cec5SDimitry Andric return false; 10040b57cec5SDimitry Andric } 10050b57cec5SDimitry Andric 10060b57cec5SDimitry Andric /// Given a mergeable constant with the specified size and relocation 10070b57cec5SDimitry Andric /// information, return a section that it should be placed in. 10080b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant( 10090b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 10105ffd83dbSDimitry Andric Align &Alignment) const { 10110b57cec5SDimitry Andric if (Kind.isMergeableConst4() && MergeableConst4Section) 10120b57cec5SDimitry Andric return MergeableConst4Section; 10130b57cec5SDimitry Andric if (Kind.isMergeableConst8() && MergeableConst8Section) 10140b57cec5SDimitry Andric return MergeableConst8Section; 10150b57cec5SDimitry Andric if (Kind.isMergeableConst16() && MergeableConst16Section) 10160b57cec5SDimitry Andric return MergeableConst16Section; 10170b57cec5SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section) 10180b57cec5SDimitry Andric return MergeableConst32Section; 10190b57cec5SDimitry Andric if (Kind.isReadOnly()) 10200b57cec5SDimitry Andric return ReadOnlySection; 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andric assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 10230b57cec5SDimitry Andric return DataRelROSection; 10240b57cec5SDimitry Andric } 10250b57cec5SDimitry Andric 10265ffd83dbSDimitry Andric /// Returns a unique section for the given machine basic block. 10275ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock( 10285ffd83dbSDimitry Andric const Function &F, const MachineBasicBlock &MBB, 10295ffd83dbSDimitry Andric const TargetMachine &TM) const { 10305ffd83dbSDimitry Andric assert(MBB.isBeginSection() && "Basic block does not start a section!"); 10315ffd83dbSDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 10325ffd83dbSDimitry Andric 1033e8d8bef9SDimitry Andric // For cold sections use the .text.split. prefix along with the parent 10345ffd83dbSDimitry Andric // function name. All cold blocks for the same function go to the same 10355ffd83dbSDimitry Andric // section. Similarly all exception blocks are grouped by symbol name 10365ffd83dbSDimitry Andric // under the .text.eh prefix. For regular sections, we either use a unique 10375ffd83dbSDimitry Andric // name, or a unique ID for the section. 10385ffd83dbSDimitry Andric SmallString<128> Name; 10395f757f3fSDimitry Andric StringRef FunctionSectionName = MBB.getParent()->getSection()->getName(); 1040*0fca6ea1SDimitry Andric if (FunctionSectionName == ".text" || 10415f757f3fSDimitry Andric FunctionSectionName.starts_with(".text.")) { 10425f757f3fSDimitry Andric // Function is in a regular .text section. 10435f757f3fSDimitry Andric StringRef FunctionName = MBB.getParent()->getName(); 10445ffd83dbSDimitry Andric if (MBB.getSectionID() == MBBSectionID::ColdSectionID) { 1045e8d8bef9SDimitry Andric Name += BBSectionsColdTextPrefix; 10465f757f3fSDimitry Andric Name += FunctionName; 10475ffd83dbSDimitry Andric } else if (MBB.getSectionID() == MBBSectionID::ExceptionSectionID) { 10485ffd83dbSDimitry Andric Name += ".text.eh."; 10495f757f3fSDimitry Andric Name += FunctionName; 10505ffd83dbSDimitry Andric } else { 10515f757f3fSDimitry Andric Name += FunctionSectionName; 10525ffd83dbSDimitry Andric if (TM.getUniqueBasicBlockSectionNames()) { 10535f757f3fSDimitry Andric if (!Name.ends_with(".")) 10545ffd83dbSDimitry Andric Name += "."; 10555ffd83dbSDimitry Andric Name += MBB.getSymbol()->getName(); 10565ffd83dbSDimitry Andric } else { 10575ffd83dbSDimitry Andric UniqueID = NextUniqueID++; 10585ffd83dbSDimitry Andric } 10595ffd83dbSDimitry Andric } 10605f757f3fSDimitry Andric } else { 10615f757f3fSDimitry Andric // If the original function has a custom non-dot-text section, then emit 10625f757f3fSDimitry Andric // all basic block sections into that section too, each with a unique id. 10635f757f3fSDimitry Andric Name = FunctionSectionName; 10645f757f3fSDimitry Andric UniqueID = NextUniqueID++; 10655f757f3fSDimitry Andric } 10665ffd83dbSDimitry Andric 10675ffd83dbSDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; 1068e8d8bef9SDimitry Andric std::string GroupName; 10695ffd83dbSDimitry Andric if (F.hasComdat()) { 10705ffd83dbSDimitry Andric Flags |= ELF::SHF_GROUP; 10715ffd83dbSDimitry Andric GroupName = F.getComdat()->getName().str(); 10725ffd83dbSDimitry Andric } 10735ffd83dbSDimitry Andric return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags, 1074fe6060f1SDimitry Andric 0 /* Entry Size */, GroupName, 1075fe6060f1SDimitry Andric F.hasComdat(), UniqueID, nullptr); 10765ffd83dbSDimitry Andric } 10775ffd83dbSDimitry Andric 10780b57cec5SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, 10790b57cec5SDimitry Andric bool IsCtor, unsigned Priority, 10800b57cec5SDimitry Andric const MCSymbol *KeySym) { 10810b57cec5SDimitry Andric std::string Name; 10820b57cec5SDimitry Andric unsigned Type; 10830b57cec5SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; 1084fe6060f1SDimitry Andric StringRef Comdat = KeySym ? KeySym->getName() : ""; 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andric if (KeySym) 10870b57cec5SDimitry Andric Flags |= ELF::SHF_GROUP; 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric if (UseInitArray) { 10900b57cec5SDimitry Andric if (IsCtor) { 10910b57cec5SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 10920b57cec5SDimitry Andric Name = ".init_array"; 10930b57cec5SDimitry Andric } else { 10940b57cec5SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 10950b57cec5SDimitry Andric Name = ".fini_array"; 10960b57cec5SDimitry Andric } 10970b57cec5SDimitry Andric if (Priority != 65535) { 10980b57cec5SDimitry Andric Name += '.'; 10990b57cec5SDimitry Andric Name += utostr(Priority); 11000b57cec5SDimitry Andric } 11010b57cec5SDimitry Andric } else { 11020b57cec5SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority 11030b57cec5SDimitry Andric // numbering. 11040b57cec5SDimitry Andric if (IsCtor) 11050b57cec5SDimitry Andric Name = ".ctors"; 11060b57cec5SDimitry Andric else 11070b57cec5SDimitry Andric Name = ".dtors"; 11080b57cec5SDimitry Andric if (Priority != 65535) 11090b57cec5SDimitry Andric raw_string_ostream(Name) << format(".%05u", 65535 - Priority); 11100b57cec5SDimitry Andric Type = ELF::SHT_PROGBITS; 11110b57cec5SDimitry Andric } 11120b57cec5SDimitry Andric 1113fe6060f1SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, Comdat, /*IsComdat=*/true); 11140b57cec5SDimitry Andric } 11150b57cec5SDimitry Andric 11160b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 11170b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 11180b57cec5SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 11190b57cec5SDimitry Andric KeySym); 11200b57cec5SDimitry Andric } 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 11230b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 11240b57cec5SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 11250b57cec5SDimitry Andric KeySym); 11260b57cec5SDimitry Andric } 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 11290b57cec5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 11300b57cec5SDimitry Andric const TargetMachine &TM) const { 11310b57cec5SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 11320b57cec5SDimitry Andric // functions. 11330b57cec5SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 11340b57cec5SDimitry Andric return nullptr; 11350b57cec5SDimitry Andric 11364824e7fdSDimitry Andric // Basic correctness checks. 11370b57cec5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 11380b57cec5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 11390b57cec5SDimitry Andric RHS->isThreadLocal()) 11400b57cec5SDimitry Andric return nullptr; 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andric return MCBinaryExpr::createSub( 11430b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, 11440b57cec5SDimitry Andric getContext()), 11450b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 11460b57cec5SDimitry Andric } 11470b57cec5SDimitry Andric 1148e8d8bef9SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent( 1149e8d8bef9SDimitry Andric const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const { 1150e8d8bef9SDimitry Andric assert(supportDSOLocalEquivalentLowering()); 1151e8d8bef9SDimitry Andric 1152e8d8bef9SDimitry Andric const auto *GV = Equiv->getGlobalValue(); 1153e8d8bef9SDimitry Andric 1154e8d8bef9SDimitry Andric // A PLT entry is not needed for dso_local globals. 1155e8d8bef9SDimitry Andric if (GV->isDSOLocal() || GV->isImplicitDSOLocal()) 1156e8d8bef9SDimitry Andric return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext()); 1157e8d8bef9SDimitry Andric 1158e8d8bef9SDimitry Andric return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeVariantKind, 1159e8d8bef9SDimitry Andric getContext()); 1160e8d8bef9SDimitry Andric } 1161e8d8bef9SDimitry Andric 11620b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const { 11630b57cec5SDimitry Andric // Use ".GCC.command.line" since this feature is to support clang's 11640b57cec5SDimitry Andric // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the 11650b57cec5SDimitry Andric // same name. 11660b57cec5SDimitry Andric return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS, 1167fe6060f1SDimitry Andric ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); 11680b57cec5SDimitry Andric } 11690b57cec5SDimitry Andric 11700b57cec5SDimitry Andric void 11710b57cec5SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 11720b57cec5SDimitry Andric UseInitArray = UseInitArray_; 11730b57cec5SDimitry Andric MCContext &Ctx = getContext(); 11740b57cec5SDimitry Andric if (!UseInitArray) { 11750b57cec5SDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, 11760b57cec5SDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 11770b57cec5SDimitry Andric 11780b57cec5SDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, 11790b57cec5SDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 11800b57cec5SDimitry Andric return; 11810b57cec5SDimitry Andric } 11820b57cec5SDimitry Andric 11830b57cec5SDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, 11840b57cec5SDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 11850b57cec5SDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, 11860b57cec5SDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 11870b57cec5SDimitry Andric } 11880b57cec5SDimitry Andric 11890b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11900b57cec5SDimitry Andric // MachO 11910b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11920b57cec5SDimitry Andric 119304eeddc0SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() { 11940b57cec5SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 11950b57cec5SDimitry Andric } 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, 11980b57cec5SDimitry Andric const TargetMachine &TM) { 11990b57cec5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 12000b57cec5SDimitry Andric if (TM.getRelocationModel() == Reloc::Static) { 12010b57cec5SDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, 12020b57cec5SDimitry Andric SectionKind::getData()); 12030b57cec5SDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, 12040b57cec5SDimitry Andric SectionKind::getData()); 12050b57cec5SDimitry Andric } else { 12060b57cec5SDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", 12070b57cec5SDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 12080b57cec5SDimitry Andric SectionKind::getData()); 12090b57cec5SDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", 12100b57cec5SDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 12110b57cec5SDimitry Andric SectionKind::getData()); 12120b57cec5SDimitry Andric } 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andric PersonalityEncoding = 12150b57cec5SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 12160b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel; 12170b57cec5SDimitry Andric TTypeEncoding = 12180b57cec5SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 12190b57cec5SDimitry Andric } 12200b57cec5SDimitry Andric 122181ad6265SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getStaticDtorSection( 122281ad6265SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 122381ad6265SDimitry Andric return StaticDtorSection; 122406c3fb27SDimitry Andric // In userspace, we lower global destructors via atexit(), but kernel/kext 122506c3fb27SDimitry Andric // environments do not provide this function so we still need to support the 122606c3fb27SDimitry Andric // legacy way here. 122706c3fb27SDimitry Andric // See the -disable-atexit-based-global-dtor-lowering CodeGen flag for more 122806c3fb27SDimitry Andric // context. 122981ad6265SDimitry Andric } 123081ad6265SDimitry Andric 12310b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, 12320b57cec5SDimitry Andric Module &M) const { 12330b57cec5SDimitry Andric // Emit the linker options if present. 12340b57cec5SDimitry Andric if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 1235480093f4SDimitry Andric for (const auto *Option : LinkerOptions->operands()) { 12360b57cec5SDimitry Andric SmallVector<std::string, 4> StrOptions; 12370b57cec5SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 12385ffd83dbSDimitry Andric StrOptions.push_back(std::string(cast<MDString>(Piece)->getString())); 12395ffd83dbSDimitry Andric Streamer.emitLinkerOptions(StrOptions); 12400b57cec5SDimitry Andric } 12410b57cec5SDimitry Andric } 12420b57cec5SDimitry Andric 12430b57cec5SDimitry Andric unsigned VersionVal = 0; 12440b57cec5SDimitry Andric unsigned ImageInfoFlags = 0; 12450b57cec5SDimitry Andric StringRef SectionVal; 12460b57cec5SDimitry Andric 12470b57cec5SDimitry Andric GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal); 124804eeddc0SDimitry Andric emitCGProfileMetadata(Streamer, M); 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 12510b57cec5SDimitry Andric if (SectionVal.empty()) 12520b57cec5SDimitry Andric return; 12530b57cec5SDimitry Andric 12540b57cec5SDimitry Andric StringRef Segment, Section; 12550b57cec5SDimitry Andric unsigned TAA = 0, StubSize = 0; 12560b57cec5SDimitry Andric bool TAAParsed; 1257fe6060f1SDimitry Andric if (Error E = MCSectionMachO::ParseSectionSpecifier( 1258fe6060f1SDimitry Andric SectionVal, Segment, Section, TAA, TAAParsed, StubSize)) { 12590b57cec5SDimitry Andric // If invalid, report the error with report_fatal_error. 1260fe6060f1SDimitry Andric report_fatal_error("Invalid section specifier '" + Section + 1261fe6060f1SDimitry Andric "': " + toString(std::move(E)) + "."); 1262fe6060f1SDimitry Andric } 12630b57cec5SDimitry Andric 12640b57cec5SDimitry Andric // Get the section. 12650b57cec5SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 12660b57cec5SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 126781ad6265SDimitry Andric Streamer.switchSection(S); 12685ffd83dbSDimitry Andric Streamer.emitLabel(getContext(). 12690b57cec5SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 12705ffd83dbSDimitry Andric Streamer.emitInt32(VersionVal); 12715ffd83dbSDimitry Andric Streamer.emitInt32(ImageInfoFlags); 127281ad6265SDimitry Andric Streamer.addBlankLine(); 12730b57cec5SDimitry Andric } 12740b57cec5SDimitry Andric 12750b57cec5SDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 12760b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 12770b57cec5SDimitry Andric if (!C) 12780b57cec5SDimitry Andric return; 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 12810b57cec5SDimitry Andric "' cannot be lowered."); 12820b57cec5SDimitry Andric } 12830b57cec5SDimitry Andric 12840b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 12850b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1286fe6060f1SDimitry Andric 1287fe6060f1SDimitry Andric StringRef SectionName = GO->getSection(); 1288fe6060f1SDimitry Andric 128906c3fb27SDimitry Andric const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); 129006c3fb27SDimitry Andric if (GV && GV->hasImplicitSection()) { 129106c3fb27SDimitry Andric auto Attrs = GV->getAttributes(); 129206c3fb27SDimitry Andric if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { 129306c3fb27SDimitry Andric SectionName = Attrs.getAttribute("bss-section").getValueAsString(); 129406c3fb27SDimitry Andric } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { 129506c3fb27SDimitry Andric SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); 129606c3fb27SDimitry Andric } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) { 129706c3fb27SDimitry Andric SectionName = Attrs.getAttribute("relro-section").getValueAsString(); 129806c3fb27SDimitry Andric } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { 129906c3fb27SDimitry Andric SectionName = Attrs.getAttribute("data-section").getValueAsString(); 130006c3fb27SDimitry Andric } 130106c3fb27SDimitry Andric } 130206c3fb27SDimitry Andric 13030b57cec5SDimitry Andric // Parse the section specifier and create it if valid. 13040b57cec5SDimitry Andric StringRef Segment, Section; 13050b57cec5SDimitry Andric unsigned TAA = 0, StubSize = 0; 13060b57cec5SDimitry Andric bool TAAParsed; 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andric checkMachOComdat(GO); 13090b57cec5SDimitry Andric 1310fe6060f1SDimitry Andric if (Error E = MCSectionMachO::ParseSectionSpecifier( 1311fe6060f1SDimitry Andric SectionName, Segment, Section, TAA, TAAParsed, StubSize)) { 13120b57cec5SDimitry Andric // If invalid, report the error with report_fatal_error. 13130b57cec5SDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 13140b57cec5SDimitry Andric "' has an invalid section specifier '" + 1315fe6060f1SDimitry Andric GO->getSection() + "': " + toString(std::move(E)) + "."); 13160b57cec5SDimitry Andric } 13170b57cec5SDimitry Andric 13180b57cec5SDimitry Andric // Get the section. 13190b57cec5SDimitry Andric MCSectionMachO *S = 13200b57cec5SDimitry Andric getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 13210b57cec5SDimitry Andric 13220b57cec5SDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 13230b57cec5SDimitry Andric // use the value returned by getMachOSection() as a default. 13240b57cec5SDimitry Andric if (!TAAParsed) 13250b57cec5SDimitry Andric TAA = S->getTypeAndAttributes(); 13260b57cec5SDimitry Andric 13270b57cec5SDimitry Andric // Okay, now that we got the section, verify that the TAA & StubSize agree. 13280b57cec5SDimitry Andric // If the user declared multiple globals with different section flags, we need 13290b57cec5SDimitry Andric // to reject it here. 13300b57cec5SDimitry Andric if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 13310b57cec5SDimitry Andric // If invalid, report the error with report_fatal_error. 13320b57cec5SDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 13330b57cec5SDimitry Andric "' section type or attributes does not match previous" 13340b57cec5SDimitry Andric " section specifier"); 13350b57cec5SDimitry Andric } 13360b57cec5SDimitry Andric 13370b57cec5SDimitry Andric return S; 13380b57cec5SDimitry Andric } 13390b57cec5SDimitry Andric 13400b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 13410b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 13420b57cec5SDimitry Andric checkMachOComdat(GO); 13430b57cec5SDimitry Andric 13440b57cec5SDimitry Andric // Handle thread local data. 13450b57cec5SDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 13460b57cec5SDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 13470b57cec5SDimitry Andric 13480b57cec5SDimitry Andric if (Kind.isText()) 13490b57cec5SDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection; 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andric // If this is weak/linkonce, put this in a coalescable section, either in text 13520b57cec5SDimitry Andric // or data depending on if it is writable. 13530b57cec5SDimitry Andric if (GO->isWeakForLinker()) { 13540b57cec5SDimitry Andric if (Kind.isReadOnly()) 13550b57cec5SDimitry Andric return ConstTextCoalSection; 13560b57cec5SDimitry Andric if (Kind.isReadOnlyWithRel()) 13570b57cec5SDimitry Andric return ConstDataCoalSection; 13580b57cec5SDimitry Andric return DataCoalSection; 13590b57cec5SDimitry Andric } 13600b57cec5SDimitry Andric 13610b57cec5SDimitry Andric // FIXME: Alignment check should be handled by section classifier. 13620b57cec5SDimitry Andric if (Kind.isMergeable1ByteCString() && 1363*0fca6ea1SDimitry Andric GO->getDataLayout().getPreferredAlign( 13645ffd83dbSDimitry Andric cast<GlobalVariable>(GO)) < Align(32)) 13650b57cec5SDimitry Andric return CStringSection; 13660b57cec5SDimitry Andric 13670b57cec5SDimitry Andric // Do not put 16-bit arrays in the UString section if they have an 13680b57cec5SDimitry Andric // externally visible label, this runs into issues with certain linker 13690b57cec5SDimitry Andric // versions. 13700b57cec5SDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() && 1371*0fca6ea1SDimitry Andric GO->getDataLayout().getPreferredAlign( 13725ffd83dbSDimitry Andric cast<GlobalVariable>(GO)) < Align(32)) 13730b57cec5SDimitry Andric return UStringSection; 13740b57cec5SDimitry Andric 13750b57cec5SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 13760b57cec5SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 13770b57cec5SDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) { 13780b57cec5SDimitry Andric if (Kind.isMergeableConst4()) 13790b57cec5SDimitry Andric return FourByteConstantSection; 13800b57cec5SDimitry Andric if (Kind.isMergeableConst8()) 13810b57cec5SDimitry Andric return EightByteConstantSection; 13820b57cec5SDimitry Andric if (Kind.isMergeableConst16()) 13830b57cec5SDimitry Andric return SixteenByteConstantSection; 13840b57cec5SDimitry Andric } 13850b57cec5SDimitry Andric 13860b57cec5SDimitry Andric // Otherwise, if it is readonly, but not something we can specially optimize, 13870b57cec5SDimitry Andric // just drop it in .const. 13880b57cec5SDimitry Andric if (Kind.isReadOnly()) 13890b57cec5SDimitry Andric return ReadOnlySection; 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric // If this is marked const, put it into a const section. But if the dynamic 13920b57cec5SDimitry Andric // linker needs to write to it, put it in the data segment. 13930b57cec5SDimitry Andric if (Kind.isReadOnlyWithRel()) 13940b57cec5SDimitry Andric return ConstDataSection; 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andric // Put zero initialized globals with strong external linkage in the 13970b57cec5SDimitry Andric // DATA, __common section with the .zerofill directive. 13980b57cec5SDimitry Andric if (Kind.isBSSExtern()) 13990b57cec5SDimitry Andric return DataCommonSection; 14000b57cec5SDimitry Andric 14010b57cec5SDimitry Andric // Put zero initialized globals with local linkage in __DATA,__bss directive 14020b57cec5SDimitry Andric // with the .zerofill directive (aka .lcomm). 14030b57cec5SDimitry Andric if (Kind.isBSSLocal()) 14040b57cec5SDimitry Andric return DataBSSSection; 14050b57cec5SDimitry Andric 14060b57cec5SDimitry Andric // Otherwise, just drop the variable in the normal data section. 14070b57cec5SDimitry Andric return DataSection; 14080b57cec5SDimitry Andric } 14090b57cec5SDimitry Andric 14100b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 14110b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 14125ffd83dbSDimitry Andric Align &Alignment) const { 14130b57cec5SDimitry Andric // If this constant requires a relocation, we have to put it in the data 14140b57cec5SDimitry Andric // segment, not in the text segment. 14150b57cec5SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 14160b57cec5SDimitry Andric return ConstDataSection; 14170b57cec5SDimitry Andric 14180b57cec5SDimitry Andric if (Kind.isMergeableConst4()) 14190b57cec5SDimitry Andric return FourByteConstantSection; 14200b57cec5SDimitry Andric if (Kind.isMergeableConst8()) 14210b57cec5SDimitry Andric return EightByteConstantSection; 14220b57cec5SDimitry Andric if (Kind.isMergeableConst16()) 14230b57cec5SDimitry Andric return SixteenByteConstantSection; 14240b57cec5SDimitry Andric return ReadOnlySection; // .const 14250b57cec5SDimitry Andric } 14260b57cec5SDimitry Andric 142706c3fb27SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForCommandLines() const { 142806c3fb27SDimitry Andric return getContext().getMachOSection("__TEXT", "__command_line", 0, 142906c3fb27SDimitry Andric SectionKind::getReadOnly()); 143006c3fb27SDimitry Andric } 143106c3fb27SDimitry Andric 14320b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 14330b57cec5SDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 14340b57cec5SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 14350b57cec5SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 14360b57cec5SDimitry Andric 14370b57cec5SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 14380b57cec5SDimitry Andric MachineModuleInfoMachO &MachOMMI = 14390b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 14400b57cec5SDimitry Andric 14410b57cec5SDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 14420b57cec5SDimitry Andric 14430b57cec5SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 14440b57cec5SDimitry Andric // gets emitted by the asmprinter. 14450b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 14460b57cec5SDimitry Andric if (!StubSym.getPointer()) { 14470b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 14480b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 14490b57cec5SDimitry Andric } 14500b57cec5SDimitry Andric 14510b57cec5SDimitry Andric return TargetLoweringObjectFile:: 14520b57cec5SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 14530b57cec5SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 14540b57cec5SDimitry Andric } 14550b57cec5SDimitry Andric 14560b57cec5SDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 14570b57cec5SDimitry Andric MMI, Streamer); 14580b57cec5SDimitry Andric } 14590b57cec5SDimitry Andric 14600b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 14610b57cec5SDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 14620b57cec5SDimitry Andric MachineModuleInfo *MMI) const { 14630b57cec5SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 14640b57cec5SDimitry Andric MachineModuleInfoMachO &MachOMMI = 14650b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 14660b57cec5SDimitry Andric 14670b57cec5SDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 14680b57cec5SDimitry Andric 14690b57cec5SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 14700b57cec5SDimitry Andric // gets emitted by the asmprinter. 14710b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 14720b57cec5SDimitry Andric if (!StubSym.getPointer()) { 14730b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 14740b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 14750b57cec5SDimitry Andric } 14760b57cec5SDimitry Andric 14770b57cec5SDimitry Andric return SSym; 14780b57cec5SDimitry Andric } 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 14818bcb0991SDimitry Andric const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, 14828bcb0991SDimitry Andric int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { 14830b57cec5SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 14840b57cec5SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 14850b57cec5SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 14860b57cec5SDimitry Andric // computation of deltas to final external symbols. Example: 14870b57cec5SDimitry Andric // 14880b57cec5SDimitry Andric // _extgotequiv: 14890b57cec5SDimitry Andric // .long _extfoo 14900b57cec5SDimitry Andric // 14910b57cec5SDimitry Andric // _delta: 14920b57cec5SDimitry Andric // .long _extgotequiv-_delta 14930b57cec5SDimitry Andric // 14940b57cec5SDimitry Andric // is transformed to: 14950b57cec5SDimitry Andric // 14960b57cec5SDimitry Andric // _delta: 14970b57cec5SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 14980b57cec5SDimitry Andric // 14990b57cec5SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 15000b57cec5SDimitry Andric // L_extfoo$non_lazy_ptr: 15010b57cec5SDimitry Andric // .indirect_symbol _extfoo 15020b57cec5SDimitry Andric // .long 0 15030b57cec5SDimitry Andric // 15040b57cec5SDimitry Andric // The indirect symbol table (and sections of non_lazy_symbol_pointers type) 15050b57cec5SDimitry Andric // may point to both local (same translation unit) and global (other 15060b57cec5SDimitry Andric // translation units) symbols. Example: 15070b57cec5SDimitry Andric // 15080b57cec5SDimitry Andric // .section __DATA,__pointers,non_lazy_symbol_pointers 15090b57cec5SDimitry Andric // L1: 15100b57cec5SDimitry Andric // .indirect_symbol _myGlobal 15110b57cec5SDimitry Andric // .long 0 15120b57cec5SDimitry Andric // L2: 15130b57cec5SDimitry Andric // .indirect_symbol _myLocal 15140b57cec5SDimitry Andric // .long _myLocal 15150b57cec5SDimitry Andric // 15160b57cec5SDimitry Andric // If the symbol is local, instead of the symbol's index, the assembler 15170b57cec5SDimitry Andric // places the constant INDIRECT_SYMBOL_LOCAL into the indirect symbol table. 15180b57cec5SDimitry Andric // Then the linker will notice the constant in the table and will look at the 15190b57cec5SDimitry Andric // content of the symbol. 15200b57cec5SDimitry Andric MachineModuleInfoMachO &MachOMMI = 15210b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 15220b57cec5SDimitry Andric MCContext &Ctx = getContext(); 15230b57cec5SDimitry Andric 15240b57cec5SDimitry Andric // The offset must consider the original displacement from the base symbol 15250b57cec5SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 15260b57cec5SDimitry Andric Offset = -MV.getConstant(); 15270b57cec5SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 15280b57cec5SDimitry Andric 15290b57cec5SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 15300b57cec5SDimitry Andric // non_lazy_ptr stubs. 15310b57cec5SDimitry Andric SmallString<128> Name; 15320b57cec5SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 15330b57cec5SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 15340b57cec5SDimitry Andric Name += Sym->getName(); 15350b57cec5SDimitry Andric Name += Suffix; 15360b57cec5SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 15370b57cec5SDimitry Andric 15380b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 15398bcb0991SDimitry Andric 15408bcb0991SDimitry Andric if (!StubSym.getPointer()) 15410b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym), 15428bcb0991SDimitry Andric !GV->hasLocalLinkage()); 15430b57cec5SDimitry Andric 15440b57cec5SDimitry Andric const MCExpr *BSymExpr = 15450b57cec5SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 15460b57cec5SDimitry Andric const MCExpr *LHS = 15470b57cec5SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 15480b57cec5SDimitry Andric 15490b57cec5SDimitry Andric if (!Offset) 15500b57cec5SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 15510b57cec5SDimitry Andric 15520b57cec5SDimitry Andric const MCExpr *RHS = 15530b57cec5SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 15540b57cec5SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 15550b57cec5SDimitry Andric } 15560b57cec5SDimitry Andric 15570b57cec5SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 15580b57cec5SDimitry Andric const MCSection &Section) { 1559*0fca6ea1SDimitry Andric if (!MCAsmInfoDarwin::isSectionAtomizableBySymbols(Section)) 15600b57cec5SDimitry Andric return true; 15610b57cec5SDimitry Andric 1562fe6060f1SDimitry Andric // FIXME: we should be able to use private labels for sections that can't be 1563fe6060f1SDimitry Andric // dead-stripped (there's no issue with blocking atomization there), but `ld 1564fe6060f1SDimitry Andric // -r` sometimes drops the no_dead_strip attribute from sections so for safety 1565fe6060f1SDimitry Andric // we don't allow it. 15660b57cec5SDimitry Andric return false; 15670b57cec5SDimitry Andric } 15680b57cec5SDimitry Andric 15690b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 15700b57cec5SDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 15710b57cec5SDimitry Andric const TargetMachine &TM) const { 15720b57cec5SDimitry Andric bool CannotUsePrivateLabel = true; 1573349cc55cSDimitry Andric if (auto *GO = GV->getAliaseeObject()) { 15740b57cec5SDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); 15750b57cec5SDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); 15760b57cec5SDimitry Andric CannotUsePrivateLabel = 15770b57cec5SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 15780b57cec5SDimitry Andric } 15790b57cec5SDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 15800b57cec5SDimitry Andric } 15810b57cec5SDimitry Andric 15820b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 15830b57cec5SDimitry Andric // COFF 15840b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 15850b57cec5SDimitry Andric 15860b57cec5SDimitry Andric static unsigned 15870b57cec5SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 15880b57cec5SDimitry Andric unsigned Flags = 0; 15890b57cec5SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 15900b57cec5SDimitry Andric 15910b57cec5SDimitry Andric if (K.isMetadata()) 15920b57cec5SDimitry Andric Flags |= 15930b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_DISCARDABLE; 159481ad6265SDimitry Andric else if (K.isExclude()) 159581ad6265SDimitry Andric Flags |= 159681ad6265SDimitry Andric COFF::IMAGE_SCN_LNK_REMOVE | COFF::IMAGE_SCN_MEM_DISCARDABLE; 15970b57cec5SDimitry Andric else if (K.isText()) 15980b57cec5SDimitry Andric Flags |= 15990b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_EXECUTE | 16000b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 16010b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 16020b57cec5SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 16030b57cec5SDimitry Andric else if (K.isBSS()) 16040b57cec5SDimitry Andric Flags |= 16050b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 16060b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 16070b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 16080b57cec5SDimitry Andric else if (K.isThreadLocal()) 16090b57cec5SDimitry Andric Flags |= 16100b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 16110b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 16120b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 16130b57cec5SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 16140b57cec5SDimitry Andric Flags |= 16150b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 16160b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ; 16170b57cec5SDimitry Andric else if (K.isWriteable()) 16180b57cec5SDimitry Andric Flags |= 16190b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 16200b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 16210b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 16220b57cec5SDimitry Andric 16230b57cec5SDimitry Andric return Flags; 16240b57cec5SDimitry Andric } 16250b57cec5SDimitry Andric 16260b57cec5SDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 16270b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 16280b57cec5SDimitry Andric assert(C && "expected GV to have a Comdat!"); 16290b57cec5SDimitry Andric 16300b57cec5SDimitry Andric StringRef ComdatGVName = C->getName(); 16310b57cec5SDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 16320b57cec5SDimitry Andric if (!ComdatGV) 16330b57cec5SDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 16340b57cec5SDimitry Andric "' does not exist."); 16350b57cec5SDimitry Andric 16360b57cec5SDimitry Andric if (ComdatGV->getComdat() != C) 16370b57cec5SDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 16380b57cec5SDimitry Andric "' is not a key for its COMDAT."); 16390b57cec5SDimitry Andric 16400b57cec5SDimitry Andric return ComdatGV; 16410b57cec5SDimitry Andric } 16420b57cec5SDimitry Andric 16430b57cec5SDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 16440b57cec5SDimitry Andric if (const Comdat *C = GV->getComdat()) { 16450b57cec5SDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 16460b57cec5SDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 1647349cc55cSDimitry Andric ComdatKey = GA->getAliaseeObject(); 16480b57cec5SDimitry Andric if (ComdatKey == GV) { 16490b57cec5SDimitry Andric switch (C->getSelectionKind()) { 16500b57cec5SDimitry Andric case Comdat::Any: 16510b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 16520b57cec5SDimitry Andric case Comdat::ExactMatch: 16530b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 16540b57cec5SDimitry Andric case Comdat::Largest: 16550b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 1656fe6060f1SDimitry Andric case Comdat::NoDeduplicate: 16570b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 16580b57cec5SDimitry Andric case Comdat::SameSize: 16590b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 16600b57cec5SDimitry Andric } 16610b57cec5SDimitry Andric } else { 16620b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 16630b57cec5SDimitry Andric } 16640b57cec5SDimitry Andric } 16650b57cec5SDimitry Andric return 0; 16660b57cec5SDimitry Andric } 16670b57cec5SDimitry Andric 16680b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 16690b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1670297eecfbSDimitry Andric StringRef Name = GO->getSection(); 1671297eecfbSDimitry Andric if (Name == getInstrProfSectionName(IPSK_covmap, Triple::COFF, 1672297eecfbSDimitry Andric /*AddSegmentInfo=*/false) || 1673297eecfbSDimitry Andric Name == getInstrProfSectionName(IPSK_covfun, Triple::COFF, 1674297eecfbSDimitry Andric /*AddSegmentInfo=*/false) || 1675297eecfbSDimitry Andric Name == getInstrProfSectionName(IPSK_covdata, Triple::COFF, 1676297eecfbSDimitry Andric /*AddSegmentInfo=*/false) || 1677297eecfbSDimitry Andric Name == getInstrProfSectionName(IPSK_covname, Triple::COFF, 1678297eecfbSDimitry Andric /*AddSegmentInfo=*/false)) 1679297eecfbSDimitry Andric Kind = SectionKind::getMetadata(); 16800b57cec5SDimitry Andric int Selection = 0; 16810b57cec5SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 16820b57cec5SDimitry Andric StringRef COMDATSymName = ""; 16830b57cec5SDimitry Andric if (GO->hasComdat()) { 16840b57cec5SDimitry Andric Selection = getSelectionForCOFF(GO); 16850b57cec5SDimitry Andric const GlobalValue *ComdatGV; 16860b57cec5SDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 16870b57cec5SDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 16880b57cec5SDimitry Andric else 16890b57cec5SDimitry Andric ComdatGV = GO; 16900b57cec5SDimitry Andric 16910b57cec5SDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 16920b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 16930b57cec5SDimitry Andric COMDATSymName = Sym->getName(); 16940b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 16950b57cec5SDimitry Andric } else { 16960b57cec5SDimitry Andric Selection = 0; 16970b57cec5SDimitry Andric } 16980b57cec5SDimitry Andric } 16990b57cec5SDimitry Andric 1700*0fca6ea1SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, COMDATSymName, 17010b57cec5SDimitry Andric Selection); 17020b57cec5SDimitry Andric } 17030b57cec5SDimitry Andric 17040b57cec5SDimitry Andric static StringRef getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 17050b57cec5SDimitry Andric if (Kind.isText()) 17060b57cec5SDimitry Andric return ".text"; 17070b57cec5SDimitry Andric if (Kind.isBSS()) 17080b57cec5SDimitry Andric return ".bss"; 17090b57cec5SDimitry Andric if (Kind.isThreadLocal()) 17100b57cec5SDimitry Andric return ".tls$"; 17110b57cec5SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 17120b57cec5SDimitry Andric return ".rdata"; 17130b57cec5SDimitry Andric return ".data"; 17140b57cec5SDimitry Andric } 17150b57cec5SDimitry Andric 17160b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 17170b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 17180b57cec5SDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 17190b57cec5SDimitry Andric // uniqued section specifically for it. 17200b57cec5SDimitry Andric bool EmitUniquedSection; 17210b57cec5SDimitry Andric if (Kind.isText()) 17220b57cec5SDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 17230b57cec5SDimitry Andric else 17240b57cec5SDimitry Andric EmitUniquedSection = TM.getDataSections(); 17250b57cec5SDimitry Andric 17260b57cec5SDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) { 17270b57cec5SDimitry Andric SmallString<256> Name = getCOFFSectionNameForUniqueGlobal(Kind); 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 17300b57cec5SDimitry Andric 17310b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 17320b57cec5SDimitry Andric int Selection = getSelectionForCOFF(GO); 17330b57cec5SDimitry Andric if (!Selection) 17340b57cec5SDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 17350b57cec5SDimitry Andric const GlobalValue *ComdatGV; 17360b57cec5SDimitry Andric if (GO->hasComdat()) 17370b57cec5SDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 17380b57cec5SDimitry Andric else 17390b57cec5SDimitry Andric ComdatGV = GO; 17400b57cec5SDimitry Andric 17410b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 17420b57cec5SDimitry Andric if (EmitUniquedSection) 17430b57cec5SDimitry Andric UniqueID = NextUniqueID++; 17440b57cec5SDimitry Andric 17450b57cec5SDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 17460b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 17470b57cec5SDimitry Andric StringRef COMDATSymName = Sym->getName(); 17480b57cec5SDimitry Andric 1749e8d8bef9SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) 1750bdd1243dSDimitry Andric if (std::optional<StringRef> Prefix = F->getSectionPrefix()) 1751e8d8bef9SDimitry Andric raw_svector_ostream(Name) << '$' << *Prefix; 1752e8d8bef9SDimitry Andric 17530b57cec5SDimitry Andric // Append "$symbol" to the section name *before* IR-level mangling is 17540b57cec5SDimitry Andric // applied when targetting mingw. This is what GCC does, and the ld.bfd 17550b57cec5SDimitry Andric // COFF linker will not properly handle comdats otherwise. 1756fe6060f1SDimitry Andric if (getContext().getTargetTriple().isWindowsGNUEnvironment()) 17570b57cec5SDimitry Andric raw_svector_ostream(Name) << '$' << ComdatGV->getName(); 17580b57cec5SDimitry Andric 1759*0fca6ea1SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, COMDATSymName, 1760*0fca6ea1SDimitry Andric Selection, UniqueID); 17610b57cec5SDimitry Andric } else { 17620b57cec5SDimitry Andric SmallString<256> TmpData; 17630b57cec5SDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); 1764*0fca6ea1SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, TmpData, 17650b57cec5SDimitry Andric Selection, UniqueID); 17660b57cec5SDimitry Andric } 17670b57cec5SDimitry Andric } 17680b57cec5SDimitry Andric 17690b57cec5SDimitry Andric if (Kind.isText()) 17700b57cec5SDimitry Andric return TextSection; 17710b57cec5SDimitry Andric 17720b57cec5SDimitry Andric if (Kind.isThreadLocal()) 17730b57cec5SDimitry Andric return TLSDataSection; 17740b57cec5SDimitry Andric 17750b57cec5SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 17760b57cec5SDimitry Andric return ReadOnlySection; 17770b57cec5SDimitry Andric 17780b57cec5SDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 17790b57cec5SDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 17800b57cec5SDimitry Andric // entry but not a section. 17810b57cec5SDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 17820b57cec5SDimitry Andric return BSSSection; 17830b57cec5SDimitry Andric 17840b57cec5SDimitry Andric return DataSection; 17850b57cec5SDimitry Andric } 17860b57cec5SDimitry Andric 17870b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 17880b57cec5SDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 17890b57cec5SDimitry Andric const TargetMachine &TM) const { 17900b57cec5SDimitry Andric bool CannotUsePrivateLabel = false; 17910b57cec5SDimitry Andric if (GV->hasPrivateLinkage() && 17920b57cec5SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 17930b57cec5SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 17940b57cec5SDimitry Andric CannotUsePrivateLabel = true; 17950b57cec5SDimitry Andric 17960b57cec5SDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 17970b57cec5SDimitry Andric } 17980b57cec5SDimitry Andric 17990b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 18000b57cec5SDimitry Andric const Function &F, const TargetMachine &TM) const { 18010b57cec5SDimitry Andric // If the function can be removed, produce a unique section so that 18020b57cec5SDimitry Andric // the table doesn't prevent the removal. 18030b57cec5SDimitry Andric const Comdat *C = F.getComdat(); 18040b57cec5SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 18050b57cec5SDimitry Andric if (!EmitUniqueSection) 18060b57cec5SDimitry Andric return ReadOnlySection; 18070b57cec5SDimitry Andric 18080b57cec5SDimitry Andric // FIXME: we should produce a symbol for F instead. 18090b57cec5SDimitry Andric if (F.hasPrivateLinkage()) 18100b57cec5SDimitry Andric return ReadOnlySection; 18110b57cec5SDimitry Andric 18120b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(&F); 18130b57cec5SDimitry Andric StringRef COMDATSymName = Sym->getName(); 18140b57cec5SDimitry Andric 18150b57cec5SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 18160b57cec5SDimitry Andric StringRef SecName = getCOFFSectionNameForUniqueGlobal(Kind); 18170b57cec5SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 18180b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 18190b57cec5SDimitry Andric unsigned UniqueID = NextUniqueID++; 18200b57cec5SDimitry Andric 1821*0fca6ea1SDimitry Andric return getContext().getCOFFSection(SecName, Characteristics, COMDATSymName, 1822*0fca6ea1SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, 1823*0fca6ea1SDimitry Andric UniqueID); 18240b57cec5SDimitry Andric } 18250b57cec5SDimitry Andric 182606c3fb27SDimitry Andric bool TargetLoweringObjectFileCOFF::shouldPutJumpTableInFunctionSection( 182706c3fb27SDimitry Andric bool UsesLabelDifference, const Function &F) const { 182806c3fb27SDimitry Andric if (TM->getTargetTriple().getArch() == Triple::x86_64) { 182906c3fb27SDimitry Andric if (!JumpTableInFunctionSection) { 183006c3fb27SDimitry Andric // We can always create relative relocations, so use another section 183106c3fb27SDimitry Andric // that can be marked non-executable. 183206c3fb27SDimitry Andric return false; 183306c3fb27SDimitry Andric } 183406c3fb27SDimitry Andric } 183506c3fb27SDimitry Andric return TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( 183606c3fb27SDimitry Andric UsesLabelDifference, F); 183706c3fb27SDimitry Andric } 183806c3fb27SDimitry Andric 18390b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, 18400b57cec5SDimitry Andric Module &M) const { 1841e8d8bef9SDimitry Andric emitLinkerDirectives(Streamer, M); 1842e8d8bef9SDimitry Andric 1843e8d8bef9SDimitry Andric unsigned Version = 0; 1844e8d8bef9SDimitry Andric unsigned Flags = 0; 1845e8d8bef9SDimitry Andric StringRef Section; 1846e8d8bef9SDimitry Andric 1847e8d8bef9SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 1848e8d8bef9SDimitry Andric if (!Section.empty()) { 1849e8d8bef9SDimitry Andric auto &C = getContext(); 1850*0fca6ea1SDimitry Andric auto *S = C.getCOFFSection(Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1851*0fca6ea1SDimitry Andric COFF::IMAGE_SCN_MEM_READ); 185281ad6265SDimitry Andric Streamer.switchSection(S); 1853e8d8bef9SDimitry Andric Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 1854e8d8bef9SDimitry Andric Streamer.emitInt32(Version); 1855e8d8bef9SDimitry Andric Streamer.emitInt32(Flags); 185681ad6265SDimitry Andric Streamer.addBlankLine(); 1857e8d8bef9SDimitry Andric } 1858e8d8bef9SDimitry Andric 1859e8d8bef9SDimitry Andric emitCGProfileMetadata(Streamer, M); 1860e8d8bef9SDimitry Andric } 1861e8d8bef9SDimitry Andric 1862e8d8bef9SDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerDirectives( 1863e8d8bef9SDimitry Andric MCStreamer &Streamer, Module &M) const { 18640b57cec5SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 18650b57cec5SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 18660b57cec5SDimitry Andric // spec, this section is a space-separated string containing flags for 18670b57cec5SDimitry Andric // linker. 18680b57cec5SDimitry Andric MCSection *Sec = getDrectveSection(); 186981ad6265SDimitry Andric Streamer.switchSection(Sec); 1870480093f4SDimitry Andric for (const auto *Option : LinkerOptions->operands()) { 18710b57cec5SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 18720b57cec5SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 18730b57cec5SDimitry Andric std::string Directive(" "); 18745ffd83dbSDimitry Andric Directive.append(std::string(cast<MDString>(Piece)->getString())); 18755ffd83dbSDimitry Andric Streamer.emitBytes(Directive); 18760b57cec5SDimitry Andric } 18770b57cec5SDimitry Andric } 18780b57cec5SDimitry Andric } 18790b57cec5SDimitry Andric 1880e8d8bef9SDimitry Andric // Emit /EXPORT: flags for each exported global as necessary. 1881e8d8bef9SDimitry Andric std::string Flags; 1882e8d8bef9SDimitry Andric for (const GlobalValue &GV : M.global_values()) { 1883e8d8bef9SDimitry Andric raw_string_ostream OS(Flags); 1884fe6060f1SDimitry Andric emitLinkerFlagsForGlobalCOFF(OS, &GV, getContext().getTargetTriple(), 1885fe6060f1SDimitry Andric getMangler()); 1886e8d8bef9SDimitry Andric OS.flush(); 1887e8d8bef9SDimitry Andric if (!Flags.empty()) { 188881ad6265SDimitry Andric Streamer.switchSection(getDrectveSection()); 1889e8d8bef9SDimitry Andric Streamer.emitBytes(Flags); 1890e8d8bef9SDimitry Andric } 1891e8d8bef9SDimitry Andric Flags.clear(); 1892e8d8bef9SDimitry Andric } 18930b57cec5SDimitry Andric 1894e8d8bef9SDimitry Andric // Emit /INCLUDE: flags for each used global as necessary. 1895e8d8bef9SDimitry Andric if (const auto *LU = M.getNamedGlobal("llvm.used")) { 1896e8d8bef9SDimitry Andric assert(LU->hasInitializer() && "expected llvm.used to have an initializer"); 1897e8d8bef9SDimitry Andric assert(isa<ArrayType>(LU->getValueType()) && 1898e8d8bef9SDimitry Andric "expected llvm.used to be an array type"); 1899e8d8bef9SDimitry Andric if (const auto *A = cast<ConstantArray>(LU->getInitializer())) { 1900e8d8bef9SDimitry Andric for (const Value *Op : A->operands()) { 1901e8d8bef9SDimitry Andric const auto *GV = cast<GlobalValue>(Op->stripPointerCasts()); 1902e8d8bef9SDimitry Andric // Global symbols with internal or private linkage are not visible to 1903e8d8bef9SDimitry Andric // the linker, and thus would cause an error when the linker tried to 1904e8d8bef9SDimitry Andric // preserve the symbol due to the `/include:` directive. 1905e8d8bef9SDimitry Andric if (GV->hasLocalLinkage()) 1906e8d8bef9SDimitry Andric continue; 19070b57cec5SDimitry Andric 1908e8d8bef9SDimitry Andric raw_string_ostream OS(Flags); 1909fe6060f1SDimitry Andric emitLinkerFlagsForUsedCOFF(OS, GV, getContext().getTargetTriple(), 1910fe6060f1SDimitry Andric getMangler()); 1911e8d8bef9SDimitry Andric OS.flush(); 1912e8d8bef9SDimitry Andric 1913e8d8bef9SDimitry Andric if (!Flags.empty()) { 191481ad6265SDimitry Andric Streamer.switchSection(getDrectveSection()); 1915e8d8bef9SDimitry Andric Streamer.emitBytes(Flags); 1916e8d8bef9SDimitry Andric } 1917e8d8bef9SDimitry Andric Flags.clear(); 1918e8d8bef9SDimitry Andric } 1919e8d8bef9SDimitry Andric } 1920e8d8bef9SDimitry Andric } 19210b57cec5SDimitry Andric } 19220b57cec5SDimitry Andric 19230b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, 19240b57cec5SDimitry Andric const TargetMachine &TM) { 19250b57cec5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 1926e8d8bef9SDimitry Andric this->TM = &TM; 19270b57cec5SDimitry Andric const Triple &T = TM.getTargetTriple(); 19280b57cec5SDimitry Andric if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 19290b57cec5SDimitry Andric StaticCtorSection = 19300b57cec5SDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1931*0fca6ea1SDimitry Andric COFF::IMAGE_SCN_MEM_READ); 19320b57cec5SDimitry Andric StaticDtorSection = 19330b57cec5SDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1934*0fca6ea1SDimitry Andric COFF::IMAGE_SCN_MEM_READ); 19350b57cec5SDimitry Andric } else { 19360b57cec5SDimitry Andric StaticCtorSection = Ctx.getCOFFSection( 19370b57cec5SDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1938*0fca6ea1SDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE); 19390b57cec5SDimitry Andric StaticDtorSection = Ctx.getCOFFSection( 19400b57cec5SDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1941*0fca6ea1SDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE); 19420b57cec5SDimitry Andric } 19430b57cec5SDimitry Andric } 19440b57cec5SDimitry Andric 19450b57cec5SDimitry Andric static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx, 19460b57cec5SDimitry Andric const Triple &T, bool IsCtor, 19470b57cec5SDimitry Andric unsigned Priority, 19480b57cec5SDimitry Andric const MCSymbol *KeySym, 19490b57cec5SDimitry Andric MCSectionCOFF *Default) { 19500b57cec5SDimitry Andric if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 19510b57cec5SDimitry Andric // If the priority is the default, use .CRT$XCU, possibly associative. 19520b57cec5SDimitry Andric if (Priority == 65535) 19530b57cec5SDimitry Andric return Ctx.getAssociativeCOFFSection(Default, KeySym, 0); 19540b57cec5SDimitry Andric 19550b57cec5SDimitry Andric // Otherwise, we need to compute a new section name. Low priorities should 19560b57cec5SDimitry Andric // run earlier. The linker will sort sections ASCII-betically, and we need a 19570b57cec5SDimitry Andric // string that sorts between .CRT$XCA and .CRT$XCU. In the general case, we 19580b57cec5SDimitry Andric // make a name like ".CRT$XCT12345", since that runs before .CRT$XCU. Really 19590b57cec5SDimitry Andric // low priorities need to sort before 'L', since the CRT uses that 1960bdd1243dSDimitry Andric // internally, so we use ".CRT$XCA00001" for them. We have a contract with 1961bdd1243dSDimitry Andric // the frontend that "init_seg(compiler)" corresponds to priority 200 and 1962bdd1243dSDimitry Andric // "init_seg(lib)" corresponds to priority 400, and those respectively use 1963bdd1243dSDimitry Andric // 'C' and 'L' without the priority suffix. Priorities between 200 and 400 1964bdd1243dSDimitry Andric // use 'C' with the priority as a suffix. 19650b57cec5SDimitry Andric SmallString<24> Name; 1966bdd1243dSDimitry Andric char LastLetter = 'T'; 1967bdd1243dSDimitry Andric bool AddPrioritySuffix = Priority != 200 && Priority != 400; 1968bdd1243dSDimitry Andric if (Priority < 200) 1969bdd1243dSDimitry Andric LastLetter = 'A'; 1970bdd1243dSDimitry Andric else if (Priority < 400) 1971bdd1243dSDimitry Andric LastLetter = 'C'; 1972bdd1243dSDimitry Andric else if (Priority == 400) 1973bdd1243dSDimitry Andric LastLetter = 'L'; 19740b57cec5SDimitry Andric raw_svector_ostream OS(Name); 1975bdd1243dSDimitry Andric OS << ".CRT$X" << (IsCtor ? "C" : "T") << LastLetter; 1976bdd1243dSDimitry Andric if (AddPrioritySuffix) 1977bdd1243dSDimitry Andric OS << format("%05u", Priority); 19780b57cec5SDimitry Andric MCSectionCOFF *Sec = Ctx.getCOFFSection( 1979*0fca6ea1SDimitry Andric Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ); 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 | 1990*0fca6ea1SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE), 19910b57cec5SDimitry Andric KeySym, 0); 19920b57cec5SDimitry Andric } 19930b57cec5SDimitry Andric 19940b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 19950b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 1996fe6060f1SDimitry Andric return getCOFFStaticStructorSection( 1997fe6060f1SDimitry Andric getContext(), getContext().getTargetTriple(), true, Priority, KeySym, 19980b57cec5SDimitry Andric cast<MCSectionCOFF>(StaticCtorSection)); 19990b57cec5SDimitry Andric } 20000b57cec5SDimitry Andric 20010b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 20020b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 2003fe6060f1SDimitry Andric return getCOFFStaticStructorSection( 2004fe6060f1SDimitry Andric getContext(), getContext().getTargetTriple(), false, Priority, KeySym, 20050b57cec5SDimitry Andric cast<MCSectionCOFF>(StaticDtorSection)); 20060b57cec5SDimitry Andric } 20070b57cec5SDimitry Andric 20080b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( 20090b57cec5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 20100b57cec5SDimitry Andric const TargetMachine &TM) const { 20110b57cec5SDimitry Andric const Triple &T = TM.getTargetTriple(); 20120b57cec5SDimitry Andric if (T.isOSCygMing()) 20130b57cec5SDimitry Andric return nullptr; 20140b57cec5SDimitry Andric 20150b57cec5SDimitry Andric // Our symbols should exist in address space zero, cowardly no-op if 20160b57cec5SDimitry Andric // otherwise. 20170b57cec5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 20180b57cec5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0) 20190b57cec5SDimitry Andric return nullptr; 20200b57cec5SDimitry Andric 20210b57cec5SDimitry Andric // Both ptrtoint instructions must wrap global objects: 20220b57cec5SDimitry Andric // - Only global variables are eligible for image relative relocations. 20230b57cec5SDimitry Andric // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable. 20240b57cec5SDimitry Andric // We expect __ImageBase to be a global variable without a section, externally 20250b57cec5SDimitry Andric // defined. 20260b57cec5SDimitry Andric // 20270b57cec5SDimitry Andric // It should look something like this: @__ImageBase = external constant i8 20280b57cec5SDimitry Andric if (!isa<GlobalObject>(LHS) || !isa<GlobalVariable>(RHS) || 20290b57cec5SDimitry Andric LHS->isThreadLocal() || RHS->isThreadLocal() || 20300b57cec5SDimitry Andric RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() || 20310b57cec5SDimitry Andric cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection()) 20320b57cec5SDimitry Andric return nullptr; 20330b57cec5SDimitry Andric 20340b57cec5SDimitry Andric return MCSymbolRefExpr::create(TM.getSymbol(LHS), 20350b57cec5SDimitry Andric MCSymbolRefExpr::VK_COFF_IMGREL32, 20360b57cec5SDimitry Andric getContext()); 20370b57cec5SDimitry Andric } 20380b57cec5SDimitry Andric 20390b57cec5SDimitry Andric static std::string APIntToHexString(const APInt &AI) { 20400b57cec5SDimitry Andric unsigned Width = (AI.getBitWidth() / 8) * 2; 2041fe6060f1SDimitry Andric std::string HexString = toString(AI, 16, /*Signed=*/false); 20425ffd83dbSDimitry Andric llvm::transform(HexString, HexString.begin(), tolower); 20430b57cec5SDimitry Andric unsigned Size = HexString.size(); 20440b57cec5SDimitry Andric assert(Width >= Size && "hex string is too large!"); 20450b57cec5SDimitry Andric HexString.insert(HexString.begin(), Width - Size, '0'); 20460b57cec5SDimitry Andric 20470b57cec5SDimitry Andric return HexString; 20480b57cec5SDimitry Andric } 20490b57cec5SDimitry Andric 20500b57cec5SDimitry Andric static std::string scalarConstantToHexString(const Constant *C) { 20510b57cec5SDimitry Andric Type *Ty = C->getType(); 20520b57cec5SDimitry Andric if (isa<UndefValue>(C)) { 2053349cc55cSDimitry Andric return APIntToHexString(APInt::getZero(Ty->getPrimitiveSizeInBits())); 20540b57cec5SDimitry Andric } else if (const auto *CFP = dyn_cast<ConstantFP>(C)) { 20550b57cec5SDimitry Andric return APIntToHexString(CFP->getValueAPF().bitcastToAPInt()); 20560b57cec5SDimitry Andric } else if (const auto *CI = dyn_cast<ConstantInt>(C)) { 20570b57cec5SDimitry Andric return APIntToHexString(CI->getValue()); 20580b57cec5SDimitry Andric } else { 20590b57cec5SDimitry Andric unsigned NumElements; 20605ffd83dbSDimitry Andric if (auto *VTy = dyn_cast<VectorType>(Ty)) 20615ffd83dbSDimitry Andric NumElements = cast<FixedVectorType>(VTy)->getNumElements(); 20620b57cec5SDimitry Andric else 20630b57cec5SDimitry Andric NumElements = Ty->getArrayNumElements(); 20640b57cec5SDimitry Andric std::string HexString; 20650b57cec5SDimitry Andric for (int I = NumElements - 1, E = -1; I != E; --I) 20660b57cec5SDimitry Andric HexString += scalarConstantToHexString(C->getAggregateElement(I)); 20670b57cec5SDimitry Andric return HexString; 20680b57cec5SDimitry Andric } 20690b57cec5SDimitry Andric } 20700b57cec5SDimitry Andric 20710b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant( 20720b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 20735ffd83dbSDimitry Andric Align &Alignment) const { 20740b57cec5SDimitry Andric if (Kind.isMergeableConst() && C && 20750b57cec5SDimitry Andric getContext().getAsmInfo()->hasCOFFComdatConstants()) { 20760b57cec5SDimitry Andric // This creates comdat sections with the given symbol name, but unless 20770b57cec5SDimitry Andric // AsmPrinter::GetCPISymbol actually makes the symbol global, the symbol 20780b57cec5SDimitry Andric // will be created with a null storage class, which makes GNU binutils 20790b57cec5SDimitry Andric // error out. 20800b57cec5SDimitry Andric const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 20810b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 20820b57cec5SDimitry Andric COFF::IMAGE_SCN_LNK_COMDAT; 20830b57cec5SDimitry Andric std::string COMDATSymName; 20840b57cec5SDimitry Andric if (Kind.isMergeableConst4()) { 20855ffd83dbSDimitry Andric if (Alignment <= 4) { 20860b57cec5SDimitry Andric COMDATSymName = "__real@" + scalarConstantToHexString(C); 20875ffd83dbSDimitry Andric Alignment = Align(4); 20880b57cec5SDimitry Andric } 20890b57cec5SDimitry Andric } else if (Kind.isMergeableConst8()) { 20905ffd83dbSDimitry Andric if (Alignment <= 8) { 20910b57cec5SDimitry Andric COMDATSymName = "__real@" + scalarConstantToHexString(C); 20925ffd83dbSDimitry Andric Alignment = Align(8); 20930b57cec5SDimitry Andric } 20940b57cec5SDimitry Andric } else if (Kind.isMergeableConst16()) { 20950b57cec5SDimitry Andric // FIXME: These may not be appropriate for non-x86 architectures. 20965ffd83dbSDimitry Andric if (Alignment <= 16) { 20970b57cec5SDimitry Andric COMDATSymName = "__xmm@" + scalarConstantToHexString(C); 20985ffd83dbSDimitry Andric Alignment = Align(16); 20990b57cec5SDimitry Andric } 21000b57cec5SDimitry Andric } else if (Kind.isMergeableConst32()) { 21015ffd83dbSDimitry Andric if (Alignment <= 32) { 21020b57cec5SDimitry Andric COMDATSymName = "__ymm@" + scalarConstantToHexString(C); 21035ffd83dbSDimitry Andric Alignment = Align(32); 21040b57cec5SDimitry Andric } 21050b57cec5SDimitry Andric } 21060b57cec5SDimitry Andric 21070b57cec5SDimitry Andric if (!COMDATSymName.empty()) 2108*0fca6ea1SDimitry Andric return getContext().getCOFFSection(".rdata", Characteristics, 21090b57cec5SDimitry Andric COMDATSymName, 21100b57cec5SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ANY); 21110b57cec5SDimitry Andric } 21120b57cec5SDimitry Andric 21135ffd83dbSDimitry Andric return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, 21145ffd83dbSDimitry Andric Alignment); 21150b57cec5SDimitry Andric } 21160b57cec5SDimitry Andric 21170b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 21180b57cec5SDimitry Andric // Wasm 21190b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 21200b57cec5SDimitry Andric 21210b57cec5SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) { 21220b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 21230b57cec5SDimitry Andric if (!C) 21240b57cec5SDimitry Andric return nullptr; 21250b57cec5SDimitry Andric 21260b57cec5SDimitry Andric if (C->getSelectionKind() != Comdat::Any) 21270b57cec5SDimitry Andric report_fatal_error("WebAssembly COMDATs only support " 21280b57cec5SDimitry Andric "SelectionKind::Any, '" + C->getName() + "' cannot be " 21290b57cec5SDimitry Andric "lowered."); 21300b57cec5SDimitry Andric 21310b57cec5SDimitry Andric return C; 21320b57cec5SDimitry Andric } 21330b57cec5SDimitry Andric 2134*0fca6ea1SDimitry Andric static unsigned getWasmSectionFlags(SectionKind K, bool Retain) { 2135fe6060f1SDimitry Andric unsigned Flags = 0; 2136fe6060f1SDimitry Andric 2137fe6060f1SDimitry Andric if (K.isThreadLocal()) 2138fe6060f1SDimitry Andric Flags |= wasm::WASM_SEG_FLAG_TLS; 2139fe6060f1SDimitry Andric 2140fe6060f1SDimitry Andric if (K.isMergeableCString()) 2141fe6060f1SDimitry Andric Flags |= wasm::WASM_SEG_FLAG_STRINGS; 2142fe6060f1SDimitry Andric 2143*0fca6ea1SDimitry Andric if (Retain) 2144*0fca6ea1SDimitry Andric Flags |= wasm::WASM_SEG_FLAG_RETAIN; 2145*0fca6ea1SDimitry Andric 2146fe6060f1SDimitry Andric // TODO(sbc): Add suport for K.isMergeableConst() 2147fe6060f1SDimitry Andric 2148fe6060f1SDimitry Andric return Flags; 2149fe6060f1SDimitry Andric } 2150fe6060f1SDimitry Andric 2151*0fca6ea1SDimitry Andric void TargetLoweringObjectFileWasm::getModuleMetadata(Module &M) { 2152*0fca6ea1SDimitry Andric SmallVector<GlobalValue *, 4> Vec; 2153*0fca6ea1SDimitry Andric collectUsedGlobalVariables(M, Vec, false); 2154*0fca6ea1SDimitry Andric for (GlobalValue *GV : Vec) 2155*0fca6ea1SDimitry Andric if (auto *GO = dyn_cast<GlobalObject>(GV)) 2156*0fca6ea1SDimitry Andric Used.insert(GO); 2157*0fca6ea1SDimitry Andric } 2158*0fca6ea1SDimitry Andric 21590b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( 21600b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 21610b57cec5SDimitry Andric // We don't support explict section names for functions in the wasm object 21620b57cec5SDimitry Andric // format. Each function has to be in its own unique section. 21630b57cec5SDimitry Andric if (isa<Function>(GO)) { 21640b57cec5SDimitry Andric return SelectSectionForGlobal(GO, Kind, TM); 21650b57cec5SDimitry Andric } 21660b57cec5SDimitry Andric 21670b57cec5SDimitry Andric StringRef Name = GO->getSection(); 21680b57cec5SDimitry Andric 21695ffd83dbSDimitry Andric // Certain data sections we treat as named custom sections rather than 21705ffd83dbSDimitry Andric // segments within the data section. 21715ffd83dbSDimitry Andric // This could be avoided if all data segements (the wasm sense) were 21725ffd83dbSDimitry Andric // represented as their own sections (in the llvm sense). 21735ffd83dbSDimitry Andric // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138 21745ffd83dbSDimitry Andric if (Name == ".llvmcmd" || Name == ".llvmbc") 21755ffd83dbSDimitry Andric Kind = SectionKind::getMetadata(); 21760b57cec5SDimitry Andric 21770b57cec5SDimitry Andric StringRef Group = ""; 21780b57cec5SDimitry Andric if (const Comdat *C = getWasmComdat(GO)) { 21790b57cec5SDimitry Andric Group = C->getName(); 21800b57cec5SDimitry Andric } 21810b57cec5SDimitry Andric 2182*0fca6ea1SDimitry Andric unsigned Flags = getWasmSectionFlags(Kind, Used.count(GO)); 2183fe6060f1SDimitry Andric MCSectionWasm *Section = getContext().getWasmSection( 2184fe6060f1SDimitry Andric Name, Kind, Flags, Group, MCContext::GenericSectionID); 21850b57cec5SDimitry Andric 21860b57cec5SDimitry Andric return Section; 21870b57cec5SDimitry Andric } 21880b57cec5SDimitry Andric 2189*0fca6ea1SDimitry Andric static MCSectionWasm * 2190*0fca6ea1SDimitry Andric selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO, 2191*0fca6ea1SDimitry Andric SectionKind Kind, Mangler &Mang, 2192*0fca6ea1SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, 2193*0fca6ea1SDimitry Andric unsigned *NextUniqueID, bool Retain) { 21940b57cec5SDimitry Andric StringRef Group = ""; 21950b57cec5SDimitry Andric if (const Comdat *C = getWasmComdat(GO)) { 21960b57cec5SDimitry Andric Group = C->getName(); 21970b57cec5SDimitry Andric } 21980b57cec5SDimitry Andric 21990b57cec5SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 220006c3fb27SDimitry Andric SmallString<128> Name = getSectionPrefixForGlobal(Kind, /*IsLarge=*/false); 22010b57cec5SDimitry Andric 22020b57cec5SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 22030b57cec5SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 22040b57cec5SDimitry Andric if (OptionalPrefix) 2205e8d8bef9SDimitry Andric raw_svector_ostream(Name) << '.' << *OptionalPrefix; 22060b57cec5SDimitry Andric } 22070b57cec5SDimitry Andric 22080b57cec5SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 22090b57cec5SDimitry Andric Name.push_back('.'); 22100b57cec5SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 22110b57cec5SDimitry Andric } 22120b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 22130b57cec5SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 22140b57cec5SDimitry Andric UniqueID = *NextUniqueID; 22150b57cec5SDimitry Andric (*NextUniqueID)++; 22160b57cec5SDimitry Andric } 22170b57cec5SDimitry Andric 2218*0fca6ea1SDimitry Andric unsigned Flags = getWasmSectionFlags(Kind, Retain); 2219fe6060f1SDimitry Andric return Ctx.getWasmSection(Name, Kind, Flags, Group, UniqueID); 22200b57cec5SDimitry Andric } 22210b57cec5SDimitry Andric 22220b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( 22230b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 22240b57cec5SDimitry Andric 22250b57cec5SDimitry Andric if (Kind.isCommon()) 22260b57cec5SDimitry Andric report_fatal_error("mergable sections not supported yet on wasm"); 22270b57cec5SDimitry Andric 22280b57cec5SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 22290b57cec5SDimitry Andric // global value to a uniqued section specifically for it. 22300b57cec5SDimitry Andric bool EmitUniqueSection = false; 22310b57cec5SDimitry Andric if (Kind.isText()) 22320b57cec5SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 22330b57cec5SDimitry Andric else 22340b57cec5SDimitry Andric EmitUniqueSection = TM.getDataSections(); 22350b57cec5SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 2236*0fca6ea1SDimitry Andric bool Retain = Used.count(GO); 2237*0fca6ea1SDimitry Andric EmitUniqueSection |= Retain; 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andric return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 2240*0fca6ea1SDimitry Andric EmitUniqueSection, &NextUniqueID, Retain); 22410b57cec5SDimitry Andric } 22420b57cec5SDimitry Andric 22430b57cec5SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( 22440b57cec5SDimitry Andric bool UsesLabelDifference, const Function &F) const { 22450b57cec5SDimitry Andric // We can always create relative relocations, so use another section 22460b57cec5SDimitry Andric // that can be marked non-executable. 22470b57cec5SDimitry Andric return false; 22480b57cec5SDimitry Andric } 22490b57cec5SDimitry Andric 22500b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( 22510b57cec5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 22520b57cec5SDimitry Andric const TargetMachine &TM) const { 22530b57cec5SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 22540b57cec5SDimitry Andric // functions. 22550b57cec5SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 22560b57cec5SDimitry Andric return nullptr; 22570b57cec5SDimitry Andric 22584824e7fdSDimitry Andric // Basic correctness checks. 22590b57cec5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 22600b57cec5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 22610b57cec5SDimitry Andric RHS->isThreadLocal()) 22620b57cec5SDimitry Andric return nullptr; 22630b57cec5SDimitry Andric 22640b57cec5SDimitry Andric return MCBinaryExpr::createSub( 22650b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, 22660b57cec5SDimitry Andric getContext()), 22670b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 22680b57cec5SDimitry Andric } 22690b57cec5SDimitry Andric 22700b57cec5SDimitry Andric void TargetLoweringObjectFileWasm::InitializeWasm() { 22710b57cec5SDimitry Andric StaticCtorSection = 22720b57cec5SDimitry Andric getContext().getWasmSection(".init_array", SectionKind::getData()); 22730b57cec5SDimitry Andric 22740b57cec5SDimitry Andric // We don't use PersonalityEncoding and LSDAEncoding because we don't emit 22750b57cec5SDimitry Andric // .cfi directives. We use TTypeEncoding to encode typeinfo global variables. 22760b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 22770b57cec5SDimitry Andric } 22780b57cec5SDimitry Andric 22790b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticCtorSection( 22800b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 22810b57cec5SDimitry Andric return Priority == UINT16_MAX ? 22820b57cec5SDimitry Andric StaticCtorSection : 22830b57cec5SDimitry Andric getContext().getWasmSection(".init_array." + utostr(Priority), 22840b57cec5SDimitry Andric SectionKind::getData()); 22850b57cec5SDimitry Andric } 22860b57cec5SDimitry Andric 22870b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection( 22880b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 228981ad6265SDimitry Andric report_fatal_error("@llvm.global_dtors should have been lowered already"); 22900b57cec5SDimitry Andric } 22918bcb0991SDimitry Andric 22928bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 22938bcb0991SDimitry Andric // XCOFF 22948bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 2295e8d8bef9SDimitry Andric bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock( 2296e8d8bef9SDimitry Andric const MachineFunction *MF) { 2297e8d8bef9SDimitry Andric if (!MF->getLandingPads().empty()) 2298e8d8bef9SDimitry Andric return true; 2299e8d8bef9SDimitry Andric 2300e8d8bef9SDimitry Andric const Function &F = MF->getFunction(); 2301e8d8bef9SDimitry Andric if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry()) 2302e8d8bef9SDimitry Andric return false; 2303e8d8bef9SDimitry Andric 2304fe6060f1SDimitry Andric const GlobalValue *Per = 2305fe6060f1SDimitry Andric dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts()); 2306fe6060f1SDimitry Andric assert(Per && "Personality routine is not a GlobalValue type."); 2307e8d8bef9SDimitry Andric if (isNoOpWithoutInvoke(classifyEHPersonality(Per))) 2308e8d8bef9SDimitry Andric return false; 2309e8d8bef9SDimitry Andric 2310e8d8bef9SDimitry Andric return true; 2311e8d8bef9SDimitry Andric } 2312e8d8bef9SDimitry Andric 2313fe6060f1SDimitry Andric bool TargetLoweringObjectFileXCOFF::ShouldSetSSPCanaryBitInTB( 2314fe6060f1SDimitry Andric const MachineFunction *MF) { 2315fe6060f1SDimitry Andric const Function &F = MF->getFunction(); 2316fe6060f1SDimitry Andric if (!F.hasStackProtectorFnAttr()) 2317fe6060f1SDimitry Andric return false; 2318fe6060f1SDimitry Andric // FIXME: check presence of canary word 2319fe6060f1SDimitry Andric // There are cases that the stack protectors are not really inserted even if 2320fe6060f1SDimitry Andric // the attributes are on. 2321fe6060f1SDimitry Andric return true; 2322fe6060f1SDimitry Andric } 2323fe6060f1SDimitry Andric 2324e8d8bef9SDimitry Andric MCSymbol * 2325e8d8bef9SDimitry Andric TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) { 2326*0fca6ea1SDimitry Andric MCSymbol *EHInfoSym = MF->getContext().getOrCreateSymbol( 2327e8d8bef9SDimitry Andric "__ehinfo." + Twine(MF->getFunctionNumber())); 23285f757f3fSDimitry Andric cast<MCSymbolXCOFF>(EHInfoSym)->setEHInfo(); 23295f757f3fSDimitry Andric return EHInfoSym; 2330e8d8bef9SDimitry Andric } 2331e8d8bef9SDimitry Andric 23325ffd83dbSDimitry Andric MCSymbol * 23335ffd83dbSDimitry Andric TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV, 23345ffd83dbSDimitry Andric const TargetMachine &TM) const { 23355ffd83dbSDimitry Andric // We always use a qualname symbol for a GV that represents 23365ffd83dbSDimitry Andric // a declaration, a function descriptor, or a common symbol. 2337e8d8bef9SDimitry Andric // If a GV represents a GlobalVariable and -fdata-sections is enabled, we 2338e8d8bef9SDimitry Andric // also return a qualname so that a label symbol could be avoided. 23395ffd83dbSDimitry Andric // It is inherently ambiguous when the GO represents the address of a 23405ffd83dbSDimitry Andric // function, as the GO could either represent a function descriptor or a 23415ffd83dbSDimitry Andric // function entry point. We choose to always return a function descriptor 23425ffd83dbSDimitry Andric // here. 23435ffd83dbSDimitry Andric if (const GlobalObject *GO = dyn_cast<GlobalObject>(GV)) { 2344bdd1243dSDimitry Andric if (GO->isDeclarationForLinker()) 2345bdd1243dSDimitry Andric return cast<MCSectionXCOFF>(getSectionForExternalReference(GO, TM)) 2346bdd1243dSDimitry Andric ->getQualNameSymbol(); 2347bdd1243dSDimitry Andric 2348fe6060f1SDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) 2349fe6060f1SDimitry Andric if (GVar->hasAttribute("toc-data")) 2350fe6060f1SDimitry Andric return cast<MCSectionXCOFF>( 2351fe6060f1SDimitry Andric SectionForGlobal(GVar, SectionKind::getData(), TM)) 2352fe6060f1SDimitry Andric ->getQualNameSymbol(); 2353fe6060f1SDimitry Andric 23545ffd83dbSDimitry Andric SectionKind GOKind = getKindForGlobal(GO, TM); 23555ffd83dbSDimitry Andric if (GOKind.isText()) 23565ffd83dbSDimitry Andric return cast<MCSectionXCOFF>( 23575ffd83dbSDimitry Andric getSectionForFunctionDescriptor(cast<Function>(GO), TM)) 23585ffd83dbSDimitry Andric ->getQualNameSymbol(); 2359fe6060f1SDimitry Andric if ((TM.getDataSections() && !GO->hasSection()) || GO->hasCommonLinkage() || 2360fe6060f1SDimitry Andric GOKind.isBSSLocal() || GOKind.isThreadBSSLocal()) 23615ffd83dbSDimitry Andric return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM)) 23625ffd83dbSDimitry Andric ->getQualNameSymbol(); 23635ffd83dbSDimitry Andric } 23645ffd83dbSDimitry Andric 23655ffd83dbSDimitry Andric // For all other cases, fall back to getSymbol to return the unqualified name. 23665ffd83dbSDimitry Andric return nullptr; 23675ffd83dbSDimitry Andric } 23685ffd83dbSDimitry Andric 23698bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal( 23708bcb0991SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 2371e8d8bef9SDimitry Andric if (!GO->hasSection()) 2372e8d8bef9SDimitry Andric report_fatal_error("#pragma clang section is not yet supported"); 2373e8d8bef9SDimitry Andric 2374e8d8bef9SDimitry Andric StringRef SectionName = GO->getSection(); 2375fe6060f1SDimitry Andric 2376fe6060f1SDimitry Andric // Handle the XCOFF::TD case first, then deal with the rest. 2377fe6060f1SDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO)) 2378fe6060f1SDimitry Andric if (GVar->hasAttribute("toc-data")) 2379fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2380fe6060f1SDimitry Andric SectionName, Kind, 2381fe6060f1SDimitry Andric XCOFF::CsectProperties(/*MappingClass*/ XCOFF::XMC_TD, XCOFF::XTY_SD), 2382fe6060f1SDimitry Andric /* MultiSymbolsAllowed*/ true); 2383fe6060f1SDimitry Andric 2384e8d8bef9SDimitry Andric XCOFF::StorageMappingClass MappingClass; 2385e8d8bef9SDimitry Andric if (Kind.isText()) 2386e8d8bef9SDimitry Andric MappingClass = XCOFF::XMC_PR; 238706c3fb27SDimitry Andric else if (Kind.isData() || Kind.isBSS()) 2388e8d8bef9SDimitry Andric MappingClass = XCOFF::XMC_RW; 238906c3fb27SDimitry Andric else if (Kind.isReadOnlyWithRel()) 239006c3fb27SDimitry Andric MappingClass = 239106c3fb27SDimitry Andric TM.Options.XCOFFReadOnlyPointers ? XCOFF::XMC_RO : XCOFF::XMC_RW; 2392e8d8bef9SDimitry Andric else if (Kind.isReadOnly()) 2393e8d8bef9SDimitry Andric MappingClass = XCOFF::XMC_RO; 2394e8d8bef9SDimitry Andric else 2395e8d8bef9SDimitry Andric report_fatal_error("XCOFF other section types not yet implemented."); 2396e8d8bef9SDimitry Andric 2397fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2398fe6060f1SDimitry Andric SectionName, Kind, XCOFF::CsectProperties(MappingClass, XCOFF::XTY_SD), 2399fe6060f1SDimitry Andric /* MultiSymbolsAllowed*/ true); 24008bcb0991SDimitry Andric } 24018bcb0991SDimitry Andric 24025ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference( 24035ffd83dbSDimitry Andric const GlobalObject *GO, const TargetMachine &TM) const { 24045ffd83dbSDimitry Andric assert(GO->isDeclarationForLinker() && 24055ffd83dbSDimitry Andric "Tried to get ER section for a defined global."); 24065ffd83dbSDimitry Andric 24075ffd83dbSDimitry Andric SmallString<128> Name; 24085ffd83dbSDimitry Andric getNameWithPrefix(Name, GO, TM); 24095ffd83dbSDimitry Andric 2410*0fca6ea1SDimitry Andric // AIX TLS local-dynamic does not need the external reference for the 2411*0fca6ea1SDimitry Andric // "_$TLSML" symbol. 2412*0fca6ea1SDimitry Andric if (GO->getThreadLocalMode() == GlobalVariable::LocalDynamicTLSModel && 2413*0fca6ea1SDimitry Andric GO->hasName() && GO->getName() == "_$TLSML") { 2414*0fca6ea1SDimitry Andric return getContext().getXCOFFSection( 2415*0fca6ea1SDimitry Andric Name, SectionKind::getData(), 2416*0fca6ea1SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_TC, XCOFF::XTY_SD)); 2417*0fca6ea1SDimitry Andric } 2418*0fca6ea1SDimitry Andric 2419fe6060f1SDimitry Andric XCOFF::StorageMappingClass SMC = 2420fe6060f1SDimitry Andric isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA; 2421fe6060f1SDimitry Andric if (GO->isThreadLocal()) 2422fe6060f1SDimitry Andric SMC = XCOFF::XMC_UL; 2423fe6060f1SDimitry Andric 2424bdd1243dSDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO)) 2425bdd1243dSDimitry Andric if (GVar->hasAttribute("toc-data")) 2426bdd1243dSDimitry Andric SMC = XCOFF::XMC_TD; 2427bdd1243dSDimitry Andric 24285ffd83dbSDimitry Andric // Externals go into a csect of type ER. 24295ffd83dbSDimitry Andric return getContext().getXCOFFSection( 2430fe6060f1SDimitry Andric Name, SectionKind::getMetadata(), 2431fe6060f1SDimitry Andric XCOFF::CsectProperties(SMC, XCOFF::XTY_ER)); 24325ffd83dbSDimitry Andric } 24335ffd83dbSDimitry Andric 24348bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal( 24358bcb0991SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 2436fe6060f1SDimitry Andric // Handle the XCOFF::TD case first, then deal with the rest. 2437fe6060f1SDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO)) 2438fe6060f1SDimitry Andric if (GVar->hasAttribute("toc-data")) { 24398bcb0991SDimitry Andric SmallString<128> Name; 24408bcb0991SDimitry Andric getNameWithPrefix(Name, GO, TM); 2441*0fca6ea1SDimitry Andric XCOFF::SymbolType symType = 2442*0fca6ea1SDimitry Andric GO->hasCommonLinkage() ? XCOFF::XTY_CM : XCOFF::XTY_SD; 24438bcb0991SDimitry Andric return getContext().getXCOFFSection( 2444*0fca6ea1SDimitry Andric Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TD, symType), 2445fe6060f1SDimitry Andric /* MultiSymbolsAllowed*/ true); 2446fe6060f1SDimitry Andric } 2447fe6060f1SDimitry Andric 2448fe6060f1SDimitry Andric // Common symbols go into a csect with matching name which will get mapped 2449fe6060f1SDimitry Andric // into the .bss section. 2450fe6060f1SDimitry Andric // Zero-initialized local TLS symbols go into a csect with matching name which 2451fe6060f1SDimitry Andric // will get mapped into the .tbss section. 2452fe6060f1SDimitry Andric if (Kind.isBSSLocal() || GO->hasCommonLinkage() || Kind.isThreadBSSLocal()) { 2453fe6060f1SDimitry Andric SmallString<128> Name; 2454fe6060f1SDimitry Andric getNameWithPrefix(Name, GO, TM); 2455fe6060f1SDimitry Andric XCOFF::StorageMappingClass SMC = Kind.isBSSLocal() ? XCOFF::XMC_BS 2456fe6060f1SDimitry Andric : Kind.isCommon() ? XCOFF::XMC_RW 2457fe6060f1SDimitry Andric : XCOFF::XMC_UL; 2458fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2459fe6060f1SDimitry Andric Name, Kind, XCOFF::CsectProperties(SMC, XCOFF::XTY_CM)); 24608bcb0991SDimitry Andric } 24618bcb0991SDimitry Andric 2462e8d8bef9SDimitry Andric if (Kind.isText()) { 2463e8d8bef9SDimitry Andric if (TM.getFunctionSections()) { 2464e8d8bef9SDimitry Andric return cast<MCSymbolXCOFF>(getFunctionEntryPointSymbol(GO, TM)) 2465e8d8bef9SDimitry Andric ->getRepresentedCsect(); 2466e8d8bef9SDimitry Andric } 24678bcb0991SDimitry Andric return TextSection; 2468e8d8bef9SDimitry Andric } 24698bcb0991SDimitry Andric 247006c3fb27SDimitry Andric if (TM.Options.XCOFFReadOnlyPointers && Kind.isReadOnlyWithRel()) { 247106c3fb27SDimitry Andric if (!TM.getDataSections()) 247206c3fb27SDimitry Andric report_fatal_error( 247306c3fb27SDimitry Andric "ReadOnlyPointers is supported only if data sections is turned on"); 247406c3fb27SDimitry Andric 247506c3fb27SDimitry Andric SmallString<128> Name; 247606c3fb27SDimitry Andric getNameWithPrefix(Name, GO, TM); 247706c3fb27SDimitry Andric return getContext().getXCOFFSection( 247806c3fb27SDimitry Andric Name, SectionKind::getReadOnly(), 247906c3fb27SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD)); 248006c3fb27SDimitry Andric } 248106c3fb27SDimitry Andric 2482e8d8bef9SDimitry Andric // For BSS kind, zero initialized data must be emitted to the .data section 2483e8d8bef9SDimitry Andric // because external linkage control sections that get mapped to the .bss 2484e8d8bef9SDimitry Andric // section will be linked as tentative defintions, which is only appropriate 2485e8d8bef9SDimitry Andric // for SectionKind::Common. 2486e8d8bef9SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS()) { 2487e8d8bef9SDimitry Andric if (TM.getDataSections()) { 2488e8d8bef9SDimitry Andric SmallString<128> Name; 2489e8d8bef9SDimitry Andric getNameWithPrefix(Name, GO, TM); 2490fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2491fe6060f1SDimitry Andric Name, SectionKind::getData(), 2492fe6060f1SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD)); 2493e8d8bef9SDimitry Andric } 24948bcb0991SDimitry Andric return DataSection; 2495e8d8bef9SDimitry Andric } 24968bcb0991SDimitry Andric 2497e8d8bef9SDimitry Andric if (Kind.isReadOnly()) { 2498e8d8bef9SDimitry Andric if (TM.getDataSections()) { 2499e8d8bef9SDimitry Andric SmallString<128> Name; 2500e8d8bef9SDimitry Andric getNameWithPrefix(Name, GO, TM); 2501fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2502fe6060f1SDimitry Andric Name, SectionKind::getReadOnly(), 2503fe6060f1SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD)); 2504e8d8bef9SDimitry Andric } 2505480093f4SDimitry Andric return ReadOnlySection; 2506e8d8bef9SDimitry Andric } 2507480093f4SDimitry Andric 2508fe6060f1SDimitry Andric // External/weak TLS data and initialized local TLS data are not eligible 2509fe6060f1SDimitry Andric // to be put into common csect. If data sections are enabled, thread 2510fe6060f1SDimitry Andric // data are emitted into separate sections. Otherwise, thread data 2511fe6060f1SDimitry Andric // are emitted into the .tdata section. 2512fe6060f1SDimitry Andric if (Kind.isThreadLocal()) { 2513fe6060f1SDimitry Andric if (TM.getDataSections()) { 2514fe6060f1SDimitry Andric SmallString<128> Name; 2515fe6060f1SDimitry Andric getNameWithPrefix(Name, GO, TM); 2516fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2517fe6060f1SDimitry Andric Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TL, XCOFF::XTY_SD)); 2518fe6060f1SDimitry Andric } 2519fe6060f1SDimitry Andric return TLSDataSection; 2520fe6060f1SDimitry Andric } 2521fe6060f1SDimitry Andric 25228bcb0991SDimitry Andric report_fatal_error("XCOFF other section types not yet implemented."); 25238bcb0991SDimitry Andric } 25248bcb0991SDimitry Andric 2525480093f4SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForJumpTable( 2526480093f4SDimitry Andric const Function &F, const TargetMachine &TM) const { 2527480093f4SDimitry Andric assert (!F.getComdat() && "Comdat not supported on XCOFF."); 2528e8d8bef9SDimitry Andric 2529e8d8bef9SDimitry Andric if (!TM.getFunctionSections()) 2530480093f4SDimitry Andric return ReadOnlySection; 2531e8d8bef9SDimitry Andric 2532e8d8bef9SDimitry Andric // If the function can be removed, produce a unique section so that 2533e8d8bef9SDimitry Andric // the table doesn't prevent the removal. 2534e8d8bef9SDimitry Andric SmallString<128> NameStr(".rodata.jmp.."); 2535e8d8bef9SDimitry Andric getNameWithPrefix(NameStr, &F, TM); 2536fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2537fe6060f1SDimitry Andric NameStr, SectionKind::getReadOnly(), 2538fe6060f1SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD)); 2539480093f4SDimitry Andric } 2540480093f4SDimitry Andric 25418bcb0991SDimitry Andric bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection( 25428bcb0991SDimitry Andric bool UsesLabelDifference, const Function &F) const { 2543480093f4SDimitry Andric return false; 2544480093f4SDimitry Andric } 2545480093f4SDimitry Andric 2546480093f4SDimitry Andric /// Given a mergeable constant with the specified size and relocation 2547480093f4SDimitry Andric /// information, return a section that it should be placed in. 2548480093f4SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForConstant( 2549480093f4SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 25505ffd83dbSDimitry Andric Align &Alignment) const { 2551480093f4SDimitry Andric // TODO: Enable emiting constant pool to unique sections when we support it. 2552349cc55cSDimitry Andric if (Alignment > Align(16)) 2553349cc55cSDimitry Andric report_fatal_error("Alignments greater than 16 not yet supported."); 2554349cc55cSDimitry Andric 2555349cc55cSDimitry Andric if (Alignment == Align(8)) { 2556349cc55cSDimitry Andric assert(ReadOnly8Section && "Section should always be initialized."); 2557349cc55cSDimitry Andric return ReadOnly8Section; 2558349cc55cSDimitry Andric } 2559349cc55cSDimitry Andric 2560349cc55cSDimitry Andric if (Alignment == Align(16)) { 2561349cc55cSDimitry Andric assert(ReadOnly16Section && "Section should always be initialized."); 2562349cc55cSDimitry Andric return ReadOnly16Section; 2563349cc55cSDimitry Andric } 2564349cc55cSDimitry Andric 2565480093f4SDimitry Andric return ReadOnlySection; 25668bcb0991SDimitry Andric } 25678bcb0991SDimitry Andric 25688bcb0991SDimitry Andric void TargetLoweringObjectFileXCOFF::Initialize(MCContext &Ctx, 25698bcb0991SDimitry Andric const TargetMachine &TgtM) { 25708bcb0991SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TgtM); 2571e8d8bef9SDimitry Andric TTypeEncoding = 2572e8d8bef9SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel | 2573e8d8bef9SDimitry Andric (TgtM.getTargetTriple().isArch32Bit() ? dwarf::DW_EH_PE_sdata4 2574e8d8bef9SDimitry Andric : dwarf::DW_EH_PE_sdata8); 25758bcb0991SDimitry Andric PersonalityEncoding = 0; 25768bcb0991SDimitry Andric LSDAEncoding = 0; 2577e8d8bef9SDimitry Andric CallSiteEncoding = dwarf::DW_EH_PE_udata4; 2578bdd1243dSDimitry Andric 2579bdd1243dSDimitry Andric // AIX debug for thread local location is not ready. And for integrated as 2580bdd1243dSDimitry Andric // mode, the relocatable address for the thread local variable will cause 2581bdd1243dSDimitry Andric // linker error. So disable the location attribute generation for thread local 2582bdd1243dSDimitry Andric // variables for now. 2583bdd1243dSDimitry Andric // FIXME: when TLS debug on AIX is ready, remove this setting. 2584bdd1243dSDimitry Andric SupportDebugThreadLocalLocation = false; 25858bcb0991SDimitry Andric } 25868bcb0991SDimitry Andric 25878bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getStaticCtorSection( 25888bcb0991SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 2589e8d8bef9SDimitry Andric report_fatal_error("no static constructor section on AIX"); 25908bcb0991SDimitry Andric } 25918bcb0991SDimitry Andric 25928bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getStaticDtorSection( 25938bcb0991SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 2594e8d8bef9SDimitry Andric report_fatal_error("no static destructor section on AIX"); 25958bcb0991SDimitry Andric } 25968bcb0991SDimitry Andric 25978bcb0991SDimitry Andric const MCExpr *TargetLoweringObjectFileXCOFF::lowerRelativeReference( 25988bcb0991SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 25998bcb0991SDimitry Andric const TargetMachine &TM) const { 2600349cc55cSDimitry Andric /* Not implemented yet, but don't crash, return nullptr. */ 2601349cc55cSDimitry Andric return nullptr; 26028bcb0991SDimitry Andric } 26038bcb0991SDimitry Andric 2604e8d8bef9SDimitry Andric XCOFF::StorageClass 2605e8d8bef9SDimitry Andric TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) { 2606e8d8bef9SDimitry Andric assert(!isa<GlobalIFunc>(GV) && "GlobalIFunc is not supported on AIX."); 2607e8d8bef9SDimitry Andric 2608e8d8bef9SDimitry Andric switch (GV->getLinkage()) { 26098bcb0991SDimitry Andric case GlobalValue::InternalLinkage: 2610480093f4SDimitry Andric case GlobalValue::PrivateLinkage: 26118bcb0991SDimitry Andric return XCOFF::C_HIDEXT; 26128bcb0991SDimitry Andric case GlobalValue::ExternalLinkage: 26138bcb0991SDimitry Andric case GlobalValue::CommonLinkage: 26145ffd83dbSDimitry Andric case GlobalValue::AvailableExternallyLinkage: 26158bcb0991SDimitry Andric return XCOFF::C_EXT; 26168bcb0991SDimitry Andric case GlobalValue::ExternalWeakLinkage: 26175ffd83dbSDimitry Andric case GlobalValue::LinkOnceAnyLinkage: 26185ffd83dbSDimitry Andric case GlobalValue::LinkOnceODRLinkage: 26195ffd83dbSDimitry Andric case GlobalValue::WeakAnyLinkage: 26205ffd83dbSDimitry Andric case GlobalValue::WeakODRLinkage: 26218bcb0991SDimitry Andric return XCOFF::C_WEAKEXT; 26225ffd83dbSDimitry Andric case GlobalValue::AppendingLinkage: 26238bcb0991SDimitry Andric report_fatal_error( 26245ffd83dbSDimitry Andric "There is no mapping that implements AppendingLinkage for XCOFF."); 26258bcb0991SDimitry Andric } 26265ffd83dbSDimitry Andric llvm_unreachable("Unknown linkage type!"); 26275ffd83dbSDimitry Andric } 26285ffd83dbSDimitry Andric 26295ffd83dbSDimitry Andric MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol( 2630e8d8bef9SDimitry Andric const GlobalValue *Func, const TargetMachine &TM) const { 2631349cc55cSDimitry Andric assert((isa<Function>(Func) || 2632e8d8bef9SDimitry Andric (isa<GlobalAlias>(Func) && 2633349cc55cSDimitry Andric isa_and_nonnull<Function>( 2634349cc55cSDimitry Andric cast<GlobalAlias>(Func)->getAliaseeObject()))) && 2635e8d8bef9SDimitry Andric "Func must be a function or an alias which has a function as base " 2636e8d8bef9SDimitry Andric "object."); 2637e8d8bef9SDimitry Andric 26385ffd83dbSDimitry Andric SmallString<128> NameStr; 26395ffd83dbSDimitry Andric NameStr.push_back('.'); 2640e8d8bef9SDimitry Andric getNameWithPrefix(NameStr, Func, TM); 2641e8d8bef9SDimitry Andric 2642e8d8bef9SDimitry Andric // When -function-sections is enabled and explicit section is not specified, 2643e8d8bef9SDimitry Andric // it's not necessary to emit function entry point label any more. We will use 2644e8d8bef9SDimitry Andric // function entry point csect instead. And for function delcarations, the 2645e8d8bef9SDimitry Andric // undefined symbols gets treated as csect with XTY_ER property. 2646e8d8bef9SDimitry Andric if (((TM.getFunctionSections() && !Func->hasSection()) || 26478a4dda33SDimitry Andric Func->isDeclarationForLinker()) && 2648e8d8bef9SDimitry Andric isa<Function>(Func)) { 2649e8d8bef9SDimitry Andric return getContext() 2650fe6060f1SDimitry Andric .getXCOFFSection( 2651fe6060f1SDimitry Andric NameStr, SectionKind::getText(), 26528a4dda33SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_PR, Func->isDeclarationForLinker() 2653fe6060f1SDimitry Andric ? XCOFF::XTY_ER 2654fe6060f1SDimitry Andric : XCOFF::XTY_SD)) 2655e8d8bef9SDimitry Andric ->getQualNameSymbol(); 2656e8d8bef9SDimitry Andric } 2657e8d8bef9SDimitry Andric 26585ffd83dbSDimitry Andric return getContext().getOrCreateSymbol(NameStr); 26595ffd83dbSDimitry Andric } 26605ffd83dbSDimitry Andric 26615ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForFunctionDescriptor( 26625ffd83dbSDimitry Andric const Function *F, const TargetMachine &TM) const { 26635ffd83dbSDimitry Andric SmallString<128> NameStr; 26645ffd83dbSDimitry Andric getNameWithPrefix(NameStr, F, TM); 2665fe6060f1SDimitry Andric return getContext().getXCOFFSection( 2666fe6060f1SDimitry Andric NameStr, SectionKind::getData(), 2667fe6060f1SDimitry Andric XCOFF::CsectProperties(XCOFF::XMC_DS, XCOFF::XTY_SD)); 26685ffd83dbSDimitry Andric } 26695ffd83dbSDimitry Andric 26705ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry( 2671e8d8bef9SDimitry Andric const MCSymbol *Sym, const TargetMachine &TM) const { 2672*0fca6ea1SDimitry Andric const XCOFF::StorageMappingClass SMC = [](const MCSymbol *Sym, 2673*0fca6ea1SDimitry Andric const TargetMachine &TM) { 2674*0fca6ea1SDimitry Andric const MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(Sym); 2675*0fca6ea1SDimitry Andric 2676*0fca6ea1SDimitry Andric // The "_$TLSML" symbol for TLS local-dynamic mode requires XMC_TC, 2677*0fca6ea1SDimitry Andric // otherwise the AIX assembler will complain. 2678*0fca6ea1SDimitry Andric if (XSym->getSymbolTableName() == "_$TLSML") 2679*0fca6ea1SDimitry Andric return XCOFF::XMC_TC; 2680*0fca6ea1SDimitry Andric 2681*0fca6ea1SDimitry Andric // Use large code model toc entries for ehinfo symbols as they are 2682*0fca6ea1SDimitry Andric // never referenced directly. The runtime loads their TOC entry 2683*0fca6ea1SDimitry Andric // addresses from the trace-back table. 2684*0fca6ea1SDimitry Andric if (XSym->isEHInfo()) 2685*0fca6ea1SDimitry Andric return XCOFF::XMC_TE; 2686*0fca6ea1SDimitry Andric 2687*0fca6ea1SDimitry Andric // If the symbol does not have a code model specified use the module value. 2688*0fca6ea1SDimitry Andric if (!XSym->hasPerSymbolCodeModel()) 2689*0fca6ea1SDimitry Andric return TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE 2690*0fca6ea1SDimitry Andric : XCOFF::XMC_TC; 2691*0fca6ea1SDimitry Andric 2692*0fca6ea1SDimitry Andric return XSym->getPerSymbolCodeModel() == MCSymbolXCOFF::CM_Large 2693*0fca6ea1SDimitry Andric ? XCOFF::XMC_TE 2694*0fca6ea1SDimitry Andric : XCOFF::XMC_TC; 2695*0fca6ea1SDimitry Andric }(Sym, TM); 2696*0fca6ea1SDimitry Andric 26975ffd83dbSDimitry Andric return getContext().getXCOFFSection( 2698fe6060f1SDimitry Andric cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(), SectionKind::getData(), 2699*0fca6ea1SDimitry Andric XCOFF::CsectProperties(SMC, XCOFF::XTY_SD)); 2700fe6060f1SDimitry Andric } 2701fe6060f1SDimitry Andric 270281ad6265SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA( 270381ad6265SDimitry Andric const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { 270481ad6265SDimitry Andric auto *LSDA = cast<MCSectionXCOFF>(LSDASection); 270581ad6265SDimitry Andric if (TM.getFunctionSections()) { 270681ad6265SDimitry Andric // If option -ffunction-sections is on, append the function name to the 270781ad6265SDimitry Andric // name of the LSDA csect so that each function has its own LSDA csect. 270881ad6265SDimitry Andric // This helps the linker to garbage-collect EH info of unused functions. 270981ad6265SDimitry Andric SmallString<128> NameStr = LSDA->getName(); 271081ad6265SDimitry Andric raw_svector_ostream(NameStr) << '.' << F.getName(); 271181ad6265SDimitry Andric LSDA = getContext().getXCOFFSection(NameStr, LSDA->getKind(), 271281ad6265SDimitry Andric LSDA->getCsectProp()); 271381ad6265SDimitry Andric } 271481ad6265SDimitry Andric return LSDA; 271581ad6265SDimitry Andric } 2716fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 2717fe6060f1SDimitry Andric // GOFF 2718fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 271981ad6265SDimitry Andric TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default; 2720fe6060f1SDimitry Andric 2721fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( 2722fe6060f1SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 2723fe6060f1SDimitry Andric return SelectSectionForGlobal(GO, Kind, TM); 2724fe6060f1SDimitry Andric } 2725fe6060f1SDimitry Andric 2726cb14a3feSDimitry Andric MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA( 2727cb14a3feSDimitry Andric const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { 2728cb14a3feSDimitry Andric std::string Name = ".gcc_exception_table." + F.getName().str(); 2729*0fca6ea1SDimitry Andric return getContext().getGOFFSection(Name, SectionKind::getData(), nullptr, 0); 2730cb14a3feSDimitry Andric } 2731cb14a3feSDimitry Andric 2732fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( 2733fe6060f1SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 2734fe6060f1SDimitry Andric auto *Symbol = TM.getSymbol(GO); 2735fe6060f1SDimitry Andric if (Kind.isBSS()) 273681ad6265SDimitry Andric return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(), 2737*0fca6ea1SDimitry Andric nullptr, 0); 2738fe6060f1SDimitry Andric 2739fe6060f1SDimitry Andric return getContext().getObjectFileInfo()->getTextSection(); 27408bcb0991SDimitry Andric } 2741