1*0b57cec5SDimitry Andric //===- llvm/CodeGen/TargetLoweringObjectFileImpl.cpp - Object File Info ---===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file implements classes used to handle lowerings specific to common 10*0b57cec5SDimitry Andric // object file formats. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 15*0b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 16*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 17*0b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 19*0b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 20*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h" 21*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 22*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 23*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 24*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 25*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 26*0b57cec5SDimitry Andric #include "llvm/IR/Comdat.h" 27*0b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 28*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 29*0b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 30*0b57cec5SDimitry Andric #include "llvm/IR/Function.h" 31*0b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h" 32*0b57cec5SDimitry Andric #include "llvm/IR/GlobalObject.h" 33*0b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 34*0b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 35*0b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 36*0b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 37*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 38*0b57cec5SDimitry Andric #include "llvm/IR/Type.h" 39*0b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 40*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 41*0b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 42*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 43*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h" 44*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h" 45*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionWasm.h" 468bcb0991SDimitry Andric #include "llvm/MC/MCSectionXCOFF.h" 47*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 48*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 49*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 50*0b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 51*0b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h" 52*0b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProf.h" 53*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 54*0b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 55*0b57cec5SDimitry Andric #include "llvm/Support/Format.h" 56*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 57*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 58*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 59*0b57cec5SDimitry Andric #include <cassert> 60*0b57cec5SDimitry Andric #include <string> 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric using namespace llvm; 63*0b57cec5SDimitry Andric using namespace dwarf; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, 66*0b57cec5SDimitry Andric StringRef &Section) { 67*0b57cec5SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; 68*0b57cec5SDimitry Andric M.getModuleFlagsMetadata(ModuleFlags); 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric for (const auto &MFE: ModuleFlags) { 71*0b57cec5SDimitry Andric // Ignore flags with 'Require' behaviour. 72*0b57cec5SDimitry Andric if (MFE.Behavior == Module::Require) 73*0b57cec5SDimitry Andric continue; 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric StringRef Key = MFE.Key->getString(); 76*0b57cec5SDimitry Andric if (Key == "Objective-C Image Info Version") { 77*0b57cec5SDimitry Andric Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 78*0b57cec5SDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 79*0b57cec5SDimitry Andric Key == "Objective-C GC Only" || 80*0b57cec5SDimitry Andric Key == "Objective-C Is Simulated" || 81*0b57cec5SDimitry Andric Key == "Objective-C Class Properties" || 82*0b57cec5SDimitry Andric Key == "Objective-C Image Swift Version") { 83*0b57cec5SDimitry Andric Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 84*0b57cec5SDimitry Andric } else if (Key == "Objective-C Image Info Section") { 85*0b57cec5SDimitry Andric Section = cast<MDString>(MFE.Val)->getString(); 86*0b57cec5SDimitry Andric } 87*0b57cec5SDimitry Andric } 88*0b57cec5SDimitry Andric } 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 91*0b57cec5SDimitry Andric // ELF 92*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 93*0b57cec5SDimitry Andric 94*0b57cec5SDimitry Andric void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, 95*0b57cec5SDimitry Andric const TargetMachine &TgtM) { 96*0b57cec5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TgtM); 97*0b57cec5SDimitry Andric TM = &TgtM; 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric CodeModel::Model CM = TgtM.getCodeModel(); 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric switch (TgtM.getTargetTriple().getArch()) { 102*0b57cec5SDimitry Andric case Triple::arm: 103*0b57cec5SDimitry Andric case Triple::armeb: 104*0b57cec5SDimitry Andric case Triple::thumb: 105*0b57cec5SDimitry Andric case Triple::thumbeb: 106*0b57cec5SDimitry Andric if (Ctx.getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM) 107*0b57cec5SDimitry Andric break; 108*0b57cec5SDimitry Andric // Fallthrough if not using EHABI 109*0b57cec5SDimitry Andric LLVM_FALLTHROUGH; 110*0b57cec5SDimitry Andric case Triple::ppc: 111*0b57cec5SDimitry Andric case Triple::x86: 112*0b57cec5SDimitry Andric PersonalityEncoding = isPositionIndependent() 113*0b57cec5SDimitry Andric ? dwarf::DW_EH_PE_indirect | 114*0b57cec5SDimitry Andric dwarf::DW_EH_PE_pcrel | 115*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4 116*0b57cec5SDimitry Andric : dwarf::DW_EH_PE_absptr; 117*0b57cec5SDimitry Andric LSDAEncoding = isPositionIndependent() 118*0b57cec5SDimitry Andric ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 119*0b57cec5SDimitry Andric : dwarf::DW_EH_PE_absptr; 120*0b57cec5SDimitry Andric TTypeEncoding = isPositionIndependent() 121*0b57cec5SDimitry Andric ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 122*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4 123*0b57cec5SDimitry Andric : dwarf::DW_EH_PE_absptr; 124*0b57cec5SDimitry Andric break; 125*0b57cec5SDimitry Andric case Triple::x86_64: 126*0b57cec5SDimitry Andric if (isPositionIndependent()) { 127*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 128*0b57cec5SDimitry Andric ((CM == CodeModel::Small || CM == CodeModel::Medium) 129*0b57cec5SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); 130*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | 131*0b57cec5SDimitry Andric (CM == CodeModel::Small 132*0b57cec5SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); 133*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 134*0b57cec5SDimitry Andric ((CM == CodeModel::Small || CM == CodeModel::Medium) 135*0b57cec5SDimitry Andric ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); 136*0b57cec5SDimitry Andric } else { 137*0b57cec5SDimitry Andric PersonalityEncoding = 138*0b57cec5SDimitry Andric (CM == CodeModel::Small || CM == CodeModel::Medium) 139*0b57cec5SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; 140*0b57cec5SDimitry Andric LSDAEncoding = (CM == CodeModel::Small) 141*0b57cec5SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; 142*0b57cec5SDimitry Andric TTypeEncoding = (CM == CodeModel::Small) 143*0b57cec5SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; 144*0b57cec5SDimitry Andric } 145*0b57cec5SDimitry Andric break; 146*0b57cec5SDimitry Andric case Triple::hexagon: 147*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 148*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 149*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 150*0b57cec5SDimitry Andric if (isPositionIndependent()) { 151*0b57cec5SDimitry Andric PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; 152*0b57cec5SDimitry Andric LSDAEncoding |= dwarf::DW_EH_PE_pcrel; 153*0b57cec5SDimitry Andric TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; 154*0b57cec5SDimitry Andric } 155*0b57cec5SDimitry Andric break; 156*0b57cec5SDimitry Andric case Triple::aarch64: 157*0b57cec5SDimitry Andric case Triple::aarch64_be: 1588bcb0991SDimitry Andric case Triple::aarch64_32: 159*0b57cec5SDimitry Andric // The small model guarantees static code/data size < 4GB, but not where it 160*0b57cec5SDimitry Andric // will be in memory. Most of these could end up >2GB away so even a signed 161*0b57cec5SDimitry Andric // pc-relative 32-bit address is insufficient, theoretically. 162*0b57cec5SDimitry Andric if (isPositionIndependent()) { 163*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 164*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata8; 165*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; 166*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 167*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata8; 168*0b57cec5SDimitry Andric } else { 169*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 170*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 171*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 172*0b57cec5SDimitry Andric } 173*0b57cec5SDimitry Andric break; 174*0b57cec5SDimitry Andric case Triple::lanai: 175*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 176*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 177*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 178*0b57cec5SDimitry Andric break; 179*0b57cec5SDimitry Andric case Triple::mips: 180*0b57cec5SDimitry Andric case Triple::mipsel: 181*0b57cec5SDimitry Andric case Triple::mips64: 182*0b57cec5SDimitry Andric case Triple::mips64el: 183*0b57cec5SDimitry Andric // MIPS uses indirect pointer to refer personality functions and types, so 184*0b57cec5SDimitry Andric // that the eh_frame section can be read-only. DW.ref.personality will be 185*0b57cec5SDimitry Andric // generated for relocation. 186*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect; 187*0b57cec5SDimitry Andric // FIXME: The N64 ABI probably ought to use DW_EH_PE_sdata8 but we can't 188*0b57cec5SDimitry Andric // identify N64 from just a triple. 189*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 190*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 191*0b57cec5SDimitry Andric // We don't support PC-relative LSDA references in GAS so we use the default 192*0b57cec5SDimitry Andric // DW_EH_PE_absptr for those. 193*0b57cec5SDimitry Andric 194*0b57cec5SDimitry Andric // FreeBSD must be explicit about the data size and using pcrel since it's 195*0b57cec5SDimitry Andric // assembler/linker won't do the automatic conversion that the Linux tools 196*0b57cec5SDimitry Andric // do. 197*0b57cec5SDimitry Andric if (TgtM.getTargetTriple().isOSFreeBSD()) { 198*0b57cec5SDimitry Andric PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 199*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 200*0b57cec5SDimitry Andric } 201*0b57cec5SDimitry Andric break; 202*0b57cec5SDimitry Andric case Triple::ppc64: 203*0b57cec5SDimitry Andric case Triple::ppc64le: 204*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 205*0b57cec5SDimitry Andric dwarf::DW_EH_PE_udata8; 206*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; 207*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 208*0b57cec5SDimitry Andric dwarf::DW_EH_PE_udata8; 209*0b57cec5SDimitry Andric break; 210*0b57cec5SDimitry Andric case Triple::sparcel: 211*0b57cec5SDimitry Andric case Triple::sparc: 212*0b57cec5SDimitry Andric if (isPositionIndependent()) { 213*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 214*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 215*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 216*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 217*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 218*0b57cec5SDimitry Andric } else { 219*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 220*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 221*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 222*0b57cec5SDimitry Andric } 223*0b57cec5SDimitry Andric CallSiteEncoding = dwarf::DW_EH_PE_udata4; 224*0b57cec5SDimitry Andric break; 225*0b57cec5SDimitry Andric case Triple::riscv32: 226*0b57cec5SDimitry Andric case Triple::riscv64: 227*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 228*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 229*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 230*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 231*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 232*0b57cec5SDimitry Andric CallSiteEncoding = dwarf::DW_EH_PE_udata4; 233*0b57cec5SDimitry Andric break; 234*0b57cec5SDimitry Andric case Triple::sparcv9: 235*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 236*0b57cec5SDimitry Andric if (isPositionIndependent()) { 237*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 238*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 239*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 240*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 241*0b57cec5SDimitry Andric } else { 242*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 243*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 244*0b57cec5SDimitry Andric } 245*0b57cec5SDimitry Andric break; 246*0b57cec5SDimitry Andric case Triple::systemz: 247*0b57cec5SDimitry Andric // All currently-defined code models guarantee that 4-byte PC-relative 248*0b57cec5SDimitry Andric // values will be in range. 249*0b57cec5SDimitry Andric if (isPositionIndependent()) { 250*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 251*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 252*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 253*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | 254*0b57cec5SDimitry Andric dwarf::DW_EH_PE_sdata4; 255*0b57cec5SDimitry Andric } else { 256*0b57cec5SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr; 257*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr; 258*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 259*0b57cec5SDimitry Andric } 260*0b57cec5SDimitry Andric break; 261*0b57cec5SDimitry Andric default: 262*0b57cec5SDimitry Andric break; 263*0b57cec5SDimitry Andric } 264*0b57cec5SDimitry Andric } 265*0b57cec5SDimitry Andric 266*0b57cec5SDimitry Andric void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, 267*0b57cec5SDimitry Andric Module &M) const { 268*0b57cec5SDimitry Andric auto &C = getContext(); 269*0b57cec5SDimitry Andric 270*0b57cec5SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 271*0b57cec5SDimitry Andric auto *S = C.getELFSection(".linker-options", ELF::SHT_LLVM_LINKER_OPTIONS, 272*0b57cec5SDimitry Andric ELF::SHF_EXCLUDE); 273*0b57cec5SDimitry Andric 274*0b57cec5SDimitry Andric Streamer.SwitchSection(S); 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andric for (const auto &Operand : LinkerOptions->operands()) { 277*0b57cec5SDimitry Andric if (cast<MDNode>(Operand)->getNumOperands() != 2) 278*0b57cec5SDimitry Andric report_fatal_error("invalid llvm.linker.options"); 279*0b57cec5SDimitry Andric for (const auto &Option : cast<MDNode>(Operand)->operands()) { 280*0b57cec5SDimitry Andric Streamer.EmitBytes(cast<MDString>(Option)->getString()); 281*0b57cec5SDimitry Andric Streamer.EmitIntValue(0, 1); 282*0b57cec5SDimitry Andric } 283*0b57cec5SDimitry Andric } 284*0b57cec5SDimitry Andric } 285*0b57cec5SDimitry Andric 286*0b57cec5SDimitry Andric if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) { 287*0b57cec5SDimitry Andric auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES, 288*0b57cec5SDimitry Andric ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric Streamer.SwitchSection(S); 291*0b57cec5SDimitry Andric 292*0b57cec5SDimitry Andric for (const auto &Operand : DependentLibraries->operands()) { 293*0b57cec5SDimitry Andric Streamer.EmitBytes( 294*0b57cec5SDimitry Andric cast<MDString>(cast<MDNode>(Operand)->getOperand(0))->getString()); 295*0b57cec5SDimitry Andric Streamer.EmitIntValue(0, 1); 296*0b57cec5SDimitry Andric } 297*0b57cec5SDimitry Andric } 298*0b57cec5SDimitry Andric 299*0b57cec5SDimitry Andric unsigned Version = 0; 300*0b57cec5SDimitry Andric unsigned Flags = 0; 301*0b57cec5SDimitry Andric StringRef Section; 302*0b57cec5SDimitry Andric 303*0b57cec5SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 304*0b57cec5SDimitry Andric if (!Section.empty()) { 305*0b57cec5SDimitry Andric auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 306*0b57cec5SDimitry Andric Streamer.SwitchSection(S); 307*0b57cec5SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 308*0b57cec5SDimitry Andric Streamer.EmitIntValue(Version, 4); 309*0b57cec5SDimitry Andric Streamer.EmitIntValue(Flags, 4); 310*0b57cec5SDimitry Andric Streamer.AddBlankLine(); 311*0b57cec5SDimitry Andric } 312*0b57cec5SDimitry Andric 313*0b57cec5SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; 314*0b57cec5SDimitry Andric M.getModuleFlagsMetadata(ModuleFlags); 315*0b57cec5SDimitry Andric 316*0b57cec5SDimitry Andric MDNode *CFGProfile = nullptr; 317*0b57cec5SDimitry Andric 318*0b57cec5SDimitry Andric for (const auto &MFE : ModuleFlags) { 319*0b57cec5SDimitry Andric StringRef Key = MFE.Key->getString(); 320*0b57cec5SDimitry Andric if (Key == "CG Profile") { 321*0b57cec5SDimitry Andric CFGProfile = cast<MDNode>(MFE.Val); 322*0b57cec5SDimitry Andric break; 323*0b57cec5SDimitry Andric } 324*0b57cec5SDimitry Andric } 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric if (!CFGProfile) 327*0b57cec5SDimitry Andric return; 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andric auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * { 330*0b57cec5SDimitry Andric if (!MDO) 331*0b57cec5SDimitry Andric return nullptr; 332*0b57cec5SDimitry Andric auto V = cast<ValueAsMetadata>(MDO); 333*0b57cec5SDimitry Andric const Function *F = cast<Function>(V->getValue()); 334*0b57cec5SDimitry Andric return TM->getSymbol(F); 335*0b57cec5SDimitry Andric }; 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric for (const auto &Edge : CFGProfile->operands()) { 338*0b57cec5SDimitry Andric MDNode *E = cast<MDNode>(Edge); 339*0b57cec5SDimitry Andric const MCSymbol *From = GetSym(E->getOperand(0)); 340*0b57cec5SDimitry Andric const MCSymbol *To = GetSym(E->getOperand(1)); 341*0b57cec5SDimitry Andric // Skip null functions. This can happen if functions are dead stripped after 342*0b57cec5SDimitry Andric // the CGProfile pass has been run. 343*0b57cec5SDimitry Andric if (!From || !To) 344*0b57cec5SDimitry Andric continue; 345*0b57cec5SDimitry Andric uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2)) 346*0b57cec5SDimitry Andric ->getValue() 347*0b57cec5SDimitry Andric ->getUniqueInteger() 348*0b57cec5SDimitry Andric .getZExtValue(); 349*0b57cec5SDimitry Andric Streamer.emitCGProfileEntry( 350*0b57cec5SDimitry Andric MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C), 351*0b57cec5SDimitry Andric MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count); 352*0b57cec5SDimitry Andric } 353*0b57cec5SDimitry Andric } 354*0b57cec5SDimitry Andric 355*0b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( 356*0b57cec5SDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 357*0b57cec5SDimitry Andric MachineModuleInfo *MMI) const { 358*0b57cec5SDimitry Andric unsigned Encoding = getPersonalityEncoding(); 359*0b57cec5SDimitry Andric if ((Encoding & 0x80) == DW_EH_PE_indirect) 360*0b57cec5SDimitry Andric return getContext().getOrCreateSymbol(StringRef("DW.ref.") + 361*0b57cec5SDimitry Andric TM.getSymbol(GV)->getName()); 362*0b57cec5SDimitry Andric if ((Encoding & 0x70) == DW_EH_PE_absptr) 363*0b57cec5SDimitry Andric return TM.getSymbol(GV); 364*0b57cec5SDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!"); 365*0b57cec5SDimitry Andric } 366*0b57cec5SDimitry Andric 367*0b57cec5SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue( 368*0b57cec5SDimitry Andric MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { 369*0b57cec5SDimitry Andric SmallString<64> NameData("DW.ref."); 370*0b57cec5SDimitry Andric NameData += Sym->getName(); 371*0b57cec5SDimitry Andric MCSymbolELF *Label = 372*0b57cec5SDimitry Andric cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); 373*0b57cec5SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); 374*0b57cec5SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Weak); 375*0b57cec5SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; 376*0b57cec5SDimitry Andric MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), 377*0b57cec5SDimitry Andric ELF::SHT_PROGBITS, Flags, 0); 378*0b57cec5SDimitry Andric unsigned Size = DL.getPointerSize(); 379*0b57cec5SDimitry Andric Streamer.SwitchSection(Sec); 3808bcb0991SDimitry Andric Streamer.EmitValueToAlignment(DL.getPointerABIAlignment(0).value()); 381*0b57cec5SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); 382*0b57cec5SDimitry Andric const MCExpr *E = MCConstantExpr::create(Size, getContext()); 383*0b57cec5SDimitry Andric Streamer.emitELFSize(Label, E); 384*0b57cec5SDimitry Andric Streamer.EmitLabel(Label); 385*0b57cec5SDimitry Andric 386*0b57cec5SDimitry Andric Streamer.EmitSymbolValue(Sym, Size); 387*0b57cec5SDimitry Andric } 388*0b57cec5SDimitry Andric 389*0b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( 390*0b57cec5SDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 391*0b57cec5SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 392*0b57cec5SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 393*0b57cec5SDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); 394*0b57cec5SDimitry Andric 395*0b57cec5SDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM); 396*0b57cec5SDimitry Andric 397*0b57cec5SDimitry Andric // Add information about the stub reference to ELFMMI so that the stub 398*0b57cec5SDimitry Andric // gets emitted by the asmprinter. 399*0b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); 400*0b57cec5SDimitry Andric if (!StubSym.getPointer()) { 401*0b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 402*0b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 403*0b57cec5SDimitry Andric } 404*0b57cec5SDimitry Andric 405*0b57cec5SDimitry Andric return TargetLoweringObjectFile:: 406*0b57cec5SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 407*0b57cec5SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 408*0b57cec5SDimitry Andric } 409*0b57cec5SDimitry Andric 410*0b57cec5SDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 411*0b57cec5SDimitry Andric MMI, Streamer); 412*0b57cec5SDimitry Andric } 413*0b57cec5SDimitry Andric 414*0b57cec5SDimitry Andric static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) { 415*0b57cec5SDimitry Andric // N.B.: The defaults used in here are not the same ones used in MC. 416*0b57cec5SDimitry Andric // We follow gcc, MC follows gas. For example, given ".section .eh_frame", 417*0b57cec5SDimitry Andric // both gas and MC will produce a section with no flags. Given 418*0b57cec5SDimitry Andric // section(".eh_frame") gcc will produce: 419*0b57cec5SDimitry Andric // 420*0b57cec5SDimitry Andric // .section .eh_frame,"a",@progbits 421*0b57cec5SDimitry Andric 422*0b57cec5SDimitry Andric if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF, 423*0b57cec5SDimitry Andric /*AddSegmentInfo=*/false)) 424*0b57cec5SDimitry Andric return SectionKind::getMetadata(); 425*0b57cec5SDimitry Andric 426*0b57cec5SDimitry Andric if (Name.empty() || Name[0] != '.') return K; 427*0b57cec5SDimitry Andric 428*0b57cec5SDimitry Andric // Default implementation based on some magic section names. 429*0b57cec5SDimitry Andric if (Name == ".bss" || 430*0b57cec5SDimitry Andric Name.startswith(".bss.") || 431*0b57cec5SDimitry Andric Name.startswith(".gnu.linkonce.b.") || 432*0b57cec5SDimitry Andric Name.startswith(".llvm.linkonce.b.") || 433*0b57cec5SDimitry Andric Name == ".sbss" || 434*0b57cec5SDimitry Andric Name.startswith(".sbss.") || 435*0b57cec5SDimitry Andric Name.startswith(".gnu.linkonce.sb.") || 436*0b57cec5SDimitry Andric Name.startswith(".llvm.linkonce.sb.")) 437*0b57cec5SDimitry Andric return SectionKind::getBSS(); 438*0b57cec5SDimitry Andric 439*0b57cec5SDimitry Andric if (Name == ".tdata" || 440*0b57cec5SDimitry Andric Name.startswith(".tdata.") || 441*0b57cec5SDimitry Andric Name.startswith(".gnu.linkonce.td.") || 442*0b57cec5SDimitry Andric Name.startswith(".llvm.linkonce.td.")) 443*0b57cec5SDimitry Andric return SectionKind::getThreadData(); 444*0b57cec5SDimitry Andric 445*0b57cec5SDimitry Andric if (Name == ".tbss" || 446*0b57cec5SDimitry Andric Name.startswith(".tbss.") || 447*0b57cec5SDimitry Andric Name.startswith(".gnu.linkonce.tb.") || 448*0b57cec5SDimitry Andric Name.startswith(".llvm.linkonce.tb.")) 449*0b57cec5SDimitry Andric return SectionKind::getThreadBSS(); 450*0b57cec5SDimitry Andric 451*0b57cec5SDimitry Andric return K; 452*0b57cec5SDimitry Andric } 453*0b57cec5SDimitry Andric 454*0b57cec5SDimitry Andric static unsigned getELFSectionType(StringRef Name, SectionKind K) { 455*0b57cec5SDimitry Andric // Use SHT_NOTE for section whose name starts with ".note" to allow 456*0b57cec5SDimitry Andric // emitting ELF notes from C variable declaration. 457*0b57cec5SDimitry Andric // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609 458*0b57cec5SDimitry Andric if (Name.startswith(".note")) 459*0b57cec5SDimitry Andric return ELF::SHT_NOTE; 460*0b57cec5SDimitry Andric 461*0b57cec5SDimitry Andric if (Name == ".init_array") 462*0b57cec5SDimitry Andric return ELF::SHT_INIT_ARRAY; 463*0b57cec5SDimitry Andric 464*0b57cec5SDimitry Andric if (Name == ".fini_array") 465*0b57cec5SDimitry Andric return ELF::SHT_FINI_ARRAY; 466*0b57cec5SDimitry Andric 467*0b57cec5SDimitry Andric if (Name == ".preinit_array") 468*0b57cec5SDimitry Andric return ELF::SHT_PREINIT_ARRAY; 469*0b57cec5SDimitry Andric 470*0b57cec5SDimitry Andric if (K.isBSS() || K.isThreadBSS()) 471*0b57cec5SDimitry Andric return ELF::SHT_NOBITS; 472*0b57cec5SDimitry Andric 473*0b57cec5SDimitry Andric return ELF::SHT_PROGBITS; 474*0b57cec5SDimitry Andric } 475*0b57cec5SDimitry Andric 476*0b57cec5SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) { 477*0b57cec5SDimitry Andric unsigned Flags = 0; 478*0b57cec5SDimitry Andric 479*0b57cec5SDimitry Andric if (!K.isMetadata()) 480*0b57cec5SDimitry Andric Flags |= ELF::SHF_ALLOC; 481*0b57cec5SDimitry Andric 482*0b57cec5SDimitry Andric if (K.isText()) 483*0b57cec5SDimitry Andric Flags |= ELF::SHF_EXECINSTR; 484*0b57cec5SDimitry Andric 485*0b57cec5SDimitry Andric if (K.isExecuteOnly()) 486*0b57cec5SDimitry Andric Flags |= ELF::SHF_ARM_PURECODE; 487*0b57cec5SDimitry Andric 488*0b57cec5SDimitry Andric if (K.isWriteable()) 489*0b57cec5SDimitry Andric Flags |= ELF::SHF_WRITE; 490*0b57cec5SDimitry Andric 491*0b57cec5SDimitry Andric if (K.isThreadLocal()) 492*0b57cec5SDimitry Andric Flags |= ELF::SHF_TLS; 493*0b57cec5SDimitry Andric 494*0b57cec5SDimitry Andric if (K.isMergeableCString() || K.isMergeableConst()) 495*0b57cec5SDimitry Andric Flags |= ELF::SHF_MERGE; 496*0b57cec5SDimitry Andric 497*0b57cec5SDimitry Andric if (K.isMergeableCString()) 498*0b57cec5SDimitry Andric Flags |= ELF::SHF_STRINGS; 499*0b57cec5SDimitry Andric 500*0b57cec5SDimitry Andric return Flags; 501*0b57cec5SDimitry Andric } 502*0b57cec5SDimitry Andric 503*0b57cec5SDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) { 504*0b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 505*0b57cec5SDimitry Andric if (!C) 506*0b57cec5SDimitry Andric return nullptr; 507*0b57cec5SDimitry Andric 508*0b57cec5SDimitry Andric if (C->getSelectionKind() != Comdat::Any) 509*0b57cec5SDimitry Andric report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + 510*0b57cec5SDimitry Andric C->getName() + "' cannot be lowered."); 511*0b57cec5SDimitry Andric 512*0b57cec5SDimitry Andric return C; 513*0b57cec5SDimitry Andric } 514*0b57cec5SDimitry Andric 515*0b57cec5SDimitry Andric static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO, 516*0b57cec5SDimitry Andric const TargetMachine &TM) { 517*0b57cec5SDimitry Andric MDNode *MD = GO->getMetadata(LLVMContext::MD_associated); 518*0b57cec5SDimitry Andric if (!MD) 519*0b57cec5SDimitry Andric return nullptr; 520*0b57cec5SDimitry Andric 521*0b57cec5SDimitry Andric const MDOperand &Op = MD->getOperand(0); 522*0b57cec5SDimitry Andric if (!Op.get()) 523*0b57cec5SDimitry Andric return nullptr; 524*0b57cec5SDimitry Andric 525*0b57cec5SDimitry Andric auto *VM = dyn_cast<ValueAsMetadata>(Op); 526*0b57cec5SDimitry Andric if (!VM) 527*0b57cec5SDimitry Andric report_fatal_error("MD_associated operand is not ValueAsMetadata"); 528*0b57cec5SDimitry Andric 5298bcb0991SDimitry Andric auto *OtherGV = dyn_cast<GlobalValue>(VM->getValue()); 5308bcb0991SDimitry Andric return OtherGV ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGV)) : nullptr; 531*0b57cec5SDimitry Andric } 532*0b57cec5SDimitry Andric 533*0b57cec5SDimitry Andric static unsigned getEntrySizeForKind(SectionKind Kind) { 534*0b57cec5SDimitry Andric if (Kind.isMergeable1ByteCString()) 535*0b57cec5SDimitry Andric return 1; 536*0b57cec5SDimitry Andric else if (Kind.isMergeable2ByteCString()) 537*0b57cec5SDimitry Andric return 2; 538*0b57cec5SDimitry Andric else if (Kind.isMergeable4ByteCString()) 539*0b57cec5SDimitry Andric return 4; 540*0b57cec5SDimitry Andric else if (Kind.isMergeableConst4()) 541*0b57cec5SDimitry Andric return 4; 542*0b57cec5SDimitry Andric else if (Kind.isMergeableConst8()) 543*0b57cec5SDimitry Andric return 8; 544*0b57cec5SDimitry Andric else if (Kind.isMergeableConst16()) 545*0b57cec5SDimitry Andric return 16; 546*0b57cec5SDimitry Andric else if (Kind.isMergeableConst32()) 547*0b57cec5SDimitry Andric return 32; 548*0b57cec5SDimitry Andric else { 549*0b57cec5SDimitry Andric // We shouldn't have mergeable C strings or mergeable constants that we 550*0b57cec5SDimitry Andric // didn't handle above. 551*0b57cec5SDimitry Andric assert(!Kind.isMergeableCString() && "unknown string width"); 552*0b57cec5SDimitry Andric assert(!Kind.isMergeableConst() && "unknown data width"); 553*0b57cec5SDimitry Andric return 0; 554*0b57cec5SDimitry Andric } 555*0b57cec5SDimitry Andric } 556*0b57cec5SDimitry Andric 557*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( 558*0b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 559*0b57cec5SDimitry Andric StringRef SectionName = GO->getSection(); 560*0b57cec5SDimitry Andric 561*0b57cec5SDimitry Andric // Check if '#pragma clang section' name is applicable. 562*0b57cec5SDimitry Andric // Note that pragma directive overrides -ffunction-section, -fdata-section 563*0b57cec5SDimitry Andric // and so section name is exactly as user specified and not uniqued. 564*0b57cec5SDimitry Andric const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); 565*0b57cec5SDimitry Andric if (GV && GV->hasImplicitSection()) { 566*0b57cec5SDimitry Andric auto Attrs = GV->getAttributes(); 567*0b57cec5SDimitry Andric if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { 568*0b57cec5SDimitry Andric SectionName = Attrs.getAttribute("bss-section").getValueAsString(); 569*0b57cec5SDimitry Andric } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { 570*0b57cec5SDimitry Andric SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); 5718bcb0991SDimitry Andric } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) { 5728bcb0991SDimitry Andric SectionName = Attrs.getAttribute("relro-section").getValueAsString(); 573*0b57cec5SDimitry Andric } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { 574*0b57cec5SDimitry Andric SectionName = Attrs.getAttribute("data-section").getValueAsString(); 575*0b57cec5SDimitry Andric } 576*0b57cec5SDimitry Andric } 577*0b57cec5SDimitry Andric const Function *F = dyn_cast<Function>(GO); 578*0b57cec5SDimitry Andric if (F && F->hasFnAttribute("implicit-section-name")) { 579*0b57cec5SDimitry Andric SectionName = F->getFnAttribute("implicit-section-name").getValueAsString(); 580*0b57cec5SDimitry Andric } 581*0b57cec5SDimitry Andric 582*0b57cec5SDimitry Andric // Infer section flags from the section name if we can. 583*0b57cec5SDimitry Andric Kind = getELFKindForNamedSection(SectionName, Kind); 584*0b57cec5SDimitry Andric 585*0b57cec5SDimitry Andric StringRef Group = ""; 586*0b57cec5SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 587*0b57cec5SDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 588*0b57cec5SDimitry Andric Group = C->getName(); 589*0b57cec5SDimitry Andric Flags |= ELF::SHF_GROUP; 590*0b57cec5SDimitry Andric } 591*0b57cec5SDimitry Andric 592*0b57cec5SDimitry Andric // A section can have at most one associated section. Put each global with 593*0b57cec5SDimitry Andric // MD_associated in a unique section. 594*0b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 595*0b57cec5SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 596*0b57cec5SDimitry Andric if (AssociatedSymbol) { 597*0b57cec5SDimitry Andric UniqueID = NextUniqueID++; 598*0b57cec5SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 599*0b57cec5SDimitry Andric } 600*0b57cec5SDimitry Andric 601*0b57cec5SDimitry Andric MCSectionELF *Section = getContext().getELFSection( 602*0b57cec5SDimitry Andric SectionName, getELFSectionType(SectionName, Kind), Flags, 603*0b57cec5SDimitry Andric getEntrySizeForKind(Kind), Group, UniqueID, AssociatedSymbol); 604*0b57cec5SDimitry Andric // Make sure that we did not get some other section with incompatible sh_link. 605*0b57cec5SDimitry Andric // This should not be possible due to UniqueID code above. 606*0b57cec5SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol && 607*0b57cec5SDimitry Andric "Associated symbol mismatch between sections"); 608*0b57cec5SDimitry Andric return Section; 609*0b57cec5SDimitry Andric } 610*0b57cec5SDimitry Andric 611*0b57cec5SDimitry Andric /// Return the section prefix name used by options FunctionsSections and 612*0b57cec5SDimitry Andric /// DataSections. 613*0b57cec5SDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind) { 614*0b57cec5SDimitry Andric if (Kind.isText()) 615*0b57cec5SDimitry Andric return ".text"; 616*0b57cec5SDimitry Andric if (Kind.isReadOnly()) 617*0b57cec5SDimitry Andric return ".rodata"; 618*0b57cec5SDimitry Andric if (Kind.isBSS()) 619*0b57cec5SDimitry Andric return ".bss"; 620*0b57cec5SDimitry Andric if (Kind.isThreadData()) 621*0b57cec5SDimitry Andric return ".tdata"; 622*0b57cec5SDimitry Andric if (Kind.isThreadBSS()) 623*0b57cec5SDimitry Andric return ".tbss"; 624*0b57cec5SDimitry Andric if (Kind.isData()) 625*0b57cec5SDimitry Andric return ".data"; 626*0b57cec5SDimitry Andric assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 627*0b57cec5SDimitry Andric return ".data.rel.ro"; 628*0b57cec5SDimitry Andric } 629*0b57cec5SDimitry Andric 630*0b57cec5SDimitry Andric static MCSectionELF *selectELFSectionForGlobal( 631*0b57cec5SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 632*0b57cec5SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, 633*0b57cec5SDimitry Andric unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { 634*0b57cec5SDimitry Andric 635*0b57cec5SDimitry Andric StringRef Group = ""; 636*0b57cec5SDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 637*0b57cec5SDimitry Andric Flags |= ELF::SHF_GROUP; 638*0b57cec5SDimitry Andric Group = C->getName(); 639*0b57cec5SDimitry Andric } 640*0b57cec5SDimitry Andric 641*0b57cec5SDimitry Andric // Get the section entry size based on the kind. 642*0b57cec5SDimitry Andric unsigned EntrySize = getEntrySizeForKind(Kind); 643*0b57cec5SDimitry Andric 644*0b57cec5SDimitry Andric SmallString<128> Name; 645*0b57cec5SDimitry Andric if (Kind.isMergeableCString()) { 646*0b57cec5SDimitry Andric // We also need alignment here. 647*0b57cec5SDimitry Andric // FIXME: this is getting the alignment of the character, not the 648*0b57cec5SDimitry Andric // alignment of the global! 649*0b57cec5SDimitry Andric unsigned Align = GO->getParent()->getDataLayout().getPreferredAlignment( 650*0b57cec5SDimitry Andric cast<GlobalVariable>(GO)); 651*0b57cec5SDimitry Andric 652*0b57cec5SDimitry Andric std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; 653*0b57cec5SDimitry Andric Name = SizeSpec + utostr(Align); 654*0b57cec5SDimitry Andric } else if (Kind.isMergeableConst()) { 655*0b57cec5SDimitry Andric Name = ".rodata.cst"; 656*0b57cec5SDimitry Andric Name += utostr(EntrySize); 657*0b57cec5SDimitry Andric } else { 658*0b57cec5SDimitry Andric Name = getSectionPrefixForGlobal(Kind); 659*0b57cec5SDimitry Andric } 660*0b57cec5SDimitry Andric 661*0b57cec5SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 662*0b57cec5SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 663*0b57cec5SDimitry Andric if (OptionalPrefix) 664*0b57cec5SDimitry Andric Name += *OptionalPrefix; 665*0b57cec5SDimitry Andric } 666*0b57cec5SDimitry Andric 667*0b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 668*0b57cec5SDimitry Andric if (EmitUniqueSection) { 669*0b57cec5SDimitry Andric if (TM.getUniqueSectionNames()) { 670*0b57cec5SDimitry Andric Name.push_back('.'); 671*0b57cec5SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true /*MayAlwaysUsePrivate*/); 672*0b57cec5SDimitry Andric } else { 673*0b57cec5SDimitry Andric UniqueID = *NextUniqueID; 674*0b57cec5SDimitry Andric (*NextUniqueID)++; 675*0b57cec5SDimitry Andric } 676*0b57cec5SDimitry Andric } 677*0b57cec5SDimitry Andric // Use 0 as the unique ID for execute-only text. 678*0b57cec5SDimitry Andric if (Kind.isExecuteOnly()) 679*0b57cec5SDimitry Andric UniqueID = 0; 680*0b57cec5SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 681*0b57cec5SDimitry Andric EntrySize, Group, UniqueID, AssociatedSymbol); 682*0b57cec5SDimitry Andric } 683*0b57cec5SDimitry Andric 684*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( 685*0b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 686*0b57cec5SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 687*0b57cec5SDimitry Andric 688*0b57cec5SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 689*0b57cec5SDimitry Andric // global value to a uniqued section specifically for it. 690*0b57cec5SDimitry Andric bool EmitUniqueSection = false; 691*0b57cec5SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { 692*0b57cec5SDimitry Andric if (Kind.isText()) 693*0b57cec5SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 694*0b57cec5SDimitry Andric else 695*0b57cec5SDimitry Andric EmitUniqueSection = TM.getDataSections(); 696*0b57cec5SDimitry Andric } 697*0b57cec5SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 698*0b57cec5SDimitry Andric 699*0b57cec5SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 700*0b57cec5SDimitry Andric if (AssociatedSymbol) { 701*0b57cec5SDimitry Andric EmitUniqueSection = true; 702*0b57cec5SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 703*0b57cec5SDimitry Andric } 704*0b57cec5SDimitry Andric 705*0b57cec5SDimitry Andric MCSectionELF *Section = selectELFSectionForGlobal( 706*0b57cec5SDimitry Andric getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, 707*0b57cec5SDimitry Andric &NextUniqueID, AssociatedSymbol); 708*0b57cec5SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol); 709*0b57cec5SDimitry Andric return Section; 710*0b57cec5SDimitry Andric } 711*0b57cec5SDimitry Andric 712*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( 713*0b57cec5SDimitry Andric const Function &F, const TargetMachine &TM) const { 714*0b57cec5SDimitry Andric // If the function can be removed, produce a unique section so that 715*0b57cec5SDimitry Andric // the table doesn't prevent the removal. 716*0b57cec5SDimitry Andric const Comdat *C = F.getComdat(); 717*0b57cec5SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 718*0b57cec5SDimitry Andric if (!EmitUniqueSection) 719*0b57cec5SDimitry Andric return ReadOnlySection; 720*0b57cec5SDimitry Andric 721*0b57cec5SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), 722*0b57cec5SDimitry Andric getMangler(), TM, EmitUniqueSection, 723*0b57cec5SDimitry Andric ELF::SHF_ALLOC, &NextUniqueID, 724*0b57cec5SDimitry Andric /* AssociatedSymbol */ nullptr); 725*0b57cec5SDimitry Andric } 726*0b57cec5SDimitry Andric 727*0b57cec5SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( 728*0b57cec5SDimitry Andric bool UsesLabelDifference, const Function &F) const { 729*0b57cec5SDimitry Andric // We can always create relative relocations, so use another section 730*0b57cec5SDimitry Andric // that can be marked non-executable. 731*0b57cec5SDimitry Andric return false; 732*0b57cec5SDimitry Andric } 733*0b57cec5SDimitry Andric 734*0b57cec5SDimitry Andric /// Given a mergeable constant with the specified size and relocation 735*0b57cec5SDimitry Andric /// information, return a section that it should be placed in. 736*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant( 737*0b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 738*0b57cec5SDimitry Andric unsigned &Align) const { 739*0b57cec5SDimitry Andric if (Kind.isMergeableConst4() && MergeableConst4Section) 740*0b57cec5SDimitry Andric return MergeableConst4Section; 741*0b57cec5SDimitry Andric if (Kind.isMergeableConst8() && MergeableConst8Section) 742*0b57cec5SDimitry Andric return MergeableConst8Section; 743*0b57cec5SDimitry Andric if (Kind.isMergeableConst16() && MergeableConst16Section) 744*0b57cec5SDimitry Andric return MergeableConst16Section; 745*0b57cec5SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section) 746*0b57cec5SDimitry Andric return MergeableConst32Section; 747*0b57cec5SDimitry Andric if (Kind.isReadOnly()) 748*0b57cec5SDimitry Andric return ReadOnlySection; 749*0b57cec5SDimitry Andric 750*0b57cec5SDimitry Andric assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 751*0b57cec5SDimitry Andric return DataRelROSection; 752*0b57cec5SDimitry Andric } 753*0b57cec5SDimitry Andric 754*0b57cec5SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, 755*0b57cec5SDimitry Andric bool IsCtor, unsigned Priority, 756*0b57cec5SDimitry Andric const MCSymbol *KeySym) { 757*0b57cec5SDimitry Andric std::string Name; 758*0b57cec5SDimitry Andric unsigned Type; 759*0b57cec5SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; 760*0b57cec5SDimitry Andric StringRef COMDAT = KeySym ? KeySym->getName() : ""; 761*0b57cec5SDimitry Andric 762*0b57cec5SDimitry Andric if (KeySym) 763*0b57cec5SDimitry Andric Flags |= ELF::SHF_GROUP; 764*0b57cec5SDimitry Andric 765*0b57cec5SDimitry Andric if (UseInitArray) { 766*0b57cec5SDimitry Andric if (IsCtor) { 767*0b57cec5SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 768*0b57cec5SDimitry Andric Name = ".init_array"; 769*0b57cec5SDimitry Andric } else { 770*0b57cec5SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 771*0b57cec5SDimitry Andric Name = ".fini_array"; 772*0b57cec5SDimitry Andric } 773*0b57cec5SDimitry Andric if (Priority != 65535) { 774*0b57cec5SDimitry Andric Name += '.'; 775*0b57cec5SDimitry Andric Name += utostr(Priority); 776*0b57cec5SDimitry Andric } 777*0b57cec5SDimitry Andric } else { 778*0b57cec5SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority 779*0b57cec5SDimitry Andric // numbering. 780*0b57cec5SDimitry Andric if (IsCtor) 781*0b57cec5SDimitry Andric Name = ".ctors"; 782*0b57cec5SDimitry Andric else 783*0b57cec5SDimitry Andric Name = ".dtors"; 784*0b57cec5SDimitry Andric if (Priority != 65535) 785*0b57cec5SDimitry Andric raw_string_ostream(Name) << format(".%05u", 65535 - Priority); 786*0b57cec5SDimitry Andric Type = ELF::SHT_PROGBITS; 787*0b57cec5SDimitry Andric } 788*0b57cec5SDimitry Andric 789*0b57cec5SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); 790*0b57cec5SDimitry Andric } 791*0b57cec5SDimitry Andric 792*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 793*0b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 794*0b57cec5SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 795*0b57cec5SDimitry Andric KeySym); 796*0b57cec5SDimitry Andric } 797*0b57cec5SDimitry Andric 798*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 799*0b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 800*0b57cec5SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 801*0b57cec5SDimitry Andric KeySym); 802*0b57cec5SDimitry Andric } 803*0b57cec5SDimitry Andric 804*0b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 805*0b57cec5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 806*0b57cec5SDimitry Andric const TargetMachine &TM) const { 807*0b57cec5SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 808*0b57cec5SDimitry Andric // functions. 809*0b57cec5SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 810*0b57cec5SDimitry Andric return nullptr; 811*0b57cec5SDimitry Andric 812*0b57cec5SDimitry Andric // Basic sanity checks. 813*0b57cec5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 814*0b57cec5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 815*0b57cec5SDimitry Andric RHS->isThreadLocal()) 816*0b57cec5SDimitry Andric return nullptr; 817*0b57cec5SDimitry Andric 818*0b57cec5SDimitry Andric return MCBinaryExpr::createSub( 819*0b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, 820*0b57cec5SDimitry Andric getContext()), 821*0b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 822*0b57cec5SDimitry Andric } 823*0b57cec5SDimitry Andric 824*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const { 825*0b57cec5SDimitry Andric // Use ".GCC.command.line" since this feature is to support clang's 826*0b57cec5SDimitry Andric // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the 827*0b57cec5SDimitry Andric // same name. 828*0b57cec5SDimitry Andric return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS, 829*0b57cec5SDimitry Andric ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); 830*0b57cec5SDimitry Andric } 831*0b57cec5SDimitry Andric 832*0b57cec5SDimitry Andric void 833*0b57cec5SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 834*0b57cec5SDimitry Andric UseInitArray = UseInitArray_; 835*0b57cec5SDimitry Andric MCContext &Ctx = getContext(); 836*0b57cec5SDimitry Andric if (!UseInitArray) { 837*0b57cec5SDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, 838*0b57cec5SDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 839*0b57cec5SDimitry Andric 840*0b57cec5SDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, 841*0b57cec5SDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 842*0b57cec5SDimitry Andric return; 843*0b57cec5SDimitry Andric } 844*0b57cec5SDimitry Andric 845*0b57cec5SDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, 846*0b57cec5SDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 847*0b57cec5SDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, 848*0b57cec5SDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 849*0b57cec5SDimitry Andric } 850*0b57cec5SDimitry Andric 851*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 852*0b57cec5SDimitry Andric // MachO 853*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 854*0b57cec5SDimitry Andric 855*0b57cec5SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() 856*0b57cec5SDimitry Andric : TargetLoweringObjectFile() { 857*0b57cec5SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 858*0b57cec5SDimitry Andric } 859*0b57cec5SDimitry Andric 860*0b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, 861*0b57cec5SDimitry Andric const TargetMachine &TM) { 862*0b57cec5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 863*0b57cec5SDimitry Andric if (TM.getRelocationModel() == Reloc::Static) { 864*0b57cec5SDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, 865*0b57cec5SDimitry Andric SectionKind::getData()); 866*0b57cec5SDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, 867*0b57cec5SDimitry Andric SectionKind::getData()); 868*0b57cec5SDimitry Andric } else { 869*0b57cec5SDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", 870*0b57cec5SDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 871*0b57cec5SDimitry Andric SectionKind::getData()); 872*0b57cec5SDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", 873*0b57cec5SDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 874*0b57cec5SDimitry Andric SectionKind::getData()); 875*0b57cec5SDimitry Andric } 876*0b57cec5SDimitry Andric 877*0b57cec5SDimitry Andric PersonalityEncoding = 878*0b57cec5SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 879*0b57cec5SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel; 880*0b57cec5SDimitry Andric TTypeEncoding = 881*0b57cec5SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 882*0b57cec5SDimitry Andric } 883*0b57cec5SDimitry Andric 884*0b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, 885*0b57cec5SDimitry Andric Module &M) const { 886*0b57cec5SDimitry Andric // Emit the linker options if present. 887*0b57cec5SDimitry Andric if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 888*0b57cec5SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 889*0b57cec5SDimitry Andric SmallVector<std::string, 4> StrOptions; 890*0b57cec5SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 891*0b57cec5SDimitry Andric StrOptions.push_back(cast<MDString>(Piece)->getString()); 892*0b57cec5SDimitry Andric Streamer.EmitLinkerOptions(StrOptions); 893*0b57cec5SDimitry Andric } 894*0b57cec5SDimitry Andric } 895*0b57cec5SDimitry Andric 896*0b57cec5SDimitry Andric unsigned VersionVal = 0; 897*0b57cec5SDimitry Andric unsigned ImageInfoFlags = 0; 898*0b57cec5SDimitry Andric StringRef SectionVal; 899*0b57cec5SDimitry Andric 900*0b57cec5SDimitry Andric GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal); 901*0b57cec5SDimitry Andric 902*0b57cec5SDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 903*0b57cec5SDimitry Andric if (SectionVal.empty()) 904*0b57cec5SDimitry Andric return; 905*0b57cec5SDimitry Andric 906*0b57cec5SDimitry Andric StringRef Segment, Section; 907*0b57cec5SDimitry Andric unsigned TAA = 0, StubSize = 0; 908*0b57cec5SDimitry Andric bool TAAParsed; 909*0b57cec5SDimitry Andric std::string ErrorCode = 910*0b57cec5SDimitry Andric MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, 911*0b57cec5SDimitry Andric TAA, TAAParsed, StubSize); 912*0b57cec5SDimitry Andric if (!ErrorCode.empty()) 913*0b57cec5SDimitry Andric // If invalid, report the error with report_fatal_error. 914*0b57cec5SDimitry Andric report_fatal_error("Invalid section specifier '" + Section + "': " + 915*0b57cec5SDimitry Andric ErrorCode + "."); 916*0b57cec5SDimitry Andric 917*0b57cec5SDimitry Andric // Get the section. 918*0b57cec5SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 919*0b57cec5SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 920*0b57cec5SDimitry Andric Streamer.SwitchSection(S); 921*0b57cec5SDimitry Andric Streamer.EmitLabel(getContext(). 922*0b57cec5SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 923*0b57cec5SDimitry Andric Streamer.EmitIntValue(VersionVal, 4); 924*0b57cec5SDimitry Andric Streamer.EmitIntValue(ImageInfoFlags, 4); 925*0b57cec5SDimitry Andric Streamer.AddBlankLine(); 926*0b57cec5SDimitry Andric } 927*0b57cec5SDimitry Andric 928*0b57cec5SDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 929*0b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 930*0b57cec5SDimitry Andric if (!C) 931*0b57cec5SDimitry Andric return; 932*0b57cec5SDimitry Andric 933*0b57cec5SDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 934*0b57cec5SDimitry Andric "' cannot be lowered."); 935*0b57cec5SDimitry Andric } 936*0b57cec5SDimitry Andric 937*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 938*0b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 939*0b57cec5SDimitry Andric // Parse the section specifier and create it if valid. 940*0b57cec5SDimitry Andric StringRef Segment, Section; 941*0b57cec5SDimitry Andric unsigned TAA = 0, StubSize = 0; 942*0b57cec5SDimitry Andric bool TAAParsed; 943*0b57cec5SDimitry Andric 944*0b57cec5SDimitry Andric checkMachOComdat(GO); 945*0b57cec5SDimitry Andric 946*0b57cec5SDimitry Andric std::string ErrorCode = 947*0b57cec5SDimitry Andric MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, 948*0b57cec5SDimitry Andric TAA, TAAParsed, StubSize); 949*0b57cec5SDimitry Andric if (!ErrorCode.empty()) { 950*0b57cec5SDimitry Andric // If invalid, report the error with report_fatal_error. 951*0b57cec5SDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 952*0b57cec5SDimitry Andric "' has an invalid section specifier '" + 953*0b57cec5SDimitry Andric GO->getSection() + "': " + ErrorCode + "."); 954*0b57cec5SDimitry Andric } 955*0b57cec5SDimitry Andric 956*0b57cec5SDimitry Andric // Get the section. 957*0b57cec5SDimitry Andric MCSectionMachO *S = 958*0b57cec5SDimitry Andric getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 959*0b57cec5SDimitry Andric 960*0b57cec5SDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 961*0b57cec5SDimitry Andric // use the value returned by getMachOSection() as a default. 962*0b57cec5SDimitry Andric if (!TAAParsed) 963*0b57cec5SDimitry Andric TAA = S->getTypeAndAttributes(); 964*0b57cec5SDimitry Andric 965*0b57cec5SDimitry Andric // Okay, now that we got the section, verify that the TAA & StubSize agree. 966*0b57cec5SDimitry Andric // If the user declared multiple globals with different section flags, we need 967*0b57cec5SDimitry Andric // to reject it here. 968*0b57cec5SDimitry Andric if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 969*0b57cec5SDimitry Andric // If invalid, report the error with report_fatal_error. 970*0b57cec5SDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 971*0b57cec5SDimitry Andric "' section type or attributes does not match previous" 972*0b57cec5SDimitry Andric " section specifier"); 973*0b57cec5SDimitry Andric } 974*0b57cec5SDimitry Andric 975*0b57cec5SDimitry Andric return S; 976*0b57cec5SDimitry Andric } 977*0b57cec5SDimitry Andric 978*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 979*0b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 980*0b57cec5SDimitry Andric checkMachOComdat(GO); 981*0b57cec5SDimitry Andric 982*0b57cec5SDimitry Andric // Handle thread local data. 983*0b57cec5SDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 984*0b57cec5SDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 985*0b57cec5SDimitry Andric 986*0b57cec5SDimitry Andric if (Kind.isText()) 987*0b57cec5SDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection; 988*0b57cec5SDimitry Andric 989*0b57cec5SDimitry Andric // If this is weak/linkonce, put this in a coalescable section, either in text 990*0b57cec5SDimitry Andric // or data depending on if it is writable. 991*0b57cec5SDimitry Andric if (GO->isWeakForLinker()) { 992*0b57cec5SDimitry Andric if (Kind.isReadOnly()) 993*0b57cec5SDimitry Andric return ConstTextCoalSection; 994*0b57cec5SDimitry Andric if (Kind.isReadOnlyWithRel()) 995*0b57cec5SDimitry Andric return ConstDataCoalSection; 996*0b57cec5SDimitry Andric return DataCoalSection; 997*0b57cec5SDimitry Andric } 998*0b57cec5SDimitry Andric 999*0b57cec5SDimitry Andric // FIXME: Alignment check should be handled by section classifier. 1000*0b57cec5SDimitry Andric if (Kind.isMergeable1ByteCString() && 1001*0b57cec5SDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 1002*0b57cec5SDimitry Andric cast<GlobalVariable>(GO)) < 32) 1003*0b57cec5SDimitry Andric return CStringSection; 1004*0b57cec5SDimitry Andric 1005*0b57cec5SDimitry Andric // Do not put 16-bit arrays in the UString section if they have an 1006*0b57cec5SDimitry Andric // externally visible label, this runs into issues with certain linker 1007*0b57cec5SDimitry Andric // versions. 1008*0b57cec5SDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() && 1009*0b57cec5SDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 1010*0b57cec5SDimitry Andric cast<GlobalVariable>(GO)) < 32) 1011*0b57cec5SDimitry Andric return UStringSection; 1012*0b57cec5SDimitry Andric 1013*0b57cec5SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 1014*0b57cec5SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 1015*0b57cec5SDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) { 1016*0b57cec5SDimitry Andric if (Kind.isMergeableConst4()) 1017*0b57cec5SDimitry Andric return FourByteConstantSection; 1018*0b57cec5SDimitry Andric if (Kind.isMergeableConst8()) 1019*0b57cec5SDimitry Andric return EightByteConstantSection; 1020*0b57cec5SDimitry Andric if (Kind.isMergeableConst16()) 1021*0b57cec5SDimitry Andric return SixteenByteConstantSection; 1022*0b57cec5SDimitry Andric } 1023*0b57cec5SDimitry Andric 1024*0b57cec5SDimitry Andric // Otherwise, if it is readonly, but not something we can specially optimize, 1025*0b57cec5SDimitry Andric // just drop it in .const. 1026*0b57cec5SDimitry Andric if (Kind.isReadOnly()) 1027*0b57cec5SDimitry Andric return ReadOnlySection; 1028*0b57cec5SDimitry Andric 1029*0b57cec5SDimitry Andric // If this is marked const, put it into a const section. But if the dynamic 1030*0b57cec5SDimitry Andric // linker needs to write to it, put it in the data segment. 1031*0b57cec5SDimitry Andric if (Kind.isReadOnlyWithRel()) 1032*0b57cec5SDimitry Andric return ConstDataSection; 1033*0b57cec5SDimitry Andric 1034*0b57cec5SDimitry Andric // Put zero initialized globals with strong external linkage in the 1035*0b57cec5SDimitry Andric // DATA, __common section with the .zerofill directive. 1036*0b57cec5SDimitry Andric if (Kind.isBSSExtern()) 1037*0b57cec5SDimitry Andric return DataCommonSection; 1038*0b57cec5SDimitry Andric 1039*0b57cec5SDimitry Andric // Put zero initialized globals with local linkage in __DATA,__bss directive 1040*0b57cec5SDimitry Andric // with the .zerofill directive (aka .lcomm). 1041*0b57cec5SDimitry Andric if (Kind.isBSSLocal()) 1042*0b57cec5SDimitry Andric return DataBSSSection; 1043*0b57cec5SDimitry Andric 1044*0b57cec5SDimitry Andric // Otherwise, just drop the variable in the normal data section. 1045*0b57cec5SDimitry Andric return DataSection; 1046*0b57cec5SDimitry Andric } 1047*0b57cec5SDimitry Andric 1048*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 1049*0b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 1050*0b57cec5SDimitry Andric unsigned &Align) const { 1051*0b57cec5SDimitry Andric // If this constant requires a relocation, we have to put it in the data 1052*0b57cec5SDimitry Andric // segment, not in the text segment. 1053*0b57cec5SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 1054*0b57cec5SDimitry Andric return ConstDataSection; 1055*0b57cec5SDimitry Andric 1056*0b57cec5SDimitry Andric if (Kind.isMergeableConst4()) 1057*0b57cec5SDimitry Andric return FourByteConstantSection; 1058*0b57cec5SDimitry Andric if (Kind.isMergeableConst8()) 1059*0b57cec5SDimitry Andric return EightByteConstantSection; 1060*0b57cec5SDimitry Andric if (Kind.isMergeableConst16()) 1061*0b57cec5SDimitry Andric return SixteenByteConstantSection; 1062*0b57cec5SDimitry Andric return ReadOnlySection; // .const 1063*0b57cec5SDimitry Andric } 1064*0b57cec5SDimitry Andric 1065*0b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 1066*0b57cec5SDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 1067*0b57cec5SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 1068*0b57cec5SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 1069*0b57cec5SDimitry Andric 1070*0b57cec5SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 1071*0b57cec5SDimitry Andric MachineModuleInfoMachO &MachOMMI = 1072*0b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 1073*0b57cec5SDimitry Andric 1074*0b57cec5SDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 1075*0b57cec5SDimitry Andric 1076*0b57cec5SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 1077*0b57cec5SDimitry Andric // gets emitted by the asmprinter. 1078*0b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 1079*0b57cec5SDimitry Andric if (!StubSym.getPointer()) { 1080*0b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 1081*0b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 1082*0b57cec5SDimitry Andric } 1083*0b57cec5SDimitry Andric 1084*0b57cec5SDimitry Andric return TargetLoweringObjectFile:: 1085*0b57cec5SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 1086*0b57cec5SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 1087*0b57cec5SDimitry Andric } 1088*0b57cec5SDimitry Andric 1089*0b57cec5SDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 1090*0b57cec5SDimitry Andric MMI, Streamer); 1091*0b57cec5SDimitry Andric } 1092*0b57cec5SDimitry Andric 1093*0b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 1094*0b57cec5SDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 1095*0b57cec5SDimitry Andric MachineModuleInfo *MMI) const { 1096*0b57cec5SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 1097*0b57cec5SDimitry Andric MachineModuleInfoMachO &MachOMMI = 1098*0b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 1099*0b57cec5SDimitry Andric 1100*0b57cec5SDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 1101*0b57cec5SDimitry Andric 1102*0b57cec5SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 1103*0b57cec5SDimitry Andric // gets emitted by the asmprinter. 1104*0b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 1105*0b57cec5SDimitry Andric if (!StubSym.getPointer()) { 1106*0b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 1107*0b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 1108*0b57cec5SDimitry Andric } 1109*0b57cec5SDimitry Andric 1110*0b57cec5SDimitry Andric return SSym; 1111*0b57cec5SDimitry Andric } 1112*0b57cec5SDimitry Andric 1113*0b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 11148bcb0991SDimitry Andric const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, 11158bcb0991SDimitry Andric int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { 1116*0b57cec5SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 1117*0b57cec5SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 1118*0b57cec5SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 1119*0b57cec5SDimitry Andric // computation of deltas to final external symbols. Example: 1120*0b57cec5SDimitry Andric // 1121*0b57cec5SDimitry Andric // _extgotequiv: 1122*0b57cec5SDimitry Andric // .long _extfoo 1123*0b57cec5SDimitry Andric // 1124*0b57cec5SDimitry Andric // _delta: 1125*0b57cec5SDimitry Andric // .long _extgotequiv-_delta 1126*0b57cec5SDimitry Andric // 1127*0b57cec5SDimitry Andric // is transformed to: 1128*0b57cec5SDimitry Andric // 1129*0b57cec5SDimitry Andric // _delta: 1130*0b57cec5SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 1131*0b57cec5SDimitry Andric // 1132*0b57cec5SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 1133*0b57cec5SDimitry Andric // L_extfoo$non_lazy_ptr: 1134*0b57cec5SDimitry Andric // .indirect_symbol _extfoo 1135*0b57cec5SDimitry Andric // .long 0 1136*0b57cec5SDimitry Andric // 1137*0b57cec5SDimitry Andric // The indirect symbol table (and sections of non_lazy_symbol_pointers type) 1138*0b57cec5SDimitry Andric // may point to both local (same translation unit) and global (other 1139*0b57cec5SDimitry Andric // translation units) symbols. Example: 1140*0b57cec5SDimitry Andric // 1141*0b57cec5SDimitry Andric // .section __DATA,__pointers,non_lazy_symbol_pointers 1142*0b57cec5SDimitry Andric // L1: 1143*0b57cec5SDimitry Andric // .indirect_symbol _myGlobal 1144*0b57cec5SDimitry Andric // .long 0 1145*0b57cec5SDimitry Andric // L2: 1146*0b57cec5SDimitry Andric // .indirect_symbol _myLocal 1147*0b57cec5SDimitry Andric // .long _myLocal 1148*0b57cec5SDimitry Andric // 1149*0b57cec5SDimitry Andric // If the symbol is local, instead of the symbol's index, the assembler 1150*0b57cec5SDimitry Andric // places the constant INDIRECT_SYMBOL_LOCAL into the indirect symbol table. 1151*0b57cec5SDimitry Andric // Then the linker will notice the constant in the table and will look at the 1152*0b57cec5SDimitry Andric // content of the symbol. 1153*0b57cec5SDimitry Andric MachineModuleInfoMachO &MachOMMI = 1154*0b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 1155*0b57cec5SDimitry Andric MCContext &Ctx = getContext(); 1156*0b57cec5SDimitry Andric 1157*0b57cec5SDimitry Andric // The offset must consider the original displacement from the base symbol 1158*0b57cec5SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 1159*0b57cec5SDimitry Andric Offset = -MV.getConstant(); 1160*0b57cec5SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 1161*0b57cec5SDimitry Andric 1162*0b57cec5SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 1163*0b57cec5SDimitry Andric // non_lazy_ptr stubs. 1164*0b57cec5SDimitry Andric SmallString<128> Name; 1165*0b57cec5SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 1166*0b57cec5SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 1167*0b57cec5SDimitry Andric Name += Sym->getName(); 1168*0b57cec5SDimitry Andric Name += Suffix; 1169*0b57cec5SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 1170*0b57cec5SDimitry Andric 1171*0b57cec5SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 11728bcb0991SDimitry Andric 11738bcb0991SDimitry Andric if (!StubSym.getPointer()) 1174*0b57cec5SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym), 11758bcb0991SDimitry Andric !GV->hasLocalLinkage()); 1176*0b57cec5SDimitry Andric 1177*0b57cec5SDimitry Andric const MCExpr *BSymExpr = 1178*0b57cec5SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 1179*0b57cec5SDimitry Andric const MCExpr *LHS = 1180*0b57cec5SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 1181*0b57cec5SDimitry Andric 1182*0b57cec5SDimitry Andric if (!Offset) 1183*0b57cec5SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 1184*0b57cec5SDimitry Andric 1185*0b57cec5SDimitry Andric const MCExpr *RHS = 1186*0b57cec5SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 1187*0b57cec5SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 1188*0b57cec5SDimitry Andric } 1189*0b57cec5SDimitry Andric 1190*0b57cec5SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 1191*0b57cec5SDimitry Andric const MCSection &Section) { 1192*0b57cec5SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section)) 1193*0b57cec5SDimitry Andric return true; 1194*0b57cec5SDimitry Andric 1195*0b57cec5SDimitry Andric // If it is not dead stripped, it is safe to use private labels. 1196*0b57cec5SDimitry Andric const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); 1197*0b57cec5SDimitry Andric if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) 1198*0b57cec5SDimitry Andric return true; 1199*0b57cec5SDimitry Andric 1200*0b57cec5SDimitry Andric return false; 1201*0b57cec5SDimitry Andric } 1202*0b57cec5SDimitry Andric 1203*0b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 1204*0b57cec5SDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 1205*0b57cec5SDimitry Andric const TargetMachine &TM) const { 1206*0b57cec5SDimitry Andric bool CannotUsePrivateLabel = true; 1207*0b57cec5SDimitry Andric if (auto *GO = GV->getBaseObject()) { 1208*0b57cec5SDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); 1209*0b57cec5SDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); 1210*0b57cec5SDimitry Andric CannotUsePrivateLabel = 1211*0b57cec5SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 1212*0b57cec5SDimitry Andric } 1213*0b57cec5SDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 1214*0b57cec5SDimitry Andric } 1215*0b57cec5SDimitry Andric 1216*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1217*0b57cec5SDimitry Andric // COFF 1218*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1219*0b57cec5SDimitry Andric 1220*0b57cec5SDimitry Andric static unsigned 1221*0b57cec5SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 1222*0b57cec5SDimitry Andric unsigned Flags = 0; 1223*0b57cec5SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 1224*0b57cec5SDimitry Andric 1225*0b57cec5SDimitry Andric if (K.isMetadata()) 1226*0b57cec5SDimitry Andric Flags |= 1227*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_DISCARDABLE; 1228*0b57cec5SDimitry Andric else if (K.isText()) 1229*0b57cec5SDimitry Andric Flags |= 1230*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_EXECUTE | 1231*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 1232*0b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 1233*0b57cec5SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 1234*0b57cec5SDimitry Andric else if (K.isBSS()) 1235*0b57cec5SDimitry Andric Flags |= 1236*0b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 1237*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 1238*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 1239*0b57cec5SDimitry Andric else if (K.isThreadLocal()) 1240*0b57cec5SDimitry Andric Flags |= 1241*0b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1242*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 1243*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 1244*0b57cec5SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 1245*0b57cec5SDimitry Andric Flags |= 1246*0b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1247*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ; 1248*0b57cec5SDimitry Andric else if (K.isWriteable()) 1249*0b57cec5SDimitry Andric Flags |= 1250*0b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1251*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 1252*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 1253*0b57cec5SDimitry Andric 1254*0b57cec5SDimitry Andric return Flags; 1255*0b57cec5SDimitry Andric } 1256*0b57cec5SDimitry Andric 1257*0b57cec5SDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 1258*0b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 1259*0b57cec5SDimitry Andric assert(C && "expected GV to have a Comdat!"); 1260*0b57cec5SDimitry Andric 1261*0b57cec5SDimitry Andric StringRef ComdatGVName = C->getName(); 1262*0b57cec5SDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 1263*0b57cec5SDimitry Andric if (!ComdatGV) 1264*0b57cec5SDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 1265*0b57cec5SDimitry Andric "' does not exist."); 1266*0b57cec5SDimitry Andric 1267*0b57cec5SDimitry Andric if (ComdatGV->getComdat() != C) 1268*0b57cec5SDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 1269*0b57cec5SDimitry Andric "' is not a key for its COMDAT."); 1270*0b57cec5SDimitry Andric 1271*0b57cec5SDimitry Andric return ComdatGV; 1272*0b57cec5SDimitry Andric } 1273*0b57cec5SDimitry Andric 1274*0b57cec5SDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 1275*0b57cec5SDimitry Andric if (const Comdat *C = GV->getComdat()) { 1276*0b57cec5SDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 1277*0b57cec5SDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 1278*0b57cec5SDimitry Andric ComdatKey = GA->getBaseObject(); 1279*0b57cec5SDimitry Andric if (ComdatKey == GV) { 1280*0b57cec5SDimitry Andric switch (C->getSelectionKind()) { 1281*0b57cec5SDimitry Andric case Comdat::Any: 1282*0b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 1283*0b57cec5SDimitry Andric case Comdat::ExactMatch: 1284*0b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 1285*0b57cec5SDimitry Andric case Comdat::Largest: 1286*0b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 1287*0b57cec5SDimitry Andric case Comdat::NoDuplicates: 1288*0b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 1289*0b57cec5SDimitry Andric case Comdat::SameSize: 1290*0b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 1291*0b57cec5SDimitry Andric } 1292*0b57cec5SDimitry Andric } else { 1293*0b57cec5SDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 1294*0b57cec5SDimitry Andric } 1295*0b57cec5SDimitry Andric } 1296*0b57cec5SDimitry Andric return 0; 1297*0b57cec5SDimitry Andric } 1298*0b57cec5SDimitry Andric 1299*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 1300*0b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1301*0b57cec5SDimitry Andric int Selection = 0; 1302*0b57cec5SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1303*0b57cec5SDimitry Andric StringRef Name = GO->getSection(); 1304*0b57cec5SDimitry Andric StringRef COMDATSymName = ""; 1305*0b57cec5SDimitry Andric if (GO->hasComdat()) { 1306*0b57cec5SDimitry Andric Selection = getSelectionForCOFF(GO); 1307*0b57cec5SDimitry Andric const GlobalValue *ComdatGV; 1308*0b57cec5SDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 1309*0b57cec5SDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 1310*0b57cec5SDimitry Andric else 1311*0b57cec5SDimitry Andric ComdatGV = GO; 1312*0b57cec5SDimitry Andric 1313*0b57cec5SDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1314*0b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 1315*0b57cec5SDimitry Andric COMDATSymName = Sym->getName(); 1316*0b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 1317*0b57cec5SDimitry Andric } else { 1318*0b57cec5SDimitry Andric Selection = 0; 1319*0b57cec5SDimitry Andric } 1320*0b57cec5SDimitry Andric } 1321*0b57cec5SDimitry Andric 1322*0b57cec5SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 1323*0b57cec5SDimitry Andric Selection); 1324*0b57cec5SDimitry Andric } 1325*0b57cec5SDimitry Andric 1326*0b57cec5SDimitry Andric static StringRef getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 1327*0b57cec5SDimitry Andric if (Kind.isText()) 1328*0b57cec5SDimitry Andric return ".text"; 1329*0b57cec5SDimitry Andric if (Kind.isBSS()) 1330*0b57cec5SDimitry Andric return ".bss"; 1331*0b57cec5SDimitry Andric if (Kind.isThreadLocal()) 1332*0b57cec5SDimitry Andric return ".tls$"; 1333*0b57cec5SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 1334*0b57cec5SDimitry Andric return ".rdata"; 1335*0b57cec5SDimitry Andric return ".data"; 1336*0b57cec5SDimitry Andric } 1337*0b57cec5SDimitry Andric 1338*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 1339*0b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1340*0b57cec5SDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 1341*0b57cec5SDimitry Andric // uniqued section specifically for it. 1342*0b57cec5SDimitry Andric bool EmitUniquedSection; 1343*0b57cec5SDimitry Andric if (Kind.isText()) 1344*0b57cec5SDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 1345*0b57cec5SDimitry Andric else 1346*0b57cec5SDimitry Andric EmitUniquedSection = TM.getDataSections(); 1347*0b57cec5SDimitry Andric 1348*0b57cec5SDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) { 1349*0b57cec5SDimitry Andric SmallString<256> Name = getCOFFSectionNameForUniqueGlobal(Kind); 1350*0b57cec5SDimitry Andric 1351*0b57cec5SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1352*0b57cec5SDimitry Andric 1353*0b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 1354*0b57cec5SDimitry Andric int Selection = getSelectionForCOFF(GO); 1355*0b57cec5SDimitry Andric if (!Selection) 1356*0b57cec5SDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 1357*0b57cec5SDimitry Andric const GlobalValue *ComdatGV; 1358*0b57cec5SDimitry Andric if (GO->hasComdat()) 1359*0b57cec5SDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 1360*0b57cec5SDimitry Andric else 1361*0b57cec5SDimitry Andric ComdatGV = GO; 1362*0b57cec5SDimitry Andric 1363*0b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 1364*0b57cec5SDimitry Andric if (EmitUniquedSection) 1365*0b57cec5SDimitry Andric UniqueID = NextUniqueID++; 1366*0b57cec5SDimitry Andric 1367*0b57cec5SDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1368*0b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 1369*0b57cec5SDimitry Andric StringRef COMDATSymName = Sym->getName(); 1370*0b57cec5SDimitry Andric 1371*0b57cec5SDimitry Andric // Append "$symbol" to the section name *before* IR-level mangling is 1372*0b57cec5SDimitry Andric // applied when targetting mingw. This is what GCC does, and the ld.bfd 1373*0b57cec5SDimitry Andric // COFF linker will not properly handle comdats otherwise. 1374*0b57cec5SDimitry Andric if (getTargetTriple().isWindowsGNUEnvironment()) 1375*0b57cec5SDimitry Andric raw_svector_ostream(Name) << '$' << ComdatGV->getName(); 1376*0b57cec5SDimitry Andric 1377*0b57cec5SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, 1378*0b57cec5SDimitry Andric COMDATSymName, Selection, UniqueID); 1379*0b57cec5SDimitry Andric } else { 1380*0b57cec5SDimitry Andric SmallString<256> TmpData; 1381*0b57cec5SDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); 1382*0b57cec5SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, 1383*0b57cec5SDimitry Andric Selection, UniqueID); 1384*0b57cec5SDimitry Andric } 1385*0b57cec5SDimitry Andric } 1386*0b57cec5SDimitry Andric 1387*0b57cec5SDimitry Andric if (Kind.isText()) 1388*0b57cec5SDimitry Andric return TextSection; 1389*0b57cec5SDimitry Andric 1390*0b57cec5SDimitry Andric if (Kind.isThreadLocal()) 1391*0b57cec5SDimitry Andric return TLSDataSection; 1392*0b57cec5SDimitry Andric 1393*0b57cec5SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 1394*0b57cec5SDimitry Andric return ReadOnlySection; 1395*0b57cec5SDimitry Andric 1396*0b57cec5SDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 1397*0b57cec5SDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 1398*0b57cec5SDimitry Andric // entry but not a section. 1399*0b57cec5SDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 1400*0b57cec5SDimitry Andric return BSSSection; 1401*0b57cec5SDimitry Andric 1402*0b57cec5SDimitry Andric return DataSection; 1403*0b57cec5SDimitry Andric } 1404*0b57cec5SDimitry Andric 1405*0b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 1406*0b57cec5SDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 1407*0b57cec5SDimitry Andric const TargetMachine &TM) const { 1408*0b57cec5SDimitry Andric bool CannotUsePrivateLabel = false; 1409*0b57cec5SDimitry Andric if (GV->hasPrivateLinkage() && 1410*0b57cec5SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 1411*0b57cec5SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 1412*0b57cec5SDimitry Andric CannotUsePrivateLabel = true; 1413*0b57cec5SDimitry Andric 1414*0b57cec5SDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 1415*0b57cec5SDimitry Andric } 1416*0b57cec5SDimitry Andric 1417*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 1418*0b57cec5SDimitry Andric const Function &F, const TargetMachine &TM) const { 1419*0b57cec5SDimitry Andric // If the function can be removed, produce a unique section so that 1420*0b57cec5SDimitry Andric // the table doesn't prevent the removal. 1421*0b57cec5SDimitry Andric const Comdat *C = F.getComdat(); 1422*0b57cec5SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 1423*0b57cec5SDimitry Andric if (!EmitUniqueSection) 1424*0b57cec5SDimitry Andric return ReadOnlySection; 1425*0b57cec5SDimitry Andric 1426*0b57cec5SDimitry Andric // FIXME: we should produce a symbol for F instead. 1427*0b57cec5SDimitry Andric if (F.hasPrivateLinkage()) 1428*0b57cec5SDimitry Andric return ReadOnlySection; 1429*0b57cec5SDimitry Andric 1430*0b57cec5SDimitry Andric MCSymbol *Sym = TM.getSymbol(&F); 1431*0b57cec5SDimitry Andric StringRef COMDATSymName = Sym->getName(); 1432*0b57cec5SDimitry Andric 1433*0b57cec5SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 1434*0b57cec5SDimitry Andric StringRef SecName = getCOFFSectionNameForUniqueGlobal(Kind); 1435*0b57cec5SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1436*0b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 1437*0b57cec5SDimitry Andric unsigned UniqueID = NextUniqueID++; 1438*0b57cec5SDimitry Andric 1439*0b57cec5SDimitry Andric return getContext().getCOFFSection( 1440*0b57cec5SDimitry Andric SecName, Characteristics, Kind, COMDATSymName, 1441*0b57cec5SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 1442*0b57cec5SDimitry Andric } 1443*0b57cec5SDimitry Andric 1444*0b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, 1445*0b57cec5SDimitry Andric Module &M) const { 1446*0b57cec5SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 1447*0b57cec5SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 1448*0b57cec5SDimitry Andric // spec, this section is a space-separated string containing flags for 1449*0b57cec5SDimitry Andric // linker. 1450*0b57cec5SDimitry Andric MCSection *Sec = getDrectveSection(); 1451*0b57cec5SDimitry Andric Streamer.SwitchSection(Sec); 1452*0b57cec5SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 1453*0b57cec5SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 1454*0b57cec5SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 1455*0b57cec5SDimitry Andric std::string Directive(" "); 1456*0b57cec5SDimitry Andric Directive.append(cast<MDString>(Piece)->getString()); 1457*0b57cec5SDimitry Andric Streamer.EmitBytes(Directive); 1458*0b57cec5SDimitry Andric } 1459*0b57cec5SDimitry Andric } 1460*0b57cec5SDimitry Andric } 1461*0b57cec5SDimitry Andric 1462*0b57cec5SDimitry Andric unsigned Version = 0; 1463*0b57cec5SDimitry Andric unsigned Flags = 0; 1464*0b57cec5SDimitry Andric StringRef Section; 1465*0b57cec5SDimitry Andric 1466*0b57cec5SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 1467*0b57cec5SDimitry Andric if (Section.empty()) 1468*0b57cec5SDimitry Andric return; 1469*0b57cec5SDimitry Andric 1470*0b57cec5SDimitry Andric auto &C = getContext(); 1471*0b57cec5SDimitry Andric auto *S = C.getCOFFSection( 1472*0b57cec5SDimitry Andric Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, 1473*0b57cec5SDimitry Andric SectionKind::getReadOnly()); 1474*0b57cec5SDimitry Andric Streamer.SwitchSection(S); 1475*0b57cec5SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 1476*0b57cec5SDimitry Andric Streamer.EmitIntValue(Version, 4); 1477*0b57cec5SDimitry Andric Streamer.EmitIntValue(Flags, 4); 1478*0b57cec5SDimitry Andric Streamer.AddBlankLine(); 1479*0b57cec5SDimitry Andric } 1480*0b57cec5SDimitry Andric 1481*0b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, 1482*0b57cec5SDimitry Andric const TargetMachine &TM) { 1483*0b57cec5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 1484*0b57cec5SDimitry Andric const Triple &T = TM.getTargetTriple(); 1485*0b57cec5SDimitry Andric if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 1486*0b57cec5SDimitry Andric StaticCtorSection = 1487*0b57cec5SDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1488*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1489*0b57cec5SDimitry Andric SectionKind::getReadOnly()); 1490*0b57cec5SDimitry Andric StaticDtorSection = 1491*0b57cec5SDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1492*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1493*0b57cec5SDimitry Andric SectionKind::getReadOnly()); 1494*0b57cec5SDimitry Andric } else { 1495*0b57cec5SDimitry Andric StaticCtorSection = Ctx.getCOFFSection( 1496*0b57cec5SDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1497*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1498*0b57cec5SDimitry Andric SectionKind::getData()); 1499*0b57cec5SDimitry Andric StaticDtorSection = Ctx.getCOFFSection( 1500*0b57cec5SDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1501*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1502*0b57cec5SDimitry Andric SectionKind::getData()); 1503*0b57cec5SDimitry Andric } 1504*0b57cec5SDimitry Andric } 1505*0b57cec5SDimitry Andric 1506*0b57cec5SDimitry Andric static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx, 1507*0b57cec5SDimitry Andric const Triple &T, bool IsCtor, 1508*0b57cec5SDimitry Andric unsigned Priority, 1509*0b57cec5SDimitry Andric const MCSymbol *KeySym, 1510*0b57cec5SDimitry Andric MCSectionCOFF *Default) { 1511*0b57cec5SDimitry Andric if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 1512*0b57cec5SDimitry Andric // If the priority is the default, use .CRT$XCU, possibly associative. 1513*0b57cec5SDimitry Andric if (Priority == 65535) 1514*0b57cec5SDimitry Andric return Ctx.getAssociativeCOFFSection(Default, KeySym, 0); 1515*0b57cec5SDimitry Andric 1516*0b57cec5SDimitry Andric // Otherwise, we need to compute a new section name. Low priorities should 1517*0b57cec5SDimitry Andric // run earlier. The linker will sort sections ASCII-betically, and we need a 1518*0b57cec5SDimitry Andric // string that sorts between .CRT$XCA and .CRT$XCU. In the general case, we 1519*0b57cec5SDimitry Andric // make a name like ".CRT$XCT12345", since that runs before .CRT$XCU. Really 1520*0b57cec5SDimitry Andric // low priorities need to sort before 'L', since the CRT uses that 1521*0b57cec5SDimitry Andric // internally, so we use ".CRT$XCA00001" for them. 1522*0b57cec5SDimitry Andric SmallString<24> Name; 1523*0b57cec5SDimitry Andric raw_svector_ostream OS(Name); 15248bcb0991SDimitry Andric OS << ".CRT$X" << (IsCtor ? "C" : "T") << 15258bcb0991SDimitry Andric (Priority < 200 ? 'A' : 'T') << format("%05u", Priority); 1526*0b57cec5SDimitry Andric MCSectionCOFF *Sec = Ctx.getCOFFSection( 1527*0b57cec5SDimitry Andric Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, 1528*0b57cec5SDimitry Andric SectionKind::getReadOnly()); 1529*0b57cec5SDimitry Andric return Ctx.getAssociativeCOFFSection(Sec, KeySym, 0); 1530*0b57cec5SDimitry Andric } 1531*0b57cec5SDimitry Andric 1532*0b57cec5SDimitry Andric std::string Name = IsCtor ? ".ctors" : ".dtors"; 1533*0b57cec5SDimitry Andric if (Priority != 65535) 1534*0b57cec5SDimitry Andric raw_string_ostream(Name) << format(".%05u", 65535 - Priority); 1535*0b57cec5SDimitry Andric 1536*0b57cec5SDimitry Andric return Ctx.getAssociativeCOFFSection( 1537*0b57cec5SDimitry Andric Ctx.getCOFFSection(Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1538*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 1539*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_WRITE, 1540*0b57cec5SDimitry Andric SectionKind::getData()), 1541*0b57cec5SDimitry Andric KeySym, 0); 1542*0b57cec5SDimitry Andric } 1543*0b57cec5SDimitry Andric 1544*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 1545*0b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 1546*0b57cec5SDimitry Andric return getCOFFStaticStructorSection(getContext(), getTargetTriple(), true, 1547*0b57cec5SDimitry Andric Priority, KeySym, 1548*0b57cec5SDimitry Andric cast<MCSectionCOFF>(StaticCtorSection)); 1549*0b57cec5SDimitry Andric } 1550*0b57cec5SDimitry Andric 1551*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 1552*0b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 1553*0b57cec5SDimitry Andric return getCOFFStaticStructorSection(getContext(), getTargetTriple(), false, 1554*0b57cec5SDimitry Andric Priority, KeySym, 1555*0b57cec5SDimitry Andric cast<MCSectionCOFF>(StaticDtorSection)); 1556*0b57cec5SDimitry Andric } 1557*0b57cec5SDimitry Andric 1558*0b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( 1559*0b57cec5SDimitry Andric raw_ostream &OS, const GlobalValue *GV) const { 1560*0b57cec5SDimitry Andric emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); 1561*0b57cec5SDimitry Andric } 1562*0b57cec5SDimitry Andric 1563*0b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForUsed( 1564*0b57cec5SDimitry Andric raw_ostream &OS, const GlobalValue *GV) const { 1565*0b57cec5SDimitry Andric emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler()); 1566*0b57cec5SDimitry Andric } 1567*0b57cec5SDimitry Andric 1568*0b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( 1569*0b57cec5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 1570*0b57cec5SDimitry Andric const TargetMachine &TM) const { 1571*0b57cec5SDimitry Andric const Triple &T = TM.getTargetTriple(); 1572*0b57cec5SDimitry Andric if (T.isOSCygMing()) 1573*0b57cec5SDimitry Andric return nullptr; 1574*0b57cec5SDimitry Andric 1575*0b57cec5SDimitry Andric // Our symbols should exist in address space zero, cowardly no-op if 1576*0b57cec5SDimitry Andric // otherwise. 1577*0b57cec5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 1578*0b57cec5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0) 1579*0b57cec5SDimitry Andric return nullptr; 1580*0b57cec5SDimitry Andric 1581*0b57cec5SDimitry Andric // Both ptrtoint instructions must wrap global objects: 1582*0b57cec5SDimitry Andric // - Only global variables are eligible for image relative relocations. 1583*0b57cec5SDimitry Andric // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable. 1584*0b57cec5SDimitry Andric // We expect __ImageBase to be a global variable without a section, externally 1585*0b57cec5SDimitry Andric // defined. 1586*0b57cec5SDimitry Andric // 1587*0b57cec5SDimitry Andric // It should look something like this: @__ImageBase = external constant i8 1588*0b57cec5SDimitry Andric if (!isa<GlobalObject>(LHS) || !isa<GlobalVariable>(RHS) || 1589*0b57cec5SDimitry Andric LHS->isThreadLocal() || RHS->isThreadLocal() || 1590*0b57cec5SDimitry Andric RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() || 1591*0b57cec5SDimitry Andric cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection()) 1592*0b57cec5SDimitry Andric return nullptr; 1593*0b57cec5SDimitry Andric 1594*0b57cec5SDimitry Andric return MCSymbolRefExpr::create(TM.getSymbol(LHS), 1595*0b57cec5SDimitry Andric MCSymbolRefExpr::VK_COFF_IMGREL32, 1596*0b57cec5SDimitry Andric getContext()); 1597*0b57cec5SDimitry Andric } 1598*0b57cec5SDimitry Andric 1599*0b57cec5SDimitry Andric static std::string APIntToHexString(const APInt &AI) { 1600*0b57cec5SDimitry Andric unsigned Width = (AI.getBitWidth() / 8) * 2; 16018bcb0991SDimitry Andric std::string HexString = AI.toString(16, /*Signed=*/false); 16028bcb0991SDimitry Andric transform(HexString.begin(), HexString.end(), HexString.begin(), tolower); 1603*0b57cec5SDimitry Andric unsigned Size = HexString.size(); 1604*0b57cec5SDimitry Andric assert(Width >= Size && "hex string is too large!"); 1605*0b57cec5SDimitry Andric HexString.insert(HexString.begin(), Width - Size, '0'); 1606*0b57cec5SDimitry Andric 1607*0b57cec5SDimitry Andric return HexString; 1608*0b57cec5SDimitry Andric } 1609*0b57cec5SDimitry Andric 1610*0b57cec5SDimitry Andric static std::string scalarConstantToHexString(const Constant *C) { 1611*0b57cec5SDimitry Andric Type *Ty = C->getType(); 1612*0b57cec5SDimitry Andric if (isa<UndefValue>(C)) { 1613*0b57cec5SDimitry Andric return APIntToHexString(APInt::getNullValue(Ty->getPrimitiveSizeInBits())); 1614*0b57cec5SDimitry Andric } else if (const auto *CFP = dyn_cast<ConstantFP>(C)) { 1615*0b57cec5SDimitry Andric return APIntToHexString(CFP->getValueAPF().bitcastToAPInt()); 1616*0b57cec5SDimitry Andric } else if (const auto *CI = dyn_cast<ConstantInt>(C)) { 1617*0b57cec5SDimitry Andric return APIntToHexString(CI->getValue()); 1618*0b57cec5SDimitry Andric } else { 1619*0b57cec5SDimitry Andric unsigned NumElements; 1620*0b57cec5SDimitry Andric if (isa<VectorType>(Ty)) 1621*0b57cec5SDimitry Andric NumElements = Ty->getVectorNumElements(); 1622*0b57cec5SDimitry Andric else 1623*0b57cec5SDimitry Andric NumElements = Ty->getArrayNumElements(); 1624*0b57cec5SDimitry Andric std::string HexString; 1625*0b57cec5SDimitry Andric for (int I = NumElements - 1, E = -1; I != E; --I) 1626*0b57cec5SDimitry Andric HexString += scalarConstantToHexString(C->getAggregateElement(I)); 1627*0b57cec5SDimitry Andric return HexString; 1628*0b57cec5SDimitry Andric } 1629*0b57cec5SDimitry Andric } 1630*0b57cec5SDimitry Andric 1631*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant( 1632*0b57cec5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 1633*0b57cec5SDimitry Andric unsigned &Align) const { 1634*0b57cec5SDimitry Andric if (Kind.isMergeableConst() && C && 1635*0b57cec5SDimitry Andric getContext().getAsmInfo()->hasCOFFComdatConstants()) { 1636*0b57cec5SDimitry Andric // This creates comdat sections with the given symbol name, but unless 1637*0b57cec5SDimitry Andric // AsmPrinter::GetCPISymbol actually makes the symbol global, the symbol 1638*0b57cec5SDimitry Andric // will be created with a null storage class, which makes GNU binutils 1639*0b57cec5SDimitry Andric // error out. 1640*0b57cec5SDimitry Andric const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1641*0b57cec5SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 1642*0b57cec5SDimitry Andric COFF::IMAGE_SCN_LNK_COMDAT; 1643*0b57cec5SDimitry Andric std::string COMDATSymName; 1644*0b57cec5SDimitry Andric if (Kind.isMergeableConst4()) { 1645*0b57cec5SDimitry Andric if (Align <= 4) { 1646*0b57cec5SDimitry Andric COMDATSymName = "__real@" + scalarConstantToHexString(C); 1647*0b57cec5SDimitry Andric Align = 4; 1648*0b57cec5SDimitry Andric } 1649*0b57cec5SDimitry Andric } else if (Kind.isMergeableConst8()) { 1650*0b57cec5SDimitry Andric if (Align <= 8) { 1651*0b57cec5SDimitry Andric COMDATSymName = "__real@" + scalarConstantToHexString(C); 1652*0b57cec5SDimitry Andric Align = 8; 1653*0b57cec5SDimitry Andric } 1654*0b57cec5SDimitry Andric } else if (Kind.isMergeableConst16()) { 1655*0b57cec5SDimitry Andric // FIXME: These may not be appropriate for non-x86 architectures. 1656*0b57cec5SDimitry Andric if (Align <= 16) { 1657*0b57cec5SDimitry Andric COMDATSymName = "__xmm@" + scalarConstantToHexString(C); 1658*0b57cec5SDimitry Andric Align = 16; 1659*0b57cec5SDimitry Andric } 1660*0b57cec5SDimitry Andric } else if (Kind.isMergeableConst32()) { 1661*0b57cec5SDimitry Andric if (Align <= 32) { 1662*0b57cec5SDimitry Andric COMDATSymName = "__ymm@" + scalarConstantToHexString(C); 1663*0b57cec5SDimitry Andric Align = 32; 1664*0b57cec5SDimitry Andric } 1665*0b57cec5SDimitry Andric } 1666*0b57cec5SDimitry Andric 1667*0b57cec5SDimitry Andric if (!COMDATSymName.empty()) 1668*0b57cec5SDimitry Andric return getContext().getCOFFSection(".rdata", Characteristics, Kind, 1669*0b57cec5SDimitry Andric COMDATSymName, 1670*0b57cec5SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ANY); 1671*0b57cec5SDimitry Andric } 1672*0b57cec5SDimitry Andric 1673*0b57cec5SDimitry Andric return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, Align); 1674*0b57cec5SDimitry Andric } 1675*0b57cec5SDimitry Andric 1676*0b57cec5SDimitry Andric 1677*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1678*0b57cec5SDimitry Andric // Wasm 1679*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1680*0b57cec5SDimitry Andric 1681*0b57cec5SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) { 1682*0b57cec5SDimitry Andric const Comdat *C = GV->getComdat(); 1683*0b57cec5SDimitry Andric if (!C) 1684*0b57cec5SDimitry Andric return nullptr; 1685*0b57cec5SDimitry Andric 1686*0b57cec5SDimitry Andric if (C->getSelectionKind() != Comdat::Any) 1687*0b57cec5SDimitry Andric report_fatal_error("WebAssembly COMDATs only support " 1688*0b57cec5SDimitry Andric "SelectionKind::Any, '" + C->getName() + "' cannot be " 1689*0b57cec5SDimitry Andric "lowered."); 1690*0b57cec5SDimitry Andric 1691*0b57cec5SDimitry Andric return C; 1692*0b57cec5SDimitry Andric } 1693*0b57cec5SDimitry Andric 1694*0b57cec5SDimitry Andric static SectionKind getWasmKindForNamedSection(StringRef Name, SectionKind K) { 1695*0b57cec5SDimitry Andric // If we're told we have function data, then use that. 1696*0b57cec5SDimitry Andric if (K.isText()) 1697*0b57cec5SDimitry Andric return SectionKind::getText(); 1698*0b57cec5SDimitry Andric 1699*0b57cec5SDimitry Andric // Otherwise, ignore whatever section type the generic impl detected and use 1700*0b57cec5SDimitry Andric // a plain data section. 1701*0b57cec5SDimitry Andric return SectionKind::getData(); 1702*0b57cec5SDimitry Andric } 1703*0b57cec5SDimitry Andric 1704*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( 1705*0b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1706*0b57cec5SDimitry Andric // We don't support explict section names for functions in the wasm object 1707*0b57cec5SDimitry Andric // format. Each function has to be in its own unique section. 1708*0b57cec5SDimitry Andric if (isa<Function>(GO)) { 1709*0b57cec5SDimitry Andric return SelectSectionForGlobal(GO, Kind, TM); 1710*0b57cec5SDimitry Andric } 1711*0b57cec5SDimitry Andric 1712*0b57cec5SDimitry Andric StringRef Name = GO->getSection(); 1713*0b57cec5SDimitry Andric 1714*0b57cec5SDimitry Andric Kind = getWasmKindForNamedSection(Name, Kind); 1715*0b57cec5SDimitry Andric 1716*0b57cec5SDimitry Andric StringRef Group = ""; 1717*0b57cec5SDimitry Andric if (const Comdat *C = getWasmComdat(GO)) { 1718*0b57cec5SDimitry Andric Group = C->getName(); 1719*0b57cec5SDimitry Andric } 1720*0b57cec5SDimitry Andric 1721*0b57cec5SDimitry Andric MCSectionWasm* Section = 1722*0b57cec5SDimitry Andric getContext().getWasmSection(Name, Kind, Group, 1723*0b57cec5SDimitry Andric MCContext::GenericSectionID); 1724*0b57cec5SDimitry Andric 1725*0b57cec5SDimitry Andric return Section; 1726*0b57cec5SDimitry Andric } 1727*0b57cec5SDimitry Andric 1728*0b57cec5SDimitry Andric static MCSectionWasm *selectWasmSectionForGlobal( 1729*0b57cec5SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 1730*0b57cec5SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) { 1731*0b57cec5SDimitry Andric StringRef Group = ""; 1732*0b57cec5SDimitry Andric if (const Comdat *C = getWasmComdat(GO)) { 1733*0b57cec5SDimitry Andric Group = C->getName(); 1734*0b57cec5SDimitry Andric } 1735*0b57cec5SDimitry Andric 1736*0b57cec5SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 1737*0b57cec5SDimitry Andric SmallString<128> Name = getSectionPrefixForGlobal(Kind); 1738*0b57cec5SDimitry Andric 1739*0b57cec5SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 1740*0b57cec5SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 1741*0b57cec5SDimitry Andric if (OptionalPrefix) 1742*0b57cec5SDimitry Andric Name += *OptionalPrefix; 1743*0b57cec5SDimitry Andric } 1744*0b57cec5SDimitry Andric 1745*0b57cec5SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 1746*0b57cec5SDimitry Andric Name.push_back('.'); 1747*0b57cec5SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 1748*0b57cec5SDimitry Andric } 1749*0b57cec5SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 1750*0b57cec5SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 1751*0b57cec5SDimitry Andric UniqueID = *NextUniqueID; 1752*0b57cec5SDimitry Andric (*NextUniqueID)++; 1753*0b57cec5SDimitry Andric } 1754*0b57cec5SDimitry Andric 1755*0b57cec5SDimitry Andric return Ctx.getWasmSection(Name, Kind, Group, UniqueID); 1756*0b57cec5SDimitry Andric } 1757*0b57cec5SDimitry Andric 1758*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( 1759*0b57cec5SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1760*0b57cec5SDimitry Andric 1761*0b57cec5SDimitry Andric if (Kind.isCommon()) 1762*0b57cec5SDimitry Andric report_fatal_error("mergable sections not supported yet on wasm"); 1763*0b57cec5SDimitry Andric 1764*0b57cec5SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 1765*0b57cec5SDimitry Andric // global value to a uniqued section specifically for it. 1766*0b57cec5SDimitry Andric bool EmitUniqueSection = false; 1767*0b57cec5SDimitry Andric if (Kind.isText()) 1768*0b57cec5SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 1769*0b57cec5SDimitry Andric else 1770*0b57cec5SDimitry Andric EmitUniqueSection = TM.getDataSections(); 1771*0b57cec5SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 1772*0b57cec5SDimitry Andric 1773*0b57cec5SDimitry Andric return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 1774*0b57cec5SDimitry Andric EmitUniqueSection, &NextUniqueID); 1775*0b57cec5SDimitry Andric } 1776*0b57cec5SDimitry Andric 1777*0b57cec5SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( 1778*0b57cec5SDimitry Andric bool UsesLabelDifference, const Function &F) const { 1779*0b57cec5SDimitry Andric // We can always create relative relocations, so use another section 1780*0b57cec5SDimitry Andric // that can be marked non-executable. 1781*0b57cec5SDimitry Andric return false; 1782*0b57cec5SDimitry Andric } 1783*0b57cec5SDimitry Andric 1784*0b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( 1785*0b57cec5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 1786*0b57cec5SDimitry Andric const TargetMachine &TM) const { 1787*0b57cec5SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 1788*0b57cec5SDimitry Andric // functions. 1789*0b57cec5SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 1790*0b57cec5SDimitry Andric return nullptr; 1791*0b57cec5SDimitry Andric 1792*0b57cec5SDimitry Andric // Basic sanity checks. 1793*0b57cec5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 1794*0b57cec5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 1795*0b57cec5SDimitry Andric RHS->isThreadLocal()) 1796*0b57cec5SDimitry Andric return nullptr; 1797*0b57cec5SDimitry Andric 1798*0b57cec5SDimitry Andric return MCBinaryExpr::createSub( 1799*0b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, 1800*0b57cec5SDimitry Andric getContext()), 1801*0b57cec5SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 1802*0b57cec5SDimitry Andric } 1803*0b57cec5SDimitry Andric 1804*0b57cec5SDimitry Andric void TargetLoweringObjectFileWasm::InitializeWasm() { 1805*0b57cec5SDimitry Andric StaticCtorSection = 1806*0b57cec5SDimitry Andric getContext().getWasmSection(".init_array", SectionKind::getData()); 1807*0b57cec5SDimitry Andric 1808*0b57cec5SDimitry Andric // We don't use PersonalityEncoding and LSDAEncoding because we don't emit 1809*0b57cec5SDimitry Andric // .cfi directives. We use TTypeEncoding to encode typeinfo global variables. 1810*0b57cec5SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr; 1811*0b57cec5SDimitry Andric } 1812*0b57cec5SDimitry Andric 1813*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticCtorSection( 1814*0b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 1815*0b57cec5SDimitry Andric return Priority == UINT16_MAX ? 1816*0b57cec5SDimitry Andric StaticCtorSection : 1817*0b57cec5SDimitry Andric getContext().getWasmSection(".init_array." + utostr(Priority), 1818*0b57cec5SDimitry Andric SectionKind::getData()); 1819*0b57cec5SDimitry Andric } 1820*0b57cec5SDimitry Andric 1821*0b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection( 1822*0b57cec5SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 1823*0b57cec5SDimitry Andric llvm_unreachable("@llvm.global_dtors should have been lowered already"); 1824*0b57cec5SDimitry Andric return nullptr; 1825*0b57cec5SDimitry Andric } 18268bcb0991SDimitry Andric 18278bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 18288bcb0991SDimitry Andric // XCOFF 18298bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 18308bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal( 18318bcb0991SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 18328bcb0991SDimitry Andric report_fatal_error("XCOFF explicit sections not yet implemented."); 18338bcb0991SDimitry Andric } 18348bcb0991SDimitry Andric 18358bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal( 18368bcb0991SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 18378bcb0991SDimitry Andric assert(!TM.getFunctionSections() && !TM.getDataSections() && 18388bcb0991SDimitry Andric "XCOFF unique sections not yet implemented."); 18398bcb0991SDimitry Andric 18408bcb0991SDimitry Andric // Common symbols go into a csect with matching name which will get mapped 18418bcb0991SDimitry Andric // into the .bss section. 18428bcb0991SDimitry Andric if (Kind.isBSSLocal() || Kind.isCommon()) { 18438bcb0991SDimitry Andric SmallString<128> Name; 18448bcb0991SDimitry Andric getNameWithPrefix(Name, GO, TM); 18458bcb0991SDimitry Andric XCOFF::StorageClass SC = 18468bcb0991SDimitry Andric TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO); 18478bcb0991SDimitry Andric return getContext().getXCOFFSection( 18488bcb0991SDimitry Andric Name, Kind.isBSSLocal() ? XCOFF::XMC_BS : XCOFF::XMC_RW, XCOFF::XTY_CM, 18498bcb0991SDimitry Andric SC, Kind, /* BeginSymbolName */ nullptr); 18508bcb0991SDimitry Andric } 18518bcb0991SDimitry Andric 18528bcb0991SDimitry Andric if (Kind.isText()) 18538bcb0991SDimitry Andric return TextSection; 18548bcb0991SDimitry Andric 18558bcb0991SDimitry Andric if (Kind.isData()) 18568bcb0991SDimitry Andric return DataSection; 18578bcb0991SDimitry Andric 18588bcb0991SDimitry Andric report_fatal_error("XCOFF other section types not yet implemented."); 18598bcb0991SDimitry Andric } 18608bcb0991SDimitry Andric 18618bcb0991SDimitry Andric bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection( 18628bcb0991SDimitry Andric bool UsesLabelDifference, const Function &F) const { 18638bcb0991SDimitry Andric report_fatal_error("TLOF XCOFF not yet implemented."); 18648bcb0991SDimitry Andric } 18658bcb0991SDimitry Andric 18668bcb0991SDimitry Andric void TargetLoweringObjectFileXCOFF::Initialize(MCContext &Ctx, 18678bcb0991SDimitry Andric const TargetMachine &TgtM) { 18688bcb0991SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TgtM); 18698bcb0991SDimitry Andric TTypeEncoding = 0; 18708bcb0991SDimitry Andric PersonalityEncoding = 0; 18718bcb0991SDimitry Andric LSDAEncoding = 0; 18728bcb0991SDimitry Andric } 18738bcb0991SDimitry Andric 18748bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getStaticCtorSection( 18758bcb0991SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 18768bcb0991SDimitry Andric report_fatal_error("XCOFF ctor section not yet implemented."); 18778bcb0991SDimitry Andric } 18788bcb0991SDimitry Andric 18798bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getStaticDtorSection( 18808bcb0991SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 18818bcb0991SDimitry Andric report_fatal_error("XCOFF dtor section not yet implemented."); 18828bcb0991SDimitry Andric } 18838bcb0991SDimitry Andric 18848bcb0991SDimitry Andric const MCExpr *TargetLoweringObjectFileXCOFF::lowerRelativeReference( 18858bcb0991SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 18868bcb0991SDimitry Andric const TargetMachine &TM) const { 18878bcb0991SDimitry Andric report_fatal_error("XCOFF not yet implemented."); 18888bcb0991SDimitry Andric } 18898bcb0991SDimitry Andric 18908bcb0991SDimitry Andric XCOFF::StorageClass TargetLoweringObjectFileXCOFF::getStorageClassForGlobal( 18918bcb0991SDimitry Andric const GlobalObject *GO) { 18928bcb0991SDimitry Andric switch (GO->getLinkage()) { 18938bcb0991SDimitry Andric case GlobalValue::InternalLinkage: 18948bcb0991SDimitry Andric return XCOFF::C_HIDEXT; 18958bcb0991SDimitry Andric case GlobalValue::ExternalLinkage: 18968bcb0991SDimitry Andric case GlobalValue::CommonLinkage: 18978bcb0991SDimitry Andric return XCOFF::C_EXT; 18988bcb0991SDimitry Andric case GlobalValue::ExternalWeakLinkage: 18998bcb0991SDimitry Andric return XCOFF::C_WEAKEXT; 19008bcb0991SDimitry Andric default: 19018bcb0991SDimitry Andric report_fatal_error( 19028bcb0991SDimitry Andric "Unhandled linkage when mapping linkage to StorageClass."); 19038bcb0991SDimitry Andric } 19048bcb0991SDimitry Andric } 1905