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