2859 lines · cpp
1//===- llvm/CodeGen/TargetLoweringObjectFileImpl.cpp - Object File Info ---===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements classes used to handle lowerings specific to common10// object file formats.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"15#include "llvm/ADT/SmallString.h"16#include "llvm/ADT/SmallVector.h"17#include "llvm/ADT/StringExtras.h"18#include "llvm/ADT/StringRef.h"19#include "llvm/BinaryFormat/COFF.h"20#include "llvm/BinaryFormat/Dwarf.h"21#include "llvm/BinaryFormat/ELF.h"22#include "llvm/BinaryFormat/GOFF.h"23#include "llvm/BinaryFormat/MachO.h"24#include "llvm/BinaryFormat/Wasm.h"25#include "llvm/CodeGen/BasicBlockSectionUtils.h"26#include "llvm/CodeGen/MachineBasicBlock.h"27#include "llvm/CodeGen/MachineFunction.h"28#include "llvm/CodeGen/MachineJumpTableInfo.h"29#include "llvm/CodeGen/MachineModuleInfo.h"30#include "llvm/CodeGen/MachineModuleInfoImpls.h"31#include "llvm/IR/Comdat.h"32#include "llvm/IR/Constants.h"33#include "llvm/IR/DataLayout.h"34#include "llvm/IR/DerivedTypes.h"35#include "llvm/IR/DiagnosticInfo.h"36#include "llvm/IR/DiagnosticPrinter.h"37#include "llvm/IR/Function.h"38#include "llvm/IR/GlobalAlias.h"39#include "llvm/IR/GlobalObject.h"40#include "llvm/IR/GlobalValue.h"41#include "llvm/IR/GlobalVariable.h"42#include "llvm/IR/Mangler.h"43#include "llvm/IR/Metadata.h"44#include "llvm/IR/Module.h"45#include "llvm/IR/Type.h"46#include "llvm/MC/MCAsmInfo.h"47#include "llvm/MC/MCAsmInfoDarwin.h"48#include "llvm/MC/MCContext.h"49#include "llvm/MC/MCExpr.h"50#include "llvm/MC/MCGOFFAttributes.h"51#include "llvm/MC/MCSectionCOFF.h"52#include "llvm/MC/MCSectionELF.h"53#include "llvm/MC/MCSectionGOFF.h"54#include "llvm/MC/MCSectionMachO.h"55#include "llvm/MC/MCSectionWasm.h"56#include "llvm/MC/MCSectionXCOFF.h"57#include "llvm/MC/MCStreamer.h"58#include "llvm/MC/MCSymbol.h"59#include "llvm/MC/MCSymbolELF.h"60#include "llvm/MC/MCSymbolGOFF.h"61#include "llvm/MC/MCValue.h"62#include "llvm/MC/SectionKind.h"63#include "llvm/ProfileData/InstrProf.h"64#include "llvm/Support/Base64.h"65#include "llvm/Support/Casting.h"66#include "llvm/Support/CodeGen.h"67#include "llvm/Support/ErrorHandling.h"68#include "llvm/Support/Format.h"69#include "llvm/Support/Path.h"70#include "llvm/Support/raw_ostream.h"71#include "llvm/Target/TargetMachine.h"72#include "llvm/TargetParser/Triple.h"73#include <cassert>74#include <string>75 76using namespace llvm;77using namespace dwarf;78 79static cl::opt<bool> JumpTableInFunctionSection(80 "jumptable-in-function-section", cl::Hidden, cl::init(false),81 cl::desc("Putting Jump Table in function section"));82 83static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,84 StringRef &Section) {85 SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;86 M.getModuleFlagsMetadata(ModuleFlags);87 88 for (const auto &MFE: ModuleFlags) {89 // Ignore flags with 'Require' behaviour.90 if (MFE.Behavior == Module::Require)91 continue;92 93 StringRef Key = MFE.Key->getString();94 if (Key == "Objective-C Image Info Version") {95 Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue();96 } else if (Key == "Objective-C Garbage Collection" ||97 Key == "Objective-C GC Only" ||98 Key == "Objective-C Is Simulated" ||99 Key == "Objective-C Class Properties" ||100 Key == "Objective-C Image Swift Version") {101 Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue();102 } else if (Key == "Objective-C Image Info Section") {103 Section = cast<MDString>(MFE.Val)->getString();104 }105 // Backend generates L_OBJC_IMAGE_INFO from Swift ABI version + major + minor +106 // "Objective-C Garbage Collection".107 else if (Key == "Swift ABI Version") {108 Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 8;109 } else if (Key == "Swift Major Version") {110 Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 24;111 } else if (Key == "Swift Minor Version") {112 Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 16;113 }114 }115}116 117//===----------------------------------------------------------------------===//118// ELF119//===----------------------------------------------------------------------===//120 121void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,122 const TargetMachine &TgtM) {123 TargetLoweringObjectFile::Initialize(Ctx, TgtM);124 125 CodeModel::Model CM = TgtM.getCodeModel();126 InitializeELF(TgtM.Options.UseInitArray);127 128 switch (TgtM.getTargetTriple().getArch()) {129 case Triple::arm:130 case Triple::armeb:131 case Triple::thumb:132 case Triple::thumbeb:133 if (Ctx.getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM)134 break;135 // Fallthrough if not using EHABI136 [[fallthrough]];137 case Triple::ppc:138 case Triple::ppcle:139 case Triple::x86:140 PersonalityEncoding = isPositionIndependent()141 ? dwarf::DW_EH_PE_indirect |142 dwarf::DW_EH_PE_pcrel |143 dwarf::DW_EH_PE_sdata4144 : dwarf::DW_EH_PE_absptr;145 LSDAEncoding = isPositionIndependent()146 ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4147 : dwarf::DW_EH_PE_absptr;148 TTypeEncoding = isPositionIndependent()149 ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |150 dwarf::DW_EH_PE_sdata4151 : dwarf::DW_EH_PE_absptr;152 break;153 case Triple::x86_64:154 if (isPositionIndependent()) {155 PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |156 ((CM == CodeModel::Small || CM == CodeModel::Medium)157 ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);158 LSDAEncoding = dwarf::DW_EH_PE_pcrel |159 (CM == CodeModel::Small160 ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);161 TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |162 ((CM == CodeModel::Small || CM == CodeModel::Medium)163 ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);164 } else {165 PersonalityEncoding =166 (CM == CodeModel::Small || CM == CodeModel::Medium)167 ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;168 LSDAEncoding = (CM == CodeModel::Small)169 ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;170 TTypeEncoding = (CM == CodeModel::Small)171 ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;172 }173 break;174 case Triple::hexagon:175 PersonalityEncoding = dwarf::DW_EH_PE_absptr;176 LSDAEncoding = dwarf::DW_EH_PE_absptr;177 TTypeEncoding = dwarf::DW_EH_PE_absptr;178 if (isPositionIndependent()) {179 PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel;180 LSDAEncoding |= dwarf::DW_EH_PE_pcrel;181 TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel;182 }183 break;184 case Triple::aarch64:185 case Triple::aarch64_be:186 case Triple::aarch64_32:187 // The small model guarantees static code/data size < 4GB, but not where it188 // will be in memory. Most of these could end up >2GB away so even a signed189 // pc-relative 32-bit address is insufficient, theoretically.190 //191 // Use DW_EH_PE_indirect even for -fno-pic to avoid copy relocations.192 LSDAEncoding = dwarf::DW_EH_PE_pcrel |193 (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32194 ? dwarf::DW_EH_PE_sdata4195 : dwarf::DW_EH_PE_sdata8);196 PersonalityEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect;197 TTypeEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect;198 break;199 case Triple::lanai:200 LSDAEncoding = dwarf::DW_EH_PE_absptr;201 PersonalityEncoding = dwarf::DW_EH_PE_absptr;202 TTypeEncoding = dwarf::DW_EH_PE_absptr;203 break;204 case Triple::mips:205 case Triple::mipsel:206 case Triple::mips64:207 case Triple::mips64el:208 // MIPS uses indirect pointer to refer personality functions and types, so209 // that the eh_frame section can be read-only. DW.ref.personality will be210 // generated for relocation.211 PersonalityEncoding = dwarf::DW_EH_PE_indirect;212 // FIXME: The N64 ABI probably ought to use DW_EH_PE_sdata8 but we can't213 // identify N64 from just a triple.214 TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |215 dwarf::DW_EH_PE_sdata4;216 217 // FreeBSD must be explicit about the data size and using pcrel since it's218 // assembler/linker won't do the automatic conversion that the Linux tools219 // do.220 if (isPositionIndependent() || TgtM.getTargetTriple().isOSFreeBSD()) {221 PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;222 LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;223 }224 break;225 case Triple::ppc64:226 case Triple::ppc64le:227 PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |228 dwarf::DW_EH_PE_udata8;229 LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;230 TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |231 dwarf::DW_EH_PE_udata8;232 break;233 case Triple::sparcel:234 case Triple::sparc:235 if (isPositionIndependent()) {236 LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;237 PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |238 dwarf::DW_EH_PE_sdata4;239 TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |240 dwarf::DW_EH_PE_sdata4;241 } else {242 LSDAEncoding = dwarf::DW_EH_PE_absptr;243 PersonalityEncoding = dwarf::DW_EH_PE_absptr;244 TTypeEncoding = dwarf::DW_EH_PE_absptr;245 }246 CallSiteEncoding = dwarf::DW_EH_PE_udata4;247 break;248 case Triple::riscv32:249 case Triple::riscv64:250 case Triple::riscv32be:251 case Triple::riscv64be:252 LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;253 PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |254 dwarf::DW_EH_PE_sdata4;255 TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |256 dwarf::DW_EH_PE_sdata4;257 CallSiteEncoding = dwarf::DW_EH_PE_udata4;258 break;259 case Triple::sparcv9:260 LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;261 if (isPositionIndependent()) {262 PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |263 dwarf::DW_EH_PE_sdata4;264 TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |265 dwarf::DW_EH_PE_sdata4;266 } else {267 PersonalityEncoding = dwarf::DW_EH_PE_absptr;268 TTypeEncoding = dwarf::DW_EH_PE_absptr;269 }270 break;271 case Triple::systemz:272 // All currently-defined code models guarantee that 4-byte PC-relative273 // values will be in range.274 if (isPositionIndependent()) {275 PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |276 dwarf::DW_EH_PE_sdata4;277 LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;278 TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |279 dwarf::DW_EH_PE_sdata4;280 } else {281 PersonalityEncoding = dwarf::DW_EH_PE_absptr;282 LSDAEncoding = dwarf::DW_EH_PE_absptr;283 TTypeEncoding = dwarf::DW_EH_PE_absptr;284 }285 break;286 case Triple::loongarch32:287 case Triple::loongarch64:288 LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;289 PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |290 dwarf::DW_EH_PE_sdata4;291 TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |292 dwarf::DW_EH_PE_sdata4;293 break;294 default:295 break;296 }297}298 299void TargetLoweringObjectFileELF::getModuleMetadata(Module &M) {300 SmallVector<GlobalValue *, 4> Vec;301 collectUsedGlobalVariables(M, Vec, false);302 for (GlobalValue *GV : Vec)303 if (auto *GO = dyn_cast<GlobalObject>(GV))304 Used.insert(GO);305}306 307void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,308 Module &M) const {309 auto &C = getContext();310 311 emitLinkerDirectives(Streamer, M);312 313 if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) {314 auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES,315 ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);316 317 Streamer.switchSection(S);318 319 for (const auto *Operand : DependentLibraries->operands()) {320 Streamer.emitBytes(321 cast<MDString>(cast<MDNode>(Operand)->getOperand(0))->getString());322 Streamer.emitInt8(0);323 }324 }325 326 emitPseudoProbeDescMetadata(Streamer, M);327 328 if (NamedMDNode *LLVMStats = M.getNamedMetadata("llvm.stats")) {329 // Emit the metadata for llvm statistics into .llvm_stats section, which is330 // formatted as a list of key/value pair, the value is base64 encoded.331 auto *S = C.getObjectFileInfo()->getLLVMStatsSection();332 Streamer.switchSection(S);333 for (const auto *Operand : LLVMStats->operands()) {334 const auto *MD = cast<MDNode>(Operand);335 assert(MD->getNumOperands() % 2 == 0 &&336 ("Operand num should be even for a list of key/value pair"));337 for (size_t I = 0; I < MD->getNumOperands(); I += 2) {338 // Encode the key string size.339 auto *Key = cast<MDString>(MD->getOperand(I));340 Streamer.emitULEB128IntValue(Key->getString().size());341 Streamer.emitBytes(Key->getString());342 // Encode the value into a Base64 string.343 std::string Value = encodeBase64(344 Twine(mdconst::dyn_extract<ConstantInt>(MD->getOperand(I + 1))345 ->getZExtValue())346 .str());347 Streamer.emitULEB128IntValue(Value.size());348 Streamer.emitBytes(Value);349 }350 }351 }352 353 unsigned Version = 0;354 unsigned Flags = 0;355 StringRef Section;356 357 GetObjCImageInfo(M, Version, Flags, Section);358 if (!Section.empty()) {359 auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);360 Streamer.switchSection(S);361 Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));362 Streamer.emitInt32(Version);363 Streamer.emitInt32(Flags);364 Streamer.addBlankLine();365 }366 367 emitCGProfileMetadata(Streamer, M);368}369 370void TargetLoweringObjectFileELF::emitLinkerDirectives(MCStreamer &Streamer,371 Module &M) const {372 auto &C = getContext();373 if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {374 auto *S = C.getELFSection(".linker-options", ELF::SHT_LLVM_LINKER_OPTIONS,375 ELF::SHF_EXCLUDE);376 377 Streamer.switchSection(S);378 379 for (const auto *Operand : LinkerOptions->operands()) {380 if (cast<MDNode>(Operand)->getNumOperands() != 2)381 report_fatal_error("invalid llvm.linker.options");382 for (const auto &Option : cast<MDNode>(Operand)->operands()) {383 Streamer.emitBytes(cast<MDString>(Option)->getString());384 Streamer.emitInt8(0);385 }386 }387 }388}389 390MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(391 const GlobalValue *GV, const TargetMachine &TM,392 MachineModuleInfo *MMI) const {393 unsigned Encoding = getPersonalityEncoding();394 if ((Encoding & 0x80) == DW_EH_PE_indirect)395 return getContext().getOrCreateSymbol(StringRef("DW.ref.") +396 TM.getSymbol(GV)->getName());397 if ((Encoding & 0x70) == DW_EH_PE_absptr)398 return TM.getSymbol(GV);399 report_fatal_error("We do not support this DWARF encoding yet!");400}401 402void TargetLoweringObjectFileELF::emitPersonalityValue(403 MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,404 const MachineModuleInfo *MMI) const {405 SmallString<64> NameData("DW.ref.");406 NameData += Sym->getName();407 auto *Label =408 static_cast<MCSymbolELF *>(getContext().getOrCreateSymbol(NameData));409 Streamer.emitSymbolAttribute(Label, MCSA_Hidden);410 Streamer.emitSymbolAttribute(Label, MCSA_Weak);411 unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP;412 MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(),413 ELF::SHT_PROGBITS, Flags, 0);414 unsigned Size = DL.getPointerSize();415 Streamer.switchSection(Sec);416 Streamer.emitValueToAlignment(DL.getPointerABIAlignment(0));417 Streamer.emitSymbolAttribute(Label, MCSA_ELF_TypeObject);418 const MCExpr *E = MCConstantExpr::create(Size, getContext());419 Streamer.emitELFSize(Label, E);420 Streamer.emitLabel(Label);421 422 emitPersonalityValueImpl(Streamer, DL, Sym, MMI);423}424 425void TargetLoweringObjectFileELF::emitPersonalityValueImpl(426 MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,427 const MachineModuleInfo *MMI) const {428 Streamer.emitSymbolValue(Sym, DL.getPointerSize());429}430 431const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(432 const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,433 MachineModuleInfo *MMI, MCStreamer &Streamer) const {434 if (Encoding & DW_EH_PE_indirect) {435 MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();436 437 MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM);438 439 // Add information about the stub reference to ELFMMI so that the stub440 // gets emitted by the asmprinter.441 MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);442 if (!StubSym.getPointer()) {443 MCSymbol *Sym = TM.getSymbol(GV);444 StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());445 }446 447 return TargetLoweringObjectFile::448 getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()),449 Encoding & ~DW_EH_PE_indirect, Streamer);450 }451 452 return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM,453 MMI, Streamer);454}455 456static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {457 // N.B.: The defaults used in here are not the same ones used in MC.458 // We follow gcc, MC follows gas. For example, given ".section .eh_frame",459 // both gas and MC will produce a section with no flags. Given460 // section(".eh_frame") gcc will produce:461 //462 // .section .eh_frame,"a",@progbits463 464 if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF,465 /*AddSegmentInfo=*/false) ||466 Name == getInstrProfSectionName(IPSK_covfun, Triple::ELF,467 /*AddSegmentInfo=*/false) ||468 Name == getInstrProfSectionName(IPSK_covdata, Triple::ELF,469 /*AddSegmentInfo=*/false) ||470 Name == getInstrProfSectionName(IPSK_covname, Triple::ELF,471 /*AddSegmentInfo=*/false) ||472 Name == ".llvmbc" || Name == ".llvmcmd")473 return SectionKind::getMetadata();474 475 if (!Name.starts_with(".")) return K;476 477 // Default implementation based on some magic section names.478 if (Name == ".bss" || Name.starts_with(".bss.") ||479 Name.starts_with(".gnu.linkonce.b.") ||480 Name.starts_with(".llvm.linkonce.b.") || Name == ".sbss" ||481 Name.starts_with(".sbss.") || Name.starts_with(".gnu.linkonce.sb.") ||482 Name.starts_with(".llvm.linkonce.sb."))483 return SectionKind::getBSS();484 485 if (Name == ".tdata" || Name.starts_with(".tdata.") ||486 Name.starts_with(".gnu.linkonce.td.") ||487 Name.starts_with(".llvm.linkonce.td."))488 return SectionKind::getThreadData();489 490 if (Name == ".tbss" || Name.starts_with(".tbss.") ||491 Name.starts_with(".gnu.linkonce.tb.") ||492 Name.starts_with(".llvm.linkonce.tb."))493 return SectionKind::getThreadBSS();494 495 return K;496}497 498static bool hasPrefix(StringRef SectionName, StringRef Prefix) {499 return SectionName.consume_front(Prefix) &&500 (SectionName.empty() || SectionName[0] == '.');501}502 503static unsigned getELFSectionType(StringRef Name, SectionKind K) {504 // Use SHT_NOTE for section whose name starts with ".note" to allow505 // emitting ELF notes from C variable declaration.506 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609507 if (Name.starts_with(".note"))508 return ELF::SHT_NOTE;509 510 if (hasPrefix(Name, ".init_array"))511 return ELF::SHT_INIT_ARRAY;512 513 if (hasPrefix(Name, ".fini_array"))514 return ELF::SHT_FINI_ARRAY;515 516 if (hasPrefix(Name, ".preinit_array"))517 return ELF::SHT_PREINIT_ARRAY;518 519 if (hasPrefix(Name, ".llvm.offloading"))520 return ELF::SHT_LLVM_OFFLOADING;521 if (Name == ".llvm.lto")522 return ELF::SHT_LLVM_LTO;523 524 if (K.isBSS() || K.isThreadBSS())525 return ELF::SHT_NOBITS;526 527 return ELF::SHT_PROGBITS;528}529 530static unsigned getELFSectionFlags(SectionKind K, const Triple &T) {531 unsigned Flags = 0;532 533 if (!K.isMetadata() && !K.isExclude())534 Flags |= ELF::SHF_ALLOC;535 536 if (K.isExclude())537 Flags |= ELF::SHF_EXCLUDE;538 539 if (K.isText())540 Flags |= ELF::SHF_EXECINSTR;541 542 if (K.isExecuteOnly()) {543 if (T.isAArch64())544 Flags |= ELF::SHF_AARCH64_PURECODE;545 else if (T.isARM() || T.isThumb())546 Flags |= ELF::SHF_ARM_PURECODE;547 }548 549 if (K.isWriteable())550 Flags |= ELF::SHF_WRITE;551 552 if (K.isThreadLocal())553 Flags |= ELF::SHF_TLS;554 555 if (K.isMergeableCString() || K.isMergeableConst())556 Flags |= ELF::SHF_MERGE;557 558 if (K.isMergeableCString())559 Flags |= ELF::SHF_STRINGS;560 561 return Flags;562}563 564static const Comdat *getELFComdat(const GlobalValue *GV) {565 const Comdat *C = GV->getComdat();566 if (!C)567 return nullptr;568 569 if (C->getSelectionKind() != Comdat::Any &&570 C->getSelectionKind() != Comdat::NoDeduplicate)571 report_fatal_error("ELF COMDATs only support SelectionKind::Any and "572 "SelectionKind::NoDeduplicate, '" +573 C->getName() + "' cannot be lowered.");574 575 return C;576}577 578static const MCSymbolELF *getLinkedToSymbol(const GlobalObject *GO,579 const TargetMachine &TM) {580 MDNode *MD = GO->getMetadata(LLVMContext::MD_associated);581 if (!MD)582 return nullptr;583 584 auto *VM = cast<ValueAsMetadata>(MD->getOperand(0).get());585 auto *OtherGV = dyn_cast<GlobalValue>(VM->getValue());586 return OtherGV ? static_cast<const MCSymbolELF *>(TM.getSymbol(OtherGV))587 : nullptr;588}589 590static unsigned getEntrySizeForKind(SectionKind Kind) {591 if (Kind.isMergeable1ByteCString())592 return 1;593 else if (Kind.isMergeable2ByteCString())594 return 2;595 else if (Kind.isMergeable4ByteCString())596 return 4;597 else if (Kind.isMergeableConst4())598 return 4;599 else if (Kind.isMergeableConst8())600 return 8;601 else if (Kind.isMergeableConst16())602 return 16;603 else if (Kind.isMergeableConst32())604 return 32;605 else {606 // We shouldn't have mergeable C strings or mergeable constants that we607 // didn't handle above.608 assert(!Kind.isMergeableCString() && "unknown string width");609 assert(!Kind.isMergeableConst() && "unknown data width");610 return 0;611 }612}613 614/// Return the section prefix name used by options FunctionsSections and615/// DataSections.616static StringRef getSectionPrefixForGlobal(SectionKind Kind, bool IsLarge) {617 if (Kind.isText())618 return IsLarge ? ".ltext" : ".text";619 if (Kind.isReadOnly())620 return IsLarge ? ".lrodata" : ".rodata";621 if (Kind.isBSS())622 return IsLarge ? ".lbss" : ".bss";623 if (Kind.isThreadData())624 return ".tdata";625 if (Kind.isThreadBSS())626 return ".tbss";627 if (Kind.isData())628 return IsLarge ? ".ldata" : ".data";629 if (Kind.isReadOnlyWithRel())630 return IsLarge ? ".ldata.rel.ro" : ".data.rel.ro";631 llvm_unreachable("Unknown section kind");632}633 634static SmallString<128>635getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,636 Mangler &Mang, const TargetMachine &TM,637 unsigned EntrySize, bool UniqueSectionName,638 const MachineJumpTableEntry *JTE) {639 SmallString<128> Name =640 getSectionPrefixForGlobal(Kind, TM.isLargeGlobalValue(GO));641 if (Kind.isMergeableCString()) {642 // We also need alignment here.643 // FIXME: this is getting the alignment of the character, not the644 // alignment of the global!645 Align Alignment = GO->getDataLayout().getPreferredAlign(646 cast<GlobalVariable>(GO));647 648 Name += ".str";649 Name += utostr(EntrySize);650 Name += ".";651 Name += utostr(Alignment.value());652 } else if (Kind.isMergeableConst()) {653 Name += ".cst";654 Name += utostr(EntrySize);655 }656 657 bool HasPrefix = false;658 if (const auto *F = dyn_cast<Function>(GO)) {659 // Jump table hotness takes precedence over its enclosing function's hotness660 // if it's known. The function's section prefix is used if jump table entry661 // hotness is unknown.662 if (JTE && JTE->Hotness != MachineFunctionDataHotness::Unknown) {663 if (JTE->Hotness == MachineFunctionDataHotness::Hot) {664 raw_svector_ostream(Name) << ".hot";665 } else {666 assert(JTE->Hotness == MachineFunctionDataHotness::Cold &&667 "Hotness must be cold");668 raw_svector_ostream(Name) << ".unlikely";669 }670 HasPrefix = true;671 } else if (std::optional<StringRef> Prefix = F->getSectionPrefix()) {672 raw_svector_ostream(Name) << '.' << *Prefix;673 HasPrefix = true;674 }675 } else if (const auto *GV = dyn_cast<GlobalVariable>(GO)) {676 if (std::optional<StringRef> Prefix = GV->getSectionPrefix()) {677 raw_svector_ostream(Name) << '.' << *Prefix;678 HasPrefix = true;679 }680 }681 682 if (UniqueSectionName) {683 Name.push_back('.');684 TM.getNameWithPrefix(Name, GO, Mang, /*MayAlwaysUsePrivate*/true);685 } else if (HasPrefix)686 // For distinguishing between .text.${text-section-prefix}. (with trailing687 // dot) and .text.${function-name}688 Name.push_back('.');689 return Name;690}691 692namespace {693class LoweringDiagnosticInfo : public DiagnosticInfo {694 const Twine &Msg;695 696public:697 LoweringDiagnosticInfo(const Twine &DiagMsg LLVM_LIFETIME_BOUND,698 DiagnosticSeverity Severity = DS_Error)699 : DiagnosticInfo(DK_Lowering, Severity), Msg(DiagMsg) {}700 void print(DiagnosticPrinter &DP) const override { DP << Msg; }701};702}703 704/// Calculate an appropriate unique ID for a section, and update Flags,705/// EntrySize and NextUniqueID where appropriate.706static unsigned707calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName,708 SectionKind Kind, const TargetMachine &TM,709 MCContext &Ctx, Mangler &Mang, unsigned &Flags,710 unsigned &EntrySize, unsigned &NextUniqueID,711 const bool Retain, const bool ForceUnique) {712 // Increment uniqueID if we are forced to emit a unique section.713 // This works perfectly fine with section attribute or pragma section as the714 // sections with the same name are grouped together by the assembler.715 if (ForceUnique)716 return NextUniqueID++;717 718 // A section can have at most one associated section. Put each global with719 // MD_associated in a unique section.720 const bool Associated = GO->getMetadata(LLVMContext::MD_associated);721 if (Associated) {722 Flags |= ELF::SHF_LINK_ORDER;723 return NextUniqueID++;724 }725 726 if (Retain) {727 if (TM.getTargetTriple().isOSSolaris())728 Flags |= ELF::SHF_SUNW_NODISCARD;729 else if (Ctx.getAsmInfo()->useIntegratedAssembler() ||730 Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36))731 Flags |= ELF::SHF_GNU_RETAIN;732 return NextUniqueID++;733 }734 735 // If two symbols with differing sizes end up in the same mergeable section736 // that section can be assigned an incorrect entry size. To avoid this we737 // usually put symbols of the same size into distinct mergeable sections with738 // the same name. Doing so relies on the ",unique ," assembly feature. This739 // feature is not available until binutils version 2.35740 // (https://sourceware.org/bugzilla/show_bug.cgi?id=25380).741 const bool SupportsUnique = Ctx.getAsmInfo()->useIntegratedAssembler() ||742 Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35);743 if (!SupportsUnique) {744 Flags &= ~ELF::SHF_MERGE;745 EntrySize = 0;746 return MCSection::NonUniqueID;747 }748 749 const bool SymbolMergeable = Flags & ELF::SHF_MERGE;750 const bool SeenSectionNameBefore =751 Ctx.isELFGenericMergeableSection(SectionName);752 // If this is the first occurrence of this section name, treat it as the753 // generic section754 if (!SymbolMergeable && !SeenSectionNameBefore) {755 if (TM.getSeparateNamedSections())756 return NextUniqueID++;757 else758 return MCSection::NonUniqueID;759 }760 761 // Symbols must be placed into sections with compatible entry sizes. Generate762 // unique sections for symbols that have not been assigned to compatible763 // sections.764 const auto PreviousID =765 Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize);766 if (PreviousID &&767 (!TM.getSeparateNamedSections() || *PreviousID == MCSection::NonUniqueID))768 return *PreviousID;769 770 // If the user has specified the same section name as would be created771 // implicitly for this symbol e.g. .rodata.str1.1, then we don't need772 // to unique the section as the entry size for this symbol will be773 // compatible with implicitly created sections.774 SmallString<128> ImplicitSectionNameStem = getELFSectionNameForGlobal(775 GO, Kind, Mang, TM, EntrySize, false, /*MJTE=*/nullptr);776 if (SymbolMergeable &&777 Ctx.isELFImplicitMergeableSectionNamePrefix(SectionName) &&778 SectionName.starts_with(ImplicitSectionNameStem))779 return MCSection::NonUniqueID;780 781 // We have seen this section name before, but with different flags or entity782 // size. Create a new unique ID.783 return NextUniqueID++;784}785 786static std::tuple<StringRef, bool, unsigned>787getGlobalObjectInfo(const GlobalObject *GO, const TargetMachine &TM) {788 StringRef Group = "";789 bool IsComdat = false;790 unsigned Flags = 0;791 if (const Comdat *C = getELFComdat(GO)) {792 Flags |= ELF::SHF_GROUP;793 Group = C->getName();794 IsComdat = C->getSelectionKind() == Comdat::Any;795 }796 if (TM.isLargeGlobalValue(GO))797 Flags |= ELF::SHF_X86_64_LARGE;798 return {Group, IsComdat, Flags};799}800 801static StringRef handlePragmaClangSection(const GlobalObject *GO,802 SectionKind Kind) {803 // Check if '#pragma clang section' name is applicable.804 // Note that pragma directive overrides -ffunction-section, -fdata-section805 // and so section name is exactly as user specified and not uniqued.806 const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO);807 if (GV && GV->hasImplicitSection()) {808 auto Attrs = GV->getAttributes();809 if (Attrs.hasAttribute("bss-section") && Kind.isBSS())810 return Attrs.getAttribute("bss-section").getValueAsString();811 else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly())812 return Attrs.getAttribute("rodata-section").getValueAsString();813 else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel())814 return Attrs.getAttribute("relro-section").getValueAsString();815 else if (Attrs.hasAttribute("data-section") && Kind.isData())816 return Attrs.getAttribute("data-section").getValueAsString();817 }818 819 return GO->getSection();820}821 822static MCSection *selectExplicitSectionGlobal(const GlobalObject *GO,823 SectionKind Kind,824 const TargetMachine &TM,825 MCContext &Ctx, Mangler &Mang,826 unsigned &NextUniqueID,827 bool Retain, bool ForceUnique) {828 StringRef SectionName = handlePragmaClangSection(GO, Kind);829 830 // Infer section flags from the section name if we can.831 Kind = getELFKindForNamedSection(SectionName, Kind);832 833 unsigned Flags = getELFSectionFlags(Kind, TM.getTargetTriple());834 auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM);835 Flags |= ExtraFlags;836 837 unsigned EntrySize = getEntrySizeForKind(Kind);838 const unsigned UniqueID = calcUniqueIDUpdateFlagsAndSize(839 GO, SectionName, Kind, TM, Ctx, Mang, Flags, EntrySize, NextUniqueID,840 Retain, ForceUnique);841 842 const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);843 MCSectionELF *Section = Ctx.getELFSection(844 SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize,845 Group, IsComdat, UniqueID, LinkedToSym);846 // Make sure that we did not get some other section with incompatible sh_link.847 // This should not be possible due to UniqueID code above.848 assert(Section->getLinkedToSymbol() == LinkedToSym &&849 "Associated symbol mismatch between sections");850 851 if (!(Ctx.getAsmInfo()->useIntegratedAssembler() ||852 Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35))) {853 // If we are using GNU as before 2.35, then this symbol might have854 // been placed in an incompatible mergeable section. Emit an error if this855 // is the case to avoid creating broken output.856 if ((Section->getFlags() & ELF::SHF_MERGE) &&857 (Section->getEntrySize() != getEntrySizeForKind(Kind)))858 GO->getContext().diagnose(LoweringDiagnosticInfo(859 "Symbol '" + GO->getName() + "' from module '" +860 (GO->getParent() ? GO->getParent()->getSourceFileName() : "unknown") +861 "' required a section with entry-size=" +862 Twine(getEntrySizeForKind(Kind)) + " but was placed in section '" +863 SectionName + "' with entry-size=" + Twine(Section->getEntrySize()) +864 ": Explicit assignment by pragma or attribute of an incompatible "865 "symbol to this section?"));866 }867 868 return Section;869}870 871MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(872 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {873 return selectExplicitSectionGlobal(GO, Kind, TM, getContext(), getMangler(),874 NextUniqueID, Used.count(GO),875 /* ForceUnique = */false);876}877 878static MCSectionELF *selectELFSectionForGlobal(879 MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,880 const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags,881 unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol,882 const MachineJumpTableEntry *MJTE = nullptr) {883 884 auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM);885 Flags |= ExtraFlags;886 887 // Get the section entry size based on the kind.888 unsigned EntrySize = getEntrySizeForKind(Kind);889 890 bool UniqueSectionName = false;891 unsigned UniqueID = MCSection::NonUniqueID;892 if (EmitUniqueSection) {893 if (TM.getUniqueSectionNames()) {894 UniqueSectionName = true;895 } else {896 UniqueID = *NextUniqueID;897 (*NextUniqueID)++;898 }899 }900 SmallString<128> Name = getELFSectionNameForGlobal(901 GO, Kind, Mang, TM, EntrySize, UniqueSectionName, MJTE);902 903 // Use 0 as the unique ID for execute-only text.904 if (Kind.isExecuteOnly())905 UniqueID = 0;906 return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,907 EntrySize, Group, IsComdat, UniqueID,908 AssociatedSymbol);909}910 911static MCSection *selectELFSectionForGlobal(912 MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,913 const TargetMachine &TM, bool Retain, bool EmitUniqueSection,914 unsigned Flags, unsigned *NextUniqueID) {915 const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);916 if (LinkedToSym) {917 EmitUniqueSection = true;918 Flags |= ELF::SHF_LINK_ORDER;919 }920 if (Retain) {921 if (TM.getTargetTriple().isOSSolaris()) {922 EmitUniqueSection = true;923 Flags |= ELF::SHF_SUNW_NODISCARD;924 } else if (Ctx.getAsmInfo()->useIntegratedAssembler() ||925 Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) {926 EmitUniqueSection = true;927 Flags |= ELF::SHF_GNU_RETAIN;928 }929 }930 931 MCSectionELF *Section = selectELFSectionForGlobal(932 Ctx, GO, Kind, Mang, TM, EmitUniqueSection, Flags,933 NextUniqueID, LinkedToSym);934 assert(Section->getLinkedToSymbol() == LinkedToSym);935 return Section;936}937 938MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(939 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {940 unsigned Flags = getELFSectionFlags(Kind, TM.getTargetTriple());941 942 // If we have -ffunction-section or -fdata-section then we should emit the943 // global value to a uniqued section specifically for it.944 bool EmitUniqueSection = false;945 if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) {946 if (Kind.isText())947 EmitUniqueSection = TM.getFunctionSections();948 else949 EmitUniqueSection = TM.getDataSections();950 }951 EmitUniqueSection |= GO->hasComdat();952 return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,953 Used.count(GO), EmitUniqueSection, Flags,954 &NextUniqueID);955}956 957MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction(958 const Function &F, const TargetMachine &TM) const {959 SectionKind Kind = SectionKind::getText();960 unsigned Flags = getELFSectionFlags(Kind, TM.getTargetTriple());961 // If the function's section names is pre-determined via pragma or a962 // section attribute, call selectExplicitSectionGlobal.963 if (F.hasSection())964 return selectExplicitSectionGlobal(965 &F, Kind, TM, getContext(), getMangler(), NextUniqueID,966 Used.count(&F), /* ForceUnique = */true);967 968 return selectELFSectionForGlobal(969 getContext(), &F, Kind, getMangler(), TM, Used.count(&F),970 /*EmitUniqueSection=*/true, Flags, &NextUniqueID);971}972 973MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(974 const Function &F, const TargetMachine &TM) const {975 return getSectionForJumpTable(F, TM, /*JTE=*/nullptr);976}977 978MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(979 const Function &F, const TargetMachine &TM,980 const MachineJumpTableEntry *JTE) const {981 // If the function can be removed, produce a unique section so that982 // the table doesn't prevent the removal.983 const Comdat *C = F.getComdat();984 bool EmitUniqueSection = TM.getFunctionSections() || C;985 if (!EmitUniqueSection && !TM.getEnableStaticDataPartitioning())986 return ReadOnlySection;987 988 return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(),989 getMangler(), TM, EmitUniqueSection,990 ELF::SHF_ALLOC, &NextUniqueID,991 /* AssociatedSymbol */ nullptr, JTE);992}993 994MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(995 const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {996 // If neither COMDAT nor function sections, use the monolithic LSDA section.997 // Re-use this path if LSDASection is null as in the Arm EHABI.998 if (!LSDASection || (!F.hasComdat() && !TM.getFunctionSections()))999 return LSDASection;1000 1001 const auto *LSDA = static_cast<const MCSectionELF *>(LSDASection);1002 unsigned Flags = LSDA->getFlags();1003 const MCSymbolELF *LinkedToSym = nullptr;1004 StringRef Group;1005 bool IsComdat = false;1006 if (const Comdat *C = getELFComdat(&F)) {1007 Flags |= ELF::SHF_GROUP;1008 Group = C->getName();1009 IsComdat = C->getSelectionKind() == Comdat::Any;1010 }1011 // Use SHF_LINK_ORDER to facilitate --gc-sections if we can use GNU ld>=2.361012 // or LLD, which support mixed SHF_LINK_ORDER & non-SHF_LINK_ORDER.1013 if (TM.getFunctionSections() &&1014 (getContext().getAsmInfo()->useIntegratedAssembler() &&1015 getContext().getAsmInfo()->binutilsIsAtLeast(2, 36))) {1016 Flags |= ELF::SHF_LINK_ORDER;1017 LinkedToSym = static_cast<const MCSymbolELF *>(&FnSym);1018 }1019 1020 // Append the function name as the suffix like GCC, assuming1021 // -funique-section-names applies to .gcc_except_table sections.1022 return getContext().getELFSection(1023 (TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName()1024 : LSDA->getName()),1025 LSDA->getType(), Flags, 0, Group, IsComdat, MCSection::NonUniqueID,1026 LinkedToSym);1027}1028 1029bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(1030 bool UsesLabelDifference, const Function &F) const {1031 // We can always create relative relocations, so use another section1032 // that can be marked non-executable.1033 return false;1034}1035 1036/// Given a mergeable constant with the specified size and relocation1037/// information, return a section that it should be placed in.1038MCSection *TargetLoweringObjectFileELF::getSectionForConstant(1039 const DataLayout &DL, SectionKind Kind, const Constant *C,1040 Align &Alignment) const {1041 if (Kind.isMergeableConst4() && MergeableConst4Section)1042 return MergeableConst4Section;1043 if (Kind.isMergeableConst8() && MergeableConst8Section)1044 return MergeableConst8Section;1045 if (Kind.isMergeableConst16() && MergeableConst16Section)1046 return MergeableConst16Section;1047 if (Kind.isMergeableConst32() && MergeableConst32Section)1048 return MergeableConst32Section;1049 if (Kind.isReadOnly())1050 return ReadOnlySection;1051 1052 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");1053 return DataRelROSection;1054}1055 1056MCSection *TargetLoweringObjectFileELF::getSectionForConstant(1057 const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment,1058 StringRef SectionSuffix) const {1059 // TODO: Share code between this function and1060 // MCObjectInfo::initELFMCObjectFileInfo.1061 if (SectionSuffix.empty())1062 return getSectionForConstant(DL, Kind, C, Alignment);1063 1064 auto &Context = getContext();1065 if (Kind.isMergeableConst4() && MergeableConst4Section)1066 return Context.getELFSection(".rodata.cst4." + SectionSuffix + ".",1067 ELF::SHT_PROGBITS,1068 ELF::SHF_ALLOC | ELF::SHF_MERGE, 4);1069 if (Kind.isMergeableConst8() && MergeableConst8Section)1070 return Context.getELFSection(".rodata.cst8." + SectionSuffix + ".",1071 ELF::SHT_PROGBITS,1072 ELF::SHF_ALLOC | ELF::SHF_MERGE, 8);1073 if (Kind.isMergeableConst16() && MergeableConst16Section)1074 return Context.getELFSection(".rodata.cst16." + SectionSuffix + ".",1075 ELF::SHT_PROGBITS,1076 ELF::SHF_ALLOC | ELF::SHF_MERGE, 16);1077 if (Kind.isMergeableConst32() && MergeableConst32Section)1078 return Context.getELFSection(".rodata.cst32." + SectionSuffix + ".",1079 ELF::SHT_PROGBITS,1080 ELF::SHF_ALLOC | ELF::SHF_MERGE, 32);1081 if (Kind.isReadOnly())1082 return Context.getELFSection(".rodata." + SectionSuffix + ".",1083 ELF::SHT_PROGBITS, ELF::SHF_ALLOC);1084 1085 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");1086 return Context.getELFSection(".data.rel.ro." + SectionSuffix + ".",1087 ELF::SHT_PROGBITS,1088 ELF::SHF_ALLOC | ELF::SHF_WRITE);1089}1090 1091/// Returns a unique section for the given machine basic block.1092MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(1093 const Function &F, const MachineBasicBlock &MBB,1094 const TargetMachine &TM) const {1095 assert(MBB.isBeginSection() && "Basic block does not start a section!");1096 unsigned UniqueID = MCSection::NonUniqueID;1097 1098 // For cold sections use the .text.split. prefix along with the parent1099 // function name. All cold blocks for the same function go to the same1100 // section. Similarly all exception blocks are grouped by symbol name1101 // under the .text.eh prefix. For regular sections, we either use a unique1102 // name, or a unique ID for the section.1103 SmallString<128> Name;1104 StringRef FunctionSectionName = MBB.getParent()->getSection()->getName();1105 if (FunctionSectionName == ".text" ||1106 FunctionSectionName.starts_with(".text.")) {1107 // Function is in a regular .text section.1108 StringRef FunctionName = MBB.getParent()->getName();1109 if (MBB.getSectionID() == MBBSectionID::ColdSectionID) {1110 Name += BBSectionsColdTextPrefix;1111 Name += FunctionName;1112 } else if (MBB.getSectionID() == MBBSectionID::ExceptionSectionID) {1113 Name += ".text.eh.";1114 Name += FunctionName;1115 } else {1116 Name += FunctionSectionName;1117 if (TM.getUniqueBasicBlockSectionNames()) {1118 if (!Name.ends_with("."))1119 Name += ".";1120 Name += MBB.getSymbol()->getName();1121 } else {1122 UniqueID = NextUniqueID++;1123 }1124 }1125 } else {1126 // If the original function has a custom non-dot-text section, then emit1127 // all basic block sections into that section too, each with a unique id.1128 Name = FunctionSectionName;1129 UniqueID = NextUniqueID++;1130 }1131 1132 unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;1133 std::string GroupName;1134 if (F.hasComdat()) {1135 Flags |= ELF::SHF_GROUP;1136 GroupName = F.getComdat()->getName().str();1137 }1138 return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags,1139 0 /* Entry Size */, GroupName,1140 F.hasComdat(), UniqueID, nullptr);1141}1142 1143static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,1144 bool IsCtor, unsigned Priority,1145 const MCSymbol *KeySym) {1146 std::string Name;1147 unsigned Type;1148 unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE;1149 StringRef Comdat = KeySym ? KeySym->getName() : "";1150 1151 if (KeySym)1152 Flags |= ELF::SHF_GROUP;1153 1154 if (UseInitArray) {1155 if (IsCtor) {1156 Type = ELF::SHT_INIT_ARRAY;1157 Name = ".init_array";1158 } else {1159 Type = ELF::SHT_FINI_ARRAY;1160 Name = ".fini_array";1161 }1162 if (Priority != 65535) {1163 Name += '.';1164 Name += utostr(Priority);1165 }1166 } else {1167 // The default scheme is .ctor / .dtor, so we have to invert the priority1168 // numbering.1169 if (IsCtor)1170 Name = ".ctors";1171 else1172 Name = ".dtors";1173 if (Priority != 65535)1174 raw_string_ostream(Name) << format(".%05u", 65535 - Priority);1175 Type = ELF::SHT_PROGBITS;1176 }1177 1178 return Ctx.getELFSection(Name, Type, Flags, 0, Comdat, /*IsComdat=*/true);1179}1180 1181MCSection *TargetLoweringObjectFileELF::getStaticCtorSection(1182 unsigned Priority, const MCSymbol *KeySym) const {1183 return getStaticStructorSection(getContext(), UseInitArray, true, Priority,1184 KeySym);1185}1186 1187MCSection *TargetLoweringObjectFileELF::getStaticDtorSection(1188 unsigned Priority, const MCSymbol *KeySym) const {1189 return getStaticStructorSection(getContext(), UseInitArray, false, Priority,1190 KeySym);1191}1192 1193const MCExpr *TargetLoweringObjectFileELF::lowerSymbolDifference(1194 const MCSymbol *LHS, const MCSymbol *RHS, int64_t Addend,1195 std::optional<int64_t> PCRelativeOffset) const {1196 auto &Ctx = getContext();1197 const MCExpr *Res;1198 // Return a relocatable expression with the PLT specifier, %plt(GV) or1199 // %plt(GV-RHS).1200 if (PCRelativeOffset && PLTPCRelativeSpecifier) {1201 Res = MCSymbolRefExpr::create(LHS, Ctx);1202 // The current location is RHS plus *PCRelativeOffset. Compensate for it.1203 Addend += *PCRelativeOffset;1204 if (Addend)1205 Res = MCBinaryExpr::createAdd(Res, MCConstantExpr::create(Addend, Ctx),1206 Ctx);1207 return MCSpecifierExpr::create(Res, PLTPCRelativeSpecifier, getContext());1208 }1209 1210 if (!PLTRelativeSpecifier)1211 return nullptr;1212 Res = MCBinaryExpr::createSub(1213 MCSymbolRefExpr::create(LHS, PLTRelativeSpecifier, Ctx),1214 MCSymbolRefExpr::create(RHS, Ctx), Ctx);1215 if (Addend)1216 Res =1217 MCBinaryExpr::createAdd(Res, MCConstantExpr::create(Addend, Ctx), Ctx);1218 return Res;1219}1220 1221// Reference the PLT entry of a function, optionally with a subtrahend (`RHS`).1222const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent(1223 const MCSymbol *LHS, const MCSymbol *RHS, int64_t Addend,1224 std::optional<int64_t> PCRelativeOffset, const TargetMachine &TM) const {1225 if (RHS)1226 return lowerSymbolDifference(LHS, RHS, Addend, PCRelativeOffset);1227 1228 // Only the legacy MCSymbolRefExpr::VariantKind approach is implemented.1229 // Reference LHS@plt or LHS@plt - RHS.1230 if (PLTRelativeSpecifier)1231 return MCSymbolRefExpr::create(LHS, PLTRelativeSpecifier, getContext());1232 return nullptr;1233}1234 1235MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {1236 // Use ".GCC.command.line" since this feature is to support clang's1237 // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the1238 // same name.1239 return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS,1240 ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);1241}1242 1243void1244TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) {1245 UseInitArray = UseInitArray_;1246 MCContext &Ctx = getContext();1247 if (!UseInitArray) {1248 StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS,1249 ELF::SHF_ALLOC | ELF::SHF_WRITE);1250 1251 StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS,1252 ELF::SHF_ALLOC | ELF::SHF_WRITE);1253 return;1254 }1255 1256 StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY,1257 ELF::SHF_WRITE | ELF::SHF_ALLOC);1258 StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY,1259 ELF::SHF_WRITE | ELF::SHF_ALLOC);1260}1261 1262//===----------------------------------------------------------------------===//1263// MachO1264//===----------------------------------------------------------------------===//1265 1266TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() {1267 SupportIndirectSymViaGOTPCRel = true;1268}1269 1270void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,1271 const TargetMachine &TM) {1272 TargetLoweringObjectFile::Initialize(Ctx, TM);1273 if (TM.getRelocationModel() == Reloc::Static) {1274 StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0,1275 SectionKind::getData());1276 StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0,1277 SectionKind::getData());1278 } else {1279 StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func",1280 MachO::S_MOD_INIT_FUNC_POINTERS,1281 SectionKind::getData());1282 StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func",1283 MachO::S_MOD_TERM_FUNC_POINTERS,1284 SectionKind::getData());1285 }1286 1287 PersonalityEncoding =1288 dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;1289 LSDAEncoding = dwarf::DW_EH_PE_pcrel;1290 TTypeEncoding =1291 dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;1292}1293 1294MCSection *TargetLoweringObjectFileMachO::getStaticDtorSection(1295 unsigned Priority, const MCSymbol *KeySym) const {1296 return StaticDtorSection;1297 // In userspace, we lower global destructors via atexit(), but kernel/kext1298 // environments do not provide this function so we still need to support the1299 // legacy way here.1300 // See the -disable-atexit-based-global-dtor-lowering CodeGen flag for more1301 // context.1302}1303 1304void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer,1305 Module &M) const {1306 // Emit the linker options if present.1307 emitLinkerDirectives(Streamer, M);1308 1309 unsigned VersionVal = 0;1310 unsigned ImageInfoFlags = 0;1311 StringRef SectionVal;1312 1313 GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal);1314 emitCGProfileMetadata(Streamer, M);1315 1316 // The section is mandatory. If we don't have it, then we don't have GC info.1317 if (SectionVal.empty())1318 return;1319 1320 StringRef Segment, Section;1321 unsigned TAA = 0, StubSize = 0;1322 bool TAAParsed;1323 if (Error E = MCSectionMachO::ParseSectionSpecifier(1324 SectionVal, Segment, Section, TAA, TAAParsed, StubSize)) {1325 // If invalid, report the error with report_fatal_error.1326 report_fatal_error("Invalid section specifier '" + Section +1327 "': " + toString(std::move(E)) + ".");1328 }1329 1330 // Get the section.1331 MCSectionMachO *S = getContext().getMachOSection(1332 Segment, Section, TAA, StubSize, SectionKind::getData());1333 Streamer.switchSection(S);1334 Streamer.emitLabel(getContext().1335 getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO")));1336 Streamer.emitInt32(VersionVal);1337 Streamer.emitInt32(ImageInfoFlags);1338 Streamer.addBlankLine();1339}1340 1341void TargetLoweringObjectFileMachO::emitLinkerDirectives(MCStreamer &Streamer,1342 Module &M) const {1343 if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {1344 for (const auto *Option : LinkerOptions->operands()) {1345 SmallVector<std::string, 4> StrOptions;1346 for (const auto &Piece : cast<MDNode>(Option)->operands())1347 StrOptions.push_back(std::string(cast<MDString>(Piece)->getString()));1348 Streamer.emitLinkerOptions(StrOptions);1349 }1350 }1351}1352 1353static void checkMachOComdat(const GlobalValue *GV) {1354 const Comdat *C = GV->getComdat();1355 if (!C)1356 return;1357 1358 report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() +1359 "' cannot be lowered.");1360}1361 1362MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(1363 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {1364 1365 StringRef SectionName = handlePragmaClangSection(GO, Kind);1366 1367 // Parse the section specifier and create it if valid.1368 StringRef Segment, Section;1369 unsigned TAA = 0, StubSize = 0;1370 bool TAAParsed;1371 1372 checkMachOComdat(GO);1373 1374 if (Error E = MCSectionMachO::ParseSectionSpecifier(1375 SectionName, Segment, Section, TAA, TAAParsed, StubSize)) {1376 // If invalid, report the error with report_fatal_error.1377 report_fatal_error("Global variable '" + GO->getName() +1378 "' has an invalid section specifier '" +1379 GO->getSection() + "': " + toString(std::move(E)) + ".");1380 }1381 1382 // Get the section.1383 MCSectionMachO *S =1384 getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind);1385 1386 // If TAA wasn't set by ParseSectionSpecifier() above,1387 // use the value returned by getMachOSection() as a default.1388 if (!TAAParsed)1389 TAA = S->getTypeAndAttributes();1390 1391 // Okay, now that we got the section, verify that the TAA & StubSize agree.1392 // If the user declared multiple globals with different section flags, we need1393 // to reject it here.1394 if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {1395 // If invalid, report the error with report_fatal_error.1396 report_fatal_error("Global variable '" + GO->getName() +1397 "' section type or attributes does not match previous"1398 " section specifier");1399 }1400 1401 return S;1402}1403 1404MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal(1405 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {1406 checkMachOComdat(GO);1407 1408 // Handle thread local data.1409 if (Kind.isThreadBSS()) return TLSBSSSection;1410 if (Kind.isThreadData()) return TLSDataSection;1411 1412 if (Kind.isText())1413 return GO->isWeakForLinker() ? TextCoalSection : TextSection;1414 1415 // If this is weak/linkonce, put this in a coalescable section, either in text1416 // or data depending on if it is writable.1417 if (GO->isWeakForLinker()) {1418 if (Kind.isReadOnly())1419 return ConstTextCoalSection;1420 if (Kind.isReadOnlyWithRel())1421 return ConstDataCoalSection;1422 return DataCoalSection;1423 }1424 1425 // FIXME: Alignment check should be handled by section classifier.1426 if (Kind.isMergeable1ByteCString() &&1427 GO->getDataLayout().getPreferredAlign(1428 cast<GlobalVariable>(GO)) < Align(32))1429 return CStringSection;1430 1431 // Do not put 16-bit arrays in the UString section if they have an1432 // externally visible label, this runs into issues with certain linker1433 // versions.1434 if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() &&1435 GO->getDataLayout().getPreferredAlign(1436 cast<GlobalVariable>(GO)) < Align(32))1437 return UStringSection;1438 1439 // With MachO only variables whose corresponding symbol starts with 'l' or1440 // 'L' can be merged, so we only try merging GVs with private linkage.1441 if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) {1442 if (Kind.isMergeableConst4())1443 return FourByteConstantSection;1444 if (Kind.isMergeableConst8())1445 return EightByteConstantSection;1446 if (Kind.isMergeableConst16())1447 return SixteenByteConstantSection;1448 }1449 1450 // Otherwise, if it is readonly, but not something we can specially optimize,1451 // just drop it in .const.1452 if (Kind.isReadOnly())1453 return ReadOnlySection;1454 1455 // If this is marked const, put it into a const section. But if the dynamic1456 // linker needs to write to it, put it in the data segment.1457 if (Kind.isReadOnlyWithRel())1458 return ConstDataSection;1459 1460 // Put zero initialized globals with strong external linkage in the1461 // DATA, __common section with the .zerofill directive.1462 if (Kind.isBSSExtern())1463 return DataCommonSection;1464 1465 // Put zero initialized globals with local linkage in __DATA,__bss directive1466 // with the .zerofill directive (aka .lcomm).1467 if (Kind.isBSSLocal())1468 return DataBSSSection;1469 1470 // Otherwise, just drop the variable in the normal data section.1471 return DataSection;1472}1473 1474MCSection *TargetLoweringObjectFileMachO::getSectionForConstant(1475 const DataLayout &DL, SectionKind Kind, const Constant *C,1476 Align &Alignment) const {1477 // If this constant requires a relocation, we have to put it in the data1478 // segment, not in the text segment.1479 if (Kind.isData() || Kind.isReadOnlyWithRel())1480 return ConstDataSection;1481 1482 if (Kind.isMergeableConst4())1483 return FourByteConstantSection;1484 if (Kind.isMergeableConst8())1485 return EightByteConstantSection;1486 if (Kind.isMergeableConst16())1487 return SixteenByteConstantSection;1488 return ReadOnlySection; // .const1489}1490 1491MCSection *TargetLoweringObjectFileMachO::getSectionForCommandLines() const {1492 return getContext().getMachOSection("__TEXT", "__command_line", 0,1493 SectionKind::getReadOnly());1494}1495 1496const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference(1497 const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,1498 MachineModuleInfo *MMI, MCStreamer &Streamer) const {1499 // The mach-o version of this method defaults to returning a stub reference.1500 1501 if (Encoding & DW_EH_PE_indirect) {1502 MachineModuleInfoMachO &MachOMMI =1503 MMI->getObjFileInfo<MachineModuleInfoMachO>();1504 1505 MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM);1506 1507 // Add information about the stub reference to MachOMMI so that the stub1508 // gets emitted by the asmprinter.1509 MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);1510 if (!StubSym.getPointer()) {1511 MCSymbol *Sym = TM.getSymbol(GV);1512 StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());1513 }1514 1515 return TargetLoweringObjectFile::1516 getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()),1517 Encoding & ~DW_EH_PE_indirect, Streamer);1518 }1519 1520 return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM,1521 MMI, Streamer);1522}1523 1524MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol(1525 const GlobalValue *GV, const TargetMachine &TM,1526 MachineModuleInfo *MMI) const {1527 // The mach-o version of this method defaults to returning a stub reference.1528 MachineModuleInfoMachO &MachOMMI =1529 MMI->getObjFileInfo<MachineModuleInfoMachO>();1530 1531 MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM);1532 1533 // Add information about the stub reference to MachOMMI so that the stub1534 // gets emitted by the asmprinter.1535 MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);1536 if (!StubSym.getPointer()) {1537 MCSymbol *Sym = TM.getSymbol(GV);1538 StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());1539 }1540 1541 return SSym;1542}1543 1544const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel(1545 const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,1546 int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {1547 // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation1548 // as 64-bit do, we replace the GOT equivalent by accessing the final symbol1549 // through a non_lazy_ptr stub instead. One advantage is that it allows the1550 // computation of deltas to final external symbols. Example:1551 //1552 // _extgotequiv:1553 // .long _extfoo1554 //1555 // _delta:1556 // .long _extgotequiv-_delta1557 //1558 // is transformed to:1559 //1560 // _delta:1561 // .long L_extfoo$non_lazy_ptr-(_delta+0)1562 //1563 // .section __IMPORT,__pointers,non_lazy_symbol_pointers1564 // L_extfoo$non_lazy_ptr:1565 // .indirect_symbol _extfoo1566 // .long 01567 //1568 // The indirect symbol table (and sections of non_lazy_symbol_pointers type)1569 // may point to both local (same translation unit) and global (other1570 // translation units) symbols. Example:1571 //1572 // .section __DATA,__pointers,non_lazy_symbol_pointers1573 // L1:1574 // .indirect_symbol _myGlobal1575 // .long 01576 // L2:1577 // .indirect_symbol _myLocal1578 // .long _myLocal1579 //1580 // If the symbol is local, instead of the symbol's index, the assembler1581 // places the constant INDIRECT_SYMBOL_LOCAL into the indirect symbol table.1582 // Then the linker will notice the constant in the table and will look at the1583 // content of the symbol.1584 MachineModuleInfoMachO &MachOMMI =1585 MMI->getObjFileInfo<MachineModuleInfoMachO>();1586 MCContext &Ctx = getContext();1587 1588 // The offset must consider the original displacement from the base symbol1589 // since 32-bit targets don't have a GOTPCREL to fold the PC displacement.1590 Offset = -MV.getConstant();1591 const MCSymbol *BaseSym = MV.getSubSym();1592 1593 // Access the final symbol via sym$non_lazy_ptr and generate the appropriated1594 // non_lazy_ptr stubs.1595 SmallString<128> Name;1596 StringRef Suffix = "$non_lazy_ptr";1597 Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix();1598 Name += Sym->getName();1599 Name += Suffix;1600 MCSymbol *Stub = Ctx.getOrCreateSymbol(Name);1601 1602 MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub);1603 1604 if (!StubSym.getPointer())1605 StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym),1606 !GV->hasLocalLinkage());1607 1608 const MCExpr *BSymExpr = MCSymbolRefExpr::create(BaseSym, Ctx);1609 const MCExpr *LHS = MCSymbolRefExpr::create(Stub, Ctx);1610 1611 if (!Offset)1612 return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx);1613 1614 const MCExpr *RHS =1615 MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx);1616 return MCBinaryExpr::createSub(LHS, RHS, Ctx);1617}1618 1619static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo,1620 const MCSection &Section) {1621 if (!MCAsmInfoDarwin::isSectionAtomizableBySymbols(Section))1622 return true;1623 1624 // FIXME: we should be able to use private labels for sections that can't be1625 // dead-stripped (there's no issue with blocking atomization there), but `ld1626 // -r` sometimes drops the no_dead_strip attribute from sections so for safety1627 // we don't allow it.1628 return false;1629}1630 1631void TargetLoweringObjectFileMachO::getNameWithPrefix(1632 SmallVectorImpl<char> &OutName, const GlobalValue *GV,1633 const TargetMachine &TM) const {1634 bool CannotUsePrivateLabel = true;1635 if (auto *GO = GV->getAliaseeObject()) {1636 SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM);1637 const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM);1638 CannotUsePrivateLabel =1639 !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection);1640 }1641 getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);1642}1643 1644//===----------------------------------------------------------------------===//1645// COFF1646//===----------------------------------------------------------------------===//1647 1648static unsigned1649getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) {1650 unsigned Flags = 0;1651 bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb;1652 1653 if (K.isMetadata())1654 Flags |=1655 COFF::IMAGE_SCN_MEM_DISCARDABLE;1656 else if (K.isExclude())1657 Flags |=1658 COFF::IMAGE_SCN_LNK_REMOVE | COFF::IMAGE_SCN_MEM_DISCARDABLE;1659 else if (K.isText())1660 Flags |=1661 COFF::IMAGE_SCN_MEM_EXECUTE |1662 COFF::IMAGE_SCN_MEM_READ |1663 COFF::IMAGE_SCN_CNT_CODE |1664 (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0);1665 else if (K.isBSS())1666 Flags |=1667 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |1668 COFF::IMAGE_SCN_MEM_READ |1669 COFF::IMAGE_SCN_MEM_WRITE;1670 else if (K.isThreadLocal())1671 Flags |=1672 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |1673 COFF::IMAGE_SCN_MEM_READ |1674 COFF::IMAGE_SCN_MEM_WRITE;1675 else if (K.isReadOnly() || K.isReadOnlyWithRel())1676 Flags |=1677 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |1678 COFF::IMAGE_SCN_MEM_READ;1679 else if (K.isWriteable())1680 Flags |=1681 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |1682 COFF::IMAGE_SCN_MEM_READ |1683 COFF::IMAGE_SCN_MEM_WRITE;1684 1685 return Flags;1686}1687 1688static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) {1689 const Comdat *C = GV->getComdat();1690 assert(C && "expected GV to have a Comdat!");1691 1692 StringRef ComdatGVName = C->getName();1693 const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName);1694 if (!ComdatGV)1695 report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +1696 "' does not exist.");1697 1698 if (ComdatGV->getComdat() != C)1699 report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +1700 "' is not a key for its COMDAT.");1701 1702 return ComdatGV;1703}1704 1705static int getSelectionForCOFF(const GlobalValue *GV) {1706 if (const Comdat *C = GV->getComdat()) {1707 const GlobalValue *ComdatKey = getComdatGVForCOFF(GV);1708 if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey))1709 ComdatKey = GA->getAliaseeObject();1710 if (ComdatKey == GV) {1711 switch (C->getSelectionKind()) {1712 case Comdat::Any:1713 return COFF::IMAGE_COMDAT_SELECT_ANY;1714 case Comdat::ExactMatch:1715 return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH;1716 case Comdat::Largest:1717 return COFF::IMAGE_COMDAT_SELECT_LARGEST;1718 case Comdat::NoDeduplicate:1719 return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;1720 case Comdat::SameSize:1721 return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE;1722 }1723 } else {1724 return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;1725 }1726 }1727 return 0;1728}1729 1730MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(1731 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {1732 StringRef Name = handlePragmaClangSection(GO, Kind);1733 if (Name == getInstrProfSectionName(IPSK_covmap, Triple::COFF,1734 /*AddSegmentInfo=*/false) ||1735 Name == getInstrProfSectionName(IPSK_covfun, Triple::COFF,1736 /*AddSegmentInfo=*/false) ||1737 Name == getInstrProfSectionName(IPSK_covdata, Triple::COFF,1738 /*AddSegmentInfo=*/false) ||1739 Name == getInstrProfSectionName(IPSK_covname, Triple::COFF,1740 /*AddSegmentInfo=*/false) ||1741 Name == ".llvmbc" || Name == ".llvmcmd")1742 Kind = SectionKind::getMetadata();1743 int Selection = 0;1744 unsigned Characteristics = getCOFFSectionFlags(Kind, TM);1745 StringRef COMDATSymName = "";1746 if (GO->hasComdat()) {1747 Selection = getSelectionForCOFF(GO);1748 const GlobalValue *ComdatGV;1749 if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)1750 ComdatGV = getComdatGVForCOFF(GO);1751 else1752 ComdatGV = GO;1753 1754 if (!ComdatGV->hasPrivateLinkage()) {1755 MCSymbol *Sym = TM.getSymbol(ComdatGV);1756 COMDATSymName = Sym->getName();1757 Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;1758 } else {1759 Selection = 0;1760 }1761 }1762 1763 return getContext().getCOFFSection(Name, Characteristics, COMDATSymName,1764 Selection);1765}1766 1767static StringRef getCOFFSectionNameForUniqueGlobal(SectionKind Kind) {1768 if (Kind.isText())1769 return ".text";1770 if (Kind.isBSS())1771 return ".bss";1772 if (Kind.isThreadLocal())1773 return ".tls$";1774 if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())1775 return ".rdata";1776 return ".data";1777}1778 1779MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(1780 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {1781 // If we have -ffunction-sections then we should emit the global value to a1782 // uniqued section specifically for it.1783 bool EmitUniquedSection;1784 if (Kind.isText())1785 EmitUniquedSection = TM.getFunctionSections();1786 else1787 EmitUniquedSection = TM.getDataSections();1788 1789 if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) {1790 SmallString<256> Name = getCOFFSectionNameForUniqueGlobal(Kind);1791 1792 unsigned Characteristics = getCOFFSectionFlags(Kind, TM);1793 1794 Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;1795 int Selection = getSelectionForCOFF(GO);1796 if (!Selection)1797 Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;1798 const GlobalValue *ComdatGV;1799 if (GO->hasComdat())1800 ComdatGV = getComdatGVForCOFF(GO);1801 else1802 ComdatGV = GO;1803 1804 unsigned UniqueID = MCSection::NonUniqueID;1805 if (EmitUniquedSection)1806 UniqueID = NextUniqueID++;1807 1808 if (!ComdatGV->hasPrivateLinkage()) {1809 MCSymbol *Sym = TM.getSymbol(ComdatGV);1810 StringRef COMDATSymName = Sym->getName();1811 1812 if (const auto *F = dyn_cast<Function>(GO))1813 if (std::optional<StringRef> Prefix = F->getSectionPrefix())1814 raw_svector_ostream(Name) << '$' << *Prefix;1815 1816 // Append "$symbol" to the section name *before* IR-level mangling is1817 // applied when targetting mingw. This is what GCC does, and the ld.bfd1818 // COFF linker will not properly handle comdats otherwise.1819 if (getContext().getTargetTriple().isOSCygMing())1820 raw_svector_ostream(Name) << '$' << ComdatGV->getName();1821 1822 return getContext().getCOFFSection(Name, Characteristics, COMDATSymName,1823 Selection, UniqueID);1824 } else {1825 SmallString<256> TmpData;1826 getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true);1827 return getContext().getCOFFSection(Name, Characteristics, TmpData,1828 Selection, UniqueID);1829 }1830 }1831 1832 if (Kind.isText())1833 return TextSection;1834 1835 if (Kind.isThreadLocal())1836 return TLSDataSection;1837 1838 if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())1839 return ReadOnlySection;1840 1841 // Note: we claim that common symbols are put in BSSSection, but they are1842 // really emitted with the magic .comm directive, which creates a symbol table1843 // entry but not a section.1844 if (Kind.isBSS() || Kind.isCommon())1845 return BSSSection;1846 1847 return DataSection;1848}1849 1850void TargetLoweringObjectFileCOFF::getNameWithPrefix(1851 SmallVectorImpl<char> &OutName, const GlobalValue *GV,1852 const TargetMachine &TM) const {1853 bool CannotUsePrivateLabel = false;1854 if (GV->hasPrivateLinkage() &&1855 ((isa<Function>(GV) && TM.getFunctionSections()) ||1856 (isa<GlobalVariable>(GV) && TM.getDataSections())))1857 CannotUsePrivateLabel = true;1858 1859 getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);1860}1861 1862MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(1863 const Function &F, const TargetMachine &TM) const {1864 // If the function can be removed, produce a unique section so that1865 // the table doesn't prevent the removal.1866 const Comdat *C = F.getComdat();1867 bool EmitUniqueSection = TM.getFunctionSections() || C;1868 if (!EmitUniqueSection)1869 return ReadOnlySection;1870 1871 // FIXME: we should produce a symbol for F instead.1872 if (F.hasPrivateLinkage())1873 return ReadOnlySection;1874 1875 MCSymbol *Sym = TM.getSymbol(&F);1876 StringRef COMDATSymName = Sym->getName();1877 1878 SectionKind Kind = SectionKind::getReadOnly();1879 StringRef SecName = getCOFFSectionNameForUniqueGlobal(Kind);1880 unsigned Characteristics = getCOFFSectionFlags(Kind, TM);1881 Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;1882 unsigned UniqueID = NextUniqueID++;1883 1884 return getContext().getCOFFSection(SecName, Characteristics, COMDATSymName,1885 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE,1886 UniqueID);1887}1888 1889bool TargetLoweringObjectFileCOFF::shouldPutJumpTableInFunctionSection(1890 bool UsesLabelDifference, const Function &F) const {1891 if (TM->getTargetTriple().getArch() == Triple::x86_64) {1892 if (!JumpTableInFunctionSection) {1893 // We can always create relative relocations, so use another section1894 // that can be marked non-executable.1895 return false;1896 }1897 }1898 return TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection(1899 UsesLabelDifference, F);1900}1901 1902void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,1903 Module &M) const {1904 emitLinkerDirectives(Streamer, M);1905 1906 unsigned Version = 0;1907 unsigned Flags = 0;1908 StringRef Section;1909 1910 GetObjCImageInfo(M, Version, Flags, Section);1911 if (!Section.empty()) {1912 auto &C = getContext();1913 auto *S = C.getCOFFSection(Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |1914 COFF::IMAGE_SCN_MEM_READ);1915 Streamer.switchSection(S);1916 Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));1917 Streamer.emitInt32(Version);1918 Streamer.emitInt32(Flags);1919 Streamer.addBlankLine();1920 }1921 1922 emitCGProfileMetadata(Streamer, M);1923 emitPseudoProbeDescMetadata(Streamer, M, [](MCStreamer &Streamer) {1924 if (MCSymbol *Sym =1925 static_cast<MCSectionCOFF *>(Streamer.getCurrentSectionOnly())1926 ->getCOMDATSymbol())1927 if (Sym->isUndefined())1928 Streamer.emitLabel(Sym);1929 });1930}1931 1932void TargetLoweringObjectFileCOFF::emitLinkerDirectives(1933 MCStreamer &Streamer, Module &M) const {1934 if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {1935 // Emit the linker options to the linker .drectve section. According to the1936 // spec, this section is a space-separated string containing flags for1937 // linker.1938 MCSection *Sec = getDrectveSection();1939 Streamer.switchSection(Sec);1940 for (const auto *Option : LinkerOptions->operands()) {1941 for (const auto &Piece : cast<MDNode>(Option)->operands()) {1942 // Lead with a space for consistency with our dllexport implementation.1943 std::string Directive(" ");1944 Directive.append(std::string(cast<MDString>(Piece)->getString()));1945 Streamer.emitBytes(Directive);1946 }1947 }1948 }1949 1950 // Emit /EXPORT: flags for each exported global as necessary.1951 std::string Flags;1952 for (const GlobalValue &GV : M.global_values()) {1953 raw_string_ostream OS(Flags);1954 emitLinkerFlagsForGlobalCOFF(OS, &GV, getContext().getTargetTriple(),1955 getMangler());1956 OS.flush();1957 if (!Flags.empty()) {1958 Streamer.switchSection(getDrectveSection());1959 Streamer.emitBytes(Flags);1960 }1961 Flags.clear();1962 }1963 1964 // Emit /INCLUDE: flags for each used global as necessary.1965 if (const auto *LU = M.getNamedGlobal("llvm.used")) {1966 assert(LU->hasInitializer() && "expected llvm.used to have an initializer");1967 assert(isa<ArrayType>(LU->getValueType()) &&1968 "expected llvm.used to be an array type");1969 if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {1970 for (const Value *Op : A->operands()) {1971 const auto *GV = cast<GlobalValue>(Op->stripPointerCasts());1972 // Global symbols with internal or private linkage are not visible to1973 // the linker, and thus would cause an error when the linker tried to1974 // preserve the symbol due to the `/include:` directive.1975 if (GV->hasLocalLinkage())1976 continue;1977 1978 raw_string_ostream OS(Flags);1979 emitLinkerFlagsForUsedCOFF(OS, GV, getContext().getTargetTriple(),1980 getMangler());1981 OS.flush();1982 1983 if (!Flags.empty()) {1984 Streamer.switchSection(getDrectveSection());1985 Streamer.emitBytes(Flags);1986 }1987 Flags.clear();1988 }1989 }1990 }1991}1992 1993void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,1994 const TargetMachine &TM) {1995 TargetLoweringObjectFile::Initialize(Ctx, TM);1996 this->TM = &TM;1997 const Triple &T = TM.getTargetTriple();1998 if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {1999 StaticCtorSection =2000 Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |2001 COFF::IMAGE_SCN_MEM_READ);2002 StaticDtorSection =2003 Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |2004 COFF::IMAGE_SCN_MEM_READ);2005 } else {2006 StaticCtorSection = Ctx.getCOFFSection(2007 ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |2008 COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE);2009 StaticDtorSection = Ctx.getCOFFSection(2010 ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |2011 COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE);2012 }2013}2014 2015static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx,2016 const Triple &T, bool IsCtor,2017 unsigned Priority,2018 const MCSymbol *KeySym,2019 MCSectionCOFF *Default) {2020 if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {2021 // If the priority is the default, use .CRT$XCU, possibly associative.2022 if (Priority == 65535)2023 return Ctx.getAssociativeCOFFSection(Default, KeySym, 0);2024 2025 // Otherwise, we need to compute a new section name. Low priorities should2026 // run earlier. The linker will sort sections ASCII-betically, and we need a2027 // string that sorts between .CRT$XCA and .CRT$XCU. In the general case, we2028 // make a name like ".CRT$XCT12345", since that runs before .CRT$XCU. Really2029 // low priorities need to sort before 'L', since the CRT uses that2030 // internally, so we use ".CRT$XCA00001" for them. We have a contract with2031 // the frontend that "init_seg(compiler)" corresponds to priority 200 and2032 // "init_seg(lib)" corresponds to priority 400, and those respectively use2033 // 'C' and 'L' without the priority suffix. Priorities between 200 and 4002034 // use 'C' with the priority as a suffix.2035 SmallString<24> Name;2036 char LastLetter = 'T';2037 bool AddPrioritySuffix = Priority != 200 && Priority != 400;2038 if (Priority < 200)2039 LastLetter = 'A';2040 else if (Priority < 400)2041 LastLetter = 'C';2042 else if (Priority == 400)2043 LastLetter = 'L';2044 raw_svector_ostream OS(Name);2045 OS << ".CRT$X" << (IsCtor ? "C" : "T") << LastLetter;2046 if (AddPrioritySuffix)2047 OS << format("%05u", Priority);2048 MCSectionCOFF *Sec = Ctx.getCOFFSection(2049 Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ);2050 return Ctx.getAssociativeCOFFSection(Sec, KeySym, 0);2051 }2052 2053 std::string Name = IsCtor ? ".ctors" : ".dtors";2054 if (Priority != 65535)2055 raw_string_ostream(Name) << format(".%05u", 65535 - Priority);2056 2057 return Ctx.getAssociativeCOFFSection(2058 Ctx.getCOFFSection(Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |2059 COFF::IMAGE_SCN_MEM_READ |2060 COFF::IMAGE_SCN_MEM_WRITE),2061 KeySym, 0);2062}2063 2064MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(2065 unsigned Priority, const MCSymbol *KeySym) const {2066 return getCOFFStaticStructorSection(2067 getContext(), getContext().getTargetTriple(), true, Priority, KeySym,2068 static_cast<MCSectionCOFF *>(StaticCtorSection));2069}2070 2071MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(2072 unsigned Priority, const MCSymbol *KeySym) const {2073 return getCOFFStaticStructorSection(2074 getContext(), getContext().getTargetTriple(), false, Priority, KeySym,2075 static_cast<MCSectionCOFF *>(StaticDtorSection));2076}2077 2078const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(2079 const GlobalValue *LHS, const GlobalValue *RHS, int64_t Addend,2080 std::optional<int64_t> PCRelativeOffset, const TargetMachine &TM) const {2081 const Triple &T = TM.getTargetTriple();2082 if (T.isOSCygMing())2083 return nullptr;2084 2085 // Our symbols should exist in address space zero, cowardly no-op if2086 // otherwise.2087 if (LHS->getType()->getPointerAddressSpace() != 0 ||2088 RHS->getType()->getPointerAddressSpace() != 0)2089 return nullptr;2090 2091 // Both ptrtoint instructions must wrap global objects:2092 // - Only global variables are eligible for image relative relocations.2093 // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable.2094 // We expect __ImageBase to be a global variable without a section, externally2095 // defined.2096 //2097 // It should look something like this: @__ImageBase = external constant i82098 if (!isa<GlobalObject>(LHS) || !isa<GlobalVariable>(RHS) ||2099 LHS->isThreadLocal() || RHS->isThreadLocal() ||2100 RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() ||2101 cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection())2102 return nullptr;2103 2104 const MCExpr *Res = MCSymbolRefExpr::create(2105 TM.getSymbol(LHS), MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());2106 if (Addend != 0)2107 Res = MCBinaryExpr::createAdd(2108 Res, MCConstantExpr::create(Addend, getContext()), getContext());2109 return Res;2110}2111 2112static std::string APIntToHexString(const APInt &AI) {2113 unsigned Width = (AI.getBitWidth() / 8) * 2;2114 std::string HexString = toString(AI, 16, /*Signed=*/false);2115 llvm::transform(HexString, HexString.begin(), tolower);2116 unsigned Size = HexString.size();2117 assert(Width >= Size && "hex string is too large!");2118 HexString.insert(HexString.begin(), Width - Size, '0');2119 2120 return HexString;2121}2122 2123static std::string scalarConstantToHexString(const Constant *C) {2124 Type *Ty = C->getType();2125 if (isa<UndefValue>(C)) {2126 return APIntToHexString(APInt::getZero(Ty->getPrimitiveSizeInBits()));2127 } else if (const auto *CFP = dyn_cast<ConstantFP>(C)) {2128 return APIntToHexString(CFP->getValueAPF().bitcastToAPInt());2129 } else if (const auto *CI = dyn_cast<ConstantInt>(C)) {2130 return APIntToHexString(CI->getValue());2131 } else {2132 unsigned NumElements;2133 if (auto *VTy = dyn_cast<VectorType>(Ty))2134 NumElements = cast<FixedVectorType>(VTy)->getNumElements();2135 else2136 NumElements = Ty->getArrayNumElements();2137 std::string HexString;2138 for (int I = NumElements - 1, E = -1; I != E; --I)2139 HexString += scalarConstantToHexString(C->getAggregateElement(I));2140 return HexString;2141 }2142}2143 2144MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant(2145 const DataLayout &DL, SectionKind Kind, const Constant *C,2146 Align &Alignment) const {2147 if (Kind.isMergeableConst() && C &&2148 getContext().getAsmInfo()->hasCOFFComdatConstants()) {2149 // This creates comdat sections with the given symbol name, but unless2150 // AsmPrinter::GetCPISymbol actually makes the symbol global, the symbol2151 // will be created with a null storage class, which makes GNU binutils2152 // error out.2153 const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |2154 COFF::IMAGE_SCN_MEM_READ |2155 COFF::IMAGE_SCN_LNK_COMDAT;2156 std::string COMDATSymName;2157 if (Kind.isMergeableConst4()) {2158 if (Alignment <= 4) {2159 COMDATSymName = "__real@" + scalarConstantToHexString(C);2160 Alignment = Align(4);2161 }2162 } else if (Kind.isMergeableConst8()) {2163 if (Alignment <= 8) {2164 COMDATSymName = "__real@" + scalarConstantToHexString(C);2165 Alignment = Align(8);2166 }2167 } else if (Kind.isMergeableConst16()) {2168 // FIXME: These may not be appropriate for non-x86 architectures.2169 if (Alignment <= 16) {2170 COMDATSymName = "__xmm@" + scalarConstantToHexString(C);2171 Alignment = Align(16);2172 }2173 } else if (Kind.isMergeableConst32()) {2174 if (Alignment <= 32) {2175 COMDATSymName = "__ymm@" + scalarConstantToHexString(C);2176 Alignment = Align(32);2177 }2178 }2179 2180 if (!COMDATSymName.empty())2181 return getContext().getCOFFSection(".rdata", Characteristics,2182 COMDATSymName,2183 COFF::IMAGE_COMDAT_SELECT_ANY);2184 }2185 2186 return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C,2187 Alignment);2188}2189 2190//===----------------------------------------------------------------------===//2191// Wasm2192//===----------------------------------------------------------------------===//2193 2194static const Comdat *getWasmComdat(const GlobalValue *GV) {2195 const Comdat *C = GV->getComdat();2196 if (!C)2197 return nullptr;2198 2199 if (C->getSelectionKind() != Comdat::Any)2200 report_fatal_error("WebAssembly COMDATs only support "2201 "SelectionKind::Any, '" + C->getName() + "' cannot be "2202 "lowered.");2203 2204 return C;2205}2206 2207static unsigned getWasmSectionFlags(SectionKind K, bool Retain) {2208 unsigned Flags = 0;2209 2210 if (K.isThreadLocal())2211 Flags |= wasm::WASM_SEG_FLAG_TLS;2212 2213 if (K.isMergeableCString())2214 Flags |= wasm::WASM_SEG_FLAG_STRINGS;2215 2216 if (Retain)2217 Flags |= wasm::WASM_SEG_FLAG_RETAIN;2218 2219 // TODO(sbc): Add suport for K.isMergeableConst()2220 2221 return Flags;2222}2223 2224void TargetLoweringObjectFileWasm::getModuleMetadata(Module &M) {2225 SmallVector<GlobalValue *, 4> Vec;2226 collectUsedGlobalVariables(M, Vec, false);2227 for (GlobalValue *GV : Vec)2228 if (auto *GO = dyn_cast<GlobalObject>(GV))2229 Used.insert(GO);2230}2231 2232MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(2233 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {2234 // We don't support explict section names for functions in the wasm object2235 // format. Each function has to be in its own unique section.2236 if (isa<Function>(GO)) {2237 return SelectSectionForGlobal(GO, Kind, TM);2238 }2239 2240 StringRef Name = GO->getSection();2241 2242 // Certain data sections we treat as named custom sections rather than2243 // segments within the data section.2244 // This could be avoided if all data segements (the wasm sense) were2245 // represented as their own sections (in the llvm sense).2246 // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/1382247 if (Name == getInstrProfSectionName(IPSK_covmap, Triple::Wasm,2248 /*AddSegmentInfo=*/false) ||2249 Name == getInstrProfSectionName(IPSK_covfun, Triple::Wasm,2250 /*AddSegmentInfo=*/false) ||2251 Name == ".llvmbc" || Name == ".llvmcmd")2252 Kind = SectionKind::getMetadata();2253 2254 StringRef Group = "";2255 if (const Comdat *C = getWasmComdat(GO)) {2256 Group = C->getName();2257 }2258 2259 unsigned Flags = getWasmSectionFlags(Kind, Used.count(GO));2260 MCSectionWasm *Section = getContext().getWasmSection(Name, Kind, Flags, Group,2261 MCSection::NonUniqueID);2262 2263 return Section;2264}2265 2266static MCSectionWasm *2267selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO,2268 SectionKind Kind, Mangler &Mang,2269 const TargetMachine &TM, bool EmitUniqueSection,2270 unsigned *NextUniqueID, bool Retain) {2271 StringRef Group = "";2272 if (const Comdat *C = getWasmComdat(GO)) {2273 Group = C->getName();2274 }2275 2276 bool UniqueSectionNames = TM.getUniqueSectionNames();2277 SmallString<128> Name = getSectionPrefixForGlobal(Kind, /*IsLarge=*/false);2278 2279 if (const auto *F = dyn_cast<Function>(GO)) {2280 const auto &OptionalPrefix = F->getSectionPrefix();2281 if (OptionalPrefix)2282 raw_svector_ostream(Name) << '.' << *OptionalPrefix;2283 }2284 2285 if (EmitUniqueSection && UniqueSectionNames) {2286 Name.push_back('.');2287 TM.getNameWithPrefix(Name, GO, Mang, true);2288 }2289 unsigned UniqueID = MCSection::NonUniqueID;2290 if (EmitUniqueSection && !UniqueSectionNames) {2291 UniqueID = *NextUniqueID;2292 (*NextUniqueID)++;2293 }2294 2295 unsigned Flags = getWasmSectionFlags(Kind, Retain);2296 return Ctx.getWasmSection(Name, Kind, Flags, Group, UniqueID);2297}2298 2299MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal(2300 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {2301 2302 if (Kind.isCommon())2303 report_fatal_error("mergable sections not supported yet on wasm");2304 2305 // If we have -ffunction-section or -fdata-section then we should emit the2306 // global value to a uniqued section specifically for it.2307 bool EmitUniqueSection = false;2308 if (Kind.isText())2309 EmitUniqueSection = TM.getFunctionSections();2310 else2311 EmitUniqueSection = TM.getDataSections();2312 EmitUniqueSection |= GO->hasComdat();2313 bool Retain = Used.count(GO);2314 EmitUniqueSection |= Retain;2315 2316 return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,2317 EmitUniqueSection, &NextUniqueID, Retain);2318}2319 2320bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection(2321 bool UsesLabelDifference, const Function &F) const {2322 // We can always create relative relocations, so use another section2323 // that can be marked non-executable.2324 return false;2325}2326 2327void TargetLoweringObjectFileWasm::InitializeWasm() {2328 StaticCtorSection =2329 getContext().getWasmSection(".init_array", SectionKind::getData());2330 2331 // We don't use PersonalityEncoding and LSDAEncoding because we don't emit2332 // .cfi directives. We use TTypeEncoding to encode typeinfo global variables.2333 TTypeEncoding = dwarf::DW_EH_PE_absptr;2334}2335 2336MCSection *TargetLoweringObjectFileWasm::getStaticCtorSection(2337 unsigned Priority, const MCSymbol *KeySym) const {2338 return Priority == UINT16_MAX ?2339 StaticCtorSection :2340 getContext().getWasmSection(".init_array." + utostr(Priority),2341 SectionKind::getData());2342}2343 2344MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection(2345 unsigned Priority, const MCSymbol *KeySym) const {2346 report_fatal_error("@llvm.global_dtors should have been lowered already");2347}2348 2349//===----------------------------------------------------------------------===//2350// XCOFF2351//===----------------------------------------------------------------------===//2352bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(2353 const MachineFunction *MF) {2354 if (!MF->getLandingPads().empty())2355 return true;2356 2357 const Function &F = MF->getFunction();2358 if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry())2359 return false;2360 2361 const GlobalValue *Per =2362 dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());2363 assert(Per && "Personality routine is not a GlobalValue type.");2364 if (isNoOpWithoutInvoke(classifyEHPersonality(Per)))2365 return false;2366 2367 return true;2368}2369 2370bool TargetLoweringObjectFileXCOFF::ShouldSetSSPCanaryBitInTB(2371 const MachineFunction *MF) {2372 const Function &F = MF->getFunction();2373 if (!F.hasStackProtectorFnAttr())2374 return false;2375 // FIXME: check presence of canary word2376 // There are cases that the stack protectors are not really inserted even if2377 // the attributes are on.2378 return true;2379}2380 2381MCSymbol *2382TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) {2383 auto *EHInfoSym =2384 static_cast<MCSymbolXCOFF *>(MF->getContext().getOrCreateSymbol(2385 "__ehinfo." + Twine(MF->getFunctionNumber())));2386 EHInfoSym->setEHInfo();2387 return EHInfoSym;2388}2389 2390MCSymbol *2391TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,2392 const TargetMachine &TM) const {2393 // We always use a qualname symbol for a GV that represents2394 // a declaration, a function descriptor, or a common symbol.2395 // If a GV represents a GlobalVariable and -fdata-sections is enabled, we2396 // also return a qualname so that a label symbol could be avoided.2397 // It is inherently ambiguous when the GO represents the address of a2398 // function, as the GO could either represent a function descriptor or a2399 // function entry point. We choose to always return a function descriptor2400 // here.2401 if (const GlobalObject *GO = dyn_cast<GlobalObject>(GV)) {2402 if (GO->isDeclarationForLinker())2403 return static_cast<const MCSectionXCOFF *>(2404 getSectionForExternalReference(GO, TM))2405 ->getQualNameSymbol();2406 2407 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))2408 if (GVar->hasAttribute("toc-data"))2409 return static_cast<const MCSectionXCOFF *>(2410 SectionForGlobal(GVar, SectionKind::getData(), TM))2411 ->getQualNameSymbol();2412 2413 SectionKind GOKind = getKindForGlobal(GO, TM);2414 if (GOKind.isText())2415 return static_cast<const MCSectionXCOFF *>(2416 getSectionForFunctionDescriptor(cast<Function>(GO), TM))2417 ->getQualNameSymbol();2418 if ((TM.getDataSections() && !GO->hasSection()) || GO->hasCommonLinkage() ||2419 GOKind.isBSSLocal() || GOKind.isThreadBSSLocal())2420 return static_cast<const MCSectionXCOFF *>(2421 SectionForGlobal(GO, GOKind, TM))2422 ->getQualNameSymbol();2423 }2424 2425 // For all other cases, fall back to getSymbol to return the unqualified name.2426 return nullptr;2427}2428 2429MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(2430 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {2431 if (!GO->hasSection())2432 report_fatal_error("#pragma clang section is not yet supported");2433 2434 StringRef SectionName = GO->getSection();2435 2436 // Handle the XCOFF::TD case first, then deal with the rest.2437 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))2438 if (GVar->hasAttribute("toc-data"))2439 return getContext().getXCOFFSection(2440 SectionName, Kind,2441 XCOFF::CsectProperties(/*MappingClass*/ XCOFF::XMC_TD, XCOFF::XTY_SD),2442 /* MultiSymbolsAllowed*/ true);2443 2444 XCOFF::StorageMappingClass MappingClass;2445 if (Kind.isText())2446 MappingClass = XCOFF::XMC_PR;2447 else if (Kind.isData() || Kind.isBSS())2448 MappingClass = XCOFF::XMC_RW;2449 else if (Kind.isReadOnlyWithRel())2450 MappingClass =2451 TM.Options.XCOFFReadOnlyPointers ? XCOFF::XMC_RO : XCOFF::XMC_RW;2452 else if (Kind.isReadOnly())2453 MappingClass = XCOFF::XMC_RO;2454 else2455 report_fatal_error("XCOFF other section types not yet implemented.");2456 2457 return getContext().getXCOFFSection(2458 SectionName, Kind, XCOFF::CsectProperties(MappingClass, XCOFF::XTY_SD),2459 /* MultiSymbolsAllowed*/ true);2460}2461 2462MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference(2463 const GlobalObject *GO, const TargetMachine &TM) const {2464 assert(GO->isDeclarationForLinker() &&2465 "Tried to get ER section for a defined global.");2466 2467 SmallString<128> Name;2468 getNameWithPrefix(Name, GO, TM);2469 2470 // AIX TLS local-dynamic does not need the external reference for the2471 // "_$TLSML" symbol.2472 if (GO->getThreadLocalMode() == GlobalVariable::LocalDynamicTLSModel &&2473 GO->hasName() && GO->getName() == "_$TLSML") {2474 return getContext().getXCOFFSection(2475 Name, SectionKind::getData(),2476 XCOFF::CsectProperties(XCOFF::XMC_TC, XCOFF::XTY_SD));2477 }2478 2479 XCOFF::StorageMappingClass SMC =2480 isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA;2481 if (GO->isThreadLocal())2482 SMC = XCOFF::XMC_UL;2483 2484 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))2485 if (GVar->hasAttribute("toc-data"))2486 SMC = XCOFF::XMC_TD;2487 2488 // Externals go into a csect of type ER.2489 return getContext().getXCOFFSection(2490 Name, SectionKind::getMetadata(),2491 XCOFF::CsectProperties(SMC, XCOFF::XTY_ER));2492}2493 2494MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(2495 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {2496 // Handle the XCOFF::TD case first, then deal with the rest.2497 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))2498 if (GVar->hasAttribute("toc-data")) {2499 SmallString<128> Name;2500 getNameWithPrefix(Name, GO, TM);2501 XCOFF::SymbolType symType =2502 GO->hasCommonLinkage() ? XCOFF::XTY_CM : XCOFF::XTY_SD;2503 return getContext().getXCOFFSection(2504 Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TD, symType),2505 /* MultiSymbolsAllowed*/ true);2506 }2507 2508 // Common symbols go into a csect with matching name which will get mapped2509 // into the .bss section.2510 // Zero-initialized local TLS symbols go into a csect with matching name which2511 // will get mapped into the .tbss section.2512 if (Kind.isBSSLocal() || GO->hasCommonLinkage() || Kind.isThreadBSSLocal()) {2513 SmallString<128> Name;2514 getNameWithPrefix(Name, GO, TM);2515 XCOFF::StorageMappingClass SMC = Kind.isBSSLocal() ? XCOFF::XMC_BS2516 : Kind.isCommon() ? XCOFF::XMC_RW2517 : XCOFF::XMC_UL;2518 return getContext().getXCOFFSection(2519 Name, Kind, XCOFF::CsectProperties(SMC, XCOFF::XTY_CM));2520 }2521 2522 if (Kind.isText()) {2523 if (TM.getFunctionSections()) {2524 return static_cast<const MCSymbolXCOFF *>(2525 getFunctionEntryPointSymbol(GO, TM))2526 ->getRepresentedCsect();2527 }2528 return TextSection;2529 }2530 2531 if (TM.Options.XCOFFReadOnlyPointers && Kind.isReadOnlyWithRel()) {2532 if (!TM.getDataSections())2533 report_fatal_error(2534 "ReadOnlyPointers is supported only if data sections is turned on");2535 2536 SmallString<128> Name;2537 getNameWithPrefix(Name, GO, TM);2538 return getContext().getXCOFFSection(2539 Name, SectionKind::getReadOnly(),2540 XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));2541 }2542 2543 // For BSS kind, zero initialized data must be emitted to the .data section2544 // because external linkage control sections that get mapped to the .bss2545 // section will be linked as tentative defintions, which is only appropriate2546 // for SectionKind::Common.2547 if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS()) {2548 if (TM.getDataSections()) {2549 SmallString<128> Name;2550 getNameWithPrefix(Name, GO, TM);2551 return getContext().getXCOFFSection(2552 Name, SectionKind::getData(),2553 XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD));2554 }2555 return DataSection;2556 }2557 2558 if (Kind.isReadOnly()) {2559 if (TM.getDataSections()) {2560 SmallString<128> Name;2561 getNameWithPrefix(Name, GO, TM);2562 return getContext().getXCOFFSection(2563 Name, SectionKind::getReadOnly(),2564 XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));2565 }2566 return ReadOnlySection;2567 }2568 2569 // External/weak TLS data and initialized local TLS data are not eligible2570 // to be put into common csect. If data sections are enabled, thread2571 // data are emitted into separate sections. Otherwise, thread data2572 // are emitted into the .tdata section.2573 if (Kind.isThreadLocal()) {2574 if (TM.getDataSections()) {2575 SmallString<128> Name;2576 getNameWithPrefix(Name, GO, TM);2577 return getContext().getXCOFFSection(2578 Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TL, XCOFF::XTY_SD));2579 }2580 return TLSDataSection;2581 }2582 2583 report_fatal_error("XCOFF other section types not yet implemented.");2584}2585 2586MCSection *TargetLoweringObjectFileXCOFF::getSectionForJumpTable(2587 const Function &F, const TargetMachine &TM) const {2588 assert (!F.getComdat() && "Comdat not supported on XCOFF.");2589 2590 if (!TM.getFunctionSections())2591 return ReadOnlySection;2592 2593 // If the function can be removed, produce a unique section so that2594 // the table doesn't prevent the removal.2595 SmallString<128> NameStr(".rodata.jmp..");2596 getNameWithPrefix(NameStr, &F, TM);2597 return getContext().getXCOFFSection(2598 NameStr, SectionKind::getReadOnly(),2599 XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));2600}2601 2602bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection(2603 bool UsesLabelDifference, const Function &F) const {2604 return false;2605}2606 2607/// Given a mergeable constant with the specified size and relocation2608/// information, return a section that it should be placed in.2609MCSection *TargetLoweringObjectFileXCOFF::getSectionForConstant(2610 const DataLayout &DL, SectionKind Kind, const Constant *C,2611 Align &Alignment) const {2612 // TODO: Enable emiting constant pool to unique sections when we support it.2613 if (Alignment > Align(16))2614 report_fatal_error("Alignments greater than 16 not yet supported.");2615 2616 if (Alignment == Align(8)) {2617 assert(ReadOnly8Section && "Section should always be initialized.");2618 return ReadOnly8Section;2619 }2620 2621 if (Alignment == Align(16)) {2622 assert(ReadOnly16Section && "Section should always be initialized.");2623 return ReadOnly16Section;2624 }2625 2626 return ReadOnlySection;2627}2628 2629void TargetLoweringObjectFileXCOFF::Initialize(MCContext &Ctx,2630 const TargetMachine &TgtM) {2631 TargetLoweringObjectFile::Initialize(Ctx, TgtM);2632 TTypeEncoding =2633 dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |2634 (TgtM.getTargetTriple().isArch32Bit() ? dwarf::DW_EH_PE_sdata42635 : dwarf::DW_EH_PE_sdata8);2636 PersonalityEncoding = 0;2637 LSDAEncoding = 0;2638 CallSiteEncoding = dwarf::DW_EH_PE_udata4;2639 2640 // AIX debug for thread local location is not ready. And for integrated as2641 // mode, the relocatable address for the thread local variable will cause2642 // linker error. So disable the location attribute generation for thread local2643 // variables for now.2644 // FIXME: when TLS debug on AIX is ready, remove this setting.2645 SupportDebugThreadLocalLocation = false;2646}2647 2648MCSection *TargetLoweringObjectFileXCOFF::getStaticCtorSection(2649 unsigned Priority, const MCSymbol *KeySym) const {2650 report_fatal_error("no static constructor section on AIX");2651}2652 2653MCSection *TargetLoweringObjectFileXCOFF::getStaticDtorSection(2654 unsigned Priority, const MCSymbol *KeySym) const {2655 report_fatal_error("no static destructor section on AIX");2656}2657 2658XCOFF::StorageClass2659TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) {2660 assert(!isa<GlobalIFunc>(GV) && "GlobalIFunc is not supported on AIX.");2661 2662 switch (GV->getLinkage()) {2663 case GlobalValue::InternalLinkage:2664 case GlobalValue::PrivateLinkage:2665 return XCOFF::C_HIDEXT;2666 case GlobalValue::ExternalLinkage:2667 case GlobalValue::CommonLinkage:2668 case GlobalValue::AvailableExternallyLinkage:2669 return XCOFF::C_EXT;2670 case GlobalValue::ExternalWeakLinkage:2671 case GlobalValue::LinkOnceAnyLinkage:2672 case GlobalValue::LinkOnceODRLinkage:2673 case GlobalValue::WeakAnyLinkage:2674 case GlobalValue::WeakODRLinkage:2675 return XCOFF::C_WEAKEXT;2676 case GlobalValue::AppendingLinkage:2677 report_fatal_error(2678 "There is no mapping that implements AppendingLinkage for XCOFF.");2679 }2680 llvm_unreachable("Unknown linkage type!");2681}2682 2683MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol(2684 const GlobalValue *Func, const TargetMachine &TM) const {2685 assert((isa<Function>(Func) ||2686 (isa<GlobalAlias>(Func) &&2687 isa_and_nonnull<Function>(2688 cast<GlobalAlias>(Func)->getAliaseeObject()))) &&2689 "Func must be a function or an alias which has a function as base "2690 "object.");2691 2692 SmallString<128> NameStr;2693 NameStr.push_back('.');2694 getNameWithPrefix(NameStr, Func, TM);2695 2696 // When -function-sections is enabled and explicit section is not specified,2697 // it's not necessary to emit function entry point label any more. We will use2698 // function entry point csect instead. And for function delcarations, the2699 // undefined symbols gets treated as csect with XTY_ER property.2700 if (((TM.getFunctionSections() && !Func->hasSection()) ||2701 Func->isDeclarationForLinker()) &&2702 isa<Function>(Func)) {2703 return getContext()2704 .getXCOFFSection(2705 NameStr, SectionKind::getText(),2706 XCOFF::CsectProperties(XCOFF::XMC_PR, Func->isDeclarationForLinker()2707 ? XCOFF::XTY_ER2708 : XCOFF::XTY_SD))2709 ->getQualNameSymbol();2710 }2711 2712 return getContext().getOrCreateSymbol(NameStr);2713}2714 2715MCSection *TargetLoweringObjectFileXCOFF::getSectionForFunctionDescriptor(2716 const Function *F, const TargetMachine &TM) const {2717 SmallString<128> NameStr;2718 getNameWithPrefix(NameStr, F, TM);2719 return getContext().getXCOFFSection(2720 NameStr, SectionKind::getData(),2721 XCOFF::CsectProperties(XCOFF::XMC_DS, XCOFF::XTY_SD));2722}2723 2724MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry(2725 const MCSymbol *Sym, const TargetMachine &TM) const {2726 const XCOFF::StorageMappingClass SMC = [](const MCSymbol *Sym,2727 const TargetMachine &TM) {2728 auto *XSym = static_cast<const MCSymbolXCOFF *>(Sym);2729 2730 // The "_$TLSML" symbol for TLS local-dynamic mode requires XMC_TC,2731 // otherwise the AIX assembler will complain.2732 if (XSym->getSymbolTableName() == "_$TLSML")2733 return XCOFF::XMC_TC;2734 2735 // Use large code model toc entries for ehinfo symbols as they are2736 // never referenced directly. The runtime loads their TOC entry2737 // addresses from the trace-back table.2738 if (XSym->isEHInfo())2739 return XCOFF::XMC_TE;2740 2741 // If the symbol does not have a code model specified use the module value.2742 if (!XSym->hasPerSymbolCodeModel())2743 return TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE2744 : XCOFF::XMC_TC;2745 2746 return XSym->getPerSymbolCodeModel() == MCSymbolXCOFF::CM_Large2747 ? XCOFF::XMC_TE2748 : XCOFF::XMC_TC;2749 }(Sym, TM);2750 2751 return getContext().getXCOFFSection(2752 static_cast<const MCSymbolXCOFF *>(Sym)->getSymbolTableName(),2753 SectionKind::getData(), XCOFF::CsectProperties(SMC, XCOFF::XTY_SD));2754}2755 2756MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA(2757 const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {2758 auto *LSDA = static_cast<MCSectionXCOFF *>(LSDASection);2759 if (TM.getFunctionSections()) {2760 // If option -ffunction-sections is on, append the function name to the2761 // name of the LSDA csect so that each function has its own LSDA csect.2762 // This helps the linker to garbage-collect EH info of unused functions.2763 SmallString<128> NameStr = LSDA->getName();2764 raw_svector_ostream(NameStr) << '.' << F.getName();2765 LSDA = getContext().getXCOFFSection(NameStr, LSDA->getKind(),2766 LSDA->getCsectProp());2767 }2768 return LSDA;2769}2770//===----------------------------------------------------------------------===//2771// GOFF2772//===----------------------------------------------------------------------===//2773TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default;2774 2775void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {2776 // Construct the default names for the root SD and the ADA PR symbol.2777 StringRef FileName = sys::path::stem(M.getSourceFileName());2778 if (FileName.size() > 1 && FileName.starts_with('<') &&2779 FileName.ends_with('>'))2780 FileName = FileName.substr(1, FileName.size() - 2);2781 DefaultRootSDName = Twine(FileName).concat("#C").str();2782 DefaultADAPRName = Twine(FileName).concat("#S").str();2783 MCSectionGOFF *RootSD =2784 static_cast<MCSectionGOFF *>(TextSection)->getParent();2785 MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADASection);2786 RootSD->setName(DefaultRootSDName);2787 ADAPR->setName(DefaultADAPRName);2788 // Initialize the label for the text section.2789 MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>(2790 getContext().getOrCreateSymbol(RootSD->getName()));2791 TextLD->setLDAttributes(GOFF::LDAttr{2792 false, GOFF::ESD_EXE_CODE, GOFF::ESD_BST_Strong, GOFF::ESD_LT_XPLink,2793 GOFF::ESD_AMODE_64, GOFF::ESD_BSC_Section});2794 TextLD->setADA(ADAPR);2795 TextSection->setBeginSymbol(TextLD);2796}2797 2798MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(2799 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {2800 return SelectSectionForGlobal(GO, Kind, TM);2801}2802 2803MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(2804 const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {2805 std::string Name = ".gcc_exception_table." + F.getName().str();2806 2807 MCSectionGOFF *WSA = getContext().getGOFFSection(2808 SectionKind::getMetadata(), GOFF::CLASS_WSA,2809 GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts,2810 GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,2811 GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,2812 GOFF::ESD_ALIGN_Fullword, 0},2813 static_cast<MCSectionGOFF *>(TextSection)->getParent());2814 return getContext().getGOFFSection(SectionKind::getData(), Name,2815 GOFF::PRAttr{true, GOFF::ESD_EXE_DATA,2816 GOFF::ESD_LT_XPLink,2817 GOFF::ESD_BSC_Section, 0},2818 WSA);2819}2820 2821MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(2822 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {2823 auto *Symbol = TM.getSymbol(GO);2824 2825 if (Kind.isBSS() || Kind.isData()) {2826 GOFF::ESDBindingScope PRBindingScope =2827 GO->hasExternalLinkage()2828 ? (GO->hasDefaultVisibility() ? GOFF::ESD_BSC_ImportExport2829 : GOFF::ESD_BSC_Library)2830 : GOFF::ESD_BSC_Section;2831 GOFF::ESDBindingScope SDBindingScope =2832 PRBindingScope == GOFF::ESD_BSC_Section ? GOFF::ESD_BSC_Section2833 : GOFF::ESD_BSC_Unspecified;2834 MaybeAlign Alignment;2835 if (auto *F = dyn_cast<Function>(GO))2836 Alignment = F->getAlign();2837 else if (auto *V = dyn_cast<GlobalVariable>(GO))2838 Alignment = V->getAlign();2839 GOFF::ESDAlignment Align =2840 Alignment ? static_cast<GOFF::ESDAlignment>(Log2(*Alignment))2841 : GOFF::ESD_ALIGN_Doubleword;2842 MCSectionGOFF *SD = getContext().getGOFFSection(2843 SectionKind::getMetadata(), Symbol->getName(),2844 GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope});2845 MCSectionGOFF *ED = getContext().getGOFFSection(2846 SectionKind::getMetadata(), GOFF::CLASS_WSA,2847 GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts,2848 GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,2849 GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align, 0},2850 SD);2851 return getContext().getGOFFSection(Kind, Symbol->getName(),2852 GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,2853 GOFF::ESD_LT_XPLink,2854 PRBindingScope, 0},2855 ED);2856 }2857 return TextSection;2858}2859