10b57cec5SDimitry Andric //===- llvm/CodeGen/TargetLoweringObjectFileImpl.cpp - Object File Info ---===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements classes used to handle lowerings specific to common
100b57cec5SDimitry Andric // object file formats.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
150b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
170b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
190b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
200b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
210b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
220b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h"
23fe6060f1SDimitry Andric #include "llvm/BinaryFormat/Wasm.h"
24e8d8bef9SDimitry Andric #include "llvm/CodeGen/BasicBlockSectionUtils.h"
255ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
265ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h"
290b57cec5SDimitry Andric #include "llvm/IR/Comdat.h"
300b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
310b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
320b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
335ffd83dbSDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
345ffd83dbSDimitry Andric #include "llvm/IR/DiagnosticPrinter.h"
350b57cec5SDimitry Andric #include "llvm/IR/Function.h"
360b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h"
370b57cec5SDimitry Andric #include "llvm/IR/GlobalObject.h"
380b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
390b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h"
400b57cec5SDimitry Andric #include "llvm/IR/Mangler.h"
410b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
420b57cec5SDimitry Andric #include "llvm/IR/Module.h"
43e8d8bef9SDimitry Andric #include "llvm/IR/PseudoProbe.h"
440b57cec5SDimitry Andric #include "llvm/IR/Type.h"
450b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
460b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
470b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
480b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h"
490b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h"
50fe6060f1SDimitry Andric #include "llvm/MC/MCSectionGOFF.h"
510b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h"
520b57cec5SDimitry Andric #include "llvm/MC/MCSectionWasm.h"
538bcb0991SDimitry Andric #include "llvm/MC/MCSectionXCOFF.h"
540b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
550b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
560b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h"
570b57cec5SDimitry Andric #include "llvm/MC/MCValue.h"
580b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h"
590b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProf.h"
60bdd1243dSDimitry Andric #include "llvm/Support/Base64.h"
610b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
620b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
630b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
645ffd83dbSDimitry Andric #include "llvm/Support/Format.h"
650b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
660b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
67*fe013be4SDimitry Andric #include "llvm/TargetParser/Triple.h"
680b57cec5SDimitry Andric #include <cassert>
690b57cec5SDimitry Andric #include <string>
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric using namespace llvm;
720b57cec5SDimitry Andric using namespace dwarf;
730b57cec5SDimitry Andric 
74*fe013be4SDimitry Andric static cl::opt<bool> JumpTableInFunctionSection(
75*fe013be4SDimitry Andric     "jumptable-in-function-section", cl::Hidden, cl::init(false),
76*fe013be4SDimitry Andric     cl::desc("Putting Jump Table in function section"));
77*fe013be4SDimitry Andric 
780b57cec5SDimitry Andric static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
790b57cec5SDimitry Andric                              StringRef &Section) {
800b57cec5SDimitry Andric   SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
810b57cec5SDimitry Andric   M.getModuleFlagsMetadata(ModuleFlags);
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   for (const auto &MFE: ModuleFlags) {
840b57cec5SDimitry Andric     // Ignore flags with 'Require' behaviour.
850b57cec5SDimitry Andric     if (MFE.Behavior == Module::Require)
860b57cec5SDimitry Andric       continue;
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric     StringRef Key = MFE.Key->getString();
890b57cec5SDimitry Andric     if (Key == "Objective-C Image Info Version") {
900b57cec5SDimitry Andric       Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue();
910b57cec5SDimitry Andric     } else if (Key == "Objective-C Garbage Collection" ||
920b57cec5SDimitry Andric                Key == "Objective-C GC Only" ||
930b57cec5SDimitry Andric                Key == "Objective-C Is Simulated" ||
940b57cec5SDimitry Andric                Key == "Objective-C Class Properties" ||
950b57cec5SDimitry Andric                Key == "Objective-C Image Swift Version") {
960b57cec5SDimitry Andric       Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue();
970b57cec5SDimitry Andric     } else if (Key == "Objective-C Image Info Section") {
980b57cec5SDimitry Andric       Section = cast<MDString>(MFE.Val)->getString();
990b57cec5SDimitry Andric     }
1005ffd83dbSDimitry Andric     // Backend generates L_OBJC_IMAGE_INFO from Swift ABI version + major + minor +
1015ffd83dbSDimitry Andric     // "Objective-C Garbage Collection".
1025ffd83dbSDimitry Andric     else if (Key == "Swift ABI Version") {
1035ffd83dbSDimitry Andric       Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 8;
1045ffd83dbSDimitry Andric     } else if (Key == "Swift Major Version") {
1055ffd83dbSDimitry Andric       Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 24;
1065ffd83dbSDimitry Andric     } else if (Key == "Swift Minor Version") {
1075ffd83dbSDimitry Andric       Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 16;
1085ffd83dbSDimitry Andric     }
1090b57cec5SDimitry Andric   }
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1130b57cec5SDimitry Andric //                                  ELF
1140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1150b57cec5SDimitry Andric 
11604eeddc0SDimitry Andric TargetLoweringObjectFileELF::TargetLoweringObjectFileELF() {
117e8d8bef9SDimitry Andric   SupportDSOLocalEquivalentLowering = true;
118e8d8bef9SDimitry Andric }
119e8d8bef9SDimitry Andric 
1200b57cec5SDimitry Andric void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
1210b57cec5SDimitry Andric                                              const TargetMachine &TgtM) {
1220b57cec5SDimitry Andric   TargetLoweringObjectFile::Initialize(Ctx, TgtM);
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   CodeModel::Model CM = TgtM.getCodeModel();
1255ffd83dbSDimitry Andric   InitializeELF(TgtM.Options.UseInitArray);
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   switch (TgtM.getTargetTriple().getArch()) {
1280b57cec5SDimitry Andric   case Triple::arm:
1290b57cec5SDimitry Andric   case Triple::armeb:
1300b57cec5SDimitry Andric   case Triple::thumb:
1310b57cec5SDimitry Andric   case Triple::thumbeb:
1320b57cec5SDimitry Andric     if (Ctx.getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM)
1330b57cec5SDimitry Andric       break;
1340b57cec5SDimitry Andric     // Fallthrough if not using EHABI
135bdd1243dSDimitry Andric     [[fallthrough]];
1360b57cec5SDimitry Andric   case Triple::ppc:
137e8d8bef9SDimitry Andric   case Triple::ppcle:
1380b57cec5SDimitry Andric   case Triple::x86:
1390b57cec5SDimitry Andric     PersonalityEncoding = isPositionIndependent()
1400b57cec5SDimitry Andric                               ? dwarf::DW_EH_PE_indirect |
1410b57cec5SDimitry Andric                                     dwarf::DW_EH_PE_pcrel |
1420b57cec5SDimitry Andric                                     dwarf::DW_EH_PE_sdata4
1430b57cec5SDimitry Andric                               : dwarf::DW_EH_PE_absptr;
1440b57cec5SDimitry Andric     LSDAEncoding = isPositionIndependent()
1450b57cec5SDimitry Andric                        ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
1460b57cec5SDimitry Andric                        : dwarf::DW_EH_PE_absptr;
1470b57cec5SDimitry Andric     TTypeEncoding = isPositionIndependent()
1480b57cec5SDimitry Andric                         ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
1490b57cec5SDimitry Andric                               dwarf::DW_EH_PE_sdata4
1500b57cec5SDimitry Andric                         : dwarf::DW_EH_PE_absptr;
1510b57cec5SDimitry Andric     break;
1520b57cec5SDimitry Andric   case Triple::x86_64:
1530b57cec5SDimitry Andric     if (isPositionIndependent()) {
1540b57cec5SDimitry Andric       PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
1550b57cec5SDimitry Andric         ((CM == CodeModel::Small || CM == CodeModel::Medium)
1560b57cec5SDimitry Andric          ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
1570b57cec5SDimitry Andric       LSDAEncoding = dwarf::DW_EH_PE_pcrel |
1580b57cec5SDimitry Andric         (CM == CodeModel::Small
1590b57cec5SDimitry Andric          ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
1600b57cec5SDimitry Andric       TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
1610b57cec5SDimitry Andric         ((CM == CodeModel::Small || CM == CodeModel::Medium)
162fe6060f1SDimitry Andric          ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
1630b57cec5SDimitry Andric     } else {
1640b57cec5SDimitry Andric       PersonalityEncoding =
1650b57cec5SDimitry Andric         (CM == CodeModel::Small || CM == CodeModel::Medium)
1660b57cec5SDimitry Andric         ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
1670b57cec5SDimitry Andric       LSDAEncoding = (CM == CodeModel::Small)
1680b57cec5SDimitry Andric         ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
1690b57cec5SDimitry Andric       TTypeEncoding = (CM == CodeModel::Small)
1700b57cec5SDimitry Andric         ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
1710b57cec5SDimitry Andric     }
1720b57cec5SDimitry Andric     break;
1730b57cec5SDimitry Andric   case Triple::hexagon:
1740b57cec5SDimitry Andric     PersonalityEncoding = dwarf::DW_EH_PE_absptr;
1750b57cec5SDimitry Andric     LSDAEncoding = dwarf::DW_EH_PE_absptr;
1760b57cec5SDimitry Andric     TTypeEncoding = dwarf::DW_EH_PE_absptr;
1770b57cec5SDimitry Andric     if (isPositionIndependent()) {
1780b57cec5SDimitry Andric       PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel;
1790b57cec5SDimitry Andric       LSDAEncoding |= dwarf::DW_EH_PE_pcrel;
1800b57cec5SDimitry Andric       TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel;
1810b57cec5SDimitry Andric     }
1820b57cec5SDimitry Andric     break;
1830b57cec5SDimitry Andric   case Triple::aarch64:
1840b57cec5SDimitry Andric   case Triple::aarch64_be:
1858bcb0991SDimitry Andric   case Triple::aarch64_32:
1860b57cec5SDimitry Andric     // The small model guarantees static code/data size < 4GB, but not where it
1870b57cec5SDimitry Andric     // will be in memory. Most of these could end up >2GB away so even a signed
1880b57cec5SDimitry Andric     // pc-relative 32-bit address is insufficient, theoretically.
189*fe013be4SDimitry Andric     //
190*fe013be4SDimitry Andric     // Use DW_EH_PE_indirect even for -fno-pic to avoid copy relocations.
191*fe013be4SDimitry Andric     LSDAEncoding = dwarf::DW_EH_PE_pcrel |
192*fe013be4SDimitry Andric                    (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32
193*fe013be4SDimitry Andric                         ? dwarf::DW_EH_PE_sdata4
194*fe013be4SDimitry Andric                         : dwarf::DW_EH_PE_sdata8);
195*fe013be4SDimitry Andric     PersonalityEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect;
196*fe013be4SDimitry Andric     TTypeEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect;
1970b57cec5SDimitry Andric     break;
1980b57cec5SDimitry Andric   case Triple::lanai:
1990b57cec5SDimitry Andric     LSDAEncoding = dwarf::DW_EH_PE_absptr;
2000b57cec5SDimitry Andric     PersonalityEncoding = dwarf::DW_EH_PE_absptr;
2010b57cec5SDimitry Andric     TTypeEncoding = dwarf::DW_EH_PE_absptr;
2020b57cec5SDimitry Andric     break;
2030b57cec5SDimitry Andric   case Triple::mips:
2040b57cec5SDimitry Andric   case Triple::mipsel:
2050b57cec5SDimitry Andric   case Triple::mips64:
2060b57cec5SDimitry Andric   case Triple::mips64el:
2070b57cec5SDimitry Andric     // MIPS uses indirect pointer to refer personality functions and types, so
2080b57cec5SDimitry Andric     // that the eh_frame section can be read-only. DW.ref.personality will be
2090b57cec5SDimitry Andric     // generated for relocation.
2100b57cec5SDimitry Andric     PersonalityEncoding = dwarf::DW_EH_PE_indirect;
2110b57cec5SDimitry Andric     // FIXME: The N64 ABI probably ought to use DW_EH_PE_sdata8 but we can't
2120b57cec5SDimitry Andric     //        identify N64 from just a triple.
2130b57cec5SDimitry Andric     TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2140b57cec5SDimitry Andric                     dwarf::DW_EH_PE_sdata4;
2150b57cec5SDimitry Andric     // We don't support PC-relative LSDA references in GAS so we use the default
2160b57cec5SDimitry Andric     // DW_EH_PE_absptr for those.
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric     // FreeBSD must be explicit about the data size and using pcrel since it's
2190b57cec5SDimitry Andric     // assembler/linker won't do the automatic conversion that the Linux tools
2200b57cec5SDimitry Andric     // do.
2210b57cec5SDimitry Andric     if (TgtM.getTargetTriple().isOSFreeBSD()) {
2220b57cec5SDimitry Andric       PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
2230b57cec5SDimitry Andric       LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
2240b57cec5SDimitry Andric     }
2250b57cec5SDimitry Andric     break;
2260b57cec5SDimitry Andric   case Triple::ppc64:
2270b57cec5SDimitry Andric   case Triple::ppc64le:
2280b57cec5SDimitry Andric     PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2290b57cec5SDimitry Andric       dwarf::DW_EH_PE_udata8;
2300b57cec5SDimitry Andric     LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
2310b57cec5SDimitry Andric     TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2320b57cec5SDimitry Andric       dwarf::DW_EH_PE_udata8;
2330b57cec5SDimitry Andric     break;
2340b57cec5SDimitry Andric   case Triple::sparcel:
2350b57cec5SDimitry Andric   case Triple::sparc:
2360b57cec5SDimitry Andric     if (isPositionIndependent()) {
2370b57cec5SDimitry Andric       LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
2380b57cec5SDimitry Andric       PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2390b57cec5SDimitry Andric         dwarf::DW_EH_PE_sdata4;
2400b57cec5SDimitry Andric       TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2410b57cec5SDimitry Andric         dwarf::DW_EH_PE_sdata4;
2420b57cec5SDimitry Andric     } else {
2430b57cec5SDimitry Andric       LSDAEncoding = dwarf::DW_EH_PE_absptr;
2440b57cec5SDimitry Andric       PersonalityEncoding = dwarf::DW_EH_PE_absptr;
2450b57cec5SDimitry Andric       TTypeEncoding = dwarf::DW_EH_PE_absptr;
2460b57cec5SDimitry Andric     }
2470b57cec5SDimitry Andric     CallSiteEncoding = dwarf::DW_EH_PE_udata4;
2480b57cec5SDimitry Andric     break;
2490b57cec5SDimitry Andric   case Triple::riscv32:
2500b57cec5SDimitry Andric   case Triple::riscv64:
2510b57cec5SDimitry Andric     LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
2520b57cec5SDimitry Andric     PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2530b57cec5SDimitry Andric                           dwarf::DW_EH_PE_sdata4;
2540b57cec5SDimitry Andric     TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2550b57cec5SDimitry Andric                     dwarf::DW_EH_PE_sdata4;
2560b57cec5SDimitry Andric     CallSiteEncoding = dwarf::DW_EH_PE_udata4;
2570b57cec5SDimitry Andric     break;
2580b57cec5SDimitry Andric   case Triple::sparcv9:
2590b57cec5SDimitry Andric     LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
2600b57cec5SDimitry Andric     if (isPositionIndependent()) {
2610b57cec5SDimitry Andric       PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2620b57cec5SDimitry Andric         dwarf::DW_EH_PE_sdata4;
2630b57cec5SDimitry Andric       TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2640b57cec5SDimitry Andric         dwarf::DW_EH_PE_sdata4;
2650b57cec5SDimitry Andric     } else {
2660b57cec5SDimitry Andric       PersonalityEncoding = dwarf::DW_EH_PE_absptr;
2670b57cec5SDimitry Andric       TTypeEncoding = dwarf::DW_EH_PE_absptr;
2680b57cec5SDimitry Andric     }
2690b57cec5SDimitry Andric     break;
2700b57cec5SDimitry Andric   case Triple::systemz:
2710b57cec5SDimitry Andric     // All currently-defined code models guarantee that 4-byte PC-relative
2720b57cec5SDimitry Andric     // values will be in range.
2730b57cec5SDimitry Andric     if (isPositionIndependent()) {
2740b57cec5SDimitry Andric       PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2750b57cec5SDimitry Andric         dwarf::DW_EH_PE_sdata4;
2760b57cec5SDimitry Andric       LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
2770b57cec5SDimitry Andric       TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
2780b57cec5SDimitry Andric         dwarf::DW_EH_PE_sdata4;
2790b57cec5SDimitry Andric     } else {
2800b57cec5SDimitry Andric       PersonalityEncoding = dwarf::DW_EH_PE_absptr;
2810b57cec5SDimitry Andric       LSDAEncoding = dwarf::DW_EH_PE_absptr;
2820b57cec5SDimitry Andric       TTypeEncoding = dwarf::DW_EH_PE_absptr;
2830b57cec5SDimitry Andric     }
2840b57cec5SDimitry Andric     break;
285bdd1243dSDimitry Andric   case Triple::loongarch32:
286bdd1243dSDimitry Andric   case Triple::loongarch64:
287bdd1243dSDimitry Andric     LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
288bdd1243dSDimitry Andric     PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
289bdd1243dSDimitry Andric                           dwarf::DW_EH_PE_sdata4;
290bdd1243dSDimitry Andric     TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
291bdd1243dSDimitry Andric                     dwarf::DW_EH_PE_sdata4;
292bdd1243dSDimitry Andric     break;
2930b57cec5SDimitry Andric   default:
2940b57cec5SDimitry Andric     break;
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric 
298fe6060f1SDimitry Andric void TargetLoweringObjectFileELF::getModuleMetadata(Module &M) {
299fe6060f1SDimitry Andric   SmallVector<GlobalValue *, 4> Vec;
300fe6060f1SDimitry Andric   collectUsedGlobalVariables(M, Vec, false);
301fe6060f1SDimitry Andric   for (GlobalValue *GV : Vec)
302fe6060f1SDimitry Andric     if (auto *GO = dyn_cast<GlobalObject>(GV))
303fe6060f1SDimitry Andric       Used.insert(GO);
304fe6060f1SDimitry Andric }
305fe6060f1SDimitry Andric 
3060b57cec5SDimitry Andric void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
3070b57cec5SDimitry Andric                                                      Module &M) const {
3080b57cec5SDimitry Andric   auto &C = getContext();
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
3110b57cec5SDimitry Andric     auto *S = C.getELFSection(".linker-options", ELF::SHT_LLVM_LINKER_OPTIONS,
3120b57cec5SDimitry Andric                               ELF::SHF_EXCLUDE);
3130b57cec5SDimitry Andric 
31481ad6265SDimitry Andric     Streamer.switchSection(S);
3150b57cec5SDimitry Andric 
316480093f4SDimitry Andric     for (const auto *Operand : LinkerOptions->operands()) {
3170b57cec5SDimitry Andric       if (cast<MDNode>(Operand)->getNumOperands() != 2)
3180b57cec5SDimitry Andric         report_fatal_error("invalid llvm.linker.options");
3190b57cec5SDimitry Andric       for (const auto &Option : cast<MDNode>(Operand)->operands()) {
3205ffd83dbSDimitry Andric         Streamer.emitBytes(cast<MDString>(Option)->getString());
3215ffd83dbSDimitry Andric         Streamer.emitInt8(0);
3220b57cec5SDimitry Andric       }
3230b57cec5SDimitry Andric     }
3240b57cec5SDimitry Andric   }
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) {
3270b57cec5SDimitry Andric     auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES,
328fe6060f1SDimitry Andric                               ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
3290b57cec5SDimitry Andric 
33081ad6265SDimitry Andric     Streamer.switchSection(S);
3310b57cec5SDimitry Andric 
332480093f4SDimitry Andric     for (const auto *Operand : DependentLibraries->operands()) {
3335ffd83dbSDimitry Andric       Streamer.emitBytes(
3340b57cec5SDimitry Andric           cast<MDString>(cast<MDNode>(Operand)->getOperand(0))->getString());
3355ffd83dbSDimitry Andric       Streamer.emitInt8(0);
3360b57cec5SDimitry Andric     }
3370b57cec5SDimitry Andric   }
3380b57cec5SDimitry Andric 
339e8d8bef9SDimitry Andric   if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) {
340e8d8bef9SDimitry Andric     // Emit a descriptor for every function including functions that have an
341e8d8bef9SDimitry Andric     // available external linkage. We may not want this for imported functions
342e8d8bef9SDimitry Andric     // that has code in another thinLTO module but we don't have a good way to
343e8d8bef9SDimitry Andric     // tell them apart from inline functions defined in header files. Therefore
344e8d8bef9SDimitry Andric     // we put each descriptor in a separate comdat section and rely on the
345e8d8bef9SDimitry Andric     // linker to deduplicate.
346e8d8bef9SDimitry Andric     for (const auto *Operand : FuncInfo->operands()) {
347e8d8bef9SDimitry Andric       const auto *MD = cast<MDNode>(Operand);
348e8d8bef9SDimitry Andric       auto *GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
349e8d8bef9SDimitry Andric       auto *Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
350e8d8bef9SDimitry Andric       auto *Name = cast<MDString>(MD->getOperand(2));
351e8d8bef9SDimitry Andric       auto *S = C.getObjectFileInfo()->getPseudoProbeDescSection(
352e8d8bef9SDimitry Andric           TM->getFunctionSections() ? Name->getString() : StringRef());
353e8d8bef9SDimitry Andric 
35481ad6265SDimitry Andric       Streamer.switchSection(S);
355e8d8bef9SDimitry Andric       Streamer.emitInt64(GUID->getZExtValue());
356e8d8bef9SDimitry Andric       Streamer.emitInt64(Hash->getZExtValue());
357e8d8bef9SDimitry Andric       Streamer.emitULEB128IntValue(Name->getString().size());
358e8d8bef9SDimitry Andric       Streamer.emitBytes(Name->getString());
359e8d8bef9SDimitry Andric     }
360e8d8bef9SDimitry Andric   }
361e8d8bef9SDimitry Andric 
362bdd1243dSDimitry Andric   if (NamedMDNode *LLVMStats = M.getNamedMetadata("llvm.stats")) {
363bdd1243dSDimitry Andric     // Emit the metadata for llvm statistics into .llvm_stats section, which is
364bdd1243dSDimitry Andric     // formatted as a list of key/value pair, the value is base64 encoded.
365bdd1243dSDimitry Andric     auto *S = C.getObjectFileInfo()->getLLVMStatsSection();
366bdd1243dSDimitry Andric     Streamer.switchSection(S);
367bdd1243dSDimitry Andric     for (const auto *Operand : LLVMStats->operands()) {
368bdd1243dSDimitry Andric       const auto *MD = cast<MDNode>(Operand);
369bdd1243dSDimitry Andric       assert(MD->getNumOperands() % 2 == 0 &&
370bdd1243dSDimitry Andric              ("Operand num should be even for a list of key/value pair"));
371bdd1243dSDimitry Andric       for (size_t I = 0; I < MD->getNumOperands(); I += 2) {
372bdd1243dSDimitry Andric         // Encode the key string size.
373bdd1243dSDimitry Andric         auto *Key = cast<MDString>(MD->getOperand(I));
374bdd1243dSDimitry Andric         Streamer.emitULEB128IntValue(Key->getString().size());
375bdd1243dSDimitry Andric         Streamer.emitBytes(Key->getString());
376bdd1243dSDimitry Andric         // Encode the value into a Base64 string.
377bdd1243dSDimitry Andric         std::string Value = encodeBase64(
378bdd1243dSDimitry Andric             Twine(mdconst::dyn_extract<ConstantInt>(MD->getOperand(I + 1))
379bdd1243dSDimitry Andric                       ->getZExtValue())
380bdd1243dSDimitry Andric                 .str());
381bdd1243dSDimitry Andric         Streamer.emitULEB128IntValue(Value.size());
382bdd1243dSDimitry Andric         Streamer.emitBytes(Value);
383bdd1243dSDimitry Andric       }
384bdd1243dSDimitry Andric     }
385bdd1243dSDimitry Andric   }
386bdd1243dSDimitry Andric 
3870b57cec5SDimitry Andric   unsigned Version = 0;
3880b57cec5SDimitry Andric   unsigned Flags = 0;
3890b57cec5SDimitry Andric   StringRef Section;
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric   GetObjCImageInfo(M, Version, Flags, Section);
3920b57cec5SDimitry Andric   if (!Section.empty()) {
3930b57cec5SDimitry Andric     auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
39481ad6265SDimitry Andric     Streamer.switchSection(S);
3955ffd83dbSDimitry Andric     Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
3965ffd83dbSDimitry Andric     Streamer.emitInt32(Version);
3975ffd83dbSDimitry Andric     Streamer.emitInt32(Flags);
39881ad6265SDimitry Andric     Streamer.addBlankLine();
3990b57cec5SDimitry Andric   }
4000b57cec5SDimitry Andric 
401e8d8bef9SDimitry Andric   emitCGProfileMetadata(Streamer, M);
4020b57cec5SDimitry Andric }
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
4050b57cec5SDimitry Andric     const GlobalValue *GV, const TargetMachine &TM,
4060b57cec5SDimitry Andric     MachineModuleInfo *MMI) const {
4070b57cec5SDimitry Andric   unsigned Encoding = getPersonalityEncoding();
4080b57cec5SDimitry Andric   if ((Encoding & 0x80) == DW_EH_PE_indirect)
4090b57cec5SDimitry Andric     return getContext().getOrCreateSymbol(StringRef("DW.ref.") +
4100b57cec5SDimitry Andric                                           TM.getSymbol(GV)->getName());
4110b57cec5SDimitry Andric   if ((Encoding & 0x70) == DW_EH_PE_absptr)
4120b57cec5SDimitry Andric     return TM.getSymbol(GV);
4130b57cec5SDimitry Andric   report_fatal_error("We do not support this DWARF encoding yet!");
4140b57cec5SDimitry Andric }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue(
4170b57cec5SDimitry Andric     MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const {
4180b57cec5SDimitry Andric   SmallString<64> NameData("DW.ref.");
4190b57cec5SDimitry Andric   NameData += Sym->getName();
4200b57cec5SDimitry Andric   MCSymbolELF *Label =
4210b57cec5SDimitry Andric       cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData));
4225ffd83dbSDimitry Andric   Streamer.emitSymbolAttribute(Label, MCSA_Hidden);
4235ffd83dbSDimitry Andric   Streamer.emitSymbolAttribute(Label, MCSA_Weak);
4240b57cec5SDimitry Andric   unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP;
4250b57cec5SDimitry Andric   MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(),
4260b57cec5SDimitry Andric                                                    ELF::SHT_PROGBITS, Flags, 0);
4270b57cec5SDimitry Andric   unsigned Size = DL.getPointerSize();
42881ad6265SDimitry Andric   Streamer.switchSection(Sec);
429bdd1243dSDimitry Andric   Streamer.emitValueToAlignment(DL.getPointerABIAlignment(0));
4305ffd83dbSDimitry Andric   Streamer.emitSymbolAttribute(Label, MCSA_ELF_TypeObject);
4310b57cec5SDimitry Andric   const MCExpr *E = MCConstantExpr::create(Size, getContext());
4320b57cec5SDimitry Andric   Streamer.emitELFSize(Label, E);
4335ffd83dbSDimitry Andric   Streamer.emitLabel(Label);
4340b57cec5SDimitry Andric 
4355ffd83dbSDimitry Andric   Streamer.emitSymbolValue(Sym, Size);
4360b57cec5SDimitry Andric }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(
4390b57cec5SDimitry Andric     const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,
4400b57cec5SDimitry Andric     MachineModuleInfo *MMI, MCStreamer &Streamer) const {
4410b57cec5SDimitry Andric   if (Encoding & DW_EH_PE_indirect) {
4420b57cec5SDimitry Andric     MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric     MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM);
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric     // Add information about the stub reference to ELFMMI so that the stub
4470b57cec5SDimitry Andric     // gets emitted by the asmprinter.
4480b57cec5SDimitry Andric     MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
4490b57cec5SDimitry Andric     if (!StubSym.getPointer()) {
4500b57cec5SDimitry Andric       MCSymbol *Sym = TM.getSymbol(GV);
4510b57cec5SDimitry Andric       StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
4520b57cec5SDimitry Andric     }
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric     return TargetLoweringObjectFile::
4550b57cec5SDimitry Andric       getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()),
4560b57cec5SDimitry Andric                         Encoding & ~DW_EH_PE_indirect, Streamer);
4570b57cec5SDimitry Andric   }
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM,
4600b57cec5SDimitry Andric                                                            MMI, Streamer);
4610b57cec5SDimitry Andric }
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
4640b57cec5SDimitry Andric   // N.B.: The defaults used in here are not the same ones used in MC.
4650b57cec5SDimitry Andric   // We follow gcc, MC follows gas. For example, given ".section .eh_frame",
4660b57cec5SDimitry Andric   // both gas and MC will produce a section with no flags. Given
4670b57cec5SDimitry Andric   // section(".eh_frame") gcc will produce:
4680b57cec5SDimitry Andric   //
4690b57cec5SDimitry Andric   //   .section   .eh_frame,"a",@progbits
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric   if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF,
4725ffd83dbSDimitry Andric                                       /*AddSegmentInfo=*/false) ||
4735ffd83dbSDimitry Andric       Name == getInstrProfSectionName(IPSK_covfun, Triple::ELF,
474e8d8bef9SDimitry Andric                                       /*AddSegmentInfo=*/false) ||
475e8d8bef9SDimitry Andric       Name == ".llvmbc" || Name == ".llvmcmd")
4760b57cec5SDimitry Andric     return SectionKind::getMetadata();
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric   if (Name.empty() || Name[0] != '.') return K;
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric   // Default implementation based on some magic section names.
4810b57cec5SDimitry Andric   if (Name == ".bss" ||
4820b57cec5SDimitry Andric       Name.startswith(".bss.") ||
4830b57cec5SDimitry Andric       Name.startswith(".gnu.linkonce.b.") ||
4840b57cec5SDimitry Andric       Name.startswith(".llvm.linkonce.b.") ||
4850b57cec5SDimitry Andric       Name == ".sbss" ||
4860b57cec5SDimitry Andric       Name.startswith(".sbss.") ||
4870b57cec5SDimitry Andric       Name.startswith(".gnu.linkonce.sb.") ||
4880b57cec5SDimitry Andric       Name.startswith(".llvm.linkonce.sb."))
4890b57cec5SDimitry Andric     return SectionKind::getBSS();
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric   if (Name == ".tdata" ||
4920b57cec5SDimitry Andric       Name.startswith(".tdata.") ||
4930b57cec5SDimitry Andric       Name.startswith(".gnu.linkonce.td.") ||
4940b57cec5SDimitry Andric       Name.startswith(".llvm.linkonce.td."))
4950b57cec5SDimitry Andric     return SectionKind::getThreadData();
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   if (Name == ".tbss" ||
4980b57cec5SDimitry Andric       Name.startswith(".tbss.") ||
4990b57cec5SDimitry Andric       Name.startswith(".gnu.linkonce.tb.") ||
5000b57cec5SDimitry Andric       Name.startswith(".llvm.linkonce.tb."))
5010b57cec5SDimitry Andric     return SectionKind::getThreadBSS();
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric   return K;
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric 
50604eeddc0SDimitry Andric static bool hasPrefix(StringRef SectionName, StringRef Prefix) {
50704eeddc0SDimitry Andric   return SectionName.consume_front(Prefix) &&
50804eeddc0SDimitry Andric          (SectionName.empty() || SectionName[0] == '.');
50904eeddc0SDimitry Andric }
51004eeddc0SDimitry Andric 
5110b57cec5SDimitry Andric static unsigned getELFSectionType(StringRef Name, SectionKind K) {
5120b57cec5SDimitry Andric   // Use SHT_NOTE for section whose name starts with ".note" to allow
5130b57cec5SDimitry Andric   // emitting ELF notes from C variable declaration.
5140b57cec5SDimitry Andric   // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609
5150b57cec5SDimitry Andric   if (Name.startswith(".note"))
5160b57cec5SDimitry Andric     return ELF::SHT_NOTE;
5170b57cec5SDimitry Andric 
51804eeddc0SDimitry Andric   if (hasPrefix(Name, ".init_array"))
5190b57cec5SDimitry Andric     return ELF::SHT_INIT_ARRAY;
5200b57cec5SDimitry Andric 
52104eeddc0SDimitry Andric   if (hasPrefix(Name, ".fini_array"))
5220b57cec5SDimitry Andric     return ELF::SHT_FINI_ARRAY;
5230b57cec5SDimitry Andric 
52404eeddc0SDimitry Andric   if (hasPrefix(Name, ".preinit_array"))
5250b57cec5SDimitry Andric     return ELF::SHT_PREINIT_ARRAY;
5260b57cec5SDimitry Andric 
527753f127fSDimitry Andric   if (hasPrefix(Name, ".llvm.offloading"))
528753f127fSDimitry Andric     return ELF::SHT_LLVM_OFFLOADING;
529753f127fSDimitry Andric 
5300b57cec5SDimitry Andric   if (K.isBSS() || K.isThreadBSS())
5310b57cec5SDimitry Andric     return ELF::SHT_NOBITS;
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   return ELF::SHT_PROGBITS;
5340b57cec5SDimitry Andric }
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) {
5370b57cec5SDimitry Andric   unsigned Flags = 0;
5380b57cec5SDimitry Andric 
53981ad6265SDimitry Andric   if (!K.isMetadata() && !K.isExclude())
5400b57cec5SDimitry Andric     Flags |= ELF::SHF_ALLOC;
5410b57cec5SDimitry Andric 
54281ad6265SDimitry Andric   if (K.isExclude())
54381ad6265SDimitry Andric     Flags |= ELF::SHF_EXCLUDE;
54481ad6265SDimitry Andric 
5450b57cec5SDimitry Andric   if (K.isText())
5460b57cec5SDimitry Andric     Flags |= ELF::SHF_EXECINSTR;
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric   if (K.isExecuteOnly())
5490b57cec5SDimitry Andric     Flags |= ELF::SHF_ARM_PURECODE;
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric   if (K.isWriteable())
5520b57cec5SDimitry Andric     Flags |= ELF::SHF_WRITE;
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric   if (K.isThreadLocal())
5550b57cec5SDimitry Andric     Flags |= ELF::SHF_TLS;
5560b57cec5SDimitry Andric 
5570b57cec5SDimitry Andric   if (K.isMergeableCString() || K.isMergeableConst())
5580b57cec5SDimitry Andric     Flags |= ELF::SHF_MERGE;
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric   if (K.isMergeableCString())
5610b57cec5SDimitry Andric     Flags |= ELF::SHF_STRINGS;
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric   return Flags;
5640b57cec5SDimitry Andric }
5650b57cec5SDimitry Andric 
5660b57cec5SDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) {
5670b57cec5SDimitry Andric   const Comdat *C = GV->getComdat();
5680b57cec5SDimitry Andric   if (!C)
5690b57cec5SDimitry Andric     return nullptr;
5700b57cec5SDimitry Andric 
571fe6060f1SDimitry Andric   if (C->getSelectionKind() != Comdat::Any &&
572fe6060f1SDimitry Andric       C->getSelectionKind() != Comdat::NoDeduplicate)
573fe6060f1SDimitry Andric     report_fatal_error("ELF COMDATs only support SelectionKind::Any and "
574fe6060f1SDimitry Andric                        "SelectionKind::NoDeduplicate, '" +
5750b57cec5SDimitry Andric                        C->getName() + "' cannot be lowered.");
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric   return C;
5780b57cec5SDimitry Andric }
5790b57cec5SDimitry Andric 
5805ffd83dbSDimitry Andric static const MCSymbolELF *getLinkedToSymbol(const GlobalObject *GO,
5810b57cec5SDimitry Andric                                             const TargetMachine &TM) {
5820b57cec5SDimitry Andric   MDNode *MD = GO->getMetadata(LLVMContext::MD_associated);
5830b57cec5SDimitry Andric   if (!MD)
5840b57cec5SDimitry Andric     return nullptr;
5850b57cec5SDimitry Andric 
586*fe013be4SDimitry Andric   auto *VM = cast<ValueAsMetadata>(MD->getOperand(0).get());
5878bcb0991SDimitry Andric   auto *OtherGV = dyn_cast<GlobalValue>(VM->getValue());
5888bcb0991SDimitry Andric   return OtherGV ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGV)) : nullptr;
5890b57cec5SDimitry Andric }
5900b57cec5SDimitry Andric 
5910b57cec5SDimitry Andric static unsigned getEntrySizeForKind(SectionKind Kind) {
5920b57cec5SDimitry Andric   if (Kind.isMergeable1ByteCString())
5930b57cec5SDimitry Andric     return 1;
5940b57cec5SDimitry Andric   else if (Kind.isMergeable2ByteCString())
5950b57cec5SDimitry Andric     return 2;
5960b57cec5SDimitry Andric   else if (Kind.isMergeable4ByteCString())
5970b57cec5SDimitry Andric     return 4;
5980b57cec5SDimitry Andric   else if (Kind.isMergeableConst4())
5990b57cec5SDimitry Andric     return 4;
6000b57cec5SDimitry Andric   else if (Kind.isMergeableConst8())
6010b57cec5SDimitry Andric     return 8;
6020b57cec5SDimitry Andric   else if (Kind.isMergeableConst16())
6030b57cec5SDimitry Andric     return 16;
6040b57cec5SDimitry Andric   else if (Kind.isMergeableConst32())
6050b57cec5SDimitry Andric     return 32;
6060b57cec5SDimitry Andric   else {
6070b57cec5SDimitry Andric     // We shouldn't have mergeable C strings or mergeable constants that we
6080b57cec5SDimitry Andric     // didn't handle above.
6090b57cec5SDimitry Andric     assert(!Kind.isMergeableCString() && "unknown string width");
6100b57cec5SDimitry Andric     assert(!Kind.isMergeableConst() && "unknown data width");
6110b57cec5SDimitry Andric     return 0;
6120b57cec5SDimitry Andric   }
6130b57cec5SDimitry Andric }
6140b57cec5SDimitry Andric 
6155ffd83dbSDimitry Andric /// Return the section prefix name used by options FunctionsSections and
6165ffd83dbSDimitry Andric /// DataSections.
617*fe013be4SDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind, bool IsLarge) {
6185ffd83dbSDimitry Andric   if (Kind.isText())
6195ffd83dbSDimitry Andric     return ".text";
6205ffd83dbSDimitry Andric   if (Kind.isReadOnly())
621*fe013be4SDimitry Andric     return IsLarge ? ".lrodata" : ".rodata";
6225ffd83dbSDimitry Andric   if (Kind.isBSS())
623*fe013be4SDimitry 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())
629*fe013be4SDimitry Andric     return IsLarge ? ".ldata" : ".data";
6305ffd83dbSDimitry Andric   if (Kind.isReadOnlyWithRel())
631*fe013be4SDimitry Andric     return IsLarge ? ".ldata.rel.ro" : ".data.rel.ro";
6325ffd83dbSDimitry Andric   llvm_unreachable("Unknown section kind");
6335ffd83dbSDimitry Andric }
6345ffd83dbSDimitry Andric 
6355ffd83dbSDimitry Andric static SmallString<128>
6365ffd83dbSDimitry Andric getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
6375ffd83dbSDimitry Andric                            Mangler &Mang, const TargetMachine &TM,
6385ffd83dbSDimitry Andric                            unsigned EntrySize, bool UniqueSectionName) {
6395ffd83dbSDimitry Andric   SmallString<128> Name;
6405ffd83dbSDimitry Andric   if (Kind.isMergeableCString()) {
6415ffd83dbSDimitry Andric     // We also need alignment here.
6425ffd83dbSDimitry Andric     // FIXME: this is getting the alignment of the character, not the
6435ffd83dbSDimitry Andric     // alignment of the global!
6445ffd83dbSDimitry Andric     Align Alignment = GO->getParent()->getDataLayout().getPreferredAlign(
6455ffd83dbSDimitry Andric         cast<GlobalVariable>(GO));
6465ffd83dbSDimitry Andric 
6475ffd83dbSDimitry Andric     std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + ".";
6485ffd83dbSDimitry Andric     Name = SizeSpec + utostr(Alignment.value());
6495ffd83dbSDimitry Andric   } else if (Kind.isMergeableConst()) {
6505ffd83dbSDimitry Andric     Name = ".rodata.cst";
6515ffd83dbSDimitry Andric     Name += utostr(EntrySize);
6525ffd83dbSDimitry Andric   } else {
653*fe013be4SDimitry Andric     bool IsLarge = false;
654*fe013be4SDimitry Andric     if (isa<GlobalVariable>(GO))
655*fe013be4SDimitry Andric       IsLarge = TM.isLargeData();
656*fe013be4SDimitry Andric     Name = getSectionPrefixForGlobal(Kind, IsLarge);
6575ffd83dbSDimitry Andric   }
6585ffd83dbSDimitry Andric 
6595ffd83dbSDimitry Andric   bool HasPrefix = false;
6605ffd83dbSDimitry Andric   if (const auto *F = dyn_cast<Function>(GO)) {
661bdd1243dSDimitry Andric     if (std::optional<StringRef> Prefix = F->getSectionPrefix()) {
662e8d8bef9SDimitry Andric       raw_svector_ostream(Name) << '.' << *Prefix;
6635ffd83dbSDimitry Andric       HasPrefix = true;
6645ffd83dbSDimitry Andric     }
6655ffd83dbSDimitry Andric   }
6665ffd83dbSDimitry Andric 
6675ffd83dbSDimitry Andric   if (UniqueSectionName) {
6685ffd83dbSDimitry Andric     Name.push_back('.');
6695ffd83dbSDimitry Andric     TM.getNameWithPrefix(Name, GO, Mang, /*MayAlwaysUsePrivate*/true);
6705ffd83dbSDimitry Andric   } else if (HasPrefix)
671fe6060f1SDimitry Andric     // For distinguishing between .text.${text-section-prefix}. (with trailing
672fe6060f1SDimitry Andric     // dot) and .text.${function-name}
6735ffd83dbSDimitry Andric     Name.push_back('.');
6745ffd83dbSDimitry Andric   return Name;
6755ffd83dbSDimitry Andric }
6765ffd83dbSDimitry Andric 
6775ffd83dbSDimitry Andric namespace {
6785ffd83dbSDimitry Andric class LoweringDiagnosticInfo : public DiagnosticInfo {
6795ffd83dbSDimitry Andric   const Twine &Msg;
6805ffd83dbSDimitry Andric 
6815ffd83dbSDimitry Andric public:
6825ffd83dbSDimitry Andric   LoweringDiagnosticInfo(const Twine &DiagMsg,
6835ffd83dbSDimitry Andric                          DiagnosticSeverity Severity = DS_Error)
6845ffd83dbSDimitry Andric       : DiagnosticInfo(DK_Lowering, Severity), Msg(DiagMsg) {}
6855ffd83dbSDimitry Andric   void print(DiagnosticPrinter &DP) const override { DP << Msg; }
6865ffd83dbSDimitry Andric };
6875ffd83dbSDimitry Andric }
6885ffd83dbSDimitry Andric 
689fe6060f1SDimitry Andric /// Calculate an appropriate unique ID for a section, and update Flags,
690fe6060f1SDimitry Andric /// EntrySize and NextUniqueID where appropriate.
691fe6060f1SDimitry Andric static unsigned
692fe6060f1SDimitry Andric calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName,
693fe6060f1SDimitry Andric                                SectionKind Kind, const TargetMachine &TM,
694fe6060f1SDimitry Andric                                MCContext &Ctx, Mangler &Mang, unsigned &Flags,
695fe6060f1SDimitry Andric                                unsigned &EntrySize, unsigned &NextUniqueID,
696fe6060f1SDimitry Andric                                const bool Retain, const bool ForceUnique) {
697fe6060f1SDimitry Andric   // Increment uniqueID if we are forced to emit a unique section.
698fe6060f1SDimitry Andric   // This works perfectly fine with section attribute or pragma section as the
699fe6060f1SDimitry Andric   // sections with the same name are grouped together by the assembler.
700fe6060f1SDimitry Andric   if (ForceUnique)
701fe6060f1SDimitry Andric     return NextUniqueID++;
702fe6060f1SDimitry Andric 
703fe6060f1SDimitry Andric   // A section can have at most one associated section. Put each global with
704fe6060f1SDimitry Andric   // MD_associated in a unique section.
705fe6060f1SDimitry Andric   const bool Associated = GO->getMetadata(LLVMContext::MD_associated);
706fe6060f1SDimitry Andric   if (Associated) {
707fe6060f1SDimitry Andric     Flags |= ELF::SHF_LINK_ORDER;
708fe6060f1SDimitry Andric     return NextUniqueID++;
709fe6060f1SDimitry Andric   }
710fe6060f1SDimitry Andric 
711fe6060f1SDimitry Andric   if (Retain) {
71281ad6265SDimitry Andric     if (TM.getTargetTriple().isOSSolaris())
71381ad6265SDimitry Andric       Flags |= ELF::SHF_SUNW_NODISCARD;
71481ad6265SDimitry Andric     else if (Ctx.getAsmInfo()->useIntegratedAssembler() ||
71581ad6265SDimitry Andric              Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36))
716fe6060f1SDimitry Andric       Flags |= ELF::SHF_GNU_RETAIN;
717fe6060f1SDimitry Andric     return NextUniqueID++;
718fe6060f1SDimitry Andric   }
719fe6060f1SDimitry Andric 
720fe6060f1SDimitry Andric   // If two symbols with differing sizes end up in the same mergeable section
721fe6060f1SDimitry Andric   // that section can be assigned an incorrect entry size. To avoid this we
722fe6060f1SDimitry Andric   // usually put symbols of the same size into distinct mergeable sections with
723fe6060f1SDimitry Andric   // the same name. Doing so relies on the ",unique ," assembly feature. This
724fe6060f1SDimitry Andric   // feature is not avalible until bintuils version 2.35
725fe6060f1SDimitry Andric   // (https://sourceware.org/bugzilla/show_bug.cgi?id=25380).
726fe6060f1SDimitry Andric   const bool SupportsUnique = Ctx.getAsmInfo()->useIntegratedAssembler() ||
727fe6060f1SDimitry Andric                               Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35);
728fe6060f1SDimitry Andric   if (!SupportsUnique) {
729fe6060f1SDimitry Andric     Flags &= ~ELF::SHF_MERGE;
730fe6060f1SDimitry Andric     EntrySize = 0;
731fe6060f1SDimitry Andric     return MCContext::GenericSectionID;
732fe6060f1SDimitry Andric   }
733fe6060f1SDimitry Andric 
734fe6060f1SDimitry Andric   const bool SymbolMergeable = Flags & ELF::SHF_MERGE;
735fe6060f1SDimitry Andric   const bool SeenSectionNameBefore =
736fe6060f1SDimitry Andric       Ctx.isELFGenericMergeableSection(SectionName);
737fe6060f1SDimitry Andric   // If this is the first ocurrence of this section name, treat it as the
738fe6060f1SDimitry Andric   // generic section
739fe6060f1SDimitry Andric   if (!SymbolMergeable && !SeenSectionNameBefore)
740fe6060f1SDimitry Andric     return MCContext::GenericSectionID;
741fe6060f1SDimitry Andric 
742fe6060f1SDimitry Andric   // Symbols must be placed into sections with compatible entry sizes. Generate
743fe6060f1SDimitry Andric   // unique sections for symbols that have not been assigned to compatible
744fe6060f1SDimitry Andric   // sections.
745fe6060f1SDimitry Andric   const auto PreviousID =
746fe6060f1SDimitry Andric       Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize);
747fe6060f1SDimitry Andric   if (PreviousID)
748fe6060f1SDimitry Andric     return *PreviousID;
749fe6060f1SDimitry Andric 
750fe6060f1SDimitry Andric   // If the user has specified the same section name as would be created
751fe6060f1SDimitry Andric   // implicitly for this symbol e.g. .rodata.str1.1, then we don't need
752fe6060f1SDimitry Andric   // to unique the section as the entry size for this symbol will be
753fe6060f1SDimitry Andric   // compatible with implicitly created sections.
754fe6060f1SDimitry Andric   SmallString<128> ImplicitSectionNameStem =
755fe6060f1SDimitry Andric       getELFSectionNameForGlobal(GO, Kind, Mang, TM, EntrySize, false);
756fe6060f1SDimitry Andric   if (SymbolMergeable &&
757fe6060f1SDimitry Andric       Ctx.isELFImplicitMergeableSectionNamePrefix(SectionName) &&
758fe6060f1SDimitry Andric       SectionName.startswith(ImplicitSectionNameStem))
759fe6060f1SDimitry Andric     return MCContext::GenericSectionID;
760fe6060f1SDimitry Andric 
761fe6060f1SDimitry Andric   // We have seen this section name before, but with different flags or entity
762fe6060f1SDimitry Andric   // size. Create a new unique ID.
763fe6060f1SDimitry Andric   return NextUniqueID++;
764fe6060f1SDimitry Andric }
765fe6060f1SDimitry Andric 
766fe6060f1SDimitry Andric static MCSection *selectExplicitSectionGlobal(
767fe6060f1SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM,
768fe6060f1SDimitry Andric     MCContext &Ctx, Mangler &Mang, unsigned &NextUniqueID,
769fe6060f1SDimitry Andric     bool Retain, bool ForceUnique) {
7700b57cec5SDimitry Andric   StringRef SectionName = GO->getSection();
7710b57cec5SDimitry Andric 
7720b57cec5SDimitry Andric   // Check if '#pragma clang section' name is applicable.
7730b57cec5SDimitry Andric   // Note that pragma directive overrides -ffunction-section, -fdata-section
7740b57cec5SDimitry Andric   // and so section name is exactly as user specified and not uniqued.
7750b57cec5SDimitry Andric   const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO);
7760b57cec5SDimitry Andric   if (GV && GV->hasImplicitSection()) {
7770b57cec5SDimitry Andric     auto Attrs = GV->getAttributes();
7780b57cec5SDimitry Andric     if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) {
7790b57cec5SDimitry Andric       SectionName = Attrs.getAttribute("bss-section").getValueAsString();
7800b57cec5SDimitry Andric     } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
7810b57cec5SDimitry Andric       SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
7828bcb0991SDimitry Andric     } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) {
7838bcb0991SDimitry Andric       SectionName = Attrs.getAttribute("relro-section").getValueAsString();
7840b57cec5SDimitry Andric     } else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
7850b57cec5SDimitry Andric       SectionName = Attrs.getAttribute("data-section").getValueAsString();
7860b57cec5SDimitry Andric     }
7870b57cec5SDimitry Andric   }
7880b57cec5SDimitry Andric   const Function *F = dyn_cast<Function>(GO);
7890b57cec5SDimitry Andric   if (F && F->hasFnAttribute("implicit-section-name")) {
7900b57cec5SDimitry Andric     SectionName = F->getFnAttribute("implicit-section-name").getValueAsString();
7910b57cec5SDimitry Andric   }
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric   // Infer section flags from the section name if we can.
7940b57cec5SDimitry Andric   Kind = getELFKindForNamedSection(SectionName, Kind);
7950b57cec5SDimitry Andric 
7960b57cec5SDimitry Andric   StringRef Group = "";
797fe6060f1SDimitry Andric   bool IsComdat = false;
7980b57cec5SDimitry Andric   unsigned Flags = getELFSectionFlags(Kind);
7990b57cec5SDimitry Andric   if (const Comdat *C = getELFComdat(GO)) {
8000b57cec5SDimitry Andric     Group = C->getName();
801fe6060f1SDimitry Andric     IsComdat = C->getSelectionKind() == Comdat::Any;
8020b57cec5SDimitry Andric     Flags |= ELF::SHF_GROUP;
8030b57cec5SDimitry Andric   }
8040b57cec5SDimitry Andric 
8055ffd83dbSDimitry Andric   unsigned EntrySize = getEntrySizeForKind(Kind);
806fe6060f1SDimitry Andric   const unsigned UniqueID = calcUniqueIDUpdateFlagsAndSize(
807fe6060f1SDimitry Andric       GO, SectionName, Kind, TM, Ctx, Mang, Flags, EntrySize, NextUniqueID,
808fe6060f1SDimitry Andric       Retain, ForceUnique);
8095ffd83dbSDimitry Andric 
8105ffd83dbSDimitry Andric   const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
811fe6060f1SDimitry Andric   MCSectionELF *Section = Ctx.getELFSection(
812fe6060f1SDimitry Andric       SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize,
813fe6060f1SDimitry Andric       Group, IsComdat, UniqueID, LinkedToSym);
8140b57cec5SDimitry Andric   // Make sure that we did not get some other section with incompatible sh_link.
8150b57cec5SDimitry Andric   // This should not be possible due to UniqueID code above.
8165ffd83dbSDimitry Andric   assert(Section->getLinkedToSymbol() == LinkedToSym &&
8170b57cec5SDimitry Andric          "Associated symbol mismatch between sections");
8185ffd83dbSDimitry Andric 
819fe6060f1SDimitry Andric   if (!(Ctx.getAsmInfo()->useIntegratedAssembler() ||
820fe6060f1SDimitry Andric         Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35))) {
821e8d8bef9SDimitry Andric     // If we are using GNU as before 2.35, then this symbol might have
8225ffd83dbSDimitry Andric     // been placed in an incompatible mergeable section. Emit an error if this
8235ffd83dbSDimitry Andric     // is the case to avoid creating broken output.
8245ffd83dbSDimitry Andric     if ((Section->getFlags() & ELF::SHF_MERGE) &&
8255ffd83dbSDimitry Andric         (Section->getEntrySize() != getEntrySizeForKind(Kind)))
8265ffd83dbSDimitry Andric       GO->getContext().diagnose(LoweringDiagnosticInfo(
8275ffd83dbSDimitry Andric           "Symbol '" + GO->getName() + "' from module '" +
8285ffd83dbSDimitry Andric           (GO->getParent() ? GO->getParent()->getSourceFileName() : "unknown") +
8295ffd83dbSDimitry Andric           "' required a section with entry-size=" +
8305ffd83dbSDimitry Andric           Twine(getEntrySizeForKind(Kind)) + " but was placed in section '" +
8315ffd83dbSDimitry Andric           SectionName + "' with entry-size=" + Twine(Section->getEntrySize()) +
8325ffd83dbSDimitry Andric           ": Explicit assignment by pragma or attribute of an incompatible "
8335ffd83dbSDimitry Andric           "symbol to this section?"));
8340b57cec5SDimitry Andric   }
8350b57cec5SDimitry Andric 
8365ffd83dbSDimitry Andric   return Section;
8370b57cec5SDimitry Andric }
8380b57cec5SDimitry Andric 
839fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
840fe6060f1SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
841fe6060f1SDimitry Andric   return selectExplicitSectionGlobal(GO, Kind, TM, getContext(), getMangler(),
842fe6060f1SDimitry Andric                                      NextUniqueID, Used.count(GO),
843fe6060f1SDimitry Andric                                      /* ForceUnique = */false);
844fe6060f1SDimitry Andric }
845fe6060f1SDimitry Andric 
8460b57cec5SDimitry Andric static MCSectionELF *selectELFSectionForGlobal(
8470b57cec5SDimitry Andric     MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
8480b57cec5SDimitry Andric     const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags,
8490b57cec5SDimitry Andric     unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) {
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric   StringRef Group = "";
852fe6060f1SDimitry Andric   bool IsComdat = false;
8530b57cec5SDimitry Andric   if (const Comdat *C = getELFComdat(GO)) {
8540b57cec5SDimitry Andric     Flags |= ELF::SHF_GROUP;
8550b57cec5SDimitry Andric     Group = C->getName();
856fe6060f1SDimitry Andric     IsComdat = C->getSelectionKind() == Comdat::Any;
8570b57cec5SDimitry Andric   }
858*fe013be4SDimitry Andric   if (isa<GlobalVariable>(GO)) {
859*fe013be4SDimitry Andric     if (TM.isLargeData()) {
860*fe013be4SDimitry Andric       assert(TM.getTargetTriple().getArch() == Triple::x86_64);
861*fe013be4SDimitry Andric       Flags |= ELF::SHF_X86_64_LARGE;
862*fe013be4SDimitry Andric     }
863*fe013be4SDimitry Andric   }
8640b57cec5SDimitry Andric 
8650b57cec5SDimitry Andric   // Get the section entry size based on the kind.
8660b57cec5SDimitry Andric   unsigned EntrySize = getEntrySizeForKind(Kind);
8670b57cec5SDimitry Andric 
8685ffd83dbSDimitry Andric   bool UniqueSectionName = false;
8690b57cec5SDimitry Andric   unsigned UniqueID = MCContext::GenericSectionID;
8700b57cec5SDimitry Andric   if (EmitUniqueSection) {
8710b57cec5SDimitry Andric     if (TM.getUniqueSectionNames()) {
8725ffd83dbSDimitry Andric       UniqueSectionName = true;
8730b57cec5SDimitry Andric     } else {
8740b57cec5SDimitry Andric       UniqueID = *NextUniqueID;
8750b57cec5SDimitry Andric       (*NextUniqueID)++;
8760b57cec5SDimitry Andric     }
8770b57cec5SDimitry Andric   }
8785ffd83dbSDimitry Andric   SmallString<128> Name = getELFSectionNameForGlobal(
8795ffd83dbSDimitry Andric       GO, Kind, Mang, TM, EntrySize, UniqueSectionName);
8805ffd83dbSDimitry Andric 
8810b57cec5SDimitry Andric   // Use 0 as the unique ID for execute-only text.
8820b57cec5SDimitry Andric   if (Kind.isExecuteOnly())
8830b57cec5SDimitry Andric     UniqueID = 0;
8840b57cec5SDimitry Andric   return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
885fe6060f1SDimitry Andric                            EntrySize, Group, IsComdat, UniqueID,
886fe6060f1SDimitry Andric                            AssociatedSymbol);
887fe6060f1SDimitry Andric }
888fe6060f1SDimitry Andric 
889fe6060f1SDimitry Andric static MCSection *selectELFSectionForGlobal(
890fe6060f1SDimitry Andric     MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
891fe6060f1SDimitry Andric     const TargetMachine &TM, bool Retain, bool EmitUniqueSection,
892fe6060f1SDimitry Andric     unsigned Flags, unsigned *NextUniqueID) {
893fe6060f1SDimitry Andric   const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
894fe6060f1SDimitry Andric   if (LinkedToSym) {
895fe6060f1SDimitry Andric     EmitUniqueSection = true;
896fe6060f1SDimitry Andric     Flags |= ELF::SHF_LINK_ORDER;
897fe6060f1SDimitry Andric   }
89881ad6265SDimitry Andric   if (Retain) {
89981ad6265SDimitry Andric     if (TM.getTargetTriple().isOSSolaris()) {
90081ad6265SDimitry Andric       EmitUniqueSection = true;
90181ad6265SDimitry Andric       Flags |= ELF::SHF_SUNW_NODISCARD;
90281ad6265SDimitry Andric     } else if (Ctx.getAsmInfo()->useIntegratedAssembler() ||
90381ad6265SDimitry Andric                Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) {
904fe6060f1SDimitry Andric       EmitUniqueSection = true;
905fe6060f1SDimitry Andric       Flags |= ELF::SHF_GNU_RETAIN;
906fe6060f1SDimitry Andric     }
90781ad6265SDimitry Andric   }
908fe6060f1SDimitry Andric 
909fe6060f1SDimitry Andric   MCSectionELF *Section = selectELFSectionForGlobal(
910fe6060f1SDimitry Andric       Ctx, GO, Kind, Mang, TM, EmitUniqueSection, Flags,
911fe6060f1SDimitry Andric       NextUniqueID, LinkedToSym);
912fe6060f1SDimitry Andric   assert(Section->getLinkedToSymbol() == LinkedToSym);
913fe6060f1SDimitry Andric   return Section;
9140b57cec5SDimitry Andric }
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
9170b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
9180b57cec5SDimitry Andric   unsigned Flags = getELFSectionFlags(Kind);
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric   // If we have -ffunction-section or -fdata-section then we should emit the
9210b57cec5SDimitry Andric   // global value to a uniqued section specifically for it.
9220b57cec5SDimitry Andric   bool EmitUniqueSection = false;
9230b57cec5SDimitry Andric   if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) {
9240b57cec5SDimitry Andric     if (Kind.isText())
9250b57cec5SDimitry Andric       EmitUniqueSection = TM.getFunctionSections();
9260b57cec5SDimitry Andric     else
9270b57cec5SDimitry Andric       EmitUniqueSection = TM.getDataSections();
9280b57cec5SDimitry Andric   }
9290b57cec5SDimitry Andric   EmitUniqueSection |= GO->hasComdat();
930fe6060f1SDimitry Andric   return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
931fe6060f1SDimitry Andric                                    Used.count(GO), EmitUniqueSection, Flags,
932fe6060f1SDimitry Andric                                    &NextUniqueID);
9330b57cec5SDimitry Andric }
9340b57cec5SDimitry Andric 
935fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction(
936fe6060f1SDimitry Andric     const Function &F, const TargetMachine &TM) const {
937fe6060f1SDimitry Andric   SectionKind Kind = SectionKind::getText();
938fe6060f1SDimitry Andric   unsigned Flags = getELFSectionFlags(Kind);
939fe6060f1SDimitry Andric   // If the function's section names is pre-determined via pragma or a
940fe6060f1SDimitry Andric   // section attribute, call selectExplicitSectionGlobal.
941fe6060f1SDimitry Andric   if (F.hasSection() || F.hasFnAttribute("implicit-section-name"))
942fe6060f1SDimitry Andric     return selectExplicitSectionGlobal(
943fe6060f1SDimitry Andric         &F, Kind, TM, getContext(), getMangler(), NextUniqueID,
944fe6060f1SDimitry Andric         Used.count(&F), /* ForceUnique = */true);
945fe6060f1SDimitry Andric   else
946fe6060f1SDimitry Andric     return selectELFSectionForGlobal(
947fe6060f1SDimitry Andric         getContext(), &F, Kind, getMangler(), TM, Used.count(&F),
948fe6060f1SDimitry Andric         /*EmitUniqueSection=*/true, Flags, &NextUniqueID);
9490b57cec5SDimitry Andric }
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
9520b57cec5SDimitry Andric     const Function &F, const TargetMachine &TM) const {
9530b57cec5SDimitry Andric   // If the function can be removed, produce a unique section so that
9540b57cec5SDimitry Andric   // the table doesn't prevent the removal.
9550b57cec5SDimitry Andric   const Comdat *C = F.getComdat();
9560b57cec5SDimitry Andric   bool EmitUniqueSection = TM.getFunctionSections() || C;
9570b57cec5SDimitry Andric   if (!EmitUniqueSection)
9580b57cec5SDimitry Andric     return ReadOnlySection;
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric   return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(),
9610b57cec5SDimitry Andric                                    getMangler(), TM, EmitUniqueSection,
9620b57cec5SDimitry Andric                                    ELF::SHF_ALLOC, &NextUniqueID,
9630b57cec5SDimitry Andric                                    /* AssociatedSymbol */ nullptr);
9640b57cec5SDimitry Andric }
9650b57cec5SDimitry Andric 
966fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(
967fe6060f1SDimitry Andric     const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {
968e8d8bef9SDimitry Andric   // If neither COMDAT nor function sections, use the monolithic LSDA section.
969e8d8bef9SDimitry Andric   // Re-use this path if LSDASection is null as in the Arm EHABI.
970e8d8bef9SDimitry Andric   if (!LSDASection || (!F.hasComdat() && !TM.getFunctionSections()))
971e8d8bef9SDimitry Andric     return LSDASection;
972e8d8bef9SDimitry Andric 
973e8d8bef9SDimitry Andric   const auto *LSDA = cast<MCSectionELF>(LSDASection);
974e8d8bef9SDimitry Andric   unsigned Flags = LSDA->getFlags();
975fe6060f1SDimitry Andric   const MCSymbolELF *LinkedToSym = nullptr;
976e8d8bef9SDimitry Andric   StringRef Group;
977fe6060f1SDimitry Andric   bool IsComdat = false;
978fe6060f1SDimitry Andric   if (const Comdat *C = getELFComdat(&F)) {
979e8d8bef9SDimitry Andric     Flags |= ELF::SHF_GROUP;
980fe6060f1SDimitry Andric     Group = C->getName();
981fe6060f1SDimitry Andric     IsComdat = C->getSelectionKind() == Comdat::Any;
982fe6060f1SDimitry Andric   }
983fe6060f1SDimitry Andric   // Use SHF_LINK_ORDER to facilitate --gc-sections if we can use GNU ld>=2.36
984fe6060f1SDimitry Andric   // or LLD, which support mixed SHF_LINK_ORDER & non-SHF_LINK_ORDER.
985fe6060f1SDimitry Andric   if (TM.getFunctionSections() &&
986fe6060f1SDimitry Andric       (getContext().getAsmInfo()->useIntegratedAssembler() &&
987fe6060f1SDimitry Andric        getContext().getAsmInfo()->binutilsIsAtLeast(2, 36))) {
988fe6060f1SDimitry Andric     Flags |= ELF::SHF_LINK_ORDER;
989fe6060f1SDimitry Andric     LinkedToSym = cast<MCSymbolELF>(&FnSym);
990e8d8bef9SDimitry Andric   }
991e8d8bef9SDimitry Andric 
992e8d8bef9SDimitry Andric   // Append the function name as the suffix like GCC, assuming
993e8d8bef9SDimitry Andric   // -funique-section-names applies to .gcc_except_table sections.
994fe6060f1SDimitry Andric   return getContext().getELFSection(
995fe6060f1SDimitry Andric       (TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName()
996fe6060f1SDimitry Andric                                   : LSDA->getName()),
997fe6060f1SDimitry Andric       LSDA->getType(), Flags, 0, Group, IsComdat, MCSection::NonUniqueID,
998fe6060f1SDimitry Andric       LinkedToSym);
999e8d8bef9SDimitry Andric }
1000e8d8bef9SDimitry Andric 
10010b57cec5SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
10020b57cec5SDimitry Andric     bool UsesLabelDifference, const Function &F) const {
10030b57cec5SDimitry Andric   // We can always create relative relocations, so use another section
10040b57cec5SDimitry Andric   // that can be marked non-executable.
10050b57cec5SDimitry Andric   return false;
10060b57cec5SDimitry Andric }
10070b57cec5SDimitry Andric 
10080b57cec5SDimitry Andric /// Given a mergeable constant with the specified size and relocation
10090b57cec5SDimitry Andric /// information, return a section that it should be placed in.
10100b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant(
10110b57cec5SDimitry Andric     const DataLayout &DL, SectionKind Kind, const Constant *C,
10125ffd83dbSDimitry Andric     Align &Alignment) const {
10130b57cec5SDimitry Andric   if (Kind.isMergeableConst4() && MergeableConst4Section)
10140b57cec5SDimitry Andric     return MergeableConst4Section;
10150b57cec5SDimitry Andric   if (Kind.isMergeableConst8() && MergeableConst8Section)
10160b57cec5SDimitry Andric     return MergeableConst8Section;
10170b57cec5SDimitry Andric   if (Kind.isMergeableConst16() && MergeableConst16Section)
10180b57cec5SDimitry Andric     return MergeableConst16Section;
10190b57cec5SDimitry Andric   if (Kind.isMergeableConst32() && MergeableConst32Section)
10200b57cec5SDimitry Andric     return MergeableConst32Section;
10210b57cec5SDimitry Andric   if (Kind.isReadOnly())
10220b57cec5SDimitry Andric     return ReadOnlySection;
10230b57cec5SDimitry Andric 
10240b57cec5SDimitry Andric   assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
10250b57cec5SDimitry Andric   return DataRelROSection;
10260b57cec5SDimitry Andric }
10270b57cec5SDimitry Andric 
10285ffd83dbSDimitry Andric /// Returns a unique section for the given machine basic block.
10295ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
10305ffd83dbSDimitry Andric     const Function &F, const MachineBasicBlock &MBB,
10315ffd83dbSDimitry Andric     const TargetMachine &TM) const {
10325ffd83dbSDimitry Andric   assert(MBB.isBeginSection() && "Basic block does not start a section!");
10335ffd83dbSDimitry Andric   unsigned UniqueID = MCContext::GenericSectionID;
10345ffd83dbSDimitry Andric 
1035e8d8bef9SDimitry Andric   // For cold sections use the .text.split. prefix along with the parent
10365ffd83dbSDimitry Andric   // function name. All cold blocks for the same function go to the same
10375ffd83dbSDimitry Andric   // section. Similarly all exception blocks are grouped by symbol name
10385ffd83dbSDimitry Andric   // under the .text.eh prefix. For regular sections, we either use a unique
10395ffd83dbSDimitry Andric   // name, or a unique ID for the section.
10405ffd83dbSDimitry Andric   SmallString<128> Name;
10415ffd83dbSDimitry Andric   if (MBB.getSectionID() == MBBSectionID::ColdSectionID) {
1042e8d8bef9SDimitry Andric     Name += BBSectionsColdTextPrefix;
10435ffd83dbSDimitry Andric     Name += MBB.getParent()->getName();
10445ffd83dbSDimitry Andric   } else if (MBB.getSectionID() == MBBSectionID::ExceptionSectionID) {
10455ffd83dbSDimitry Andric     Name += ".text.eh.";
10465ffd83dbSDimitry Andric     Name += MBB.getParent()->getName();
10475ffd83dbSDimitry Andric   } else {
10485ffd83dbSDimitry Andric     Name += MBB.getParent()->getSection()->getName();
10495ffd83dbSDimitry Andric     if (TM.getUniqueBasicBlockSectionNames()) {
1050fe6060f1SDimitry Andric       if (!Name.endswith("."))
10515ffd83dbSDimitry Andric         Name += ".";
10525ffd83dbSDimitry Andric       Name += MBB.getSymbol()->getName();
10535ffd83dbSDimitry Andric     } else {
10545ffd83dbSDimitry Andric       UniqueID = NextUniqueID++;
10555ffd83dbSDimitry Andric     }
10565ffd83dbSDimitry Andric   }
10575ffd83dbSDimitry Andric 
10585ffd83dbSDimitry Andric   unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
1059e8d8bef9SDimitry Andric   std::string GroupName;
10605ffd83dbSDimitry Andric   if (F.hasComdat()) {
10615ffd83dbSDimitry Andric     Flags |= ELF::SHF_GROUP;
10625ffd83dbSDimitry Andric     GroupName = F.getComdat()->getName().str();
10635ffd83dbSDimitry Andric   }
10645ffd83dbSDimitry Andric   return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags,
1065fe6060f1SDimitry Andric                                     0 /* Entry Size */, GroupName,
1066fe6060f1SDimitry Andric                                     F.hasComdat(), UniqueID, nullptr);
10675ffd83dbSDimitry Andric }
10685ffd83dbSDimitry Andric 
10690b57cec5SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
10700b57cec5SDimitry Andric                                               bool IsCtor, unsigned Priority,
10710b57cec5SDimitry Andric                                               const MCSymbol *KeySym) {
10720b57cec5SDimitry Andric   std::string Name;
10730b57cec5SDimitry Andric   unsigned Type;
10740b57cec5SDimitry Andric   unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE;
1075fe6060f1SDimitry Andric   StringRef Comdat = KeySym ? KeySym->getName() : "";
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric   if (KeySym)
10780b57cec5SDimitry Andric     Flags |= ELF::SHF_GROUP;
10790b57cec5SDimitry Andric 
10800b57cec5SDimitry Andric   if (UseInitArray) {
10810b57cec5SDimitry Andric     if (IsCtor) {
10820b57cec5SDimitry Andric       Type = ELF::SHT_INIT_ARRAY;
10830b57cec5SDimitry Andric       Name = ".init_array";
10840b57cec5SDimitry Andric     } else {
10850b57cec5SDimitry Andric       Type = ELF::SHT_FINI_ARRAY;
10860b57cec5SDimitry Andric       Name = ".fini_array";
10870b57cec5SDimitry Andric     }
10880b57cec5SDimitry Andric     if (Priority != 65535) {
10890b57cec5SDimitry Andric       Name += '.';
10900b57cec5SDimitry Andric       Name += utostr(Priority);
10910b57cec5SDimitry Andric     }
10920b57cec5SDimitry Andric   } else {
10930b57cec5SDimitry Andric     // The default scheme is .ctor / .dtor, so we have to invert the priority
10940b57cec5SDimitry Andric     // numbering.
10950b57cec5SDimitry Andric     if (IsCtor)
10960b57cec5SDimitry Andric       Name = ".ctors";
10970b57cec5SDimitry Andric     else
10980b57cec5SDimitry Andric       Name = ".dtors";
10990b57cec5SDimitry Andric     if (Priority != 65535)
11000b57cec5SDimitry Andric       raw_string_ostream(Name) << format(".%05u", 65535 - Priority);
11010b57cec5SDimitry Andric     Type = ELF::SHT_PROGBITS;
11020b57cec5SDimitry Andric   }
11030b57cec5SDimitry Andric 
1104fe6060f1SDimitry Andric   return Ctx.getELFSection(Name, Type, Flags, 0, Comdat, /*IsComdat=*/true);
11050b57cec5SDimitry Andric }
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection(
11080b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
11090b57cec5SDimitry Andric   return getStaticStructorSection(getContext(), UseInitArray, true, Priority,
11100b57cec5SDimitry Andric                                   KeySym);
11110b57cec5SDimitry Andric }
11120b57cec5SDimitry Andric 
11130b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection(
11140b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
11150b57cec5SDimitry Andric   return getStaticStructorSection(getContext(), UseInitArray, false, Priority,
11160b57cec5SDimitry Andric                                   KeySym);
11170b57cec5SDimitry Andric }
11180b57cec5SDimitry Andric 
11190b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
11200b57cec5SDimitry Andric     const GlobalValue *LHS, const GlobalValue *RHS,
11210b57cec5SDimitry Andric     const TargetMachine &TM) const {
11220b57cec5SDimitry Andric   // We may only use a PLT-relative relocation to refer to unnamed_addr
11230b57cec5SDimitry Andric   // functions.
11240b57cec5SDimitry Andric   if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
11250b57cec5SDimitry Andric     return nullptr;
11260b57cec5SDimitry Andric 
11274824e7fdSDimitry Andric   // Basic correctness checks.
11280b57cec5SDimitry Andric   if (LHS->getType()->getPointerAddressSpace() != 0 ||
11290b57cec5SDimitry Andric       RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() ||
11300b57cec5SDimitry Andric       RHS->isThreadLocal())
11310b57cec5SDimitry Andric     return nullptr;
11320b57cec5SDimitry Andric 
11330b57cec5SDimitry Andric   return MCBinaryExpr::createSub(
11340b57cec5SDimitry Andric       MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind,
11350b57cec5SDimitry Andric                               getContext()),
11360b57cec5SDimitry Andric       MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
11370b57cec5SDimitry Andric }
11380b57cec5SDimitry Andric 
1139e8d8bef9SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent(
1140e8d8bef9SDimitry Andric     const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const {
1141e8d8bef9SDimitry Andric   assert(supportDSOLocalEquivalentLowering());
1142e8d8bef9SDimitry Andric 
1143e8d8bef9SDimitry Andric   const auto *GV = Equiv->getGlobalValue();
1144e8d8bef9SDimitry Andric 
1145e8d8bef9SDimitry Andric   // A PLT entry is not needed for dso_local globals.
1146e8d8bef9SDimitry Andric   if (GV->isDSOLocal() || GV->isImplicitDSOLocal())
1147e8d8bef9SDimitry Andric     return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext());
1148e8d8bef9SDimitry Andric 
1149e8d8bef9SDimitry Andric   return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeVariantKind,
1150e8d8bef9SDimitry Andric                                  getContext());
1151e8d8bef9SDimitry Andric }
1152e8d8bef9SDimitry Andric 
11530b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
11540b57cec5SDimitry Andric   // Use ".GCC.command.line" since this feature is to support clang's
11550b57cec5SDimitry Andric   // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the
11560b57cec5SDimitry Andric   // same name.
11570b57cec5SDimitry Andric   return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS,
1158fe6060f1SDimitry Andric                                     ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
11590b57cec5SDimitry Andric }
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric void
11620b57cec5SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) {
11630b57cec5SDimitry Andric   UseInitArray = UseInitArray_;
11640b57cec5SDimitry Andric   MCContext &Ctx = getContext();
11650b57cec5SDimitry Andric   if (!UseInitArray) {
11660b57cec5SDimitry Andric     StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS,
11670b57cec5SDimitry Andric                                           ELF::SHF_ALLOC | ELF::SHF_WRITE);
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric     StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS,
11700b57cec5SDimitry Andric                                           ELF::SHF_ALLOC | ELF::SHF_WRITE);
11710b57cec5SDimitry Andric     return;
11720b57cec5SDimitry Andric   }
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric   StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY,
11750b57cec5SDimitry Andric                                         ELF::SHF_WRITE | ELF::SHF_ALLOC);
11760b57cec5SDimitry Andric   StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY,
11770b57cec5SDimitry Andric                                         ELF::SHF_WRITE | ELF::SHF_ALLOC);
11780b57cec5SDimitry Andric }
11790b57cec5SDimitry Andric 
11800b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11810b57cec5SDimitry Andric //                                 MachO
11820b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11830b57cec5SDimitry Andric 
118404eeddc0SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() {
11850b57cec5SDimitry Andric   SupportIndirectSymViaGOTPCRel = true;
11860b57cec5SDimitry Andric }
11870b57cec5SDimitry Andric 
11880b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
11890b57cec5SDimitry Andric                                                const TargetMachine &TM) {
11900b57cec5SDimitry Andric   TargetLoweringObjectFile::Initialize(Ctx, TM);
11910b57cec5SDimitry Andric   if (TM.getRelocationModel() == Reloc::Static) {
11920b57cec5SDimitry Andric     StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0,
11930b57cec5SDimitry Andric                                             SectionKind::getData());
11940b57cec5SDimitry Andric     StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0,
11950b57cec5SDimitry Andric                                             SectionKind::getData());
11960b57cec5SDimitry Andric   } else {
11970b57cec5SDimitry Andric     StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func",
11980b57cec5SDimitry Andric                                             MachO::S_MOD_INIT_FUNC_POINTERS,
11990b57cec5SDimitry Andric                                             SectionKind::getData());
12000b57cec5SDimitry Andric     StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func",
12010b57cec5SDimitry Andric                                             MachO::S_MOD_TERM_FUNC_POINTERS,
12020b57cec5SDimitry Andric                                             SectionKind::getData());
12030b57cec5SDimitry Andric   }
12040b57cec5SDimitry Andric 
12050b57cec5SDimitry Andric   PersonalityEncoding =
12060b57cec5SDimitry Andric       dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
12070b57cec5SDimitry Andric   LSDAEncoding = dwarf::DW_EH_PE_pcrel;
12080b57cec5SDimitry Andric   TTypeEncoding =
12090b57cec5SDimitry Andric       dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
12100b57cec5SDimitry Andric }
12110b57cec5SDimitry Andric 
121281ad6265SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getStaticDtorSection(
121381ad6265SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
121481ad6265SDimitry Andric   return StaticDtorSection;
1215*fe013be4SDimitry Andric   // In userspace, we lower global destructors via atexit(), but kernel/kext
1216*fe013be4SDimitry Andric   // environments do not provide this function so we still need to support the
1217*fe013be4SDimitry Andric   // legacy way here.
1218*fe013be4SDimitry Andric   // See the -disable-atexit-based-global-dtor-lowering CodeGen flag for more
1219*fe013be4SDimitry Andric   // context.
122081ad6265SDimitry Andric }
122181ad6265SDimitry Andric 
12220b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer,
12230b57cec5SDimitry Andric                                                        Module &M) const {
12240b57cec5SDimitry Andric   // Emit the linker options if present.
12250b57cec5SDimitry Andric   if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
1226480093f4SDimitry Andric     for (const auto *Option : LinkerOptions->operands()) {
12270b57cec5SDimitry Andric       SmallVector<std::string, 4> StrOptions;
12280b57cec5SDimitry Andric       for (const auto &Piece : cast<MDNode>(Option)->operands())
12295ffd83dbSDimitry Andric         StrOptions.push_back(std::string(cast<MDString>(Piece)->getString()));
12305ffd83dbSDimitry Andric       Streamer.emitLinkerOptions(StrOptions);
12310b57cec5SDimitry Andric     }
12320b57cec5SDimitry Andric   }
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric   unsigned VersionVal = 0;
12350b57cec5SDimitry Andric   unsigned ImageInfoFlags = 0;
12360b57cec5SDimitry Andric   StringRef SectionVal;
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric   GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal);
123904eeddc0SDimitry Andric   emitCGProfileMetadata(Streamer, M);
12400b57cec5SDimitry Andric 
12410b57cec5SDimitry Andric   // The section is mandatory. If we don't have it, then we don't have GC info.
12420b57cec5SDimitry Andric   if (SectionVal.empty())
12430b57cec5SDimitry Andric     return;
12440b57cec5SDimitry Andric 
12450b57cec5SDimitry Andric   StringRef Segment, Section;
12460b57cec5SDimitry Andric   unsigned TAA = 0, StubSize = 0;
12470b57cec5SDimitry Andric   bool TAAParsed;
1248fe6060f1SDimitry Andric   if (Error E = MCSectionMachO::ParseSectionSpecifier(
1249fe6060f1SDimitry Andric           SectionVal, Segment, Section, TAA, TAAParsed, StubSize)) {
12500b57cec5SDimitry Andric     // If invalid, report the error with report_fatal_error.
1251fe6060f1SDimitry Andric     report_fatal_error("Invalid section specifier '" + Section +
1252fe6060f1SDimitry Andric                        "': " + toString(std::move(E)) + ".");
1253fe6060f1SDimitry Andric   }
12540b57cec5SDimitry Andric 
12550b57cec5SDimitry Andric   // Get the section.
12560b57cec5SDimitry Andric   MCSectionMachO *S = getContext().getMachOSection(
12570b57cec5SDimitry Andric       Segment, Section, TAA, StubSize, SectionKind::getData());
125881ad6265SDimitry Andric   Streamer.switchSection(S);
12595ffd83dbSDimitry Andric   Streamer.emitLabel(getContext().
12600b57cec5SDimitry Andric                      getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO")));
12615ffd83dbSDimitry Andric   Streamer.emitInt32(VersionVal);
12625ffd83dbSDimitry Andric   Streamer.emitInt32(ImageInfoFlags);
126381ad6265SDimitry Andric   Streamer.addBlankLine();
12640b57cec5SDimitry Andric }
12650b57cec5SDimitry Andric 
12660b57cec5SDimitry Andric static void checkMachOComdat(const GlobalValue *GV) {
12670b57cec5SDimitry Andric   const Comdat *C = GV->getComdat();
12680b57cec5SDimitry Andric   if (!C)
12690b57cec5SDimitry Andric     return;
12700b57cec5SDimitry Andric 
12710b57cec5SDimitry Andric   report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() +
12720b57cec5SDimitry Andric                      "' cannot be lowered.");
12730b57cec5SDimitry Andric }
12740b57cec5SDimitry Andric 
12750b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
12760b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
1277fe6060f1SDimitry Andric 
1278fe6060f1SDimitry Andric   StringRef SectionName = GO->getSection();
1279fe6060f1SDimitry Andric 
1280*fe013be4SDimitry Andric   const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO);
1281*fe013be4SDimitry Andric   if (GV && GV->hasImplicitSection()) {
1282*fe013be4SDimitry Andric     auto Attrs = GV->getAttributes();
1283*fe013be4SDimitry Andric     if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) {
1284*fe013be4SDimitry Andric       SectionName = Attrs.getAttribute("bss-section").getValueAsString();
1285*fe013be4SDimitry Andric     } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
1286*fe013be4SDimitry Andric       SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
1287*fe013be4SDimitry Andric     } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) {
1288*fe013be4SDimitry Andric       SectionName = Attrs.getAttribute("relro-section").getValueAsString();
1289*fe013be4SDimitry Andric     } else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
1290*fe013be4SDimitry Andric       SectionName = Attrs.getAttribute("data-section").getValueAsString();
1291*fe013be4SDimitry Andric     }
1292*fe013be4SDimitry Andric   }
1293*fe013be4SDimitry Andric 
1294fe6060f1SDimitry Andric   const Function *F = dyn_cast<Function>(GO);
1295fe6060f1SDimitry Andric   if (F && F->hasFnAttribute("implicit-section-name")) {
1296fe6060f1SDimitry Andric     SectionName = F->getFnAttribute("implicit-section-name").getValueAsString();
1297fe6060f1SDimitry Andric   }
1298fe6060f1SDimitry Andric 
12990b57cec5SDimitry Andric   // Parse the section specifier and create it if valid.
13000b57cec5SDimitry Andric   StringRef Segment, Section;
13010b57cec5SDimitry Andric   unsigned TAA = 0, StubSize = 0;
13020b57cec5SDimitry Andric   bool TAAParsed;
13030b57cec5SDimitry Andric 
13040b57cec5SDimitry Andric   checkMachOComdat(GO);
13050b57cec5SDimitry Andric 
1306fe6060f1SDimitry Andric   if (Error E = MCSectionMachO::ParseSectionSpecifier(
1307fe6060f1SDimitry Andric           SectionName, Segment, Section, TAA, TAAParsed, StubSize)) {
13080b57cec5SDimitry Andric     // If invalid, report the error with report_fatal_error.
13090b57cec5SDimitry Andric     report_fatal_error("Global variable '" + GO->getName() +
13100b57cec5SDimitry Andric                        "' has an invalid section specifier '" +
1311fe6060f1SDimitry Andric                        GO->getSection() + "': " + toString(std::move(E)) + ".");
13120b57cec5SDimitry Andric   }
13130b57cec5SDimitry Andric 
13140b57cec5SDimitry Andric   // Get the section.
13150b57cec5SDimitry Andric   MCSectionMachO *S =
13160b57cec5SDimitry Andric       getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind);
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric   // If TAA wasn't set by ParseSectionSpecifier() above,
13190b57cec5SDimitry Andric   // use the value returned by getMachOSection() as a default.
13200b57cec5SDimitry Andric   if (!TAAParsed)
13210b57cec5SDimitry Andric     TAA = S->getTypeAndAttributes();
13220b57cec5SDimitry Andric 
13230b57cec5SDimitry Andric   // Okay, now that we got the section, verify that the TAA & StubSize agree.
13240b57cec5SDimitry Andric   // If the user declared multiple globals with different section flags, we need
13250b57cec5SDimitry Andric   // to reject it here.
13260b57cec5SDimitry Andric   if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {
13270b57cec5SDimitry Andric     // If invalid, report the error with report_fatal_error.
13280b57cec5SDimitry Andric     report_fatal_error("Global variable '" + GO->getName() +
13290b57cec5SDimitry Andric                        "' section type or attributes does not match previous"
13300b57cec5SDimitry Andric                        " section specifier");
13310b57cec5SDimitry Andric   }
13320b57cec5SDimitry Andric 
13330b57cec5SDimitry Andric   return S;
13340b57cec5SDimitry Andric }
13350b57cec5SDimitry Andric 
13360b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal(
13370b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
13380b57cec5SDimitry Andric   checkMachOComdat(GO);
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric   // Handle thread local data.
13410b57cec5SDimitry Andric   if (Kind.isThreadBSS()) return TLSBSSSection;
13420b57cec5SDimitry Andric   if (Kind.isThreadData()) return TLSDataSection;
13430b57cec5SDimitry Andric 
13440b57cec5SDimitry Andric   if (Kind.isText())
13450b57cec5SDimitry Andric     return GO->isWeakForLinker() ? TextCoalSection : TextSection;
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric   // If this is weak/linkonce, put this in a coalescable section, either in text
13480b57cec5SDimitry Andric   // or data depending on if it is writable.
13490b57cec5SDimitry Andric   if (GO->isWeakForLinker()) {
13500b57cec5SDimitry Andric     if (Kind.isReadOnly())
13510b57cec5SDimitry Andric       return ConstTextCoalSection;
13520b57cec5SDimitry Andric     if (Kind.isReadOnlyWithRel())
13530b57cec5SDimitry Andric       return ConstDataCoalSection;
13540b57cec5SDimitry Andric     return DataCoalSection;
13550b57cec5SDimitry Andric   }
13560b57cec5SDimitry Andric 
13570b57cec5SDimitry Andric   // FIXME: Alignment check should be handled by section classifier.
13580b57cec5SDimitry Andric   if (Kind.isMergeable1ByteCString() &&
13595ffd83dbSDimitry Andric       GO->getParent()->getDataLayout().getPreferredAlign(
13605ffd83dbSDimitry Andric           cast<GlobalVariable>(GO)) < Align(32))
13610b57cec5SDimitry Andric     return CStringSection;
13620b57cec5SDimitry Andric 
13630b57cec5SDimitry Andric   // Do not put 16-bit arrays in the UString section if they have an
13640b57cec5SDimitry Andric   // externally visible label, this runs into issues with certain linker
13650b57cec5SDimitry Andric   // versions.
13660b57cec5SDimitry Andric   if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() &&
13675ffd83dbSDimitry Andric       GO->getParent()->getDataLayout().getPreferredAlign(
13685ffd83dbSDimitry Andric           cast<GlobalVariable>(GO)) < Align(32))
13690b57cec5SDimitry Andric     return UStringSection;
13700b57cec5SDimitry Andric 
13710b57cec5SDimitry Andric   // With MachO only variables whose corresponding symbol starts with 'l' or
13720b57cec5SDimitry Andric   // 'L' can be merged, so we only try merging GVs with private linkage.
13730b57cec5SDimitry Andric   if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) {
13740b57cec5SDimitry Andric     if (Kind.isMergeableConst4())
13750b57cec5SDimitry Andric       return FourByteConstantSection;
13760b57cec5SDimitry Andric     if (Kind.isMergeableConst8())
13770b57cec5SDimitry Andric       return EightByteConstantSection;
13780b57cec5SDimitry Andric     if (Kind.isMergeableConst16())
13790b57cec5SDimitry Andric       return SixteenByteConstantSection;
13800b57cec5SDimitry Andric   }
13810b57cec5SDimitry Andric 
13820b57cec5SDimitry Andric   // Otherwise, if it is readonly, but not something we can specially optimize,
13830b57cec5SDimitry Andric   // just drop it in .const.
13840b57cec5SDimitry Andric   if (Kind.isReadOnly())
13850b57cec5SDimitry Andric     return ReadOnlySection;
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric   // If this is marked const, put it into a const section.  But if the dynamic
13880b57cec5SDimitry Andric   // linker needs to write to it, put it in the data segment.
13890b57cec5SDimitry Andric   if (Kind.isReadOnlyWithRel())
13900b57cec5SDimitry Andric     return ConstDataSection;
13910b57cec5SDimitry Andric 
13920b57cec5SDimitry Andric   // Put zero initialized globals with strong external linkage in the
13930b57cec5SDimitry Andric   // DATA, __common section with the .zerofill directive.
13940b57cec5SDimitry Andric   if (Kind.isBSSExtern())
13950b57cec5SDimitry Andric     return DataCommonSection;
13960b57cec5SDimitry Andric 
13970b57cec5SDimitry Andric   // Put zero initialized globals with local linkage in __DATA,__bss directive
13980b57cec5SDimitry Andric   // with the .zerofill directive (aka .lcomm).
13990b57cec5SDimitry Andric   if (Kind.isBSSLocal())
14000b57cec5SDimitry Andric     return DataBSSSection;
14010b57cec5SDimitry Andric 
14020b57cec5SDimitry Andric   // Otherwise, just drop the variable in the normal data section.
14030b57cec5SDimitry Andric   return DataSection;
14040b57cec5SDimitry Andric }
14050b57cec5SDimitry Andric 
14060b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant(
14070b57cec5SDimitry Andric     const DataLayout &DL, SectionKind Kind, const Constant *C,
14085ffd83dbSDimitry Andric     Align &Alignment) const {
14090b57cec5SDimitry Andric   // If this constant requires a relocation, we have to put it in the data
14100b57cec5SDimitry Andric   // segment, not in the text segment.
14110b57cec5SDimitry Andric   if (Kind.isData() || Kind.isReadOnlyWithRel())
14120b57cec5SDimitry Andric     return ConstDataSection;
14130b57cec5SDimitry Andric 
14140b57cec5SDimitry Andric   if (Kind.isMergeableConst4())
14150b57cec5SDimitry Andric     return FourByteConstantSection;
14160b57cec5SDimitry Andric   if (Kind.isMergeableConst8())
14170b57cec5SDimitry Andric     return EightByteConstantSection;
14180b57cec5SDimitry Andric   if (Kind.isMergeableConst16())
14190b57cec5SDimitry Andric     return SixteenByteConstantSection;
14200b57cec5SDimitry Andric   return ReadOnlySection;  // .const
14210b57cec5SDimitry Andric }
14220b57cec5SDimitry Andric 
1423*fe013be4SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForCommandLines() const {
1424*fe013be4SDimitry Andric   return getContext().getMachOSection("__TEXT", "__command_line", 0,
1425*fe013be4SDimitry Andric                                       SectionKind::getReadOnly());
1426*fe013be4SDimitry Andric }
1427*fe013be4SDimitry Andric 
14280b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference(
14290b57cec5SDimitry Andric     const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,
14300b57cec5SDimitry Andric     MachineModuleInfo *MMI, MCStreamer &Streamer) const {
14310b57cec5SDimitry Andric   // The mach-o version of this method defaults to returning a stub reference.
14320b57cec5SDimitry Andric 
14330b57cec5SDimitry Andric   if (Encoding & DW_EH_PE_indirect) {
14340b57cec5SDimitry Andric     MachineModuleInfoMachO &MachOMMI =
14350b57cec5SDimitry Andric       MMI->getObjFileInfo<MachineModuleInfoMachO>();
14360b57cec5SDimitry Andric 
14370b57cec5SDimitry Andric     MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM);
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric     // Add information about the stub reference to MachOMMI so that the stub
14400b57cec5SDimitry Andric     // gets emitted by the asmprinter.
14410b57cec5SDimitry Andric     MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
14420b57cec5SDimitry Andric     if (!StubSym.getPointer()) {
14430b57cec5SDimitry Andric       MCSymbol *Sym = TM.getSymbol(GV);
14440b57cec5SDimitry Andric       StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
14450b57cec5SDimitry Andric     }
14460b57cec5SDimitry Andric 
14470b57cec5SDimitry Andric     return TargetLoweringObjectFile::
14480b57cec5SDimitry Andric       getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()),
14490b57cec5SDimitry Andric                         Encoding & ~DW_EH_PE_indirect, Streamer);
14500b57cec5SDimitry Andric   }
14510b57cec5SDimitry Andric 
14520b57cec5SDimitry Andric   return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM,
14530b57cec5SDimitry Andric                                                            MMI, Streamer);
14540b57cec5SDimitry Andric }
14550b57cec5SDimitry Andric 
14560b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol(
14570b57cec5SDimitry Andric     const GlobalValue *GV, const TargetMachine &TM,
14580b57cec5SDimitry Andric     MachineModuleInfo *MMI) const {
14590b57cec5SDimitry Andric   // The mach-o version of this method defaults to returning a stub reference.
14600b57cec5SDimitry Andric   MachineModuleInfoMachO &MachOMMI =
14610b57cec5SDimitry Andric     MMI->getObjFileInfo<MachineModuleInfoMachO>();
14620b57cec5SDimitry Andric 
14630b57cec5SDimitry Andric   MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM);
14640b57cec5SDimitry Andric 
14650b57cec5SDimitry Andric   // Add information about the stub reference to MachOMMI so that the stub
14660b57cec5SDimitry Andric   // gets emitted by the asmprinter.
14670b57cec5SDimitry Andric   MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
14680b57cec5SDimitry Andric   if (!StubSym.getPointer()) {
14690b57cec5SDimitry Andric     MCSymbol *Sym = TM.getSymbol(GV);
14700b57cec5SDimitry Andric     StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
14710b57cec5SDimitry Andric   }
14720b57cec5SDimitry Andric 
14730b57cec5SDimitry Andric   return SSym;
14740b57cec5SDimitry Andric }
14750b57cec5SDimitry Andric 
14760b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel(
14778bcb0991SDimitry Andric     const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
14788bcb0991SDimitry Andric     int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
14790b57cec5SDimitry Andric   // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation
14800b57cec5SDimitry Andric   // as 64-bit do, we replace the GOT equivalent by accessing the final symbol
14810b57cec5SDimitry Andric   // through a non_lazy_ptr stub instead. One advantage is that it allows the
14820b57cec5SDimitry Andric   // computation of deltas to final external symbols. Example:
14830b57cec5SDimitry Andric   //
14840b57cec5SDimitry Andric   //    _extgotequiv:
14850b57cec5SDimitry Andric   //       .long   _extfoo
14860b57cec5SDimitry Andric   //
14870b57cec5SDimitry Andric   //    _delta:
14880b57cec5SDimitry Andric   //       .long   _extgotequiv-_delta
14890b57cec5SDimitry Andric   //
14900b57cec5SDimitry Andric   // is transformed to:
14910b57cec5SDimitry Andric   //
14920b57cec5SDimitry Andric   //    _delta:
14930b57cec5SDimitry Andric   //       .long   L_extfoo$non_lazy_ptr-(_delta+0)
14940b57cec5SDimitry Andric   //
14950b57cec5SDimitry Andric   //       .section        __IMPORT,__pointers,non_lazy_symbol_pointers
14960b57cec5SDimitry Andric   //    L_extfoo$non_lazy_ptr:
14970b57cec5SDimitry Andric   //       .indirect_symbol        _extfoo
14980b57cec5SDimitry Andric   //       .long   0
14990b57cec5SDimitry Andric   //
15000b57cec5SDimitry Andric   // The indirect symbol table (and sections of non_lazy_symbol_pointers type)
15010b57cec5SDimitry Andric   // may point to both local (same translation unit) and global (other
15020b57cec5SDimitry Andric   // translation units) symbols. Example:
15030b57cec5SDimitry Andric   //
15040b57cec5SDimitry Andric   // .section __DATA,__pointers,non_lazy_symbol_pointers
15050b57cec5SDimitry Andric   // L1:
15060b57cec5SDimitry Andric   //    .indirect_symbol _myGlobal
15070b57cec5SDimitry Andric   //    .long 0
15080b57cec5SDimitry Andric   // L2:
15090b57cec5SDimitry Andric   //    .indirect_symbol _myLocal
15100b57cec5SDimitry Andric   //    .long _myLocal
15110b57cec5SDimitry Andric   //
15120b57cec5SDimitry Andric   // If the symbol is local, instead of the symbol's index, the assembler
15130b57cec5SDimitry Andric   // places the constant INDIRECT_SYMBOL_LOCAL into the indirect symbol table.
15140b57cec5SDimitry Andric   // Then the linker will notice the constant in the table and will look at the
15150b57cec5SDimitry Andric   // content of the symbol.
15160b57cec5SDimitry Andric   MachineModuleInfoMachO &MachOMMI =
15170b57cec5SDimitry Andric     MMI->getObjFileInfo<MachineModuleInfoMachO>();
15180b57cec5SDimitry Andric   MCContext &Ctx = getContext();
15190b57cec5SDimitry Andric 
15200b57cec5SDimitry Andric   // The offset must consider the original displacement from the base symbol
15210b57cec5SDimitry Andric   // since 32-bit targets don't have a GOTPCREL to fold the PC displacement.
15220b57cec5SDimitry Andric   Offset = -MV.getConstant();
15230b57cec5SDimitry Andric   const MCSymbol *BaseSym = &MV.getSymB()->getSymbol();
15240b57cec5SDimitry Andric 
15250b57cec5SDimitry Andric   // Access the final symbol via sym$non_lazy_ptr and generate the appropriated
15260b57cec5SDimitry Andric   // non_lazy_ptr stubs.
15270b57cec5SDimitry Andric   SmallString<128> Name;
15280b57cec5SDimitry Andric   StringRef Suffix = "$non_lazy_ptr";
15290b57cec5SDimitry Andric   Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix();
15300b57cec5SDimitry Andric   Name += Sym->getName();
15310b57cec5SDimitry Andric   Name += Suffix;
15320b57cec5SDimitry Andric   MCSymbol *Stub = Ctx.getOrCreateSymbol(Name);
15330b57cec5SDimitry Andric 
15340b57cec5SDimitry Andric   MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub);
15358bcb0991SDimitry Andric 
15368bcb0991SDimitry Andric   if (!StubSym.getPointer())
15370b57cec5SDimitry Andric     StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym),
15388bcb0991SDimitry Andric                                                  !GV->hasLocalLinkage());
15390b57cec5SDimitry Andric 
15400b57cec5SDimitry Andric   const MCExpr *BSymExpr =
15410b57cec5SDimitry Andric     MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx);
15420b57cec5SDimitry Andric   const MCExpr *LHS =
15430b57cec5SDimitry Andric     MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx);
15440b57cec5SDimitry Andric 
15450b57cec5SDimitry Andric   if (!Offset)
15460b57cec5SDimitry Andric     return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx);
15470b57cec5SDimitry Andric 
15480b57cec5SDimitry Andric   const MCExpr *RHS =
15490b57cec5SDimitry Andric     MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx);
15500b57cec5SDimitry Andric   return MCBinaryExpr::createSub(LHS, RHS, Ctx);
15510b57cec5SDimitry Andric }
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo,
15540b57cec5SDimitry Andric                                const MCSection &Section) {
15550b57cec5SDimitry Andric   if (!AsmInfo.isSectionAtomizableBySymbols(Section))
15560b57cec5SDimitry Andric     return true;
15570b57cec5SDimitry Andric 
1558fe6060f1SDimitry Andric   // FIXME: we should be able to use private labels for sections that can't be
1559fe6060f1SDimitry Andric   // dead-stripped (there's no issue with blocking atomization there), but `ld
1560fe6060f1SDimitry Andric   // -r` sometimes drops the no_dead_strip attribute from sections so for safety
1561fe6060f1SDimitry Andric   // we don't allow it.
15620b57cec5SDimitry Andric   return false;
15630b57cec5SDimitry Andric }
15640b57cec5SDimitry Andric 
15650b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix(
15660b57cec5SDimitry Andric     SmallVectorImpl<char> &OutName, const GlobalValue *GV,
15670b57cec5SDimitry Andric     const TargetMachine &TM) const {
15680b57cec5SDimitry Andric   bool CannotUsePrivateLabel = true;
1569349cc55cSDimitry Andric   if (auto *GO = GV->getAliaseeObject()) {
15700b57cec5SDimitry Andric     SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM);
15710b57cec5SDimitry Andric     const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM);
15720b57cec5SDimitry Andric     CannotUsePrivateLabel =
15730b57cec5SDimitry Andric         !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection);
15740b57cec5SDimitry Andric   }
15750b57cec5SDimitry Andric   getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);
15760b57cec5SDimitry Andric }
15770b57cec5SDimitry Andric 
15780b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15790b57cec5SDimitry Andric //                                  COFF
15800b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15810b57cec5SDimitry Andric 
15820b57cec5SDimitry Andric static unsigned
15830b57cec5SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) {
15840b57cec5SDimitry Andric   unsigned Flags = 0;
15850b57cec5SDimitry Andric   bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb;
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric   if (K.isMetadata())
15880b57cec5SDimitry Andric     Flags |=
15890b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_DISCARDABLE;
159081ad6265SDimitry Andric   else if (K.isExclude())
159181ad6265SDimitry Andric     Flags |=
159281ad6265SDimitry Andric       COFF::IMAGE_SCN_LNK_REMOVE | COFF::IMAGE_SCN_MEM_DISCARDABLE;
15930b57cec5SDimitry Andric   else if (K.isText())
15940b57cec5SDimitry Andric     Flags |=
15950b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_EXECUTE |
15960b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
15970b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_CODE |
15980b57cec5SDimitry Andric       (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0);
15990b57cec5SDimitry Andric   else if (K.isBSS())
16000b57cec5SDimitry Andric     Flags |=
16010b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
16020b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
16030b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_WRITE;
16040b57cec5SDimitry Andric   else if (K.isThreadLocal())
16050b57cec5SDimitry Andric     Flags |=
16060b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
16070b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
16080b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_WRITE;
16090b57cec5SDimitry Andric   else if (K.isReadOnly() || K.isReadOnlyWithRel())
16100b57cec5SDimitry Andric     Flags |=
16110b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
16120b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ;
16130b57cec5SDimitry Andric   else if (K.isWriteable())
16140b57cec5SDimitry Andric     Flags |=
16150b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
16160b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
16170b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_WRITE;
16180b57cec5SDimitry Andric 
16190b57cec5SDimitry Andric   return Flags;
16200b57cec5SDimitry Andric }
16210b57cec5SDimitry Andric 
16220b57cec5SDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) {
16230b57cec5SDimitry Andric   const Comdat *C = GV->getComdat();
16240b57cec5SDimitry Andric   assert(C && "expected GV to have a Comdat!");
16250b57cec5SDimitry Andric 
16260b57cec5SDimitry Andric   StringRef ComdatGVName = C->getName();
16270b57cec5SDimitry Andric   const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName);
16280b57cec5SDimitry Andric   if (!ComdatGV)
16290b57cec5SDimitry Andric     report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +
16300b57cec5SDimitry Andric                        "' does not exist.");
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric   if (ComdatGV->getComdat() != C)
16330b57cec5SDimitry Andric     report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +
16340b57cec5SDimitry Andric                        "' is not a key for its COMDAT.");
16350b57cec5SDimitry Andric 
16360b57cec5SDimitry Andric   return ComdatGV;
16370b57cec5SDimitry Andric }
16380b57cec5SDimitry Andric 
16390b57cec5SDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) {
16400b57cec5SDimitry Andric   if (const Comdat *C = GV->getComdat()) {
16410b57cec5SDimitry Andric     const GlobalValue *ComdatKey = getComdatGVForCOFF(GV);
16420b57cec5SDimitry Andric     if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey))
1643349cc55cSDimitry Andric       ComdatKey = GA->getAliaseeObject();
16440b57cec5SDimitry Andric     if (ComdatKey == GV) {
16450b57cec5SDimitry Andric       switch (C->getSelectionKind()) {
16460b57cec5SDimitry Andric       case Comdat::Any:
16470b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_ANY;
16480b57cec5SDimitry Andric       case Comdat::ExactMatch:
16490b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH;
16500b57cec5SDimitry Andric       case Comdat::Largest:
16510b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_LARGEST;
1652fe6060f1SDimitry Andric       case Comdat::NoDeduplicate:
16530b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;
16540b57cec5SDimitry Andric       case Comdat::SameSize:
16550b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE;
16560b57cec5SDimitry Andric       }
16570b57cec5SDimitry Andric     } else {
16580b57cec5SDimitry Andric       return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
16590b57cec5SDimitry Andric     }
16600b57cec5SDimitry Andric   }
16610b57cec5SDimitry Andric   return 0;
16620b57cec5SDimitry Andric }
16630b57cec5SDimitry Andric 
16640b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
16650b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
16660b57cec5SDimitry Andric   int Selection = 0;
16670b57cec5SDimitry Andric   unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
16680b57cec5SDimitry Andric   StringRef Name = GO->getSection();
16690b57cec5SDimitry Andric   StringRef COMDATSymName = "";
16700b57cec5SDimitry Andric   if (GO->hasComdat()) {
16710b57cec5SDimitry Andric     Selection = getSelectionForCOFF(GO);
16720b57cec5SDimitry Andric     const GlobalValue *ComdatGV;
16730b57cec5SDimitry Andric     if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
16740b57cec5SDimitry Andric       ComdatGV = getComdatGVForCOFF(GO);
16750b57cec5SDimitry Andric     else
16760b57cec5SDimitry Andric       ComdatGV = GO;
16770b57cec5SDimitry Andric 
16780b57cec5SDimitry Andric     if (!ComdatGV->hasPrivateLinkage()) {
16790b57cec5SDimitry Andric       MCSymbol *Sym = TM.getSymbol(ComdatGV);
16800b57cec5SDimitry Andric       COMDATSymName = Sym->getName();
16810b57cec5SDimitry Andric       Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
16820b57cec5SDimitry Andric     } else {
16830b57cec5SDimitry Andric       Selection = 0;
16840b57cec5SDimitry Andric     }
16850b57cec5SDimitry Andric   }
16860b57cec5SDimitry Andric 
16870b57cec5SDimitry Andric   return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
16880b57cec5SDimitry Andric                                      Selection);
16890b57cec5SDimitry Andric }
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric static StringRef getCOFFSectionNameForUniqueGlobal(SectionKind Kind) {
16920b57cec5SDimitry Andric   if (Kind.isText())
16930b57cec5SDimitry Andric     return ".text";
16940b57cec5SDimitry Andric   if (Kind.isBSS())
16950b57cec5SDimitry Andric     return ".bss";
16960b57cec5SDimitry Andric   if (Kind.isThreadLocal())
16970b57cec5SDimitry Andric     return ".tls$";
16980b57cec5SDimitry Andric   if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())
16990b57cec5SDimitry Andric     return ".rdata";
17000b57cec5SDimitry Andric   return ".data";
17010b57cec5SDimitry Andric }
17020b57cec5SDimitry Andric 
17030b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
17040b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
17050b57cec5SDimitry Andric   // If we have -ffunction-sections then we should emit the global value to a
17060b57cec5SDimitry Andric   // uniqued section specifically for it.
17070b57cec5SDimitry Andric   bool EmitUniquedSection;
17080b57cec5SDimitry Andric   if (Kind.isText())
17090b57cec5SDimitry Andric     EmitUniquedSection = TM.getFunctionSections();
17100b57cec5SDimitry Andric   else
17110b57cec5SDimitry Andric     EmitUniquedSection = TM.getDataSections();
17120b57cec5SDimitry Andric 
17130b57cec5SDimitry Andric   if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) {
17140b57cec5SDimitry Andric     SmallString<256> Name = getCOFFSectionNameForUniqueGlobal(Kind);
17150b57cec5SDimitry Andric 
17160b57cec5SDimitry Andric     unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
17170b57cec5SDimitry Andric 
17180b57cec5SDimitry Andric     Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
17190b57cec5SDimitry Andric     int Selection = getSelectionForCOFF(GO);
17200b57cec5SDimitry Andric     if (!Selection)
17210b57cec5SDimitry Andric       Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;
17220b57cec5SDimitry Andric     const GlobalValue *ComdatGV;
17230b57cec5SDimitry Andric     if (GO->hasComdat())
17240b57cec5SDimitry Andric       ComdatGV = getComdatGVForCOFF(GO);
17250b57cec5SDimitry Andric     else
17260b57cec5SDimitry Andric       ComdatGV = GO;
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric     unsigned UniqueID = MCContext::GenericSectionID;
17290b57cec5SDimitry Andric     if (EmitUniquedSection)
17300b57cec5SDimitry Andric       UniqueID = NextUniqueID++;
17310b57cec5SDimitry Andric 
17320b57cec5SDimitry Andric     if (!ComdatGV->hasPrivateLinkage()) {
17330b57cec5SDimitry Andric       MCSymbol *Sym = TM.getSymbol(ComdatGV);
17340b57cec5SDimitry Andric       StringRef COMDATSymName = Sym->getName();
17350b57cec5SDimitry Andric 
1736e8d8bef9SDimitry Andric       if (const auto *F = dyn_cast<Function>(GO))
1737bdd1243dSDimitry Andric         if (std::optional<StringRef> Prefix = F->getSectionPrefix())
1738e8d8bef9SDimitry Andric           raw_svector_ostream(Name) << '$' << *Prefix;
1739e8d8bef9SDimitry Andric 
17400b57cec5SDimitry Andric       // Append "$symbol" to the section name *before* IR-level mangling is
17410b57cec5SDimitry Andric       // applied when targetting mingw. This is what GCC does, and the ld.bfd
17420b57cec5SDimitry Andric       // COFF linker will not properly handle comdats otherwise.
1743fe6060f1SDimitry Andric       if (getContext().getTargetTriple().isWindowsGNUEnvironment())
17440b57cec5SDimitry Andric         raw_svector_ostream(Name) << '$' << ComdatGV->getName();
17450b57cec5SDimitry Andric 
17460b57cec5SDimitry Andric       return getContext().getCOFFSection(Name, Characteristics, Kind,
17470b57cec5SDimitry Andric                                          COMDATSymName, Selection, UniqueID);
17480b57cec5SDimitry Andric     } else {
17490b57cec5SDimitry Andric       SmallString<256> TmpData;
17500b57cec5SDimitry Andric       getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true);
17510b57cec5SDimitry Andric       return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData,
17520b57cec5SDimitry Andric                                          Selection, UniqueID);
17530b57cec5SDimitry Andric     }
17540b57cec5SDimitry Andric   }
17550b57cec5SDimitry Andric 
17560b57cec5SDimitry Andric   if (Kind.isText())
17570b57cec5SDimitry Andric     return TextSection;
17580b57cec5SDimitry Andric 
17590b57cec5SDimitry Andric   if (Kind.isThreadLocal())
17600b57cec5SDimitry Andric     return TLSDataSection;
17610b57cec5SDimitry Andric 
17620b57cec5SDimitry Andric   if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())
17630b57cec5SDimitry Andric     return ReadOnlySection;
17640b57cec5SDimitry Andric 
17650b57cec5SDimitry Andric   // Note: we claim that common symbols are put in BSSSection, but they are
17660b57cec5SDimitry Andric   // really emitted with the magic .comm directive, which creates a symbol table
17670b57cec5SDimitry Andric   // entry but not a section.
17680b57cec5SDimitry Andric   if (Kind.isBSS() || Kind.isCommon())
17690b57cec5SDimitry Andric     return BSSSection;
17700b57cec5SDimitry Andric 
17710b57cec5SDimitry Andric   return DataSection;
17720b57cec5SDimitry Andric }
17730b57cec5SDimitry Andric 
17740b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix(
17750b57cec5SDimitry Andric     SmallVectorImpl<char> &OutName, const GlobalValue *GV,
17760b57cec5SDimitry Andric     const TargetMachine &TM) const {
17770b57cec5SDimitry Andric   bool CannotUsePrivateLabel = false;
17780b57cec5SDimitry Andric   if (GV->hasPrivateLinkage() &&
17790b57cec5SDimitry Andric       ((isa<Function>(GV) && TM.getFunctionSections()) ||
17800b57cec5SDimitry Andric        (isa<GlobalVariable>(GV) && TM.getDataSections())))
17810b57cec5SDimitry Andric     CannotUsePrivateLabel = true;
17820b57cec5SDimitry Andric 
17830b57cec5SDimitry Andric   getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);
17840b57cec5SDimitry Andric }
17850b57cec5SDimitry Andric 
17860b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
17870b57cec5SDimitry Andric     const Function &F, const TargetMachine &TM) const {
17880b57cec5SDimitry Andric   // If the function can be removed, produce a unique section so that
17890b57cec5SDimitry Andric   // the table doesn't prevent the removal.
17900b57cec5SDimitry Andric   const Comdat *C = F.getComdat();
17910b57cec5SDimitry Andric   bool EmitUniqueSection = TM.getFunctionSections() || C;
17920b57cec5SDimitry Andric   if (!EmitUniqueSection)
17930b57cec5SDimitry Andric     return ReadOnlySection;
17940b57cec5SDimitry Andric 
17950b57cec5SDimitry Andric   // FIXME: we should produce a symbol for F instead.
17960b57cec5SDimitry Andric   if (F.hasPrivateLinkage())
17970b57cec5SDimitry Andric     return ReadOnlySection;
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric   MCSymbol *Sym = TM.getSymbol(&F);
18000b57cec5SDimitry Andric   StringRef COMDATSymName = Sym->getName();
18010b57cec5SDimitry Andric 
18020b57cec5SDimitry Andric   SectionKind Kind = SectionKind::getReadOnly();
18030b57cec5SDimitry Andric   StringRef SecName = getCOFFSectionNameForUniqueGlobal(Kind);
18040b57cec5SDimitry Andric   unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
18050b57cec5SDimitry Andric   Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
18060b57cec5SDimitry Andric   unsigned UniqueID = NextUniqueID++;
18070b57cec5SDimitry Andric 
18080b57cec5SDimitry Andric   return getContext().getCOFFSection(
18090b57cec5SDimitry Andric       SecName, Characteristics, Kind, COMDATSymName,
18100b57cec5SDimitry Andric       COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
18110b57cec5SDimitry Andric }
18120b57cec5SDimitry Andric 
1813*fe013be4SDimitry Andric bool TargetLoweringObjectFileCOFF::shouldPutJumpTableInFunctionSection(
1814*fe013be4SDimitry Andric     bool UsesLabelDifference, const Function &F) const {
1815*fe013be4SDimitry Andric   if (TM->getTargetTriple().getArch() == Triple::x86_64) {
1816*fe013be4SDimitry Andric     if (!JumpTableInFunctionSection) {
1817*fe013be4SDimitry Andric       // We can always create relative relocations, so use another section
1818*fe013be4SDimitry Andric       // that can be marked non-executable.
1819*fe013be4SDimitry Andric       return false;
1820*fe013be4SDimitry Andric     }
1821*fe013be4SDimitry Andric   }
1822*fe013be4SDimitry Andric   return TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection(
1823*fe013be4SDimitry Andric     UsesLabelDifference, F);
1824*fe013be4SDimitry Andric }
1825*fe013be4SDimitry Andric 
18260b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
18270b57cec5SDimitry Andric                                                       Module &M) const {
1828e8d8bef9SDimitry Andric   emitLinkerDirectives(Streamer, M);
1829e8d8bef9SDimitry Andric 
1830e8d8bef9SDimitry Andric   unsigned Version = 0;
1831e8d8bef9SDimitry Andric   unsigned Flags = 0;
1832e8d8bef9SDimitry Andric   StringRef Section;
1833e8d8bef9SDimitry Andric 
1834e8d8bef9SDimitry Andric   GetObjCImageInfo(M, Version, Flags, Section);
1835e8d8bef9SDimitry Andric   if (!Section.empty()) {
1836e8d8bef9SDimitry Andric     auto &C = getContext();
1837e8d8bef9SDimitry Andric     auto *S = C.getCOFFSection(Section,
1838e8d8bef9SDimitry Andric                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1839e8d8bef9SDimitry Andric                                    COFF::IMAGE_SCN_MEM_READ,
1840e8d8bef9SDimitry Andric                                SectionKind::getReadOnly());
184181ad6265SDimitry Andric     Streamer.switchSection(S);
1842e8d8bef9SDimitry Andric     Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
1843e8d8bef9SDimitry Andric     Streamer.emitInt32(Version);
1844e8d8bef9SDimitry Andric     Streamer.emitInt32(Flags);
184581ad6265SDimitry Andric     Streamer.addBlankLine();
1846e8d8bef9SDimitry Andric   }
1847e8d8bef9SDimitry Andric 
1848e8d8bef9SDimitry Andric   emitCGProfileMetadata(Streamer, M);
1849e8d8bef9SDimitry Andric }
1850e8d8bef9SDimitry Andric 
1851e8d8bef9SDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
1852e8d8bef9SDimitry Andric     MCStreamer &Streamer, Module &M) const {
18530b57cec5SDimitry Andric   if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
18540b57cec5SDimitry Andric     // Emit the linker options to the linker .drectve section.  According to the
18550b57cec5SDimitry Andric     // spec, this section is a space-separated string containing flags for
18560b57cec5SDimitry Andric     // linker.
18570b57cec5SDimitry Andric     MCSection *Sec = getDrectveSection();
185881ad6265SDimitry Andric     Streamer.switchSection(Sec);
1859480093f4SDimitry Andric     for (const auto *Option : LinkerOptions->operands()) {
18600b57cec5SDimitry Andric       for (const auto &Piece : cast<MDNode>(Option)->operands()) {
18610b57cec5SDimitry Andric         // Lead with a space for consistency with our dllexport implementation.
18620b57cec5SDimitry Andric         std::string Directive(" ");
18635ffd83dbSDimitry Andric         Directive.append(std::string(cast<MDString>(Piece)->getString()));
18645ffd83dbSDimitry Andric         Streamer.emitBytes(Directive);
18650b57cec5SDimitry Andric       }
18660b57cec5SDimitry Andric     }
18670b57cec5SDimitry Andric   }
18680b57cec5SDimitry Andric 
1869e8d8bef9SDimitry Andric   // Emit /EXPORT: flags for each exported global as necessary.
1870e8d8bef9SDimitry Andric   std::string Flags;
1871e8d8bef9SDimitry Andric   for (const GlobalValue &GV : M.global_values()) {
1872e8d8bef9SDimitry Andric     raw_string_ostream OS(Flags);
1873fe6060f1SDimitry Andric     emitLinkerFlagsForGlobalCOFF(OS, &GV, getContext().getTargetTriple(),
1874fe6060f1SDimitry Andric                                  getMangler());
1875e8d8bef9SDimitry Andric     OS.flush();
1876e8d8bef9SDimitry Andric     if (!Flags.empty()) {
187781ad6265SDimitry Andric       Streamer.switchSection(getDrectveSection());
1878e8d8bef9SDimitry Andric       Streamer.emitBytes(Flags);
1879e8d8bef9SDimitry Andric     }
1880e8d8bef9SDimitry Andric     Flags.clear();
1881e8d8bef9SDimitry Andric   }
18820b57cec5SDimitry Andric 
1883e8d8bef9SDimitry Andric   // Emit /INCLUDE: flags for each used global as necessary.
1884e8d8bef9SDimitry Andric   if (const auto *LU = M.getNamedGlobal("llvm.used")) {
1885e8d8bef9SDimitry Andric     assert(LU->hasInitializer() && "expected llvm.used to have an initializer");
1886e8d8bef9SDimitry Andric     assert(isa<ArrayType>(LU->getValueType()) &&
1887e8d8bef9SDimitry Andric            "expected llvm.used to be an array type");
1888e8d8bef9SDimitry Andric     if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {
1889e8d8bef9SDimitry Andric       for (const Value *Op : A->operands()) {
1890e8d8bef9SDimitry Andric         const auto *GV = cast<GlobalValue>(Op->stripPointerCasts());
1891e8d8bef9SDimitry Andric         // Global symbols with internal or private linkage are not visible to
1892e8d8bef9SDimitry Andric         // the linker, and thus would cause an error when the linker tried to
1893e8d8bef9SDimitry Andric         // preserve the symbol due to the `/include:` directive.
1894e8d8bef9SDimitry Andric         if (GV->hasLocalLinkage())
1895e8d8bef9SDimitry Andric           continue;
18960b57cec5SDimitry Andric 
1897e8d8bef9SDimitry Andric         raw_string_ostream OS(Flags);
1898fe6060f1SDimitry Andric         emitLinkerFlagsForUsedCOFF(OS, GV, getContext().getTargetTriple(),
1899fe6060f1SDimitry Andric                                    getMangler());
1900e8d8bef9SDimitry Andric         OS.flush();
1901e8d8bef9SDimitry Andric 
1902e8d8bef9SDimitry Andric         if (!Flags.empty()) {
190381ad6265SDimitry Andric           Streamer.switchSection(getDrectveSection());
1904e8d8bef9SDimitry Andric           Streamer.emitBytes(Flags);
1905e8d8bef9SDimitry Andric         }
1906e8d8bef9SDimitry Andric         Flags.clear();
1907e8d8bef9SDimitry Andric       }
1908e8d8bef9SDimitry Andric     }
1909e8d8bef9SDimitry Andric   }
19100b57cec5SDimitry Andric }
19110b57cec5SDimitry Andric 
19120b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
19130b57cec5SDimitry Andric                                               const TargetMachine &TM) {
19140b57cec5SDimitry Andric   TargetLoweringObjectFile::Initialize(Ctx, TM);
1915e8d8bef9SDimitry Andric   this->TM = &TM;
19160b57cec5SDimitry Andric   const Triple &T = TM.getTargetTriple();
19170b57cec5SDimitry Andric   if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
19180b57cec5SDimitry Andric     StaticCtorSection =
19190b57cec5SDimitry Andric         Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19200b57cec5SDimitry Andric                                            COFF::IMAGE_SCN_MEM_READ,
19210b57cec5SDimitry Andric                            SectionKind::getReadOnly());
19220b57cec5SDimitry Andric     StaticDtorSection =
19230b57cec5SDimitry Andric         Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19240b57cec5SDimitry Andric                                            COFF::IMAGE_SCN_MEM_READ,
19250b57cec5SDimitry Andric                            SectionKind::getReadOnly());
19260b57cec5SDimitry Andric   } else {
19270b57cec5SDimitry Andric     StaticCtorSection = Ctx.getCOFFSection(
19280b57cec5SDimitry Andric         ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19290b57cec5SDimitry Andric                       COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE,
19300b57cec5SDimitry Andric         SectionKind::getData());
19310b57cec5SDimitry Andric     StaticDtorSection = Ctx.getCOFFSection(
19320b57cec5SDimitry Andric         ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19330b57cec5SDimitry Andric                       COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE,
19340b57cec5SDimitry Andric         SectionKind::getData());
19350b57cec5SDimitry Andric   }
19360b57cec5SDimitry Andric }
19370b57cec5SDimitry Andric 
19380b57cec5SDimitry Andric static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx,
19390b57cec5SDimitry Andric                                                    const Triple &T, bool IsCtor,
19400b57cec5SDimitry Andric                                                    unsigned Priority,
19410b57cec5SDimitry Andric                                                    const MCSymbol *KeySym,
19420b57cec5SDimitry Andric                                                    MCSectionCOFF *Default) {
19430b57cec5SDimitry Andric   if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
19440b57cec5SDimitry Andric     // If the priority is the default, use .CRT$XCU, possibly associative.
19450b57cec5SDimitry Andric     if (Priority == 65535)
19460b57cec5SDimitry Andric       return Ctx.getAssociativeCOFFSection(Default, KeySym, 0);
19470b57cec5SDimitry Andric 
19480b57cec5SDimitry Andric     // Otherwise, we need to compute a new section name. Low priorities should
19490b57cec5SDimitry Andric     // run earlier. The linker will sort sections ASCII-betically, and we need a
19500b57cec5SDimitry Andric     // string that sorts between .CRT$XCA and .CRT$XCU. In the general case, we
19510b57cec5SDimitry Andric     // make a name like ".CRT$XCT12345", since that runs before .CRT$XCU. Really
19520b57cec5SDimitry Andric     // low priorities need to sort before 'L', since the CRT uses that
1953bdd1243dSDimitry Andric     // internally, so we use ".CRT$XCA00001" for them. We have a contract with
1954bdd1243dSDimitry Andric     // the frontend that "init_seg(compiler)" corresponds to priority 200 and
1955bdd1243dSDimitry Andric     // "init_seg(lib)" corresponds to priority 400, and those respectively use
1956bdd1243dSDimitry Andric     // 'C' and 'L' without the priority suffix. Priorities between 200 and 400
1957bdd1243dSDimitry Andric     // use 'C' with the priority as a suffix.
19580b57cec5SDimitry Andric     SmallString<24> Name;
1959bdd1243dSDimitry Andric     char LastLetter = 'T';
1960bdd1243dSDimitry Andric     bool AddPrioritySuffix = Priority != 200 && Priority != 400;
1961bdd1243dSDimitry Andric     if (Priority < 200)
1962bdd1243dSDimitry Andric       LastLetter = 'A';
1963bdd1243dSDimitry Andric     else if (Priority < 400)
1964bdd1243dSDimitry Andric       LastLetter = 'C';
1965bdd1243dSDimitry Andric     else if (Priority == 400)
1966bdd1243dSDimitry Andric       LastLetter = 'L';
19670b57cec5SDimitry Andric     raw_svector_ostream OS(Name);
1968bdd1243dSDimitry Andric     OS << ".CRT$X" << (IsCtor ? "C" : "T") << LastLetter;
1969bdd1243dSDimitry Andric     if (AddPrioritySuffix)
1970bdd1243dSDimitry Andric       OS << format("%05u", Priority);
19710b57cec5SDimitry Andric     MCSectionCOFF *Sec = Ctx.getCOFFSection(
19720b57cec5SDimitry Andric         Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
19730b57cec5SDimitry Andric         SectionKind::getReadOnly());
19740b57cec5SDimitry Andric     return Ctx.getAssociativeCOFFSection(Sec, KeySym, 0);
19750b57cec5SDimitry Andric   }
19760b57cec5SDimitry Andric 
19770b57cec5SDimitry Andric   std::string Name = IsCtor ? ".ctors" : ".dtors";
19780b57cec5SDimitry Andric   if (Priority != 65535)
19790b57cec5SDimitry Andric     raw_string_ostream(Name) << format(".%05u", 65535 - Priority);
19800b57cec5SDimitry Andric 
19810b57cec5SDimitry Andric   return Ctx.getAssociativeCOFFSection(
19820b57cec5SDimitry Andric       Ctx.getCOFFSection(Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19830b57cec5SDimitry Andric                                    COFF::IMAGE_SCN_MEM_READ |
19840b57cec5SDimitry Andric                                    COFF::IMAGE_SCN_MEM_WRITE,
19850b57cec5SDimitry Andric                          SectionKind::getData()),
19860b57cec5SDimitry Andric       KeySym, 0);
19870b57cec5SDimitry Andric }
19880b57cec5SDimitry Andric 
19890b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
19900b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
1991fe6060f1SDimitry Andric   return getCOFFStaticStructorSection(
1992fe6060f1SDimitry Andric       getContext(), getContext().getTargetTriple(), true, Priority, KeySym,
19930b57cec5SDimitry Andric       cast<MCSectionCOFF>(StaticCtorSection));
19940b57cec5SDimitry Andric }
19950b57cec5SDimitry Andric 
19960b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
19970b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
1998fe6060f1SDimitry Andric   return getCOFFStaticStructorSection(
1999fe6060f1SDimitry Andric       getContext(), getContext().getTargetTriple(), false, Priority, KeySym,
20000b57cec5SDimitry Andric       cast<MCSectionCOFF>(StaticDtorSection));
20010b57cec5SDimitry Andric }
20020b57cec5SDimitry Andric 
20030b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
20040b57cec5SDimitry Andric     const GlobalValue *LHS, const GlobalValue *RHS,
20050b57cec5SDimitry Andric     const TargetMachine &TM) const {
20060b57cec5SDimitry Andric   const Triple &T = TM.getTargetTriple();
20070b57cec5SDimitry Andric   if (T.isOSCygMing())
20080b57cec5SDimitry Andric     return nullptr;
20090b57cec5SDimitry Andric 
20100b57cec5SDimitry Andric   // Our symbols should exist in address space zero, cowardly no-op if
20110b57cec5SDimitry Andric   // otherwise.
20120b57cec5SDimitry Andric   if (LHS->getType()->getPointerAddressSpace() != 0 ||
20130b57cec5SDimitry Andric       RHS->getType()->getPointerAddressSpace() != 0)
20140b57cec5SDimitry Andric     return nullptr;
20150b57cec5SDimitry Andric 
20160b57cec5SDimitry Andric   // Both ptrtoint instructions must wrap global objects:
20170b57cec5SDimitry Andric   // - Only global variables are eligible for image relative relocations.
20180b57cec5SDimitry Andric   // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable.
20190b57cec5SDimitry Andric   // We expect __ImageBase to be a global variable without a section, externally
20200b57cec5SDimitry Andric   // defined.
20210b57cec5SDimitry Andric   //
20220b57cec5SDimitry Andric   // It should look something like this: @__ImageBase = external constant i8
20230b57cec5SDimitry Andric   if (!isa<GlobalObject>(LHS) || !isa<GlobalVariable>(RHS) ||
20240b57cec5SDimitry Andric       LHS->isThreadLocal() || RHS->isThreadLocal() ||
20250b57cec5SDimitry Andric       RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() ||
20260b57cec5SDimitry Andric       cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection())
20270b57cec5SDimitry Andric     return nullptr;
20280b57cec5SDimitry Andric 
20290b57cec5SDimitry Andric   return MCSymbolRefExpr::create(TM.getSymbol(LHS),
20300b57cec5SDimitry Andric                                  MCSymbolRefExpr::VK_COFF_IMGREL32,
20310b57cec5SDimitry Andric                                  getContext());
20320b57cec5SDimitry Andric }
20330b57cec5SDimitry Andric 
20340b57cec5SDimitry Andric static std::string APIntToHexString(const APInt &AI) {
20350b57cec5SDimitry Andric   unsigned Width = (AI.getBitWidth() / 8) * 2;
2036fe6060f1SDimitry Andric   std::string HexString = toString(AI, 16, /*Signed=*/false);
20375ffd83dbSDimitry Andric   llvm::transform(HexString, HexString.begin(), tolower);
20380b57cec5SDimitry Andric   unsigned Size = HexString.size();
20390b57cec5SDimitry Andric   assert(Width >= Size && "hex string is too large!");
20400b57cec5SDimitry Andric   HexString.insert(HexString.begin(), Width - Size, '0');
20410b57cec5SDimitry Andric 
20420b57cec5SDimitry Andric   return HexString;
20430b57cec5SDimitry Andric }
20440b57cec5SDimitry Andric 
20450b57cec5SDimitry Andric static std::string scalarConstantToHexString(const Constant *C) {
20460b57cec5SDimitry Andric   Type *Ty = C->getType();
20470b57cec5SDimitry Andric   if (isa<UndefValue>(C)) {
2048349cc55cSDimitry Andric     return APIntToHexString(APInt::getZero(Ty->getPrimitiveSizeInBits()));
20490b57cec5SDimitry Andric   } else if (const auto *CFP = dyn_cast<ConstantFP>(C)) {
20500b57cec5SDimitry Andric     return APIntToHexString(CFP->getValueAPF().bitcastToAPInt());
20510b57cec5SDimitry Andric   } else if (const auto *CI = dyn_cast<ConstantInt>(C)) {
20520b57cec5SDimitry Andric     return APIntToHexString(CI->getValue());
20530b57cec5SDimitry Andric   } else {
20540b57cec5SDimitry Andric     unsigned NumElements;
20555ffd83dbSDimitry Andric     if (auto *VTy = dyn_cast<VectorType>(Ty))
20565ffd83dbSDimitry Andric       NumElements = cast<FixedVectorType>(VTy)->getNumElements();
20570b57cec5SDimitry Andric     else
20580b57cec5SDimitry Andric       NumElements = Ty->getArrayNumElements();
20590b57cec5SDimitry Andric     std::string HexString;
20600b57cec5SDimitry Andric     for (int I = NumElements - 1, E = -1; I != E; --I)
20610b57cec5SDimitry Andric       HexString += scalarConstantToHexString(C->getAggregateElement(I));
20620b57cec5SDimitry Andric     return HexString;
20630b57cec5SDimitry Andric   }
20640b57cec5SDimitry Andric }
20650b57cec5SDimitry Andric 
20660b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant(
20670b57cec5SDimitry Andric     const DataLayout &DL, SectionKind Kind, const Constant *C,
20685ffd83dbSDimitry Andric     Align &Alignment) const {
20690b57cec5SDimitry Andric   if (Kind.isMergeableConst() && C &&
20700b57cec5SDimitry Andric       getContext().getAsmInfo()->hasCOFFComdatConstants()) {
20710b57cec5SDimitry Andric     // This creates comdat sections with the given symbol name, but unless
20720b57cec5SDimitry Andric     // AsmPrinter::GetCPISymbol actually makes the symbol global, the symbol
20730b57cec5SDimitry Andric     // will be created with a null storage class, which makes GNU binutils
20740b57cec5SDimitry Andric     // error out.
20750b57cec5SDimitry Andric     const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
20760b57cec5SDimitry Andric                                      COFF::IMAGE_SCN_MEM_READ |
20770b57cec5SDimitry Andric                                      COFF::IMAGE_SCN_LNK_COMDAT;
20780b57cec5SDimitry Andric     std::string COMDATSymName;
20790b57cec5SDimitry Andric     if (Kind.isMergeableConst4()) {
20805ffd83dbSDimitry Andric       if (Alignment <= 4) {
20810b57cec5SDimitry Andric         COMDATSymName = "__real@" + scalarConstantToHexString(C);
20825ffd83dbSDimitry Andric         Alignment = Align(4);
20830b57cec5SDimitry Andric       }
20840b57cec5SDimitry Andric     } else if (Kind.isMergeableConst8()) {
20855ffd83dbSDimitry Andric       if (Alignment <= 8) {
20860b57cec5SDimitry Andric         COMDATSymName = "__real@" + scalarConstantToHexString(C);
20875ffd83dbSDimitry Andric         Alignment = Align(8);
20880b57cec5SDimitry Andric       }
20890b57cec5SDimitry Andric     } else if (Kind.isMergeableConst16()) {
20900b57cec5SDimitry Andric       // FIXME: These may not be appropriate for non-x86 architectures.
20915ffd83dbSDimitry Andric       if (Alignment <= 16) {
20920b57cec5SDimitry Andric         COMDATSymName = "__xmm@" + scalarConstantToHexString(C);
20935ffd83dbSDimitry Andric         Alignment = Align(16);
20940b57cec5SDimitry Andric       }
20950b57cec5SDimitry Andric     } else if (Kind.isMergeableConst32()) {
20965ffd83dbSDimitry Andric       if (Alignment <= 32) {
20970b57cec5SDimitry Andric         COMDATSymName = "__ymm@" + scalarConstantToHexString(C);
20985ffd83dbSDimitry Andric         Alignment = Align(32);
20990b57cec5SDimitry Andric       }
21000b57cec5SDimitry Andric     }
21010b57cec5SDimitry Andric 
21020b57cec5SDimitry Andric     if (!COMDATSymName.empty())
21030b57cec5SDimitry Andric       return getContext().getCOFFSection(".rdata", Characteristics, Kind,
21040b57cec5SDimitry Andric                                          COMDATSymName,
21050b57cec5SDimitry Andric                                          COFF::IMAGE_COMDAT_SELECT_ANY);
21060b57cec5SDimitry Andric   }
21070b57cec5SDimitry Andric 
21085ffd83dbSDimitry Andric   return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C,
21095ffd83dbSDimitry Andric                                                          Alignment);
21100b57cec5SDimitry Andric }
21110b57cec5SDimitry Andric 
21120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21130b57cec5SDimitry Andric //                                  Wasm
21140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21150b57cec5SDimitry Andric 
21160b57cec5SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) {
21170b57cec5SDimitry Andric   const Comdat *C = GV->getComdat();
21180b57cec5SDimitry Andric   if (!C)
21190b57cec5SDimitry Andric     return nullptr;
21200b57cec5SDimitry Andric 
21210b57cec5SDimitry Andric   if (C->getSelectionKind() != Comdat::Any)
21220b57cec5SDimitry Andric     report_fatal_error("WebAssembly COMDATs only support "
21230b57cec5SDimitry Andric                        "SelectionKind::Any, '" + C->getName() + "' cannot be "
21240b57cec5SDimitry Andric                        "lowered.");
21250b57cec5SDimitry Andric 
21260b57cec5SDimitry Andric   return C;
21270b57cec5SDimitry Andric }
21280b57cec5SDimitry Andric 
2129fe6060f1SDimitry Andric static unsigned getWasmSectionFlags(SectionKind K) {
2130fe6060f1SDimitry Andric   unsigned Flags = 0;
2131fe6060f1SDimitry Andric 
2132fe6060f1SDimitry Andric   if (K.isThreadLocal())
2133fe6060f1SDimitry Andric     Flags |= wasm::WASM_SEG_FLAG_TLS;
2134fe6060f1SDimitry Andric 
2135fe6060f1SDimitry Andric   if (K.isMergeableCString())
2136fe6060f1SDimitry Andric     Flags |= wasm::WASM_SEG_FLAG_STRINGS;
2137fe6060f1SDimitry Andric 
2138fe6060f1SDimitry Andric   // TODO(sbc): Add suport for K.isMergeableConst()
2139fe6060f1SDimitry Andric 
2140fe6060f1SDimitry Andric   return Flags;
2141fe6060f1SDimitry Andric }
2142fe6060f1SDimitry Andric 
21430b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(
21440b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
21450b57cec5SDimitry Andric   // We don't support explict section names for functions in the wasm object
21460b57cec5SDimitry Andric   // format.  Each function has to be in its own unique section.
21470b57cec5SDimitry Andric   if (isa<Function>(GO)) {
21480b57cec5SDimitry Andric     return SelectSectionForGlobal(GO, Kind, TM);
21490b57cec5SDimitry Andric   }
21500b57cec5SDimitry Andric 
21510b57cec5SDimitry Andric   StringRef Name = GO->getSection();
21520b57cec5SDimitry Andric 
21535ffd83dbSDimitry Andric   // Certain data sections we treat as named custom sections rather than
21545ffd83dbSDimitry Andric   // segments within the data section.
21555ffd83dbSDimitry Andric   // This could be avoided if all data segements (the wasm sense) were
21565ffd83dbSDimitry Andric   // represented as their own sections (in the llvm sense).
21575ffd83dbSDimitry Andric   // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138
21585ffd83dbSDimitry Andric   if (Name == ".llvmcmd" || Name == ".llvmbc")
21595ffd83dbSDimitry Andric     Kind = SectionKind::getMetadata();
21600b57cec5SDimitry Andric 
21610b57cec5SDimitry Andric   StringRef Group = "";
21620b57cec5SDimitry Andric   if (const Comdat *C = getWasmComdat(GO)) {
21630b57cec5SDimitry Andric     Group = C->getName();
21640b57cec5SDimitry Andric   }
21650b57cec5SDimitry Andric 
2166fe6060f1SDimitry Andric   unsigned Flags = getWasmSectionFlags(Kind);
2167fe6060f1SDimitry Andric   MCSectionWasm *Section = getContext().getWasmSection(
2168fe6060f1SDimitry Andric       Name, Kind, Flags, Group, MCContext::GenericSectionID);
21690b57cec5SDimitry Andric 
21700b57cec5SDimitry Andric   return Section;
21710b57cec5SDimitry Andric }
21720b57cec5SDimitry Andric 
21730b57cec5SDimitry Andric static MCSectionWasm *selectWasmSectionForGlobal(
21740b57cec5SDimitry Andric     MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
21750b57cec5SDimitry Andric     const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) {
21760b57cec5SDimitry Andric   StringRef Group = "";
21770b57cec5SDimitry Andric   if (const Comdat *C = getWasmComdat(GO)) {
21780b57cec5SDimitry Andric     Group = C->getName();
21790b57cec5SDimitry Andric   }
21800b57cec5SDimitry Andric 
21810b57cec5SDimitry Andric   bool UniqueSectionNames = TM.getUniqueSectionNames();
2182*fe013be4SDimitry Andric   SmallString<128> Name = getSectionPrefixForGlobal(Kind, /*IsLarge=*/false);
21830b57cec5SDimitry Andric 
21840b57cec5SDimitry Andric   if (const auto *F = dyn_cast<Function>(GO)) {
21850b57cec5SDimitry Andric     const auto &OptionalPrefix = F->getSectionPrefix();
21860b57cec5SDimitry Andric     if (OptionalPrefix)
2187e8d8bef9SDimitry Andric       raw_svector_ostream(Name) << '.' << *OptionalPrefix;
21880b57cec5SDimitry Andric   }
21890b57cec5SDimitry Andric 
21900b57cec5SDimitry Andric   if (EmitUniqueSection && UniqueSectionNames) {
21910b57cec5SDimitry Andric     Name.push_back('.');
21920b57cec5SDimitry Andric     TM.getNameWithPrefix(Name, GO, Mang, true);
21930b57cec5SDimitry Andric   }
21940b57cec5SDimitry Andric   unsigned UniqueID = MCContext::GenericSectionID;
21950b57cec5SDimitry Andric   if (EmitUniqueSection && !UniqueSectionNames) {
21960b57cec5SDimitry Andric     UniqueID = *NextUniqueID;
21970b57cec5SDimitry Andric     (*NextUniqueID)++;
21980b57cec5SDimitry Andric   }
21990b57cec5SDimitry Andric 
2200fe6060f1SDimitry Andric   unsigned Flags = getWasmSectionFlags(Kind);
2201fe6060f1SDimitry Andric   return Ctx.getWasmSection(Name, Kind, Flags, Group, UniqueID);
22020b57cec5SDimitry Andric }
22030b57cec5SDimitry Andric 
22040b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal(
22050b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
22060b57cec5SDimitry Andric 
22070b57cec5SDimitry Andric   if (Kind.isCommon())
22080b57cec5SDimitry Andric     report_fatal_error("mergable sections not supported yet on wasm");
22090b57cec5SDimitry Andric 
22100b57cec5SDimitry Andric   // If we have -ffunction-section or -fdata-section then we should emit the
22110b57cec5SDimitry Andric   // global value to a uniqued section specifically for it.
22120b57cec5SDimitry Andric   bool EmitUniqueSection = false;
22130b57cec5SDimitry Andric   if (Kind.isText())
22140b57cec5SDimitry Andric     EmitUniqueSection = TM.getFunctionSections();
22150b57cec5SDimitry Andric   else
22160b57cec5SDimitry Andric     EmitUniqueSection = TM.getDataSections();
22170b57cec5SDimitry Andric   EmitUniqueSection |= GO->hasComdat();
22180b57cec5SDimitry Andric 
22190b57cec5SDimitry Andric   return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
22200b57cec5SDimitry Andric                                     EmitUniqueSection, &NextUniqueID);
22210b57cec5SDimitry Andric }
22220b57cec5SDimitry Andric 
22230b57cec5SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection(
22240b57cec5SDimitry Andric     bool UsesLabelDifference, const Function &F) const {
22250b57cec5SDimitry Andric   // We can always create relative relocations, so use another section
22260b57cec5SDimitry Andric   // that can be marked non-executable.
22270b57cec5SDimitry Andric   return false;
22280b57cec5SDimitry Andric }
22290b57cec5SDimitry Andric 
22300b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference(
22310b57cec5SDimitry Andric     const GlobalValue *LHS, const GlobalValue *RHS,
22320b57cec5SDimitry Andric     const TargetMachine &TM) const {
22330b57cec5SDimitry Andric   // We may only use a PLT-relative relocation to refer to unnamed_addr
22340b57cec5SDimitry Andric   // functions.
22350b57cec5SDimitry Andric   if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
22360b57cec5SDimitry Andric     return nullptr;
22370b57cec5SDimitry Andric 
22384824e7fdSDimitry Andric   // Basic correctness checks.
22390b57cec5SDimitry Andric   if (LHS->getType()->getPointerAddressSpace() != 0 ||
22400b57cec5SDimitry Andric       RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() ||
22410b57cec5SDimitry Andric       RHS->isThreadLocal())
22420b57cec5SDimitry Andric     return nullptr;
22430b57cec5SDimitry Andric 
22440b57cec5SDimitry Andric   return MCBinaryExpr::createSub(
22450b57cec5SDimitry Andric       MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None,
22460b57cec5SDimitry Andric                               getContext()),
22470b57cec5SDimitry Andric       MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
22480b57cec5SDimitry Andric }
22490b57cec5SDimitry Andric 
22500b57cec5SDimitry Andric void TargetLoweringObjectFileWasm::InitializeWasm() {
22510b57cec5SDimitry Andric   StaticCtorSection =
22520b57cec5SDimitry Andric       getContext().getWasmSection(".init_array", SectionKind::getData());
22530b57cec5SDimitry Andric 
22540b57cec5SDimitry Andric   // We don't use PersonalityEncoding and LSDAEncoding because we don't emit
22550b57cec5SDimitry Andric   // .cfi directives. We use TTypeEncoding to encode typeinfo global variables.
22560b57cec5SDimitry Andric   TTypeEncoding = dwarf::DW_EH_PE_absptr;
22570b57cec5SDimitry Andric }
22580b57cec5SDimitry Andric 
22590b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticCtorSection(
22600b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
22610b57cec5SDimitry Andric   return Priority == UINT16_MAX ?
22620b57cec5SDimitry Andric          StaticCtorSection :
22630b57cec5SDimitry Andric          getContext().getWasmSection(".init_array." + utostr(Priority),
22640b57cec5SDimitry Andric                                      SectionKind::getData());
22650b57cec5SDimitry Andric }
22660b57cec5SDimitry Andric 
22670b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection(
22680b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
226981ad6265SDimitry Andric   report_fatal_error("@llvm.global_dtors should have been lowered already");
22700b57cec5SDimitry Andric }
22718bcb0991SDimitry Andric 
22728bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
22738bcb0991SDimitry Andric //                                  XCOFF
22748bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
2275e8d8bef9SDimitry Andric bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(
2276e8d8bef9SDimitry Andric     const MachineFunction *MF) {
2277e8d8bef9SDimitry Andric   if (!MF->getLandingPads().empty())
2278e8d8bef9SDimitry Andric     return true;
2279e8d8bef9SDimitry Andric 
2280e8d8bef9SDimitry Andric   const Function &F = MF->getFunction();
2281e8d8bef9SDimitry Andric   if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry())
2282e8d8bef9SDimitry Andric     return false;
2283e8d8bef9SDimitry Andric 
2284fe6060f1SDimitry Andric   const GlobalValue *Per =
2285fe6060f1SDimitry Andric       dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
2286fe6060f1SDimitry Andric   assert(Per && "Personality routine is not a GlobalValue type.");
2287e8d8bef9SDimitry Andric   if (isNoOpWithoutInvoke(classifyEHPersonality(Per)))
2288e8d8bef9SDimitry Andric     return false;
2289e8d8bef9SDimitry Andric 
2290e8d8bef9SDimitry Andric   return true;
2291e8d8bef9SDimitry Andric }
2292e8d8bef9SDimitry Andric 
2293fe6060f1SDimitry Andric bool TargetLoweringObjectFileXCOFF::ShouldSetSSPCanaryBitInTB(
2294fe6060f1SDimitry Andric     const MachineFunction *MF) {
2295fe6060f1SDimitry Andric   const Function &F = MF->getFunction();
2296fe6060f1SDimitry Andric   if (!F.hasStackProtectorFnAttr())
2297fe6060f1SDimitry Andric     return false;
2298fe6060f1SDimitry Andric   // FIXME: check presence of canary word
2299fe6060f1SDimitry Andric   // There are cases that the stack protectors are not really inserted even if
2300fe6060f1SDimitry Andric   // the attributes are on.
2301fe6060f1SDimitry Andric   return true;
2302fe6060f1SDimitry Andric }
2303fe6060f1SDimitry Andric 
2304e8d8bef9SDimitry Andric MCSymbol *
2305e8d8bef9SDimitry Andric TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) {
2306e8d8bef9SDimitry Andric   return MF->getMMI().getContext().getOrCreateSymbol(
2307e8d8bef9SDimitry Andric       "__ehinfo." + Twine(MF->getFunctionNumber()));
2308e8d8bef9SDimitry Andric }
2309e8d8bef9SDimitry Andric 
23105ffd83dbSDimitry Andric MCSymbol *
23115ffd83dbSDimitry Andric TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
23125ffd83dbSDimitry Andric                                                const TargetMachine &TM) const {
23135ffd83dbSDimitry Andric   // We always use a qualname symbol for a GV that represents
23145ffd83dbSDimitry Andric   // a declaration, a function descriptor, or a common symbol.
2315e8d8bef9SDimitry Andric   // If a GV represents a GlobalVariable and -fdata-sections is enabled, we
2316e8d8bef9SDimitry Andric   // also return a qualname so that a label symbol could be avoided.
23175ffd83dbSDimitry Andric   // It is inherently ambiguous when the GO represents the address of a
23185ffd83dbSDimitry Andric   // function, as the GO could either represent a function descriptor or a
23195ffd83dbSDimitry Andric   // function entry point. We choose to always return a function descriptor
23205ffd83dbSDimitry Andric   // here.
23215ffd83dbSDimitry Andric   if (const GlobalObject *GO = dyn_cast<GlobalObject>(GV)) {
2322bdd1243dSDimitry Andric     if (GO->isDeclarationForLinker())
2323bdd1243dSDimitry Andric       return cast<MCSectionXCOFF>(getSectionForExternalReference(GO, TM))
2324bdd1243dSDimitry Andric           ->getQualNameSymbol();
2325bdd1243dSDimitry Andric 
2326fe6060f1SDimitry Andric     if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
2327fe6060f1SDimitry Andric       if (GVar->hasAttribute("toc-data"))
2328fe6060f1SDimitry Andric         return cast<MCSectionXCOFF>(
2329fe6060f1SDimitry Andric                    SectionForGlobal(GVar, SectionKind::getData(), TM))
2330fe6060f1SDimitry Andric             ->getQualNameSymbol();
2331fe6060f1SDimitry Andric 
23325ffd83dbSDimitry Andric     SectionKind GOKind = getKindForGlobal(GO, TM);
23335ffd83dbSDimitry Andric     if (GOKind.isText())
23345ffd83dbSDimitry Andric       return cast<MCSectionXCOFF>(
23355ffd83dbSDimitry Andric                  getSectionForFunctionDescriptor(cast<Function>(GO), TM))
23365ffd83dbSDimitry Andric           ->getQualNameSymbol();
2337fe6060f1SDimitry Andric     if ((TM.getDataSections() && !GO->hasSection()) || GO->hasCommonLinkage() ||
2338fe6060f1SDimitry Andric         GOKind.isBSSLocal() || GOKind.isThreadBSSLocal())
23395ffd83dbSDimitry Andric       return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM))
23405ffd83dbSDimitry Andric           ->getQualNameSymbol();
23415ffd83dbSDimitry Andric   }
23425ffd83dbSDimitry Andric 
23435ffd83dbSDimitry Andric   // For all other cases, fall back to getSymbol to return the unqualified name.
23445ffd83dbSDimitry Andric   return nullptr;
23455ffd83dbSDimitry Andric }
23465ffd83dbSDimitry Andric 
23478bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
23488bcb0991SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2349e8d8bef9SDimitry Andric   if (!GO->hasSection())
2350e8d8bef9SDimitry Andric     report_fatal_error("#pragma clang section is not yet supported");
2351e8d8bef9SDimitry Andric 
2352e8d8bef9SDimitry Andric   StringRef SectionName = GO->getSection();
2353fe6060f1SDimitry Andric 
2354fe6060f1SDimitry Andric   // Handle the XCOFF::TD case first, then deal with the rest.
2355fe6060f1SDimitry Andric   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))
2356fe6060f1SDimitry Andric     if (GVar->hasAttribute("toc-data"))
2357fe6060f1SDimitry Andric       return getContext().getXCOFFSection(
2358fe6060f1SDimitry Andric           SectionName, Kind,
2359fe6060f1SDimitry Andric           XCOFF::CsectProperties(/*MappingClass*/ XCOFF::XMC_TD, XCOFF::XTY_SD),
2360fe6060f1SDimitry Andric           /* MultiSymbolsAllowed*/ true);
2361fe6060f1SDimitry Andric 
2362e8d8bef9SDimitry Andric   XCOFF::StorageMappingClass MappingClass;
2363e8d8bef9SDimitry Andric   if (Kind.isText())
2364e8d8bef9SDimitry Andric     MappingClass = XCOFF::XMC_PR;
2365*fe013be4SDimitry Andric   else if (Kind.isData() || Kind.isBSS())
2366e8d8bef9SDimitry Andric     MappingClass = XCOFF::XMC_RW;
2367*fe013be4SDimitry Andric   else if (Kind.isReadOnlyWithRel())
2368*fe013be4SDimitry Andric     MappingClass =
2369*fe013be4SDimitry Andric         TM.Options.XCOFFReadOnlyPointers ? XCOFF::XMC_RO : XCOFF::XMC_RW;
2370e8d8bef9SDimitry Andric   else if (Kind.isReadOnly())
2371e8d8bef9SDimitry Andric     MappingClass = XCOFF::XMC_RO;
2372e8d8bef9SDimitry Andric   else
2373e8d8bef9SDimitry Andric     report_fatal_error("XCOFF other section types not yet implemented.");
2374e8d8bef9SDimitry Andric 
2375fe6060f1SDimitry Andric   return getContext().getXCOFFSection(
2376fe6060f1SDimitry Andric       SectionName, Kind, XCOFF::CsectProperties(MappingClass, XCOFF::XTY_SD),
2377fe6060f1SDimitry Andric       /* MultiSymbolsAllowed*/ true);
23788bcb0991SDimitry Andric }
23798bcb0991SDimitry Andric 
23805ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference(
23815ffd83dbSDimitry Andric     const GlobalObject *GO, const TargetMachine &TM) const {
23825ffd83dbSDimitry Andric   assert(GO->isDeclarationForLinker() &&
23835ffd83dbSDimitry Andric          "Tried to get ER section for a defined global.");
23845ffd83dbSDimitry Andric 
23855ffd83dbSDimitry Andric   SmallString<128> Name;
23865ffd83dbSDimitry Andric   getNameWithPrefix(Name, GO, TM);
23875ffd83dbSDimitry Andric 
2388fe6060f1SDimitry Andric   XCOFF::StorageMappingClass SMC =
2389fe6060f1SDimitry Andric       isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA;
2390fe6060f1SDimitry Andric   if (GO->isThreadLocal())
2391fe6060f1SDimitry Andric     SMC = XCOFF::XMC_UL;
2392fe6060f1SDimitry Andric 
2393bdd1243dSDimitry Andric   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))
2394bdd1243dSDimitry Andric     if (GVar->hasAttribute("toc-data"))
2395bdd1243dSDimitry Andric       SMC = XCOFF::XMC_TD;
2396bdd1243dSDimitry Andric 
23975ffd83dbSDimitry Andric   // Externals go into a csect of type ER.
23985ffd83dbSDimitry Andric   return getContext().getXCOFFSection(
2399fe6060f1SDimitry Andric       Name, SectionKind::getMetadata(),
2400fe6060f1SDimitry Andric       XCOFF::CsectProperties(SMC, XCOFF::XTY_ER));
24015ffd83dbSDimitry Andric }
24025ffd83dbSDimitry Andric 
24038bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
24048bcb0991SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2405fe6060f1SDimitry Andric   // Handle the XCOFF::TD case first, then deal with the rest.
2406fe6060f1SDimitry Andric   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))
2407fe6060f1SDimitry Andric     if (GVar->hasAttribute("toc-data")) {
24088bcb0991SDimitry Andric       SmallString<128> Name;
24098bcb0991SDimitry Andric       getNameWithPrefix(Name, GO, TM);
24108bcb0991SDimitry Andric       return getContext().getXCOFFSection(
2411fe6060f1SDimitry Andric           Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TD, XCOFF::XTY_SD),
2412fe6060f1SDimitry Andric           /* MultiSymbolsAllowed*/ true);
2413fe6060f1SDimitry Andric     }
2414fe6060f1SDimitry Andric 
2415fe6060f1SDimitry Andric   // Common symbols go into a csect with matching name which will get mapped
2416fe6060f1SDimitry Andric   // into the .bss section.
2417fe6060f1SDimitry Andric   // Zero-initialized local TLS symbols go into a csect with matching name which
2418fe6060f1SDimitry Andric   // will get mapped into the .tbss section.
2419fe6060f1SDimitry Andric   if (Kind.isBSSLocal() || GO->hasCommonLinkage() || Kind.isThreadBSSLocal()) {
2420fe6060f1SDimitry Andric     SmallString<128> Name;
2421fe6060f1SDimitry Andric     getNameWithPrefix(Name, GO, TM);
2422fe6060f1SDimitry Andric     XCOFF::StorageMappingClass SMC = Kind.isBSSLocal() ? XCOFF::XMC_BS
2423fe6060f1SDimitry Andric                                      : Kind.isCommon() ? XCOFF::XMC_RW
2424fe6060f1SDimitry Andric                                                        : XCOFF::XMC_UL;
2425fe6060f1SDimitry Andric     return getContext().getXCOFFSection(
2426fe6060f1SDimitry Andric         Name, Kind, XCOFF::CsectProperties(SMC, XCOFF::XTY_CM));
24278bcb0991SDimitry Andric   }
24288bcb0991SDimitry Andric 
2429480093f4SDimitry Andric   if (Kind.isMergeableCString()) {
24305ffd83dbSDimitry Andric     Align Alignment = GO->getParent()->getDataLayout().getPreferredAlign(
2431480093f4SDimitry Andric         cast<GlobalVariable>(GO));
2432480093f4SDimitry Andric 
2433480093f4SDimitry Andric     unsigned EntrySize = getEntrySizeForKind(Kind);
2434480093f4SDimitry Andric     std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + ".";
2435480093f4SDimitry Andric     SmallString<128> Name;
24365ffd83dbSDimitry Andric     Name = SizeSpec + utostr(Alignment.value());
2437480093f4SDimitry Andric 
2438e8d8bef9SDimitry Andric     if (TM.getDataSections())
2439e8d8bef9SDimitry Andric       getNameWithPrefix(Name, GO, TM);
2440e8d8bef9SDimitry Andric 
2441480093f4SDimitry Andric     return getContext().getXCOFFSection(
2442fe6060f1SDimitry Andric         Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD),
2443e8d8bef9SDimitry Andric         /* MultiSymbolsAllowed*/ !TM.getDataSections());
2444480093f4SDimitry Andric   }
2445480093f4SDimitry Andric 
2446e8d8bef9SDimitry Andric   if (Kind.isText()) {
2447e8d8bef9SDimitry Andric     if (TM.getFunctionSections()) {
2448e8d8bef9SDimitry Andric       return cast<MCSymbolXCOFF>(getFunctionEntryPointSymbol(GO, TM))
2449e8d8bef9SDimitry Andric           ->getRepresentedCsect();
2450e8d8bef9SDimitry Andric     }
24518bcb0991SDimitry Andric     return TextSection;
2452e8d8bef9SDimitry Andric   }
24538bcb0991SDimitry Andric 
2454*fe013be4SDimitry Andric   if (TM.Options.XCOFFReadOnlyPointers && Kind.isReadOnlyWithRel()) {
2455*fe013be4SDimitry Andric     if (!TM.getDataSections())
2456*fe013be4SDimitry Andric       report_fatal_error(
2457*fe013be4SDimitry Andric           "ReadOnlyPointers is supported only if data sections is turned on");
2458*fe013be4SDimitry Andric 
2459*fe013be4SDimitry Andric     SmallString<128> Name;
2460*fe013be4SDimitry Andric     getNameWithPrefix(Name, GO, TM);
2461*fe013be4SDimitry Andric     return getContext().getXCOFFSection(
2462*fe013be4SDimitry Andric         Name, SectionKind::getReadOnly(),
2463*fe013be4SDimitry Andric         XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));
2464*fe013be4SDimitry Andric   }
2465*fe013be4SDimitry Andric 
2466e8d8bef9SDimitry Andric   // For BSS kind, zero initialized data must be emitted to the .data section
2467e8d8bef9SDimitry Andric   // because external linkage control sections that get mapped to the .bss
2468e8d8bef9SDimitry Andric   // section will be linked as tentative defintions, which is only appropriate
2469e8d8bef9SDimitry Andric   // for SectionKind::Common.
2470e8d8bef9SDimitry Andric   if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS()) {
2471e8d8bef9SDimitry Andric     if (TM.getDataSections()) {
2472e8d8bef9SDimitry Andric       SmallString<128> Name;
2473e8d8bef9SDimitry Andric       getNameWithPrefix(Name, GO, TM);
2474fe6060f1SDimitry Andric       return getContext().getXCOFFSection(
2475fe6060f1SDimitry Andric           Name, SectionKind::getData(),
2476fe6060f1SDimitry Andric           XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD));
2477e8d8bef9SDimitry Andric     }
24788bcb0991SDimitry Andric     return DataSection;
2479e8d8bef9SDimitry Andric   }
24808bcb0991SDimitry Andric 
2481e8d8bef9SDimitry Andric   if (Kind.isReadOnly()) {
2482e8d8bef9SDimitry Andric     if (TM.getDataSections()) {
2483e8d8bef9SDimitry Andric       SmallString<128> Name;
2484e8d8bef9SDimitry Andric       getNameWithPrefix(Name, GO, TM);
2485fe6060f1SDimitry Andric       return getContext().getXCOFFSection(
2486fe6060f1SDimitry Andric           Name, SectionKind::getReadOnly(),
2487fe6060f1SDimitry Andric           XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));
2488e8d8bef9SDimitry Andric     }
2489480093f4SDimitry Andric     return ReadOnlySection;
2490e8d8bef9SDimitry Andric   }
2491480093f4SDimitry Andric 
2492fe6060f1SDimitry Andric   // External/weak TLS data and initialized local TLS data are not eligible
2493fe6060f1SDimitry Andric   // to be put into common csect. If data sections are enabled, thread
2494fe6060f1SDimitry Andric   // data are emitted into separate sections. Otherwise, thread data
2495fe6060f1SDimitry Andric   // are emitted into the .tdata section.
2496fe6060f1SDimitry Andric   if (Kind.isThreadLocal()) {
2497fe6060f1SDimitry Andric     if (TM.getDataSections()) {
2498fe6060f1SDimitry Andric       SmallString<128> Name;
2499fe6060f1SDimitry Andric       getNameWithPrefix(Name, GO, TM);
2500fe6060f1SDimitry Andric       return getContext().getXCOFFSection(
2501fe6060f1SDimitry Andric           Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TL, XCOFF::XTY_SD));
2502fe6060f1SDimitry Andric     }
2503fe6060f1SDimitry Andric     return TLSDataSection;
2504fe6060f1SDimitry Andric   }
2505fe6060f1SDimitry Andric 
25068bcb0991SDimitry Andric   report_fatal_error("XCOFF other section types not yet implemented.");
25078bcb0991SDimitry Andric }
25088bcb0991SDimitry Andric 
2509480093f4SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForJumpTable(
2510480093f4SDimitry Andric     const Function &F, const TargetMachine &TM) const {
2511480093f4SDimitry Andric   assert (!F.getComdat() && "Comdat not supported on XCOFF.");
2512e8d8bef9SDimitry Andric 
2513e8d8bef9SDimitry Andric   if (!TM.getFunctionSections())
2514480093f4SDimitry Andric     return ReadOnlySection;
2515e8d8bef9SDimitry Andric 
2516e8d8bef9SDimitry Andric   // If the function can be removed, produce a unique section so that
2517e8d8bef9SDimitry Andric   // the table doesn't prevent the removal.
2518e8d8bef9SDimitry Andric   SmallString<128> NameStr(".rodata.jmp..");
2519e8d8bef9SDimitry Andric   getNameWithPrefix(NameStr, &F, TM);
2520fe6060f1SDimitry Andric   return getContext().getXCOFFSection(
2521fe6060f1SDimitry Andric       NameStr, SectionKind::getReadOnly(),
2522fe6060f1SDimitry Andric       XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));
2523480093f4SDimitry Andric }
2524480093f4SDimitry Andric 
25258bcb0991SDimitry Andric bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection(
25268bcb0991SDimitry Andric     bool UsesLabelDifference, const Function &F) const {
2527480093f4SDimitry Andric   return false;
2528480093f4SDimitry Andric }
2529480093f4SDimitry Andric 
2530480093f4SDimitry Andric /// Given a mergeable constant with the specified size and relocation
2531480093f4SDimitry Andric /// information, return a section that it should be placed in.
2532480093f4SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForConstant(
2533480093f4SDimitry Andric     const DataLayout &DL, SectionKind Kind, const Constant *C,
25345ffd83dbSDimitry Andric     Align &Alignment) const {
2535480093f4SDimitry Andric   // TODO: Enable emiting constant pool to unique sections when we support it.
2536349cc55cSDimitry Andric   if (Alignment > Align(16))
2537349cc55cSDimitry Andric     report_fatal_error("Alignments greater than 16 not yet supported.");
2538349cc55cSDimitry Andric 
2539349cc55cSDimitry Andric   if (Alignment == Align(8)) {
2540349cc55cSDimitry Andric     assert(ReadOnly8Section && "Section should always be initialized.");
2541349cc55cSDimitry Andric     return ReadOnly8Section;
2542349cc55cSDimitry Andric   }
2543349cc55cSDimitry Andric 
2544349cc55cSDimitry Andric   if (Alignment == Align(16)) {
2545349cc55cSDimitry Andric     assert(ReadOnly16Section && "Section should always be initialized.");
2546349cc55cSDimitry Andric     return ReadOnly16Section;
2547349cc55cSDimitry Andric   }
2548349cc55cSDimitry Andric 
2549480093f4SDimitry Andric   return ReadOnlySection;
25508bcb0991SDimitry Andric }
25518bcb0991SDimitry Andric 
25528bcb0991SDimitry Andric void TargetLoweringObjectFileXCOFF::Initialize(MCContext &Ctx,
25538bcb0991SDimitry Andric                                                const TargetMachine &TgtM) {
25548bcb0991SDimitry Andric   TargetLoweringObjectFile::Initialize(Ctx, TgtM);
2555e8d8bef9SDimitry Andric   TTypeEncoding =
2556e8d8bef9SDimitry Andric       dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
2557e8d8bef9SDimitry Andric       (TgtM.getTargetTriple().isArch32Bit() ? dwarf::DW_EH_PE_sdata4
2558e8d8bef9SDimitry Andric                                             : dwarf::DW_EH_PE_sdata8);
25598bcb0991SDimitry Andric   PersonalityEncoding = 0;
25608bcb0991SDimitry Andric   LSDAEncoding = 0;
2561e8d8bef9SDimitry Andric   CallSiteEncoding = dwarf::DW_EH_PE_udata4;
2562bdd1243dSDimitry Andric 
2563bdd1243dSDimitry Andric   // AIX debug for thread local location is not ready. And for integrated as
2564bdd1243dSDimitry Andric   // mode, the relocatable address for the thread local variable will cause
2565bdd1243dSDimitry Andric   // linker error. So disable the location attribute generation for thread local
2566bdd1243dSDimitry Andric   // variables for now.
2567bdd1243dSDimitry Andric   // FIXME: when TLS debug on AIX is ready, remove this setting.
2568bdd1243dSDimitry Andric   SupportDebugThreadLocalLocation = false;
25698bcb0991SDimitry Andric }
25708bcb0991SDimitry Andric 
25718bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getStaticCtorSection(
25728bcb0991SDimitry Andric 	unsigned Priority, const MCSymbol *KeySym) const {
2573e8d8bef9SDimitry Andric   report_fatal_error("no static constructor section on AIX");
25748bcb0991SDimitry Andric }
25758bcb0991SDimitry Andric 
25768bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getStaticDtorSection(
25778bcb0991SDimitry Andric 	unsigned Priority, const MCSymbol *KeySym) const {
2578e8d8bef9SDimitry Andric   report_fatal_error("no static destructor section on AIX");
25798bcb0991SDimitry Andric }
25808bcb0991SDimitry Andric 
25818bcb0991SDimitry Andric const MCExpr *TargetLoweringObjectFileXCOFF::lowerRelativeReference(
25828bcb0991SDimitry Andric     const GlobalValue *LHS, const GlobalValue *RHS,
25838bcb0991SDimitry Andric     const TargetMachine &TM) const {
2584349cc55cSDimitry Andric   /* Not implemented yet, but don't crash, return nullptr. */
2585349cc55cSDimitry Andric   return nullptr;
25868bcb0991SDimitry Andric }
25878bcb0991SDimitry Andric 
2588e8d8bef9SDimitry Andric XCOFF::StorageClass
2589e8d8bef9SDimitry Andric TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) {
2590e8d8bef9SDimitry Andric   assert(!isa<GlobalIFunc>(GV) && "GlobalIFunc is not supported on AIX.");
2591e8d8bef9SDimitry Andric 
2592e8d8bef9SDimitry Andric   switch (GV->getLinkage()) {
25938bcb0991SDimitry Andric   case GlobalValue::InternalLinkage:
2594480093f4SDimitry Andric   case GlobalValue::PrivateLinkage:
25958bcb0991SDimitry Andric     return XCOFF::C_HIDEXT;
25968bcb0991SDimitry Andric   case GlobalValue::ExternalLinkage:
25978bcb0991SDimitry Andric   case GlobalValue::CommonLinkage:
25985ffd83dbSDimitry Andric   case GlobalValue::AvailableExternallyLinkage:
25998bcb0991SDimitry Andric     return XCOFF::C_EXT;
26008bcb0991SDimitry Andric   case GlobalValue::ExternalWeakLinkage:
26015ffd83dbSDimitry Andric   case GlobalValue::LinkOnceAnyLinkage:
26025ffd83dbSDimitry Andric   case GlobalValue::LinkOnceODRLinkage:
26035ffd83dbSDimitry Andric   case GlobalValue::WeakAnyLinkage:
26045ffd83dbSDimitry Andric   case GlobalValue::WeakODRLinkage:
26058bcb0991SDimitry Andric     return XCOFF::C_WEAKEXT;
26065ffd83dbSDimitry Andric   case GlobalValue::AppendingLinkage:
26078bcb0991SDimitry Andric     report_fatal_error(
26085ffd83dbSDimitry Andric         "There is no mapping that implements AppendingLinkage for XCOFF.");
26098bcb0991SDimitry Andric   }
26105ffd83dbSDimitry Andric   llvm_unreachable("Unknown linkage type!");
26115ffd83dbSDimitry Andric }
26125ffd83dbSDimitry Andric 
26135ffd83dbSDimitry Andric MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol(
2614e8d8bef9SDimitry Andric     const GlobalValue *Func, const TargetMachine &TM) const {
2615349cc55cSDimitry Andric   assert((isa<Function>(Func) ||
2616e8d8bef9SDimitry Andric           (isa<GlobalAlias>(Func) &&
2617349cc55cSDimitry Andric            isa_and_nonnull<Function>(
2618349cc55cSDimitry Andric                cast<GlobalAlias>(Func)->getAliaseeObject()))) &&
2619e8d8bef9SDimitry Andric          "Func must be a function or an alias which has a function as base "
2620e8d8bef9SDimitry Andric          "object.");
2621e8d8bef9SDimitry Andric 
26225ffd83dbSDimitry Andric   SmallString<128> NameStr;
26235ffd83dbSDimitry Andric   NameStr.push_back('.');
2624e8d8bef9SDimitry Andric   getNameWithPrefix(NameStr, Func, TM);
2625e8d8bef9SDimitry Andric 
2626e8d8bef9SDimitry Andric   // When -function-sections is enabled and explicit section is not specified,
2627e8d8bef9SDimitry Andric   // it's not necessary to emit function entry point label any more. We will use
2628e8d8bef9SDimitry Andric   // function entry point csect instead. And for function delcarations, the
2629e8d8bef9SDimitry Andric   // undefined symbols gets treated as csect with XTY_ER property.
2630e8d8bef9SDimitry Andric   if (((TM.getFunctionSections() && !Func->hasSection()) ||
2631e8d8bef9SDimitry Andric        Func->isDeclaration()) &&
2632e8d8bef9SDimitry Andric       isa<Function>(Func)) {
2633e8d8bef9SDimitry Andric     return getContext()
2634fe6060f1SDimitry Andric         .getXCOFFSection(
2635fe6060f1SDimitry Andric             NameStr, SectionKind::getText(),
2636fe6060f1SDimitry Andric             XCOFF::CsectProperties(XCOFF::XMC_PR, Func->isDeclaration()
2637fe6060f1SDimitry Andric                                                       ? XCOFF::XTY_ER
2638fe6060f1SDimitry Andric                                                       : XCOFF::XTY_SD))
2639e8d8bef9SDimitry Andric         ->getQualNameSymbol();
2640e8d8bef9SDimitry Andric   }
2641e8d8bef9SDimitry Andric 
26425ffd83dbSDimitry Andric   return getContext().getOrCreateSymbol(NameStr);
26435ffd83dbSDimitry Andric }
26445ffd83dbSDimitry Andric 
26455ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForFunctionDescriptor(
26465ffd83dbSDimitry Andric     const Function *F, const TargetMachine &TM) const {
26475ffd83dbSDimitry Andric   SmallString<128> NameStr;
26485ffd83dbSDimitry Andric   getNameWithPrefix(NameStr, F, TM);
2649fe6060f1SDimitry Andric   return getContext().getXCOFFSection(
2650fe6060f1SDimitry Andric       NameStr, SectionKind::getData(),
2651fe6060f1SDimitry Andric       XCOFF::CsectProperties(XCOFF::XMC_DS, XCOFF::XTY_SD));
26525ffd83dbSDimitry Andric }
26535ffd83dbSDimitry Andric 
26545ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry(
2655e8d8bef9SDimitry Andric     const MCSymbol *Sym, const TargetMachine &TM) const {
2656e8d8bef9SDimitry Andric   // Use TE storage-mapping class when large code model is enabled so that
2657e8d8bef9SDimitry Andric   // the chance of needing -bbigtoc is decreased.
26585ffd83dbSDimitry Andric   return getContext().getXCOFFSection(
2659fe6060f1SDimitry Andric       cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(), SectionKind::getData(),
2660fe6060f1SDimitry Andric       XCOFF::CsectProperties(
2661e8d8bef9SDimitry Andric           TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC,
2662fe6060f1SDimitry Andric           XCOFF::XTY_SD));
2663fe6060f1SDimitry Andric }
2664fe6060f1SDimitry Andric 
266581ad6265SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA(
266681ad6265SDimitry Andric     const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {
266781ad6265SDimitry Andric   auto *LSDA = cast<MCSectionXCOFF>(LSDASection);
266881ad6265SDimitry Andric   if (TM.getFunctionSections()) {
266981ad6265SDimitry Andric     // If option -ffunction-sections is on, append the function name to the
267081ad6265SDimitry Andric     // name of the LSDA csect so that each function has its own LSDA csect.
267181ad6265SDimitry Andric     // This helps the linker to garbage-collect EH info of unused functions.
267281ad6265SDimitry Andric     SmallString<128> NameStr = LSDA->getName();
267381ad6265SDimitry Andric     raw_svector_ostream(NameStr) << '.' << F.getName();
267481ad6265SDimitry Andric     LSDA = getContext().getXCOFFSection(NameStr, LSDA->getKind(),
267581ad6265SDimitry Andric                                         LSDA->getCsectProp());
267681ad6265SDimitry Andric   }
267781ad6265SDimitry Andric   return LSDA;
267881ad6265SDimitry Andric }
2679fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
2680fe6060f1SDimitry Andric //                                  GOFF
2681fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
268281ad6265SDimitry Andric TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default;
2683fe6060f1SDimitry Andric 
2684fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
2685fe6060f1SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2686fe6060f1SDimitry Andric   return SelectSectionForGlobal(GO, Kind, TM);
2687fe6060f1SDimitry Andric }
2688fe6060f1SDimitry Andric 
2689fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
2690fe6060f1SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2691fe6060f1SDimitry Andric   auto *Symbol = TM.getSymbol(GO);
2692fe6060f1SDimitry Andric   if (Kind.isBSS())
269381ad6265SDimitry Andric     return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(),
269481ad6265SDimitry Andric                                        nullptr, nullptr);
2695fe6060f1SDimitry Andric 
2696fe6060f1SDimitry Andric   return getContext().getObjectFileInfo()->getTextSection();
26978bcb0991SDimitry Andric }
2698