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"
67fe013be4SDimitry 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 
74fe013be4SDimitry Andric static cl::opt<bool> JumpTableInFunctionSection(
75fe013be4SDimitry Andric     "jumptable-in-function-section", cl::Hidden, cl::init(false),
76fe013be4SDimitry Andric     cl::desc("Putting Jump Table in function section"));
77fe013be4SDimitry Andric 
GetObjCImageInfo(Module & M,unsigned & Version,unsigned & Flags,StringRef & Section)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 
TargetLoweringObjectFileELF()11604eeddc0SDimitry Andric TargetLoweringObjectFileELF::TargetLoweringObjectFileELF() {
117e8d8bef9SDimitry Andric   SupportDSOLocalEquivalentLowering = true;
118e8d8bef9SDimitry Andric }
119e8d8bef9SDimitry Andric 
Initialize(MCContext & Ctx,const TargetMachine & TgtM)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.
189fe013be4SDimitry Andric     //
190fe013be4SDimitry Andric     // Use DW_EH_PE_indirect even for -fno-pic to avoid copy relocations.
191fe013be4SDimitry Andric     LSDAEncoding = dwarf::DW_EH_PE_pcrel |
192fe013be4SDimitry Andric                    (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32
193fe013be4SDimitry Andric                         ? dwarf::DW_EH_PE_sdata4
194fe013be4SDimitry Andric                         : dwarf::DW_EH_PE_sdata8);
195fe013be4SDimitry Andric     PersonalityEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect;
196fe013be4SDimitry 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 
getModuleMetadata(Module & M)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 
emitModuleMetadata(MCStreamer & Streamer,Module & M) const3060b57cec5SDimitry 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 
getCFIPersonalitySymbol(const GlobalValue * GV,const TargetMachine & TM,MachineModuleInfo * MMI) const4040b57cec5SDimitry 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 
emitPersonalityValue(MCStreamer & Streamer,const DataLayout & DL,const MCSymbol * Sym) const4160b57cec5SDimitry 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 
getTTypeGlobalReference(const GlobalValue * GV,unsigned Encoding,const TargetMachine & TM,MachineModuleInfo * MMI,MCStreamer & Streamer) const4380b57cec5SDimitry 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 
getELFKindForNamedSection(StringRef Name,SectionKind K)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) ||
475c9157d92SDimitry Andric       Name == getInstrProfSectionName(IPSK_covdata, Triple::ELF,
476c9157d92SDimitry Andric                                       /*AddSegmentInfo=*/false) ||
477c9157d92SDimitry Andric       Name == getInstrProfSectionName(IPSK_covname, Triple::ELF,
478c9157d92SDimitry Andric                                       /*AddSegmentInfo=*/false) ||
479e8d8bef9SDimitry Andric       Name == ".llvmbc" || Name == ".llvmcmd")
4800b57cec5SDimitry Andric     return SectionKind::getMetadata();
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   if (Name.empty() || Name[0] != '.') return K;
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   // Default implementation based on some magic section names.
485c9157d92SDimitry Andric   if (Name == ".bss" || Name.starts_with(".bss.") ||
486c9157d92SDimitry Andric       Name.starts_with(".gnu.linkonce.b.") ||
487c9157d92SDimitry Andric       Name.starts_with(".llvm.linkonce.b.") || Name == ".sbss" ||
488c9157d92SDimitry Andric       Name.starts_with(".sbss.") || Name.starts_with(".gnu.linkonce.sb.") ||
489c9157d92SDimitry Andric       Name.starts_with(".llvm.linkonce.sb."))
4900b57cec5SDimitry Andric     return SectionKind::getBSS();
4910b57cec5SDimitry Andric 
492c9157d92SDimitry Andric   if (Name == ".tdata" || Name.starts_with(".tdata.") ||
493c9157d92SDimitry Andric       Name.starts_with(".gnu.linkonce.td.") ||
494c9157d92SDimitry Andric       Name.starts_with(".llvm.linkonce.td."))
4950b57cec5SDimitry Andric     return SectionKind::getThreadData();
4960b57cec5SDimitry Andric 
497c9157d92SDimitry Andric   if (Name == ".tbss" || Name.starts_with(".tbss.") ||
498c9157d92SDimitry Andric       Name.starts_with(".gnu.linkonce.tb.") ||
499c9157d92SDimitry Andric       Name.starts_with(".llvm.linkonce.tb."))
5000b57cec5SDimitry Andric     return SectionKind::getThreadBSS();
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   return K;
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric 
hasPrefix(StringRef SectionName,StringRef Prefix)50504eeddc0SDimitry Andric static bool hasPrefix(StringRef SectionName, StringRef Prefix) {
50604eeddc0SDimitry Andric   return SectionName.consume_front(Prefix) &&
50704eeddc0SDimitry Andric          (SectionName.empty() || SectionName[0] == '.');
50804eeddc0SDimitry Andric }
50904eeddc0SDimitry Andric 
getELFSectionType(StringRef Name,SectionKind K)5100b57cec5SDimitry Andric static unsigned getELFSectionType(StringRef Name, SectionKind K) {
5110b57cec5SDimitry Andric   // Use SHT_NOTE for section whose name starts with ".note" to allow
5120b57cec5SDimitry Andric   // emitting ELF notes from C variable declaration.
5130b57cec5SDimitry Andric   // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609
514c9157d92SDimitry Andric   if (Name.starts_with(".note"))
5150b57cec5SDimitry Andric     return ELF::SHT_NOTE;
5160b57cec5SDimitry Andric 
51704eeddc0SDimitry Andric   if (hasPrefix(Name, ".init_array"))
5180b57cec5SDimitry Andric     return ELF::SHT_INIT_ARRAY;
5190b57cec5SDimitry Andric 
52004eeddc0SDimitry Andric   if (hasPrefix(Name, ".fini_array"))
5210b57cec5SDimitry Andric     return ELF::SHT_FINI_ARRAY;
5220b57cec5SDimitry Andric 
52304eeddc0SDimitry Andric   if (hasPrefix(Name, ".preinit_array"))
5240b57cec5SDimitry Andric     return ELF::SHT_PREINIT_ARRAY;
5250b57cec5SDimitry Andric 
526753f127fSDimitry Andric   if (hasPrefix(Name, ".llvm.offloading"))
527753f127fSDimitry Andric     return ELF::SHT_LLVM_OFFLOADING;
528753f127fSDimitry Andric 
5290b57cec5SDimitry Andric   if (K.isBSS() || K.isThreadBSS())
5300b57cec5SDimitry Andric     return ELF::SHT_NOBITS;
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric   return ELF::SHT_PROGBITS;
5330b57cec5SDimitry Andric }
5340b57cec5SDimitry Andric 
getELFSectionFlags(SectionKind K)5350b57cec5SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) {
5360b57cec5SDimitry Andric   unsigned Flags = 0;
5370b57cec5SDimitry Andric 
53881ad6265SDimitry Andric   if (!K.isMetadata() && !K.isExclude())
5390b57cec5SDimitry Andric     Flags |= ELF::SHF_ALLOC;
5400b57cec5SDimitry Andric 
54181ad6265SDimitry Andric   if (K.isExclude())
54281ad6265SDimitry Andric     Flags |= ELF::SHF_EXCLUDE;
54381ad6265SDimitry Andric 
5440b57cec5SDimitry Andric   if (K.isText())
5450b57cec5SDimitry Andric     Flags |= ELF::SHF_EXECINSTR;
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   if (K.isExecuteOnly())
5480b57cec5SDimitry Andric     Flags |= ELF::SHF_ARM_PURECODE;
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric   if (K.isWriteable())
5510b57cec5SDimitry Andric     Flags |= ELF::SHF_WRITE;
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric   if (K.isThreadLocal())
5540b57cec5SDimitry Andric     Flags |= ELF::SHF_TLS;
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric   if (K.isMergeableCString() || K.isMergeableConst())
5570b57cec5SDimitry Andric     Flags |= ELF::SHF_MERGE;
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric   if (K.isMergeableCString())
5600b57cec5SDimitry Andric     Flags |= ELF::SHF_STRINGS;
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric   return Flags;
5630b57cec5SDimitry Andric }
5640b57cec5SDimitry Andric 
getELFComdat(const GlobalValue * GV)5650b57cec5SDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) {
5660b57cec5SDimitry Andric   const Comdat *C = GV->getComdat();
5670b57cec5SDimitry Andric   if (!C)
5680b57cec5SDimitry Andric     return nullptr;
5690b57cec5SDimitry Andric 
570fe6060f1SDimitry Andric   if (C->getSelectionKind() != Comdat::Any &&
571fe6060f1SDimitry Andric       C->getSelectionKind() != Comdat::NoDeduplicate)
572fe6060f1SDimitry Andric     report_fatal_error("ELF COMDATs only support SelectionKind::Any and "
573fe6060f1SDimitry Andric                        "SelectionKind::NoDeduplicate, '" +
5740b57cec5SDimitry Andric                        C->getName() + "' cannot be lowered.");
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   return C;
5770b57cec5SDimitry Andric }
5780b57cec5SDimitry Andric 
getLinkedToSymbol(const GlobalObject * GO,const TargetMachine & TM)5795ffd83dbSDimitry Andric static const MCSymbolELF *getLinkedToSymbol(const GlobalObject *GO,
5800b57cec5SDimitry Andric                                             const TargetMachine &TM) {
5810b57cec5SDimitry Andric   MDNode *MD = GO->getMetadata(LLVMContext::MD_associated);
5820b57cec5SDimitry Andric   if (!MD)
5830b57cec5SDimitry Andric     return nullptr;
5840b57cec5SDimitry Andric 
585fe013be4SDimitry Andric   auto *VM = cast<ValueAsMetadata>(MD->getOperand(0).get());
5868bcb0991SDimitry Andric   auto *OtherGV = dyn_cast<GlobalValue>(VM->getValue());
5878bcb0991SDimitry Andric   return OtherGV ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGV)) : nullptr;
5880b57cec5SDimitry Andric }
5890b57cec5SDimitry Andric 
getEntrySizeForKind(SectionKind Kind)5900b57cec5SDimitry Andric static unsigned getEntrySizeForKind(SectionKind Kind) {
5910b57cec5SDimitry Andric   if (Kind.isMergeable1ByteCString())
5920b57cec5SDimitry Andric     return 1;
5930b57cec5SDimitry Andric   else if (Kind.isMergeable2ByteCString())
5940b57cec5SDimitry Andric     return 2;
5950b57cec5SDimitry Andric   else if (Kind.isMergeable4ByteCString())
5960b57cec5SDimitry Andric     return 4;
5970b57cec5SDimitry Andric   else if (Kind.isMergeableConst4())
5980b57cec5SDimitry Andric     return 4;
5990b57cec5SDimitry Andric   else if (Kind.isMergeableConst8())
6000b57cec5SDimitry Andric     return 8;
6010b57cec5SDimitry Andric   else if (Kind.isMergeableConst16())
6020b57cec5SDimitry Andric     return 16;
6030b57cec5SDimitry Andric   else if (Kind.isMergeableConst32())
6040b57cec5SDimitry Andric     return 32;
6050b57cec5SDimitry Andric   else {
6060b57cec5SDimitry Andric     // We shouldn't have mergeable C strings or mergeable constants that we
6070b57cec5SDimitry Andric     // didn't handle above.
6080b57cec5SDimitry Andric     assert(!Kind.isMergeableCString() && "unknown string width");
6090b57cec5SDimitry Andric     assert(!Kind.isMergeableConst() && "unknown data width");
6100b57cec5SDimitry Andric     return 0;
6110b57cec5SDimitry Andric   }
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
6145ffd83dbSDimitry Andric /// Return the section prefix name used by options FunctionsSections and
6155ffd83dbSDimitry Andric /// DataSections.
getSectionPrefixForGlobal(SectionKind Kind,bool IsLarge)616fe013be4SDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind, bool IsLarge) {
6175ffd83dbSDimitry Andric   if (Kind.isText())
618c9157d92SDimitry Andric     return IsLarge ? ".ltext" : ".text";
6195ffd83dbSDimitry Andric   if (Kind.isReadOnly())
620fe013be4SDimitry Andric     return IsLarge ? ".lrodata" : ".rodata";
6215ffd83dbSDimitry Andric   if (Kind.isBSS())
622fe013be4SDimitry Andric     return IsLarge ? ".lbss" : ".bss";
6235ffd83dbSDimitry Andric   if (Kind.isThreadData())
6245ffd83dbSDimitry Andric     return ".tdata";
6255ffd83dbSDimitry Andric   if (Kind.isThreadBSS())
6265ffd83dbSDimitry Andric     return ".tbss";
6275ffd83dbSDimitry Andric   if (Kind.isData())
628fe013be4SDimitry Andric     return IsLarge ? ".ldata" : ".data";
6295ffd83dbSDimitry Andric   if (Kind.isReadOnlyWithRel())
630fe013be4SDimitry Andric     return IsLarge ? ".ldata.rel.ro" : ".data.rel.ro";
6315ffd83dbSDimitry Andric   llvm_unreachable("Unknown section kind");
6325ffd83dbSDimitry Andric }
6335ffd83dbSDimitry Andric 
6345ffd83dbSDimitry Andric static SmallString<128>
getELFSectionNameForGlobal(const GlobalObject * GO,SectionKind Kind,Mangler & Mang,const TargetMachine & TM,unsigned EntrySize,bool UniqueSectionName)6355ffd83dbSDimitry Andric getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
6365ffd83dbSDimitry Andric                            Mangler &Mang, const TargetMachine &TM,
6375ffd83dbSDimitry Andric                            unsigned EntrySize, bool UniqueSectionName) {
6385ffd83dbSDimitry Andric   SmallString<128> Name;
6395ffd83dbSDimitry Andric   if (Kind.isMergeableCString()) {
6405ffd83dbSDimitry Andric     // We also need alignment here.
6415ffd83dbSDimitry Andric     // FIXME: this is getting the alignment of the character, not the
6425ffd83dbSDimitry Andric     // alignment of the global!
6435ffd83dbSDimitry Andric     Align Alignment = GO->getParent()->getDataLayout().getPreferredAlign(
6445ffd83dbSDimitry Andric         cast<GlobalVariable>(GO));
6455ffd83dbSDimitry Andric 
6465ffd83dbSDimitry Andric     std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + ".";
6475ffd83dbSDimitry Andric     Name = SizeSpec + utostr(Alignment.value());
6485ffd83dbSDimitry Andric   } else if (Kind.isMergeableConst()) {
6495ffd83dbSDimitry Andric     Name = ".rodata.cst";
6505ffd83dbSDimitry Andric     Name += utostr(EntrySize);
6515ffd83dbSDimitry Andric   } else {
652c9157d92SDimitry Andric     Name = getSectionPrefixForGlobal(Kind, TM.isLargeGlobalValue(GO));
6535ffd83dbSDimitry Andric   }
6545ffd83dbSDimitry Andric 
6555ffd83dbSDimitry Andric   bool HasPrefix = false;
6565ffd83dbSDimitry Andric   if (const auto *F = dyn_cast<Function>(GO)) {
657bdd1243dSDimitry Andric     if (std::optional<StringRef> Prefix = F->getSectionPrefix()) {
658e8d8bef9SDimitry Andric       raw_svector_ostream(Name) << '.' << *Prefix;
6595ffd83dbSDimitry Andric       HasPrefix = true;
6605ffd83dbSDimitry Andric     }
6615ffd83dbSDimitry Andric   }
6625ffd83dbSDimitry Andric 
6635ffd83dbSDimitry Andric   if (UniqueSectionName) {
6645ffd83dbSDimitry Andric     Name.push_back('.');
6655ffd83dbSDimitry Andric     TM.getNameWithPrefix(Name, GO, Mang, /*MayAlwaysUsePrivate*/true);
6665ffd83dbSDimitry Andric   } else if (HasPrefix)
667fe6060f1SDimitry Andric     // For distinguishing between .text.${text-section-prefix}. (with trailing
668fe6060f1SDimitry Andric     // dot) and .text.${function-name}
6695ffd83dbSDimitry Andric     Name.push_back('.');
6705ffd83dbSDimitry Andric   return Name;
6715ffd83dbSDimitry Andric }
6725ffd83dbSDimitry Andric 
6735ffd83dbSDimitry Andric namespace {
6745ffd83dbSDimitry Andric class LoweringDiagnosticInfo : public DiagnosticInfo {
6755ffd83dbSDimitry Andric   const Twine &Msg;
6765ffd83dbSDimitry Andric 
6775ffd83dbSDimitry Andric public:
LoweringDiagnosticInfo(const Twine & DiagMsg,DiagnosticSeverity Severity=DS_Error)6785ffd83dbSDimitry Andric   LoweringDiagnosticInfo(const Twine &DiagMsg,
6795ffd83dbSDimitry Andric                          DiagnosticSeverity Severity = DS_Error)
6805ffd83dbSDimitry Andric       : DiagnosticInfo(DK_Lowering, Severity), Msg(DiagMsg) {}
print(DiagnosticPrinter & DP) const6815ffd83dbSDimitry Andric   void print(DiagnosticPrinter &DP) const override { DP << Msg; }
6825ffd83dbSDimitry Andric };
6835ffd83dbSDimitry Andric }
6845ffd83dbSDimitry Andric 
685fe6060f1SDimitry Andric /// Calculate an appropriate unique ID for a section, and update Flags,
686fe6060f1SDimitry Andric /// EntrySize and NextUniqueID where appropriate.
687fe6060f1SDimitry Andric static unsigned
calcUniqueIDUpdateFlagsAndSize(const GlobalObject * GO,StringRef SectionName,SectionKind Kind,const TargetMachine & TM,MCContext & Ctx,Mangler & Mang,unsigned & Flags,unsigned & EntrySize,unsigned & NextUniqueID,const bool Retain,const bool ForceUnique)688fe6060f1SDimitry Andric calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName,
689fe6060f1SDimitry Andric                                SectionKind Kind, const TargetMachine &TM,
690fe6060f1SDimitry Andric                                MCContext &Ctx, Mangler &Mang, unsigned &Flags,
691fe6060f1SDimitry Andric                                unsigned &EntrySize, unsigned &NextUniqueID,
692fe6060f1SDimitry Andric                                const bool Retain, const bool ForceUnique) {
693fe6060f1SDimitry Andric   // Increment uniqueID if we are forced to emit a unique section.
694fe6060f1SDimitry Andric   // This works perfectly fine with section attribute or pragma section as the
695fe6060f1SDimitry Andric   // sections with the same name are grouped together by the assembler.
696fe6060f1SDimitry Andric   if (ForceUnique)
697fe6060f1SDimitry Andric     return NextUniqueID++;
698fe6060f1SDimitry Andric 
699fe6060f1SDimitry Andric   // A section can have at most one associated section. Put each global with
700fe6060f1SDimitry Andric   // MD_associated in a unique section.
701fe6060f1SDimitry Andric   const bool Associated = GO->getMetadata(LLVMContext::MD_associated);
702fe6060f1SDimitry Andric   if (Associated) {
703fe6060f1SDimitry Andric     Flags |= ELF::SHF_LINK_ORDER;
704fe6060f1SDimitry Andric     return NextUniqueID++;
705fe6060f1SDimitry Andric   }
706fe6060f1SDimitry Andric 
707fe6060f1SDimitry Andric   if (Retain) {
70881ad6265SDimitry Andric     if (TM.getTargetTriple().isOSSolaris())
70981ad6265SDimitry Andric       Flags |= ELF::SHF_SUNW_NODISCARD;
71081ad6265SDimitry Andric     else if (Ctx.getAsmInfo()->useIntegratedAssembler() ||
71181ad6265SDimitry Andric              Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36))
712fe6060f1SDimitry Andric       Flags |= ELF::SHF_GNU_RETAIN;
713fe6060f1SDimitry Andric     return NextUniqueID++;
714fe6060f1SDimitry Andric   }
715fe6060f1SDimitry Andric 
716fe6060f1SDimitry Andric   // If two symbols with differing sizes end up in the same mergeable section
717fe6060f1SDimitry Andric   // that section can be assigned an incorrect entry size. To avoid this we
718fe6060f1SDimitry Andric   // usually put symbols of the same size into distinct mergeable sections with
719fe6060f1SDimitry Andric   // the same name. Doing so relies on the ",unique ," assembly feature. This
720fe6060f1SDimitry Andric   // feature is not avalible until bintuils version 2.35
721fe6060f1SDimitry Andric   // (https://sourceware.org/bugzilla/show_bug.cgi?id=25380).
722fe6060f1SDimitry Andric   const bool SupportsUnique = Ctx.getAsmInfo()->useIntegratedAssembler() ||
723fe6060f1SDimitry Andric                               Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35);
724fe6060f1SDimitry Andric   if (!SupportsUnique) {
725fe6060f1SDimitry Andric     Flags &= ~ELF::SHF_MERGE;
726fe6060f1SDimitry Andric     EntrySize = 0;
727fe6060f1SDimitry Andric     return MCContext::GenericSectionID;
728fe6060f1SDimitry Andric   }
729fe6060f1SDimitry Andric 
730fe6060f1SDimitry Andric   const bool SymbolMergeable = Flags & ELF::SHF_MERGE;
731fe6060f1SDimitry Andric   const bool SeenSectionNameBefore =
732fe6060f1SDimitry Andric       Ctx.isELFGenericMergeableSection(SectionName);
733fe6060f1SDimitry Andric   // If this is the first ocurrence of this section name, treat it as the
734fe6060f1SDimitry Andric   // generic section
735fe6060f1SDimitry Andric   if (!SymbolMergeable && !SeenSectionNameBefore)
736fe6060f1SDimitry Andric     return MCContext::GenericSectionID;
737fe6060f1SDimitry Andric 
738fe6060f1SDimitry Andric   // Symbols must be placed into sections with compatible entry sizes. Generate
739fe6060f1SDimitry Andric   // unique sections for symbols that have not been assigned to compatible
740fe6060f1SDimitry Andric   // sections.
741fe6060f1SDimitry Andric   const auto PreviousID =
742fe6060f1SDimitry Andric       Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize);
743fe6060f1SDimitry Andric   if (PreviousID)
744fe6060f1SDimitry Andric     return *PreviousID;
745fe6060f1SDimitry Andric 
746fe6060f1SDimitry Andric   // If the user has specified the same section name as would be created
747fe6060f1SDimitry Andric   // implicitly for this symbol e.g. .rodata.str1.1, then we don't need
748fe6060f1SDimitry Andric   // to unique the section as the entry size for this symbol will be
749fe6060f1SDimitry Andric   // compatible with implicitly created sections.
750fe6060f1SDimitry Andric   SmallString<128> ImplicitSectionNameStem =
751fe6060f1SDimitry Andric       getELFSectionNameForGlobal(GO, Kind, Mang, TM, EntrySize, false);
752fe6060f1SDimitry Andric   if (SymbolMergeable &&
753fe6060f1SDimitry Andric       Ctx.isELFImplicitMergeableSectionNamePrefix(SectionName) &&
754c9157d92SDimitry Andric       SectionName.starts_with(ImplicitSectionNameStem))
755fe6060f1SDimitry Andric     return MCContext::GenericSectionID;
756fe6060f1SDimitry Andric 
757fe6060f1SDimitry Andric   // We have seen this section name before, but with different flags or entity
758fe6060f1SDimitry Andric   // size. Create a new unique ID.
759fe6060f1SDimitry Andric   return NextUniqueID++;
760fe6060f1SDimitry Andric }
761fe6060f1SDimitry Andric 
762c9157d92SDimitry Andric static std::tuple<StringRef, bool, unsigned>
getGlobalObjectInfo(const GlobalObject * GO,const TargetMachine & TM)763c9157d92SDimitry Andric getGlobalObjectInfo(const GlobalObject *GO, const TargetMachine &TM) {
764c9157d92SDimitry Andric   StringRef Group = "";
765c9157d92SDimitry Andric   bool IsComdat = false;
766c9157d92SDimitry Andric   unsigned Flags = 0;
767c9157d92SDimitry Andric   if (const Comdat *C = getELFComdat(GO)) {
768c9157d92SDimitry Andric     Flags |= ELF::SHF_GROUP;
769c9157d92SDimitry Andric     Group = C->getName();
770c9157d92SDimitry Andric     IsComdat = C->getSelectionKind() == Comdat::Any;
771c9157d92SDimitry Andric   }
772c9157d92SDimitry Andric   if (TM.isLargeGlobalValue(GO))
773c9157d92SDimitry Andric     Flags |= ELF::SHF_X86_64_LARGE;
774c9157d92SDimitry Andric   return {Group, IsComdat, Flags};
775c9157d92SDimitry Andric }
776c9157d92SDimitry Andric 
selectExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM,MCContext & Ctx,Mangler & Mang,unsigned & NextUniqueID,bool Retain,bool ForceUnique)777fe6060f1SDimitry Andric static MCSection *selectExplicitSectionGlobal(
778fe6060f1SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM,
779fe6060f1SDimitry Andric     MCContext &Ctx, Mangler &Mang, unsigned &NextUniqueID,
780fe6060f1SDimitry Andric     bool Retain, bool ForceUnique) {
7810b57cec5SDimitry Andric   StringRef SectionName = GO->getSection();
7820b57cec5SDimitry Andric 
7830b57cec5SDimitry Andric   // Check if '#pragma clang section' name is applicable.
7840b57cec5SDimitry Andric   // Note that pragma directive overrides -ffunction-section, -fdata-section
7850b57cec5SDimitry Andric   // and so section name is exactly as user specified and not uniqued.
7860b57cec5SDimitry Andric   const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO);
7870b57cec5SDimitry Andric   if (GV && GV->hasImplicitSection()) {
7880b57cec5SDimitry Andric     auto Attrs = GV->getAttributes();
7890b57cec5SDimitry Andric     if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) {
7900b57cec5SDimitry Andric       SectionName = Attrs.getAttribute("bss-section").getValueAsString();
7910b57cec5SDimitry Andric     } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
7920b57cec5SDimitry Andric       SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
7938bcb0991SDimitry Andric     } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) {
7948bcb0991SDimitry Andric       SectionName = Attrs.getAttribute("relro-section").getValueAsString();
7950b57cec5SDimitry Andric     } else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
7960b57cec5SDimitry Andric       SectionName = Attrs.getAttribute("data-section").getValueAsString();
7970b57cec5SDimitry Andric     }
7980b57cec5SDimitry Andric   }
7990b57cec5SDimitry Andric   const Function *F = dyn_cast<Function>(GO);
8000b57cec5SDimitry Andric   if (F && F->hasFnAttribute("implicit-section-name")) {
8010b57cec5SDimitry Andric     SectionName = F->getFnAttribute("implicit-section-name").getValueAsString();
8020b57cec5SDimitry Andric   }
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric   // Infer section flags from the section name if we can.
8050b57cec5SDimitry Andric   Kind = getELFKindForNamedSection(SectionName, Kind);
8060b57cec5SDimitry Andric 
8070b57cec5SDimitry Andric   unsigned Flags = getELFSectionFlags(Kind);
808c9157d92SDimitry Andric   auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM);
809c9157d92SDimitry Andric   Flags |= ExtraFlags;
8100b57cec5SDimitry Andric 
8115ffd83dbSDimitry Andric   unsigned EntrySize = getEntrySizeForKind(Kind);
812fe6060f1SDimitry Andric   const unsigned UniqueID = calcUniqueIDUpdateFlagsAndSize(
813fe6060f1SDimitry Andric       GO, SectionName, Kind, TM, Ctx, Mang, Flags, EntrySize, NextUniqueID,
814fe6060f1SDimitry Andric       Retain, ForceUnique);
8155ffd83dbSDimitry Andric 
8165ffd83dbSDimitry Andric   const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
817fe6060f1SDimitry Andric   MCSectionELF *Section = Ctx.getELFSection(
818fe6060f1SDimitry Andric       SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize,
819fe6060f1SDimitry Andric       Group, IsComdat, UniqueID, LinkedToSym);
8200b57cec5SDimitry Andric   // Make sure that we did not get some other section with incompatible sh_link.
8210b57cec5SDimitry Andric   // This should not be possible due to UniqueID code above.
8225ffd83dbSDimitry Andric   assert(Section->getLinkedToSymbol() == LinkedToSym &&
8230b57cec5SDimitry Andric          "Associated symbol mismatch between sections");
8245ffd83dbSDimitry Andric 
825fe6060f1SDimitry Andric   if (!(Ctx.getAsmInfo()->useIntegratedAssembler() ||
826fe6060f1SDimitry Andric         Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35))) {
827e8d8bef9SDimitry Andric     // If we are using GNU as before 2.35, then this symbol might have
8285ffd83dbSDimitry Andric     // been placed in an incompatible mergeable section. Emit an error if this
8295ffd83dbSDimitry Andric     // is the case to avoid creating broken output.
8305ffd83dbSDimitry Andric     if ((Section->getFlags() & ELF::SHF_MERGE) &&
8315ffd83dbSDimitry Andric         (Section->getEntrySize() != getEntrySizeForKind(Kind)))
8325ffd83dbSDimitry Andric       GO->getContext().diagnose(LoweringDiagnosticInfo(
8335ffd83dbSDimitry Andric           "Symbol '" + GO->getName() + "' from module '" +
8345ffd83dbSDimitry Andric           (GO->getParent() ? GO->getParent()->getSourceFileName() : "unknown") +
8355ffd83dbSDimitry Andric           "' required a section with entry-size=" +
8365ffd83dbSDimitry Andric           Twine(getEntrySizeForKind(Kind)) + " but was placed in section '" +
8375ffd83dbSDimitry Andric           SectionName + "' with entry-size=" + Twine(Section->getEntrySize()) +
8385ffd83dbSDimitry Andric           ": Explicit assignment by pragma or attribute of an incompatible "
8395ffd83dbSDimitry Andric           "symbol to this section?"));
8400b57cec5SDimitry Andric   }
8410b57cec5SDimitry Andric 
8425ffd83dbSDimitry Andric   return Section;
8430b57cec5SDimitry Andric }
8440b57cec5SDimitry Andric 
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const845fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
846fe6060f1SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
847fe6060f1SDimitry Andric   return selectExplicitSectionGlobal(GO, Kind, TM, getContext(), getMangler(),
848fe6060f1SDimitry Andric                                      NextUniqueID, Used.count(GO),
849fe6060f1SDimitry Andric                                      /* ForceUnique = */false);
850fe6060f1SDimitry Andric }
851fe6060f1SDimitry Andric 
selectELFSectionForGlobal(MCContext & Ctx,const GlobalObject * GO,SectionKind Kind,Mangler & Mang,const TargetMachine & TM,bool EmitUniqueSection,unsigned Flags,unsigned * NextUniqueID,const MCSymbolELF * AssociatedSymbol)8520b57cec5SDimitry Andric static MCSectionELF *selectELFSectionForGlobal(
8530b57cec5SDimitry Andric     MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
8540b57cec5SDimitry Andric     const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags,
8550b57cec5SDimitry Andric     unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) {
8560b57cec5SDimitry Andric 
857c9157d92SDimitry Andric   auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM);
858c9157d92SDimitry Andric   Flags |= ExtraFlags;
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric   // Get the section entry size based on the kind.
8610b57cec5SDimitry Andric   unsigned EntrySize = getEntrySizeForKind(Kind);
8620b57cec5SDimitry Andric 
8635ffd83dbSDimitry Andric   bool UniqueSectionName = false;
8640b57cec5SDimitry Andric   unsigned UniqueID = MCContext::GenericSectionID;
8650b57cec5SDimitry Andric   if (EmitUniqueSection) {
8660b57cec5SDimitry Andric     if (TM.getUniqueSectionNames()) {
8675ffd83dbSDimitry Andric       UniqueSectionName = true;
8680b57cec5SDimitry Andric     } else {
8690b57cec5SDimitry Andric       UniqueID = *NextUniqueID;
8700b57cec5SDimitry Andric       (*NextUniqueID)++;
8710b57cec5SDimitry Andric     }
8720b57cec5SDimitry Andric   }
8735ffd83dbSDimitry Andric   SmallString<128> Name = getELFSectionNameForGlobal(
8745ffd83dbSDimitry Andric       GO, Kind, Mang, TM, EntrySize, UniqueSectionName);
8755ffd83dbSDimitry Andric 
8760b57cec5SDimitry Andric   // Use 0 as the unique ID for execute-only text.
8770b57cec5SDimitry Andric   if (Kind.isExecuteOnly())
8780b57cec5SDimitry Andric     UniqueID = 0;
8790b57cec5SDimitry Andric   return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
880fe6060f1SDimitry Andric                            EntrySize, Group, IsComdat, UniqueID,
881fe6060f1SDimitry Andric                            AssociatedSymbol);
882fe6060f1SDimitry Andric }
883fe6060f1SDimitry Andric 
selectELFSectionForGlobal(MCContext & Ctx,const GlobalObject * GO,SectionKind Kind,Mangler & Mang,const TargetMachine & TM,bool Retain,bool EmitUniqueSection,unsigned Flags,unsigned * NextUniqueID)884fe6060f1SDimitry Andric static MCSection *selectELFSectionForGlobal(
885fe6060f1SDimitry Andric     MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
886fe6060f1SDimitry Andric     const TargetMachine &TM, bool Retain, bool EmitUniqueSection,
887fe6060f1SDimitry Andric     unsigned Flags, unsigned *NextUniqueID) {
888fe6060f1SDimitry Andric   const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
889fe6060f1SDimitry Andric   if (LinkedToSym) {
890fe6060f1SDimitry Andric     EmitUniqueSection = true;
891fe6060f1SDimitry Andric     Flags |= ELF::SHF_LINK_ORDER;
892fe6060f1SDimitry Andric   }
89381ad6265SDimitry Andric   if (Retain) {
89481ad6265SDimitry Andric     if (TM.getTargetTriple().isOSSolaris()) {
89581ad6265SDimitry Andric       EmitUniqueSection = true;
89681ad6265SDimitry Andric       Flags |= ELF::SHF_SUNW_NODISCARD;
89781ad6265SDimitry Andric     } else if (Ctx.getAsmInfo()->useIntegratedAssembler() ||
89881ad6265SDimitry Andric                Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) {
899fe6060f1SDimitry Andric       EmitUniqueSection = true;
900fe6060f1SDimitry Andric       Flags |= ELF::SHF_GNU_RETAIN;
901fe6060f1SDimitry Andric     }
90281ad6265SDimitry Andric   }
903fe6060f1SDimitry Andric 
904fe6060f1SDimitry Andric   MCSectionELF *Section = selectELFSectionForGlobal(
905fe6060f1SDimitry Andric       Ctx, GO, Kind, Mang, TM, EmitUniqueSection, Flags,
906fe6060f1SDimitry Andric       NextUniqueID, LinkedToSym);
907fe6060f1SDimitry Andric   assert(Section->getLinkedToSymbol() == LinkedToSym);
908fe6060f1SDimitry Andric   return Section;
9090b57cec5SDimitry Andric }
9100b57cec5SDimitry Andric 
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const9110b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
9120b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
9130b57cec5SDimitry Andric   unsigned Flags = getELFSectionFlags(Kind);
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric   // If we have -ffunction-section or -fdata-section then we should emit the
9160b57cec5SDimitry Andric   // global value to a uniqued section specifically for it.
9170b57cec5SDimitry Andric   bool EmitUniqueSection = false;
9180b57cec5SDimitry Andric   if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) {
9190b57cec5SDimitry Andric     if (Kind.isText())
9200b57cec5SDimitry Andric       EmitUniqueSection = TM.getFunctionSections();
9210b57cec5SDimitry Andric     else
9220b57cec5SDimitry Andric       EmitUniqueSection = TM.getDataSections();
9230b57cec5SDimitry Andric   }
9240b57cec5SDimitry Andric   EmitUniqueSection |= GO->hasComdat();
925fe6060f1SDimitry Andric   return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
926fe6060f1SDimitry Andric                                    Used.count(GO), EmitUniqueSection, Flags,
927fe6060f1SDimitry Andric                                    &NextUniqueID);
9280b57cec5SDimitry Andric }
9290b57cec5SDimitry Andric 
getUniqueSectionForFunction(const Function & F,const TargetMachine & TM) const930fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction(
931fe6060f1SDimitry Andric     const Function &F, const TargetMachine &TM) const {
932fe6060f1SDimitry Andric   SectionKind Kind = SectionKind::getText();
933fe6060f1SDimitry Andric   unsigned Flags = getELFSectionFlags(Kind);
934fe6060f1SDimitry Andric   // If the function's section names is pre-determined via pragma or a
935fe6060f1SDimitry Andric   // section attribute, call selectExplicitSectionGlobal.
936fe6060f1SDimitry Andric   if (F.hasSection() || F.hasFnAttribute("implicit-section-name"))
937fe6060f1SDimitry Andric     return selectExplicitSectionGlobal(
938fe6060f1SDimitry Andric         &F, Kind, TM, getContext(), getMangler(), NextUniqueID,
939fe6060f1SDimitry Andric         Used.count(&F), /* ForceUnique = */true);
940fe6060f1SDimitry Andric   else
941fe6060f1SDimitry Andric     return selectELFSectionForGlobal(
942fe6060f1SDimitry Andric         getContext(), &F, Kind, getMangler(), TM, Used.count(&F),
943fe6060f1SDimitry Andric         /*EmitUniqueSection=*/true, Flags, &NextUniqueID);
9440b57cec5SDimitry Andric }
9450b57cec5SDimitry Andric 
getSectionForJumpTable(const Function & F,const TargetMachine & TM) const9460b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
9470b57cec5SDimitry Andric     const Function &F, const TargetMachine &TM) const {
9480b57cec5SDimitry Andric   // If the function can be removed, produce a unique section so that
9490b57cec5SDimitry Andric   // the table doesn't prevent the removal.
9500b57cec5SDimitry Andric   const Comdat *C = F.getComdat();
9510b57cec5SDimitry Andric   bool EmitUniqueSection = TM.getFunctionSections() || C;
9520b57cec5SDimitry Andric   if (!EmitUniqueSection)
9530b57cec5SDimitry Andric     return ReadOnlySection;
9540b57cec5SDimitry Andric 
9550b57cec5SDimitry Andric   return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(),
9560b57cec5SDimitry Andric                                    getMangler(), TM, EmitUniqueSection,
9570b57cec5SDimitry Andric                                    ELF::SHF_ALLOC, &NextUniqueID,
9580b57cec5SDimitry Andric                                    /* AssociatedSymbol */ nullptr);
9590b57cec5SDimitry Andric }
9600b57cec5SDimitry Andric 
getSectionForLSDA(const Function & F,const MCSymbol & FnSym,const TargetMachine & TM) const961fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(
962fe6060f1SDimitry Andric     const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {
963e8d8bef9SDimitry Andric   // If neither COMDAT nor function sections, use the monolithic LSDA section.
964e8d8bef9SDimitry Andric   // Re-use this path if LSDASection is null as in the Arm EHABI.
965e8d8bef9SDimitry Andric   if (!LSDASection || (!F.hasComdat() && !TM.getFunctionSections()))
966e8d8bef9SDimitry Andric     return LSDASection;
967e8d8bef9SDimitry Andric 
968e8d8bef9SDimitry Andric   const auto *LSDA = cast<MCSectionELF>(LSDASection);
969e8d8bef9SDimitry Andric   unsigned Flags = LSDA->getFlags();
970fe6060f1SDimitry Andric   const MCSymbolELF *LinkedToSym = nullptr;
971e8d8bef9SDimitry Andric   StringRef Group;
972fe6060f1SDimitry Andric   bool IsComdat = false;
973fe6060f1SDimitry Andric   if (const Comdat *C = getELFComdat(&F)) {
974e8d8bef9SDimitry Andric     Flags |= ELF::SHF_GROUP;
975fe6060f1SDimitry Andric     Group = C->getName();
976fe6060f1SDimitry Andric     IsComdat = C->getSelectionKind() == Comdat::Any;
977fe6060f1SDimitry Andric   }
978fe6060f1SDimitry Andric   // Use SHF_LINK_ORDER to facilitate --gc-sections if we can use GNU ld>=2.36
979fe6060f1SDimitry Andric   // or LLD, which support mixed SHF_LINK_ORDER & non-SHF_LINK_ORDER.
980fe6060f1SDimitry Andric   if (TM.getFunctionSections() &&
981fe6060f1SDimitry Andric       (getContext().getAsmInfo()->useIntegratedAssembler() &&
982fe6060f1SDimitry Andric        getContext().getAsmInfo()->binutilsIsAtLeast(2, 36))) {
983fe6060f1SDimitry Andric     Flags |= ELF::SHF_LINK_ORDER;
984fe6060f1SDimitry Andric     LinkedToSym = cast<MCSymbolELF>(&FnSym);
985e8d8bef9SDimitry Andric   }
986e8d8bef9SDimitry Andric 
987e8d8bef9SDimitry Andric   // Append the function name as the suffix like GCC, assuming
988e8d8bef9SDimitry Andric   // -funique-section-names applies to .gcc_except_table sections.
989fe6060f1SDimitry Andric   return getContext().getELFSection(
990fe6060f1SDimitry Andric       (TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName()
991fe6060f1SDimitry Andric                                   : LSDA->getName()),
992fe6060f1SDimitry Andric       LSDA->getType(), Flags, 0, Group, IsComdat, MCSection::NonUniqueID,
993fe6060f1SDimitry Andric       LinkedToSym);
994e8d8bef9SDimitry Andric }
995e8d8bef9SDimitry Andric 
shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,const Function & F) const9960b57cec5SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
9970b57cec5SDimitry Andric     bool UsesLabelDifference, const Function &F) const {
9980b57cec5SDimitry Andric   // We can always create relative relocations, so use another section
9990b57cec5SDimitry Andric   // that can be marked non-executable.
10000b57cec5SDimitry Andric   return false;
10010b57cec5SDimitry Andric }
10020b57cec5SDimitry Andric 
10030b57cec5SDimitry Andric /// Given a mergeable constant with the specified size and relocation
10040b57cec5SDimitry Andric /// information, return a section that it should be placed in.
getSectionForConstant(const DataLayout & DL,SectionKind Kind,const Constant * C,Align & Alignment) const10050b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant(
10060b57cec5SDimitry Andric     const DataLayout &DL, SectionKind Kind, const Constant *C,
10075ffd83dbSDimitry Andric     Align &Alignment) const {
10080b57cec5SDimitry Andric   if (Kind.isMergeableConst4() && MergeableConst4Section)
10090b57cec5SDimitry Andric     return MergeableConst4Section;
10100b57cec5SDimitry Andric   if (Kind.isMergeableConst8() && MergeableConst8Section)
10110b57cec5SDimitry Andric     return MergeableConst8Section;
10120b57cec5SDimitry Andric   if (Kind.isMergeableConst16() && MergeableConst16Section)
10130b57cec5SDimitry Andric     return MergeableConst16Section;
10140b57cec5SDimitry Andric   if (Kind.isMergeableConst32() && MergeableConst32Section)
10150b57cec5SDimitry Andric     return MergeableConst32Section;
10160b57cec5SDimitry Andric   if (Kind.isReadOnly())
10170b57cec5SDimitry Andric     return ReadOnlySection;
10180b57cec5SDimitry Andric 
10190b57cec5SDimitry Andric   assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
10200b57cec5SDimitry Andric   return DataRelROSection;
10210b57cec5SDimitry Andric }
10220b57cec5SDimitry Andric 
10235ffd83dbSDimitry Andric /// Returns a unique section for the given machine basic block.
getSectionForMachineBasicBlock(const Function & F,const MachineBasicBlock & MBB,const TargetMachine & TM) const10245ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
10255ffd83dbSDimitry Andric     const Function &F, const MachineBasicBlock &MBB,
10265ffd83dbSDimitry Andric     const TargetMachine &TM) const {
10275ffd83dbSDimitry Andric   assert(MBB.isBeginSection() && "Basic block does not start a section!");
10285ffd83dbSDimitry Andric   unsigned UniqueID = MCContext::GenericSectionID;
10295ffd83dbSDimitry Andric 
1030e8d8bef9SDimitry Andric   // For cold sections use the .text.split. prefix along with the parent
10315ffd83dbSDimitry Andric   // function name. All cold blocks for the same function go to the same
10325ffd83dbSDimitry Andric   // section. Similarly all exception blocks are grouped by symbol name
10335ffd83dbSDimitry Andric   // under the .text.eh prefix. For regular sections, we either use a unique
10345ffd83dbSDimitry Andric   // name, or a unique ID for the section.
10355ffd83dbSDimitry Andric   SmallString<128> Name;
1036c9157d92SDimitry Andric   StringRef FunctionSectionName = MBB.getParent()->getSection()->getName();
1037c9157d92SDimitry Andric   if (FunctionSectionName.equals(".text") ||
1038c9157d92SDimitry Andric       FunctionSectionName.starts_with(".text.")) {
1039c9157d92SDimitry Andric     // Function is in a regular .text section.
1040c9157d92SDimitry Andric     StringRef FunctionName = MBB.getParent()->getName();
10415ffd83dbSDimitry Andric     if (MBB.getSectionID() == MBBSectionID::ColdSectionID) {
1042e8d8bef9SDimitry Andric       Name += BBSectionsColdTextPrefix;
1043c9157d92SDimitry Andric       Name += FunctionName;
10445ffd83dbSDimitry Andric     } else if (MBB.getSectionID() == MBBSectionID::ExceptionSectionID) {
10455ffd83dbSDimitry Andric       Name += ".text.eh.";
1046c9157d92SDimitry Andric       Name += FunctionName;
10475ffd83dbSDimitry Andric     } else {
1048c9157d92SDimitry Andric       Name += FunctionSectionName;
10495ffd83dbSDimitry Andric       if (TM.getUniqueBasicBlockSectionNames()) {
1050c9157d92SDimitry Andric         if (!Name.ends_with("."))
10515ffd83dbSDimitry Andric           Name += ".";
10525ffd83dbSDimitry Andric         Name += MBB.getSymbol()->getName();
10535ffd83dbSDimitry Andric       } else {
10545ffd83dbSDimitry Andric         UniqueID = NextUniqueID++;
10555ffd83dbSDimitry Andric       }
10565ffd83dbSDimitry Andric     }
1057c9157d92SDimitry Andric   } else {
1058c9157d92SDimitry Andric     // If the original function has a custom non-dot-text section, then emit
1059c9157d92SDimitry Andric     // all basic block sections into that section too, each with a unique id.
1060c9157d92SDimitry Andric     Name = FunctionSectionName;
1061c9157d92SDimitry Andric     UniqueID = NextUniqueID++;
1062c9157d92SDimitry Andric   }
10635ffd83dbSDimitry Andric 
10645ffd83dbSDimitry Andric   unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
1065e8d8bef9SDimitry Andric   std::string GroupName;
10665ffd83dbSDimitry Andric   if (F.hasComdat()) {
10675ffd83dbSDimitry Andric     Flags |= ELF::SHF_GROUP;
10685ffd83dbSDimitry Andric     GroupName = F.getComdat()->getName().str();
10695ffd83dbSDimitry Andric   }
10705ffd83dbSDimitry Andric   return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags,
1071fe6060f1SDimitry Andric                                     0 /* Entry Size */, GroupName,
1072fe6060f1SDimitry Andric                                     F.hasComdat(), UniqueID, nullptr);
10735ffd83dbSDimitry Andric }
10745ffd83dbSDimitry Andric 
getStaticStructorSection(MCContext & Ctx,bool UseInitArray,bool IsCtor,unsigned Priority,const MCSymbol * KeySym)10750b57cec5SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
10760b57cec5SDimitry Andric                                               bool IsCtor, unsigned Priority,
10770b57cec5SDimitry Andric                                               const MCSymbol *KeySym) {
10780b57cec5SDimitry Andric   std::string Name;
10790b57cec5SDimitry Andric   unsigned Type;
10800b57cec5SDimitry Andric   unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE;
1081fe6060f1SDimitry Andric   StringRef Comdat = KeySym ? KeySym->getName() : "";
10820b57cec5SDimitry Andric 
10830b57cec5SDimitry Andric   if (KeySym)
10840b57cec5SDimitry Andric     Flags |= ELF::SHF_GROUP;
10850b57cec5SDimitry Andric 
10860b57cec5SDimitry Andric   if (UseInitArray) {
10870b57cec5SDimitry Andric     if (IsCtor) {
10880b57cec5SDimitry Andric       Type = ELF::SHT_INIT_ARRAY;
10890b57cec5SDimitry Andric       Name = ".init_array";
10900b57cec5SDimitry Andric     } else {
10910b57cec5SDimitry Andric       Type = ELF::SHT_FINI_ARRAY;
10920b57cec5SDimitry Andric       Name = ".fini_array";
10930b57cec5SDimitry Andric     }
10940b57cec5SDimitry Andric     if (Priority != 65535) {
10950b57cec5SDimitry Andric       Name += '.';
10960b57cec5SDimitry Andric       Name += utostr(Priority);
10970b57cec5SDimitry Andric     }
10980b57cec5SDimitry Andric   } else {
10990b57cec5SDimitry Andric     // The default scheme is .ctor / .dtor, so we have to invert the priority
11000b57cec5SDimitry Andric     // numbering.
11010b57cec5SDimitry Andric     if (IsCtor)
11020b57cec5SDimitry Andric       Name = ".ctors";
11030b57cec5SDimitry Andric     else
11040b57cec5SDimitry Andric       Name = ".dtors";
11050b57cec5SDimitry Andric     if (Priority != 65535)
11060b57cec5SDimitry Andric       raw_string_ostream(Name) << format(".%05u", 65535 - Priority);
11070b57cec5SDimitry Andric     Type = ELF::SHT_PROGBITS;
11080b57cec5SDimitry Andric   }
11090b57cec5SDimitry Andric 
1110fe6060f1SDimitry Andric   return Ctx.getELFSection(Name, Type, Flags, 0, Comdat, /*IsComdat=*/true);
11110b57cec5SDimitry Andric }
11120b57cec5SDimitry Andric 
getStaticCtorSection(unsigned Priority,const MCSymbol * KeySym) const11130b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection(
11140b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
11150b57cec5SDimitry Andric   return getStaticStructorSection(getContext(), UseInitArray, true, Priority,
11160b57cec5SDimitry Andric                                   KeySym);
11170b57cec5SDimitry Andric }
11180b57cec5SDimitry Andric 
getStaticDtorSection(unsigned Priority,const MCSymbol * KeySym) const11190b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection(
11200b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
11210b57cec5SDimitry Andric   return getStaticStructorSection(getContext(), UseInitArray, false, Priority,
11220b57cec5SDimitry Andric                                   KeySym);
11230b57cec5SDimitry Andric }
11240b57cec5SDimitry Andric 
lowerRelativeReference(const GlobalValue * LHS,const GlobalValue * RHS,const TargetMachine & TM) const11250b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
11260b57cec5SDimitry Andric     const GlobalValue *LHS, const GlobalValue *RHS,
11270b57cec5SDimitry Andric     const TargetMachine &TM) const {
11280b57cec5SDimitry Andric   // We may only use a PLT-relative relocation to refer to unnamed_addr
11290b57cec5SDimitry Andric   // functions.
11300b57cec5SDimitry Andric   if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
11310b57cec5SDimitry Andric     return nullptr;
11320b57cec5SDimitry Andric 
11334824e7fdSDimitry Andric   // Basic correctness checks.
11340b57cec5SDimitry Andric   if (LHS->getType()->getPointerAddressSpace() != 0 ||
11350b57cec5SDimitry Andric       RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() ||
11360b57cec5SDimitry Andric       RHS->isThreadLocal())
11370b57cec5SDimitry Andric     return nullptr;
11380b57cec5SDimitry Andric 
11390b57cec5SDimitry Andric   return MCBinaryExpr::createSub(
11400b57cec5SDimitry Andric       MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind,
11410b57cec5SDimitry Andric                               getContext()),
11420b57cec5SDimitry Andric       MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
11430b57cec5SDimitry Andric }
11440b57cec5SDimitry Andric 
lowerDSOLocalEquivalent(const DSOLocalEquivalent * Equiv,const TargetMachine & TM) const1145e8d8bef9SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent(
1146e8d8bef9SDimitry Andric     const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const {
1147e8d8bef9SDimitry Andric   assert(supportDSOLocalEquivalentLowering());
1148e8d8bef9SDimitry Andric 
1149e8d8bef9SDimitry Andric   const auto *GV = Equiv->getGlobalValue();
1150e8d8bef9SDimitry Andric 
1151e8d8bef9SDimitry Andric   // A PLT entry is not needed for dso_local globals.
1152e8d8bef9SDimitry Andric   if (GV->isDSOLocal() || GV->isImplicitDSOLocal())
1153e8d8bef9SDimitry Andric     return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext());
1154e8d8bef9SDimitry Andric 
1155e8d8bef9SDimitry Andric   return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeVariantKind,
1156e8d8bef9SDimitry Andric                                  getContext());
1157e8d8bef9SDimitry Andric }
1158e8d8bef9SDimitry Andric 
getSectionForCommandLines() const11590b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
11600b57cec5SDimitry Andric   // Use ".GCC.command.line" since this feature is to support clang's
11610b57cec5SDimitry Andric   // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the
11620b57cec5SDimitry Andric   // same name.
11630b57cec5SDimitry Andric   return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS,
1164fe6060f1SDimitry Andric                                     ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
11650b57cec5SDimitry Andric }
11660b57cec5SDimitry Andric 
11670b57cec5SDimitry Andric void
InitializeELF(bool UseInitArray_)11680b57cec5SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) {
11690b57cec5SDimitry Andric   UseInitArray = UseInitArray_;
11700b57cec5SDimitry Andric   MCContext &Ctx = getContext();
11710b57cec5SDimitry Andric   if (!UseInitArray) {
11720b57cec5SDimitry Andric     StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS,
11730b57cec5SDimitry Andric                                           ELF::SHF_ALLOC | ELF::SHF_WRITE);
11740b57cec5SDimitry Andric 
11750b57cec5SDimitry Andric     StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS,
11760b57cec5SDimitry Andric                                           ELF::SHF_ALLOC | ELF::SHF_WRITE);
11770b57cec5SDimitry Andric     return;
11780b57cec5SDimitry Andric   }
11790b57cec5SDimitry Andric 
11800b57cec5SDimitry Andric   StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY,
11810b57cec5SDimitry Andric                                         ELF::SHF_WRITE | ELF::SHF_ALLOC);
11820b57cec5SDimitry Andric   StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY,
11830b57cec5SDimitry Andric                                         ELF::SHF_WRITE | ELF::SHF_ALLOC);
11840b57cec5SDimitry Andric }
11850b57cec5SDimitry Andric 
11860b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11870b57cec5SDimitry Andric //                                 MachO
11880b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11890b57cec5SDimitry Andric 
TargetLoweringObjectFileMachO()119004eeddc0SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() {
11910b57cec5SDimitry Andric   SupportIndirectSymViaGOTPCRel = true;
11920b57cec5SDimitry Andric }
11930b57cec5SDimitry Andric 
Initialize(MCContext & Ctx,const TargetMachine & TM)11940b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
11950b57cec5SDimitry Andric                                                const TargetMachine &TM) {
11960b57cec5SDimitry Andric   TargetLoweringObjectFile::Initialize(Ctx, TM);
11970b57cec5SDimitry Andric   if (TM.getRelocationModel() == Reloc::Static) {
11980b57cec5SDimitry Andric     StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0,
11990b57cec5SDimitry Andric                                             SectionKind::getData());
12000b57cec5SDimitry Andric     StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0,
12010b57cec5SDimitry Andric                                             SectionKind::getData());
12020b57cec5SDimitry Andric   } else {
12030b57cec5SDimitry Andric     StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func",
12040b57cec5SDimitry Andric                                             MachO::S_MOD_INIT_FUNC_POINTERS,
12050b57cec5SDimitry Andric                                             SectionKind::getData());
12060b57cec5SDimitry Andric     StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func",
12070b57cec5SDimitry Andric                                             MachO::S_MOD_TERM_FUNC_POINTERS,
12080b57cec5SDimitry Andric                                             SectionKind::getData());
12090b57cec5SDimitry Andric   }
12100b57cec5SDimitry Andric 
12110b57cec5SDimitry Andric   PersonalityEncoding =
12120b57cec5SDimitry Andric       dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
12130b57cec5SDimitry Andric   LSDAEncoding = dwarf::DW_EH_PE_pcrel;
12140b57cec5SDimitry Andric   TTypeEncoding =
12150b57cec5SDimitry Andric       dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
12160b57cec5SDimitry Andric }
12170b57cec5SDimitry Andric 
getStaticDtorSection(unsigned Priority,const MCSymbol * KeySym) const121881ad6265SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getStaticDtorSection(
121981ad6265SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
122081ad6265SDimitry Andric   return StaticDtorSection;
1221fe013be4SDimitry Andric   // In userspace, we lower global destructors via atexit(), but kernel/kext
1222fe013be4SDimitry Andric   // environments do not provide this function so we still need to support the
1223fe013be4SDimitry Andric   // legacy way here.
1224fe013be4SDimitry Andric   // See the -disable-atexit-based-global-dtor-lowering CodeGen flag for more
1225fe013be4SDimitry Andric   // context.
122681ad6265SDimitry Andric }
122781ad6265SDimitry Andric 
emitModuleMetadata(MCStreamer & Streamer,Module & M) const12280b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer,
12290b57cec5SDimitry Andric                                                        Module &M) const {
12300b57cec5SDimitry Andric   // Emit the linker options if present.
12310b57cec5SDimitry Andric   if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
1232480093f4SDimitry Andric     for (const auto *Option : LinkerOptions->operands()) {
12330b57cec5SDimitry Andric       SmallVector<std::string, 4> StrOptions;
12340b57cec5SDimitry Andric       for (const auto &Piece : cast<MDNode>(Option)->operands())
12355ffd83dbSDimitry Andric         StrOptions.push_back(std::string(cast<MDString>(Piece)->getString()));
12365ffd83dbSDimitry Andric       Streamer.emitLinkerOptions(StrOptions);
12370b57cec5SDimitry Andric     }
12380b57cec5SDimitry Andric   }
12390b57cec5SDimitry Andric 
12400b57cec5SDimitry Andric   unsigned VersionVal = 0;
12410b57cec5SDimitry Andric   unsigned ImageInfoFlags = 0;
12420b57cec5SDimitry Andric   StringRef SectionVal;
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric   GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal);
124504eeddc0SDimitry Andric   emitCGProfileMetadata(Streamer, M);
12460b57cec5SDimitry Andric 
12470b57cec5SDimitry Andric   // The section is mandatory. If we don't have it, then we don't have GC info.
12480b57cec5SDimitry Andric   if (SectionVal.empty())
12490b57cec5SDimitry Andric     return;
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric   StringRef Segment, Section;
12520b57cec5SDimitry Andric   unsigned TAA = 0, StubSize = 0;
12530b57cec5SDimitry Andric   bool TAAParsed;
1254fe6060f1SDimitry Andric   if (Error E = MCSectionMachO::ParseSectionSpecifier(
1255fe6060f1SDimitry Andric           SectionVal, Segment, Section, TAA, TAAParsed, StubSize)) {
12560b57cec5SDimitry Andric     // If invalid, report the error with report_fatal_error.
1257fe6060f1SDimitry Andric     report_fatal_error("Invalid section specifier '" + Section +
1258fe6060f1SDimitry Andric                        "': " + toString(std::move(E)) + ".");
1259fe6060f1SDimitry Andric   }
12600b57cec5SDimitry Andric 
12610b57cec5SDimitry Andric   // Get the section.
12620b57cec5SDimitry Andric   MCSectionMachO *S = getContext().getMachOSection(
12630b57cec5SDimitry Andric       Segment, Section, TAA, StubSize, SectionKind::getData());
126481ad6265SDimitry Andric   Streamer.switchSection(S);
12655ffd83dbSDimitry Andric   Streamer.emitLabel(getContext().
12660b57cec5SDimitry Andric                      getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO")));
12675ffd83dbSDimitry Andric   Streamer.emitInt32(VersionVal);
12685ffd83dbSDimitry Andric   Streamer.emitInt32(ImageInfoFlags);
126981ad6265SDimitry Andric   Streamer.addBlankLine();
12700b57cec5SDimitry Andric }
12710b57cec5SDimitry Andric 
checkMachOComdat(const GlobalValue * GV)12720b57cec5SDimitry Andric static void checkMachOComdat(const GlobalValue *GV) {
12730b57cec5SDimitry Andric   const Comdat *C = GV->getComdat();
12740b57cec5SDimitry Andric   if (!C)
12750b57cec5SDimitry Andric     return;
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric   report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() +
12780b57cec5SDimitry Andric                      "' cannot be lowered.");
12790b57cec5SDimitry Andric }
12800b57cec5SDimitry Andric 
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const12810b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
12820b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
1283fe6060f1SDimitry Andric 
1284fe6060f1SDimitry Andric   StringRef SectionName = GO->getSection();
1285fe6060f1SDimitry Andric 
1286fe013be4SDimitry Andric   const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO);
1287fe013be4SDimitry Andric   if (GV && GV->hasImplicitSection()) {
1288fe013be4SDimitry Andric     auto Attrs = GV->getAttributes();
1289fe013be4SDimitry Andric     if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) {
1290fe013be4SDimitry Andric       SectionName = Attrs.getAttribute("bss-section").getValueAsString();
1291fe013be4SDimitry Andric     } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
1292fe013be4SDimitry Andric       SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
1293fe013be4SDimitry Andric     } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) {
1294fe013be4SDimitry Andric       SectionName = Attrs.getAttribute("relro-section").getValueAsString();
1295fe013be4SDimitry Andric     } else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
1296fe013be4SDimitry Andric       SectionName = Attrs.getAttribute("data-section").getValueAsString();
1297fe013be4SDimitry Andric     }
1298fe013be4SDimitry Andric   }
1299fe013be4SDimitry Andric 
1300fe6060f1SDimitry Andric   const Function *F = dyn_cast<Function>(GO);
1301fe6060f1SDimitry Andric   if (F && F->hasFnAttribute("implicit-section-name")) {
1302fe6060f1SDimitry Andric     SectionName = F->getFnAttribute("implicit-section-name").getValueAsString();
1303fe6060f1SDimitry Andric   }
1304fe6060f1SDimitry Andric 
13050b57cec5SDimitry Andric   // Parse the section specifier and create it if valid.
13060b57cec5SDimitry Andric   StringRef Segment, Section;
13070b57cec5SDimitry Andric   unsigned TAA = 0, StubSize = 0;
13080b57cec5SDimitry Andric   bool TAAParsed;
13090b57cec5SDimitry Andric 
13100b57cec5SDimitry Andric   checkMachOComdat(GO);
13110b57cec5SDimitry Andric 
1312fe6060f1SDimitry Andric   if (Error E = MCSectionMachO::ParseSectionSpecifier(
1313fe6060f1SDimitry Andric           SectionName, Segment, Section, TAA, TAAParsed, StubSize)) {
13140b57cec5SDimitry Andric     // If invalid, report the error with report_fatal_error.
13150b57cec5SDimitry Andric     report_fatal_error("Global variable '" + GO->getName() +
13160b57cec5SDimitry Andric                        "' has an invalid section specifier '" +
1317fe6060f1SDimitry Andric                        GO->getSection() + "': " + toString(std::move(E)) + ".");
13180b57cec5SDimitry Andric   }
13190b57cec5SDimitry Andric 
13200b57cec5SDimitry Andric   // Get the section.
13210b57cec5SDimitry Andric   MCSectionMachO *S =
13220b57cec5SDimitry Andric       getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind);
13230b57cec5SDimitry Andric 
13240b57cec5SDimitry Andric   // If TAA wasn't set by ParseSectionSpecifier() above,
13250b57cec5SDimitry Andric   // use the value returned by getMachOSection() as a default.
13260b57cec5SDimitry Andric   if (!TAAParsed)
13270b57cec5SDimitry Andric     TAA = S->getTypeAndAttributes();
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric   // Okay, now that we got the section, verify that the TAA & StubSize agree.
13300b57cec5SDimitry Andric   // If the user declared multiple globals with different section flags, we need
13310b57cec5SDimitry Andric   // to reject it here.
13320b57cec5SDimitry Andric   if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {
13330b57cec5SDimitry Andric     // If invalid, report the error with report_fatal_error.
13340b57cec5SDimitry Andric     report_fatal_error("Global variable '" + GO->getName() +
13350b57cec5SDimitry Andric                        "' section type or attributes does not match previous"
13360b57cec5SDimitry Andric                        " section specifier");
13370b57cec5SDimitry Andric   }
13380b57cec5SDimitry Andric 
13390b57cec5SDimitry Andric   return S;
13400b57cec5SDimitry Andric }
13410b57cec5SDimitry Andric 
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const13420b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal(
13430b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
13440b57cec5SDimitry Andric   checkMachOComdat(GO);
13450b57cec5SDimitry Andric 
13460b57cec5SDimitry Andric   // Handle thread local data.
13470b57cec5SDimitry Andric   if (Kind.isThreadBSS()) return TLSBSSSection;
13480b57cec5SDimitry Andric   if (Kind.isThreadData()) return TLSDataSection;
13490b57cec5SDimitry Andric 
13500b57cec5SDimitry Andric   if (Kind.isText())
13510b57cec5SDimitry Andric     return GO->isWeakForLinker() ? TextCoalSection : TextSection;
13520b57cec5SDimitry Andric 
13530b57cec5SDimitry Andric   // If this is weak/linkonce, put this in a coalescable section, either in text
13540b57cec5SDimitry Andric   // or data depending on if it is writable.
13550b57cec5SDimitry Andric   if (GO->isWeakForLinker()) {
13560b57cec5SDimitry Andric     if (Kind.isReadOnly())
13570b57cec5SDimitry Andric       return ConstTextCoalSection;
13580b57cec5SDimitry Andric     if (Kind.isReadOnlyWithRel())
13590b57cec5SDimitry Andric       return ConstDataCoalSection;
13600b57cec5SDimitry Andric     return DataCoalSection;
13610b57cec5SDimitry Andric   }
13620b57cec5SDimitry Andric 
13630b57cec5SDimitry Andric   // FIXME: Alignment check should be handled by section classifier.
13640b57cec5SDimitry Andric   if (Kind.isMergeable1ByteCString() &&
13655ffd83dbSDimitry Andric       GO->getParent()->getDataLayout().getPreferredAlign(
13665ffd83dbSDimitry Andric           cast<GlobalVariable>(GO)) < Align(32))
13670b57cec5SDimitry Andric     return CStringSection;
13680b57cec5SDimitry Andric 
13690b57cec5SDimitry Andric   // Do not put 16-bit arrays in the UString section if they have an
13700b57cec5SDimitry Andric   // externally visible label, this runs into issues with certain linker
13710b57cec5SDimitry Andric   // versions.
13720b57cec5SDimitry Andric   if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() &&
13735ffd83dbSDimitry Andric       GO->getParent()->getDataLayout().getPreferredAlign(
13745ffd83dbSDimitry Andric           cast<GlobalVariable>(GO)) < Align(32))
13750b57cec5SDimitry Andric     return UStringSection;
13760b57cec5SDimitry Andric 
13770b57cec5SDimitry Andric   // With MachO only variables whose corresponding symbol starts with 'l' or
13780b57cec5SDimitry Andric   // 'L' can be merged, so we only try merging GVs with private linkage.
13790b57cec5SDimitry Andric   if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) {
13800b57cec5SDimitry Andric     if (Kind.isMergeableConst4())
13810b57cec5SDimitry Andric       return FourByteConstantSection;
13820b57cec5SDimitry Andric     if (Kind.isMergeableConst8())
13830b57cec5SDimitry Andric       return EightByteConstantSection;
13840b57cec5SDimitry Andric     if (Kind.isMergeableConst16())
13850b57cec5SDimitry Andric       return SixteenByteConstantSection;
13860b57cec5SDimitry Andric   }
13870b57cec5SDimitry Andric 
13880b57cec5SDimitry Andric   // Otherwise, if it is readonly, but not something we can specially optimize,
13890b57cec5SDimitry Andric   // just drop it in .const.
13900b57cec5SDimitry Andric   if (Kind.isReadOnly())
13910b57cec5SDimitry Andric     return ReadOnlySection;
13920b57cec5SDimitry Andric 
13930b57cec5SDimitry Andric   // If this is marked const, put it into a const section.  But if the dynamic
13940b57cec5SDimitry Andric   // linker needs to write to it, put it in the data segment.
13950b57cec5SDimitry Andric   if (Kind.isReadOnlyWithRel())
13960b57cec5SDimitry Andric     return ConstDataSection;
13970b57cec5SDimitry Andric 
13980b57cec5SDimitry Andric   // Put zero initialized globals with strong external linkage in the
13990b57cec5SDimitry Andric   // DATA, __common section with the .zerofill directive.
14000b57cec5SDimitry Andric   if (Kind.isBSSExtern())
14010b57cec5SDimitry Andric     return DataCommonSection;
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric   // Put zero initialized globals with local linkage in __DATA,__bss directive
14040b57cec5SDimitry Andric   // with the .zerofill directive (aka .lcomm).
14050b57cec5SDimitry Andric   if (Kind.isBSSLocal())
14060b57cec5SDimitry Andric     return DataBSSSection;
14070b57cec5SDimitry Andric 
14080b57cec5SDimitry Andric   // Otherwise, just drop the variable in the normal data section.
14090b57cec5SDimitry Andric   return DataSection;
14100b57cec5SDimitry Andric }
14110b57cec5SDimitry Andric 
getSectionForConstant(const DataLayout & DL,SectionKind Kind,const Constant * C,Align & Alignment) const14120b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant(
14130b57cec5SDimitry Andric     const DataLayout &DL, SectionKind Kind, const Constant *C,
14145ffd83dbSDimitry Andric     Align &Alignment) const {
14150b57cec5SDimitry Andric   // If this constant requires a relocation, we have to put it in the data
14160b57cec5SDimitry Andric   // segment, not in the text segment.
14170b57cec5SDimitry Andric   if (Kind.isData() || Kind.isReadOnlyWithRel())
14180b57cec5SDimitry Andric     return ConstDataSection;
14190b57cec5SDimitry Andric 
14200b57cec5SDimitry Andric   if (Kind.isMergeableConst4())
14210b57cec5SDimitry Andric     return FourByteConstantSection;
14220b57cec5SDimitry Andric   if (Kind.isMergeableConst8())
14230b57cec5SDimitry Andric     return EightByteConstantSection;
14240b57cec5SDimitry Andric   if (Kind.isMergeableConst16())
14250b57cec5SDimitry Andric     return SixteenByteConstantSection;
14260b57cec5SDimitry Andric   return ReadOnlySection;  // .const
14270b57cec5SDimitry Andric }
14280b57cec5SDimitry Andric 
getSectionForCommandLines() const1429fe013be4SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForCommandLines() const {
1430fe013be4SDimitry Andric   return getContext().getMachOSection("__TEXT", "__command_line", 0,
1431fe013be4SDimitry Andric                                       SectionKind::getReadOnly());
1432fe013be4SDimitry Andric }
1433fe013be4SDimitry Andric 
getTTypeGlobalReference(const GlobalValue * GV,unsigned Encoding,const TargetMachine & TM,MachineModuleInfo * MMI,MCStreamer & Streamer) const14340b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference(
14350b57cec5SDimitry Andric     const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,
14360b57cec5SDimitry Andric     MachineModuleInfo *MMI, MCStreamer &Streamer) const {
14370b57cec5SDimitry Andric   // The mach-o version of this method defaults to returning a stub reference.
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric   if (Encoding & DW_EH_PE_indirect) {
14400b57cec5SDimitry Andric     MachineModuleInfoMachO &MachOMMI =
14410b57cec5SDimitry Andric       MMI->getObjFileInfo<MachineModuleInfoMachO>();
14420b57cec5SDimitry Andric 
14430b57cec5SDimitry Andric     MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM);
14440b57cec5SDimitry Andric 
14450b57cec5SDimitry Andric     // Add information about the stub reference to MachOMMI so that the stub
14460b57cec5SDimitry Andric     // gets emitted by the asmprinter.
14470b57cec5SDimitry Andric     MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
14480b57cec5SDimitry Andric     if (!StubSym.getPointer()) {
14490b57cec5SDimitry Andric       MCSymbol *Sym = TM.getSymbol(GV);
14500b57cec5SDimitry Andric       StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
14510b57cec5SDimitry Andric     }
14520b57cec5SDimitry Andric 
14530b57cec5SDimitry Andric     return TargetLoweringObjectFile::
14540b57cec5SDimitry Andric       getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()),
14550b57cec5SDimitry Andric                         Encoding & ~DW_EH_PE_indirect, Streamer);
14560b57cec5SDimitry Andric   }
14570b57cec5SDimitry Andric 
14580b57cec5SDimitry Andric   return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM,
14590b57cec5SDimitry Andric                                                            MMI, Streamer);
14600b57cec5SDimitry Andric }
14610b57cec5SDimitry Andric 
getCFIPersonalitySymbol(const GlobalValue * GV,const TargetMachine & TM,MachineModuleInfo * MMI) const14620b57cec5SDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol(
14630b57cec5SDimitry Andric     const GlobalValue *GV, const TargetMachine &TM,
14640b57cec5SDimitry Andric     MachineModuleInfo *MMI) const {
14650b57cec5SDimitry Andric   // The mach-o version of this method defaults to returning a stub reference.
14660b57cec5SDimitry Andric   MachineModuleInfoMachO &MachOMMI =
14670b57cec5SDimitry Andric     MMI->getObjFileInfo<MachineModuleInfoMachO>();
14680b57cec5SDimitry Andric 
14690b57cec5SDimitry Andric   MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM);
14700b57cec5SDimitry Andric 
14710b57cec5SDimitry Andric   // Add information about the stub reference to MachOMMI so that the stub
14720b57cec5SDimitry Andric   // gets emitted by the asmprinter.
14730b57cec5SDimitry Andric   MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
14740b57cec5SDimitry Andric   if (!StubSym.getPointer()) {
14750b57cec5SDimitry Andric     MCSymbol *Sym = TM.getSymbol(GV);
14760b57cec5SDimitry Andric     StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
14770b57cec5SDimitry Andric   }
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric   return SSym;
14800b57cec5SDimitry Andric }
14810b57cec5SDimitry Andric 
getIndirectSymViaGOTPCRel(const GlobalValue * GV,const MCSymbol * Sym,const MCValue & MV,int64_t Offset,MachineModuleInfo * MMI,MCStreamer & Streamer) const14820b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel(
14838bcb0991SDimitry Andric     const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
14848bcb0991SDimitry Andric     int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
14850b57cec5SDimitry Andric   // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation
14860b57cec5SDimitry Andric   // as 64-bit do, we replace the GOT equivalent by accessing the final symbol
14870b57cec5SDimitry Andric   // through a non_lazy_ptr stub instead. One advantage is that it allows the
14880b57cec5SDimitry Andric   // computation of deltas to final external symbols. Example:
14890b57cec5SDimitry Andric   //
14900b57cec5SDimitry Andric   //    _extgotequiv:
14910b57cec5SDimitry Andric   //       .long   _extfoo
14920b57cec5SDimitry Andric   //
14930b57cec5SDimitry Andric   //    _delta:
14940b57cec5SDimitry Andric   //       .long   _extgotequiv-_delta
14950b57cec5SDimitry Andric   //
14960b57cec5SDimitry Andric   // is transformed to:
14970b57cec5SDimitry Andric   //
14980b57cec5SDimitry Andric   //    _delta:
14990b57cec5SDimitry Andric   //       .long   L_extfoo$non_lazy_ptr-(_delta+0)
15000b57cec5SDimitry Andric   //
15010b57cec5SDimitry Andric   //       .section        __IMPORT,__pointers,non_lazy_symbol_pointers
15020b57cec5SDimitry Andric   //    L_extfoo$non_lazy_ptr:
15030b57cec5SDimitry Andric   //       .indirect_symbol        _extfoo
15040b57cec5SDimitry Andric   //       .long   0
15050b57cec5SDimitry Andric   //
15060b57cec5SDimitry Andric   // The indirect symbol table (and sections of non_lazy_symbol_pointers type)
15070b57cec5SDimitry Andric   // may point to both local (same translation unit) and global (other
15080b57cec5SDimitry Andric   // translation units) symbols. Example:
15090b57cec5SDimitry Andric   //
15100b57cec5SDimitry Andric   // .section __DATA,__pointers,non_lazy_symbol_pointers
15110b57cec5SDimitry Andric   // L1:
15120b57cec5SDimitry Andric   //    .indirect_symbol _myGlobal
15130b57cec5SDimitry Andric   //    .long 0
15140b57cec5SDimitry Andric   // L2:
15150b57cec5SDimitry Andric   //    .indirect_symbol _myLocal
15160b57cec5SDimitry Andric   //    .long _myLocal
15170b57cec5SDimitry Andric   //
15180b57cec5SDimitry Andric   // If the symbol is local, instead of the symbol's index, the assembler
15190b57cec5SDimitry Andric   // places the constant INDIRECT_SYMBOL_LOCAL into the indirect symbol table.
15200b57cec5SDimitry Andric   // Then the linker will notice the constant in the table and will look at the
15210b57cec5SDimitry Andric   // content of the symbol.
15220b57cec5SDimitry Andric   MachineModuleInfoMachO &MachOMMI =
15230b57cec5SDimitry Andric     MMI->getObjFileInfo<MachineModuleInfoMachO>();
15240b57cec5SDimitry Andric   MCContext &Ctx = getContext();
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric   // The offset must consider the original displacement from the base symbol
15270b57cec5SDimitry Andric   // since 32-bit targets don't have a GOTPCREL to fold the PC displacement.
15280b57cec5SDimitry Andric   Offset = -MV.getConstant();
15290b57cec5SDimitry Andric   const MCSymbol *BaseSym = &MV.getSymB()->getSymbol();
15300b57cec5SDimitry Andric 
15310b57cec5SDimitry Andric   // Access the final symbol via sym$non_lazy_ptr and generate the appropriated
15320b57cec5SDimitry Andric   // non_lazy_ptr stubs.
15330b57cec5SDimitry Andric   SmallString<128> Name;
15340b57cec5SDimitry Andric   StringRef Suffix = "$non_lazy_ptr";
15350b57cec5SDimitry Andric   Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix();
15360b57cec5SDimitry Andric   Name += Sym->getName();
15370b57cec5SDimitry Andric   Name += Suffix;
15380b57cec5SDimitry Andric   MCSymbol *Stub = Ctx.getOrCreateSymbol(Name);
15390b57cec5SDimitry Andric 
15400b57cec5SDimitry Andric   MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub);
15418bcb0991SDimitry Andric 
15428bcb0991SDimitry Andric   if (!StubSym.getPointer())
15430b57cec5SDimitry Andric     StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym),
15448bcb0991SDimitry Andric                                                  !GV->hasLocalLinkage());
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric   const MCExpr *BSymExpr =
15470b57cec5SDimitry Andric     MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx);
15480b57cec5SDimitry Andric   const MCExpr *LHS =
15490b57cec5SDimitry Andric     MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx);
15500b57cec5SDimitry Andric 
15510b57cec5SDimitry Andric   if (!Offset)
15520b57cec5SDimitry Andric     return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx);
15530b57cec5SDimitry Andric 
15540b57cec5SDimitry Andric   const MCExpr *RHS =
15550b57cec5SDimitry Andric     MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx);
15560b57cec5SDimitry Andric   return MCBinaryExpr::createSub(LHS, RHS, Ctx);
15570b57cec5SDimitry Andric }
15580b57cec5SDimitry Andric 
canUsePrivateLabel(const MCAsmInfo & AsmInfo,const MCSection & Section)15590b57cec5SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo,
15600b57cec5SDimitry Andric                                const MCSection &Section) {
15610b57cec5SDimitry Andric   if (!AsmInfo.isSectionAtomizableBySymbols(Section))
15620b57cec5SDimitry Andric     return true;
15630b57cec5SDimitry Andric 
1564fe6060f1SDimitry Andric   // FIXME: we should be able to use private labels for sections that can't be
1565fe6060f1SDimitry Andric   // dead-stripped (there's no issue with blocking atomization there), but `ld
1566fe6060f1SDimitry Andric   // -r` sometimes drops the no_dead_strip attribute from sections so for safety
1567fe6060f1SDimitry Andric   // we don't allow it.
15680b57cec5SDimitry Andric   return false;
15690b57cec5SDimitry Andric }
15700b57cec5SDimitry Andric 
getNameWithPrefix(SmallVectorImpl<char> & OutName,const GlobalValue * GV,const TargetMachine & TM) const15710b57cec5SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix(
15720b57cec5SDimitry Andric     SmallVectorImpl<char> &OutName, const GlobalValue *GV,
15730b57cec5SDimitry Andric     const TargetMachine &TM) const {
15740b57cec5SDimitry Andric   bool CannotUsePrivateLabel = true;
1575349cc55cSDimitry Andric   if (auto *GO = GV->getAliaseeObject()) {
15760b57cec5SDimitry Andric     SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM);
15770b57cec5SDimitry Andric     const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM);
15780b57cec5SDimitry Andric     CannotUsePrivateLabel =
15790b57cec5SDimitry Andric         !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection);
15800b57cec5SDimitry Andric   }
15810b57cec5SDimitry Andric   getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);
15820b57cec5SDimitry Andric }
15830b57cec5SDimitry Andric 
15840b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15850b57cec5SDimitry Andric //                                  COFF
15860b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15870b57cec5SDimitry Andric 
15880b57cec5SDimitry Andric static unsigned
getCOFFSectionFlags(SectionKind K,const TargetMachine & TM)15890b57cec5SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) {
15900b57cec5SDimitry Andric   unsigned Flags = 0;
15910b57cec5SDimitry Andric   bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb;
15920b57cec5SDimitry Andric 
15930b57cec5SDimitry Andric   if (K.isMetadata())
15940b57cec5SDimitry Andric     Flags |=
15950b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_DISCARDABLE;
159681ad6265SDimitry Andric   else if (K.isExclude())
159781ad6265SDimitry Andric     Flags |=
159881ad6265SDimitry Andric       COFF::IMAGE_SCN_LNK_REMOVE | COFF::IMAGE_SCN_MEM_DISCARDABLE;
15990b57cec5SDimitry Andric   else if (K.isText())
16000b57cec5SDimitry Andric     Flags |=
16010b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_EXECUTE |
16020b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
16030b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_CODE |
16040b57cec5SDimitry Andric       (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0);
16050b57cec5SDimitry Andric   else if (K.isBSS())
16060b57cec5SDimitry Andric     Flags |=
16070b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
16080b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
16090b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_WRITE;
16100b57cec5SDimitry Andric   else if (K.isThreadLocal())
16110b57cec5SDimitry Andric     Flags |=
16120b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
16130b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
16140b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_WRITE;
16150b57cec5SDimitry Andric   else if (K.isReadOnly() || K.isReadOnlyWithRel())
16160b57cec5SDimitry Andric     Flags |=
16170b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
16180b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ;
16190b57cec5SDimitry Andric   else if (K.isWriteable())
16200b57cec5SDimitry Andric     Flags |=
16210b57cec5SDimitry Andric       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
16220b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
16230b57cec5SDimitry Andric       COFF::IMAGE_SCN_MEM_WRITE;
16240b57cec5SDimitry Andric 
16250b57cec5SDimitry Andric   return Flags;
16260b57cec5SDimitry Andric }
16270b57cec5SDimitry Andric 
getComdatGVForCOFF(const GlobalValue * GV)16280b57cec5SDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) {
16290b57cec5SDimitry Andric   const Comdat *C = GV->getComdat();
16300b57cec5SDimitry Andric   assert(C && "expected GV to have a Comdat!");
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric   StringRef ComdatGVName = C->getName();
16330b57cec5SDimitry Andric   const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName);
16340b57cec5SDimitry Andric   if (!ComdatGV)
16350b57cec5SDimitry Andric     report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +
16360b57cec5SDimitry Andric                        "' does not exist.");
16370b57cec5SDimitry Andric 
16380b57cec5SDimitry Andric   if (ComdatGV->getComdat() != C)
16390b57cec5SDimitry Andric     report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +
16400b57cec5SDimitry Andric                        "' is not a key for its COMDAT.");
16410b57cec5SDimitry Andric 
16420b57cec5SDimitry Andric   return ComdatGV;
16430b57cec5SDimitry Andric }
16440b57cec5SDimitry Andric 
getSelectionForCOFF(const GlobalValue * GV)16450b57cec5SDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) {
16460b57cec5SDimitry Andric   if (const Comdat *C = GV->getComdat()) {
16470b57cec5SDimitry Andric     const GlobalValue *ComdatKey = getComdatGVForCOFF(GV);
16480b57cec5SDimitry Andric     if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey))
1649349cc55cSDimitry Andric       ComdatKey = GA->getAliaseeObject();
16500b57cec5SDimitry Andric     if (ComdatKey == GV) {
16510b57cec5SDimitry Andric       switch (C->getSelectionKind()) {
16520b57cec5SDimitry Andric       case Comdat::Any:
16530b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_ANY;
16540b57cec5SDimitry Andric       case Comdat::ExactMatch:
16550b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH;
16560b57cec5SDimitry Andric       case Comdat::Largest:
16570b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_LARGEST;
1658fe6060f1SDimitry Andric       case Comdat::NoDeduplicate:
16590b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;
16600b57cec5SDimitry Andric       case Comdat::SameSize:
16610b57cec5SDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE;
16620b57cec5SDimitry Andric       }
16630b57cec5SDimitry Andric     } else {
16640b57cec5SDimitry Andric       return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
16650b57cec5SDimitry Andric     }
16660b57cec5SDimitry Andric   }
16670b57cec5SDimitry Andric   return 0;
16680b57cec5SDimitry Andric }
16690b57cec5SDimitry Andric 
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const16700b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
16710b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
1672*6c20abcdSDimitry Andric   StringRef Name = GO->getSection();
1673*6c20abcdSDimitry Andric   if (Name == getInstrProfSectionName(IPSK_covmap, Triple::COFF,
1674*6c20abcdSDimitry Andric                                       /*AddSegmentInfo=*/false) ||
1675*6c20abcdSDimitry Andric       Name == getInstrProfSectionName(IPSK_covfun, Triple::COFF,
1676*6c20abcdSDimitry Andric                                       /*AddSegmentInfo=*/false) ||
1677*6c20abcdSDimitry Andric       Name == getInstrProfSectionName(IPSK_covdata, Triple::COFF,
1678*6c20abcdSDimitry Andric                                       /*AddSegmentInfo=*/false) ||
1679*6c20abcdSDimitry Andric       Name == getInstrProfSectionName(IPSK_covname, Triple::COFF,
1680*6c20abcdSDimitry Andric                                       /*AddSegmentInfo=*/false))
1681*6c20abcdSDimitry Andric     Kind = SectionKind::getMetadata();
16820b57cec5SDimitry Andric   int Selection = 0;
16830b57cec5SDimitry Andric   unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
16840b57cec5SDimitry Andric   StringRef COMDATSymName = "";
16850b57cec5SDimitry Andric   if (GO->hasComdat()) {
16860b57cec5SDimitry Andric     Selection = getSelectionForCOFF(GO);
16870b57cec5SDimitry Andric     const GlobalValue *ComdatGV;
16880b57cec5SDimitry Andric     if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
16890b57cec5SDimitry Andric       ComdatGV = getComdatGVForCOFF(GO);
16900b57cec5SDimitry Andric     else
16910b57cec5SDimitry Andric       ComdatGV = GO;
16920b57cec5SDimitry Andric 
16930b57cec5SDimitry Andric     if (!ComdatGV->hasPrivateLinkage()) {
16940b57cec5SDimitry Andric       MCSymbol *Sym = TM.getSymbol(ComdatGV);
16950b57cec5SDimitry Andric       COMDATSymName = Sym->getName();
16960b57cec5SDimitry Andric       Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
16970b57cec5SDimitry Andric     } else {
16980b57cec5SDimitry Andric       Selection = 0;
16990b57cec5SDimitry Andric     }
17000b57cec5SDimitry Andric   }
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric   return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
17030b57cec5SDimitry Andric                                      Selection);
17040b57cec5SDimitry Andric }
17050b57cec5SDimitry Andric 
getCOFFSectionNameForUniqueGlobal(SectionKind Kind)17060b57cec5SDimitry Andric static StringRef getCOFFSectionNameForUniqueGlobal(SectionKind Kind) {
17070b57cec5SDimitry Andric   if (Kind.isText())
17080b57cec5SDimitry Andric     return ".text";
17090b57cec5SDimitry Andric   if (Kind.isBSS())
17100b57cec5SDimitry Andric     return ".bss";
17110b57cec5SDimitry Andric   if (Kind.isThreadLocal())
17120b57cec5SDimitry Andric     return ".tls$";
17130b57cec5SDimitry Andric   if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())
17140b57cec5SDimitry Andric     return ".rdata";
17150b57cec5SDimitry Andric   return ".data";
17160b57cec5SDimitry Andric }
17170b57cec5SDimitry Andric 
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const17180b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
17190b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
17200b57cec5SDimitry Andric   // If we have -ffunction-sections then we should emit the global value to a
17210b57cec5SDimitry Andric   // uniqued section specifically for it.
17220b57cec5SDimitry Andric   bool EmitUniquedSection;
17230b57cec5SDimitry Andric   if (Kind.isText())
17240b57cec5SDimitry Andric     EmitUniquedSection = TM.getFunctionSections();
17250b57cec5SDimitry Andric   else
17260b57cec5SDimitry Andric     EmitUniquedSection = TM.getDataSections();
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric   if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) {
17290b57cec5SDimitry Andric     SmallString<256> Name = getCOFFSectionNameForUniqueGlobal(Kind);
17300b57cec5SDimitry Andric 
17310b57cec5SDimitry Andric     unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
17320b57cec5SDimitry Andric 
17330b57cec5SDimitry Andric     Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
17340b57cec5SDimitry Andric     int Selection = getSelectionForCOFF(GO);
17350b57cec5SDimitry Andric     if (!Selection)
17360b57cec5SDimitry Andric       Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;
17370b57cec5SDimitry Andric     const GlobalValue *ComdatGV;
17380b57cec5SDimitry Andric     if (GO->hasComdat())
17390b57cec5SDimitry Andric       ComdatGV = getComdatGVForCOFF(GO);
17400b57cec5SDimitry Andric     else
17410b57cec5SDimitry Andric       ComdatGV = GO;
17420b57cec5SDimitry Andric 
17430b57cec5SDimitry Andric     unsigned UniqueID = MCContext::GenericSectionID;
17440b57cec5SDimitry Andric     if (EmitUniquedSection)
17450b57cec5SDimitry Andric       UniqueID = NextUniqueID++;
17460b57cec5SDimitry Andric 
17470b57cec5SDimitry Andric     if (!ComdatGV->hasPrivateLinkage()) {
17480b57cec5SDimitry Andric       MCSymbol *Sym = TM.getSymbol(ComdatGV);
17490b57cec5SDimitry Andric       StringRef COMDATSymName = Sym->getName();
17500b57cec5SDimitry Andric 
1751e8d8bef9SDimitry Andric       if (const auto *F = dyn_cast<Function>(GO))
1752bdd1243dSDimitry Andric         if (std::optional<StringRef> Prefix = F->getSectionPrefix())
1753e8d8bef9SDimitry Andric           raw_svector_ostream(Name) << '$' << *Prefix;
1754e8d8bef9SDimitry Andric 
17550b57cec5SDimitry Andric       // Append "$symbol" to the section name *before* IR-level mangling is
17560b57cec5SDimitry Andric       // applied when targetting mingw. This is what GCC does, and the ld.bfd
17570b57cec5SDimitry Andric       // COFF linker will not properly handle comdats otherwise.
1758fe6060f1SDimitry Andric       if (getContext().getTargetTriple().isWindowsGNUEnvironment())
17590b57cec5SDimitry Andric         raw_svector_ostream(Name) << '$' << ComdatGV->getName();
17600b57cec5SDimitry Andric 
17610b57cec5SDimitry Andric       return getContext().getCOFFSection(Name, Characteristics, Kind,
17620b57cec5SDimitry Andric                                          COMDATSymName, Selection, UniqueID);
17630b57cec5SDimitry Andric     } else {
17640b57cec5SDimitry Andric       SmallString<256> TmpData;
17650b57cec5SDimitry Andric       getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true);
17660b57cec5SDimitry Andric       return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData,
17670b57cec5SDimitry Andric                                          Selection, UniqueID);
17680b57cec5SDimitry Andric     }
17690b57cec5SDimitry Andric   }
17700b57cec5SDimitry Andric 
17710b57cec5SDimitry Andric   if (Kind.isText())
17720b57cec5SDimitry Andric     return TextSection;
17730b57cec5SDimitry Andric 
17740b57cec5SDimitry Andric   if (Kind.isThreadLocal())
17750b57cec5SDimitry Andric     return TLSDataSection;
17760b57cec5SDimitry Andric 
17770b57cec5SDimitry Andric   if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())
17780b57cec5SDimitry Andric     return ReadOnlySection;
17790b57cec5SDimitry Andric 
17800b57cec5SDimitry Andric   // Note: we claim that common symbols are put in BSSSection, but they are
17810b57cec5SDimitry Andric   // really emitted with the magic .comm directive, which creates a symbol table
17820b57cec5SDimitry Andric   // entry but not a section.
17830b57cec5SDimitry Andric   if (Kind.isBSS() || Kind.isCommon())
17840b57cec5SDimitry Andric     return BSSSection;
17850b57cec5SDimitry Andric 
17860b57cec5SDimitry Andric   return DataSection;
17870b57cec5SDimitry Andric }
17880b57cec5SDimitry Andric 
getNameWithPrefix(SmallVectorImpl<char> & OutName,const GlobalValue * GV,const TargetMachine & TM) const17890b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix(
17900b57cec5SDimitry Andric     SmallVectorImpl<char> &OutName, const GlobalValue *GV,
17910b57cec5SDimitry Andric     const TargetMachine &TM) const {
17920b57cec5SDimitry Andric   bool CannotUsePrivateLabel = false;
17930b57cec5SDimitry Andric   if (GV->hasPrivateLinkage() &&
17940b57cec5SDimitry Andric       ((isa<Function>(GV) && TM.getFunctionSections()) ||
17950b57cec5SDimitry Andric        (isa<GlobalVariable>(GV) && TM.getDataSections())))
17960b57cec5SDimitry Andric     CannotUsePrivateLabel = true;
17970b57cec5SDimitry Andric 
17980b57cec5SDimitry Andric   getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);
17990b57cec5SDimitry Andric }
18000b57cec5SDimitry Andric 
getSectionForJumpTable(const Function & F,const TargetMachine & TM) const18010b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
18020b57cec5SDimitry Andric     const Function &F, const TargetMachine &TM) const {
18030b57cec5SDimitry Andric   // If the function can be removed, produce a unique section so that
18040b57cec5SDimitry Andric   // the table doesn't prevent the removal.
18050b57cec5SDimitry Andric   const Comdat *C = F.getComdat();
18060b57cec5SDimitry Andric   bool EmitUniqueSection = TM.getFunctionSections() || C;
18070b57cec5SDimitry Andric   if (!EmitUniqueSection)
18080b57cec5SDimitry Andric     return ReadOnlySection;
18090b57cec5SDimitry Andric 
18100b57cec5SDimitry Andric   // FIXME: we should produce a symbol for F instead.
18110b57cec5SDimitry Andric   if (F.hasPrivateLinkage())
18120b57cec5SDimitry Andric     return ReadOnlySection;
18130b57cec5SDimitry Andric 
18140b57cec5SDimitry Andric   MCSymbol *Sym = TM.getSymbol(&F);
18150b57cec5SDimitry Andric   StringRef COMDATSymName = Sym->getName();
18160b57cec5SDimitry Andric 
18170b57cec5SDimitry Andric   SectionKind Kind = SectionKind::getReadOnly();
18180b57cec5SDimitry Andric   StringRef SecName = getCOFFSectionNameForUniqueGlobal(Kind);
18190b57cec5SDimitry Andric   unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
18200b57cec5SDimitry Andric   Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
18210b57cec5SDimitry Andric   unsigned UniqueID = NextUniqueID++;
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric   return getContext().getCOFFSection(
18240b57cec5SDimitry Andric       SecName, Characteristics, Kind, COMDATSymName,
18250b57cec5SDimitry Andric       COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
18260b57cec5SDimitry Andric }
18270b57cec5SDimitry Andric 
shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,const Function & F) const1828fe013be4SDimitry Andric bool TargetLoweringObjectFileCOFF::shouldPutJumpTableInFunctionSection(
1829fe013be4SDimitry Andric     bool UsesLabelDifference, const Function &F) const {
1830fe013be4SDimitry Andric   if (TM->getTargetTriple().getArch() == Triple::x86_64) {
1831fe013be4SDimitry Andric     if (!JumpTableInFunctionSection) {
1832fe013be4SDimitry Andric       // We can always create relative relocations, so use another section
1833fe013be4SDimitry Andric       // that can be marked non-executable.
1834fe013be4SDimitry Andric       return false;
1835fe013be4SDimitry Andric     }
1836fe013be4SDimitry Andric   }
1837fe013be4SDimitry Andric   return TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection(
1838fe013be4SDimitry Andric     UsesLabelDifference, F);
1839fe013be4SDimitry Andric }
1840fe013be4SDimitry Andric 
emitModuleMetadata(MCStreamer & Streamer,Module & M) const18410b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
18420b57cec5SDimitry Andric                                                       Module &M) const {
1843e8d8bef9SDimitry Andric   emitLinkerDirectives(Streamer, M);
1844e8d8bef9SDimitry Andric 
1845e8d8bef9SDimitry Andric   unsigned Version = 0;
1846e8d8bef9SDimitry Andric   unsigned Flags = 0;
1847e8d8bef9SDimitry Andric   StringRef Section;
1848e8d8bef9SDimitry Andric 
1849e8d8bef9SDimitry Andric   GetObjCImageInfo(M, Version, Flags, Section);
1850e8d8bef9SDimitry Andric   if (!Section.empty()) {
1851e8d8bef9SDimitry Andric     auto &C = getContext();
1852e8d8bef9SDimitry Andric     auto *S = C.getCOFFSection(Section,
1853e8d8bef9SDimitry Andric                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1854e8d8bef9SDimitry Andric                                    COFF::IMAGE_SCN_MEM_READ,
1855e8d8bef9SDimitry Andric                                SectionKind::getReadOnly());
185681ad6265SDimitry Andric     Streamer.switchSection(S);
1857e8d8bef9SDimitry Andric     Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
1858e8d8bef9SDimitry Andric     Streamer.emitInt32(Version);
1859e8d8bef9SDimitry Andric     Streamer.emitInt32(Flags);
186081ad6265SDimitry Andric     Streamer.addBlankLine();
1861e8d8bef9SDimitry Andric   }
1862e8d8bef9SDimitry Andric 
1863e8d8bef9SDimitry Andric   emitCGProfileMetadata(Streamer, M);
1864e8d8bef9SDimitry Andric }
1865e8d8bef9SDimitry Andric 
emitLinkerDirectives(MCStreamer & Streamer,Module & M) const1866e8d8bef9SDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
1867e8d8bef9SDimitry Andric     MCStreamer &Streamer, Module &M) const {
18680b57cec5SDimitry Andric   if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
18690b57cec5SDimitry Andric     // Emit the linker options to the linker .drectve section.  According to the
18700b57cec5SDimitry Andric     // spec, this section is a space-separated string containing flags for
18710b57cec5SDimitry Andric     // linker.
18720b57cec5SDimitry Andric     MCSection *Sec = getDrectveSection();
187381ad6265SDimitry Andric     Streamer.switchSection(Sec);
1874480093f4SDimitry Andric     for (const auto *Option : LinkerOptions->operands()) {
18750b57cec5SDimitry Andric       for (const auto &Piece : cast<MDNode>(Option)->operands()) {
18760b57cec5SDimitry Andric         // Lead with a space for consistency with our dllexport implementation.
18770b57cec5SDimitry Andric         std::string Directive(" ");
18785ffd83dbSDimitry Andric         Directive.append(std::string(cast<MDString>(Piece)->getString()));
18795ffd83dbSDimitry Andric         Streamer.emitBytes(Directive);
18800b57cec5SDimitry Andric       }
18810b57cec5SDimitry Andric     }
18820b57cec5SDimitry Andric   }
18830b57cec5SDimitry Andric 
1884e8d8bef9SDimitry Andric   // Emit /EXPORT: flags for each exported global as necessary.
1885e8d8bef9SDimitry Andric   std::string Flags;
1886e8d8bef9SDimitry Andric   for (const GlobalValue &GV : M.global_values()) {
1887e8d8bef9SDimitry Andric     raw_string_ostream OS(Flags);
1888fe6060f1SDimitry Andric     emitLinkerFlagsForGlobalCOFF(OS, &GV, getContext().getTargetTriple(),
1889fe6060f1SDimitry Andric                                  getMangler());
1890e8d8bef9SDimitry Andric     OS.flush();
1891e8d8bef9SDimitry Andric     if (!Flags.empty()) {
189281ad6265SDimitry Andric       Streamer.switchSection(getDrectveSection());
1893e8d8bef9SDimitry Andric       Streamer.emitBytes(Flags);
1894e8d8bef9SDimitry Andric     }
1895e8d8bef9SDimitry Andric     Flags.clear();
1896e8d8bef9SDimitry Andric   }
18970b57cec5SDimitry Andric 
1898e8d8bef9SDimitry Andric   // Emit /INCLUDE: flags for each used global as necessary.
1899e8d8bef9SDimitry Andric   if (const auto *LU = M.getNamedGlobal("llvm.used")) {
1900e8d8bef9SDimitry Andric     assert(LU->hasInitializer() && "expected llvm.used to have an initializer");
1901e8d8bef9SDimitry Andric     assert(isa<ArrayType>(LU->getValueType()) &&
1902e8d8bef9SDimitry Andric            "expected llvm.used to be an array type");
1903e8d8bef9SDimitry Andric     if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {
1904e8d8bef9SDimitry Andric       for (const Value *Op : A->operands()) {
1905e8d8bef9SDimitry Andric         const auto *GV = cast<GlobalValue>(Op->stripPointerCasts());
1906e8d8bef9SDimitry Andric         // Global symbols with internal or private linkage are not visible to
1907e8d8bef9SDimitry Andric         // the linker, and thus would cause an error when the linker tried to
1908e8d8bef9SDimitry Andric         // preserve the symbol due to the `/include:` directive.
1909e8d8bef9SDimitry Andric         if (GV->hasLocalLinkage())
1910e8d8bef9SDimitry Andric           continue;
19110b57cec5SDimitry Andric 
1912e8d8bef9SDimitry Andric         raw_string_ostream OS(Flags);
1913fe6060f1SDimitry Andric         emitLinkerFlagsForUsedCOFF(OS, GV, getContext().getTargetTriple(),
1914fe6060f1SDimitry Andric                                    getMangler());
1915e8d8bef9SDimitry Andric         OS.flush();
1916e8d8bef9SDimitry Andric 
1917e8d8bef9SDimitry Andric         if (!Flags.empty()) {
191881ad6265SDimitry Andric           Streamer.switchSection(getDrectveSection());
1919e8d8bef9SDimitry Andric           Streamer.emitBytes(Flags);
1920e8d8bef9SDimitry Andric         }
1921e8d8bef9SDimitry Andric         Flags.clear();
1922e8d8bef9SDimitry Andric       }
1923e8d8bef9SDimitry Andric     }
1924e8d8bef9SDimitry Andric   }
19250b57cec5SDimitry Andric }
19260b57cec5SDimitry Andric 
Initialize(MCContext & Ctx,const TargetMachine & TM)19270b57cec5SDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
19280b57cec5SDimitry Andric                                               const TargetMachine &TM) {
19290b57cec5SDimitry Andric   TargetLoweringObjectFile::Initialize(Ctx, TM);
1930e8d8bef9SDimitry Andric   this->TM = &TM;
19310b57cec5SDimitry Andric   const Triple &T = TM.getTargetTriple();
19320b57cec5SDimitry Andric   if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
19330b57cec5SDimitry Andric     StaticCtorSection =
19340b57cec5SDimitry Andric         Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19350b57cec5SDimitry Andric                                            COFF::IMAGE_SCN_MEM_READ,
19360b57cec5SDimitry Andric                            SectionKind::getReadOnly());
19370b57cec5SDimitry Andric     StaticDtorSection =
19380b57cec5SDimitry Andric         Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19390b57cec5SDimitry Andric                                            COFF::IMAGE_SCN_MEM_READ,
19400b57cec5SDimitry Andric                            SectionKind::getReadOnly());
19410b57cec5SDimitry Andric   } else {
19420b57cec5SDimitry Andric     StaticCtorSection = Ctx.getCOFFSection(
19430b57cec5SDimitry Andric         ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19440b57cec5SDimitry Andric                       COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE,
19450b57cec5SDimitry Andric         SectionKind::getData());
19460b57cec5SDimitry Andric     StaticDtorSection = Ctx.getCOFFSection(
19470b57cec5SDimitry Andric         ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19480b57cec5SDimitry Andric                       COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE,
19490b57cec5SDimitry Andric         SectionKind::getData());
19500b57cec5SDimitry Andric   }
19510b57cec5SDimitry Andric }
19520b57cec5SDimitry Andric 
getCOFFStaticStructorSection(MCContext & Ctx,const Triple & T,bool IsCtor,unsigned Priority,const MCSymbol * KeySym,MCSectionCOFF * Default)19530b57cec5SDimitry Andric static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx,
19540b57cec5SDimitry Andric                                                    const Triple &T, bool IsCtor,
19550b57cec5SDimitry Andric                                                    unsigned Priority,
19560b57cec5SDimitry Andric                                                    const MCSymbol *KeySym,
19570b57cec5SDimitry Andric                                                    MCSectionCOFF *Default) {
19580b57cec5SDimitry Andric   if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
19590b57cec5SDimitry Andric     // If the priority is the default, use .CRT$XCU, possibly associative.
19600b57cec5SDimitry Andric     if (Priority == 65535)
19610b57cec5SDimitry Andric       return Ctx.getAssociativeCOFFSection(Default, KeySym, 0);
19620b57cec5SDimitry Andric 
19630b57cec5SDimitry Andric     // Otherwise, we need to compute a new section name. Low priorities should
19640b57cec5SDimitry Andric     // run earlier. The linker will sort sections ASCII-betically, and we need a
19650b57cec5SDimitry Andric     // string that sorts between .CRT$XCA and .CRT$XCU. In the general case, we
19660b57cec5SDimitry Andric     // make a name like ".CRT$XCT12345", since that runs before .CRT$XCU. Really
19670b57cec5SDimitry Andric     // low priorities need to sort before 'L', since the CRT uses that
1968bdd1243dSDimitry Andric     // internally, so we use ".CRT$XCA00001" for them. We have a contract with
1969bdd1243dSDimitry Andric     // the frontend that "init_seg(compiler)" corresponds to priority 200 and
1970bdd1243dSDimitry Andric     // "init_seg(lib)" corresponds to priority 400, and those respectively use
1971bdd1243dSDimitry Andric     // 'C' and 'L' without the priority suffix. Priorities between 200 and 400
1972bdd1243dSDimitry Andric     // use 'C' with the priority as a suffix.
19730b57cec5SDimitry Andric     SmallString<24> Name;
1974bdd1243dSDimitry Andric     char LastLetter = 'T';
1975bdd1243dSDimitry Andric     bool AddPrioritySuffix = Priority != 200 && Priority != 400;
1976bdd1243dSDimitry Andric     if (Priority < 200)
1977bdd1243dSDimitry Andric       LastLetter = 'A';
1978bdd1243dSDimitry Andric     else if (Priority < 400)
1979bdd1243dSDimitry Andric       LastLetter = 'C';
1980bdd1243dSDimitry Andric     else if (Priority == 400)
1981bdd1243dSDimitry Andric       LastLetter = 'L';
19820b57cec5SDimitry Andric     raw_svector_ostream OS(Name);
1983bdd1243dSDimitry Andric     OS << ".CRT$X" << (IsCtor ? "C" : "T") << LastLetter;
1984bdd1243dSDimitry Andric     if (AddPrioritySuffix)
1985bdd1243dSDimitry Andric       OS << format("%05u", Priority);
19860b57cec5SDimitry Andric     MCSectionCOFF *Sec = Ctx.getCOFFSection(
19870b57cec5SDimitry Andric         Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
19880b57cec5SDimitry Andric         SectionKind::getReadOnly());
19890b57cec5SDimitry Andric     return Ctx.getAssociativeCOFFSection(Sec, KeySym, 0);
19900b57cec5SDimitry Andric   }
19910b57cec5SDimitry Andric 
19920b57cec5SDimitry Andric   std::string Name = IsCtor ? ".ctors" : ".dtors";
19930b57cec5SDimitry Andric   if (Priority != 65535)
19940b57cec5SDimitry Andric     raw_string_ostream(Name) << format(".%05u", 65535 - Priority);
19950b57cec5SDimitry Andric 
19960b57cec5SDimitry Andric   return Ctx.getAssociativeCOFFSection(
19970b57cec5SDimitry Andric       Ctx.getCOFFSection(Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
19980b57cec5SDimitry Andric                                    COFF::IMAGE_SCN_MEM_READ |
19990b57cec5SDimitry Andric                                    COFF::IMAGE_SCN_MEM_WRITE,
20000b57cec5SDimitry Andric                          SectionKind::getData()),
20010b57cec5SDimitry Andric       KeySym, 0);
20020b57cec5SDimitry Andric }
20030b57cec5SDimitry Andric 
getStaticCtorSection(unsigned Priority,const MCSymbol * KeySym) const20040b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
20050b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
2006fe6060f1SDimitry Andric   return getCOFFStaticStructorSection(
2007fe6060f1SDimitry Andric       getContext(), getContext().getTargetTriple(), true, Priority, KeySym,
20080b57cec5SDimitry Andric       cast<MCSectionCOFF>(StaticCtorSection));
20090b57cec5SDimitry Andric }
20100b57cec5SDimitry Andric 
getStaticDtorSection(unsigned Priority,const MCSymbol * KeySym) const20110b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
20120b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
2013fe6060f1SDimitry Andric   return getCOFFStaticStructorSection(
2014fe6060f1SDimitry Andric       getContext(), getContext().getTargetTriple(), false, Priority, KeySym,
20150b57cec5SDimitry Andric       cast<MCSectionCOFF>(StaticDtorSection));
20160b57cec5SDimitry Andric }
20170b57cec5SDimitry Andric 
lowerRelativeReference(const GlobalValue * LHS,const GlobalValue * RHS,const TargetMachine & TM) const20180b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
20190b57cec5SDimitry Andric     const GlobalValue *LHS, const GlobalValue *RHS,
20200b57cec5SDimitry Andric     const TargetMachine &TM) const {
20210b57cec5SDimitry Andric   const Triple &T = TM.getTargetTriple();
20220b57cec5SDimitry Andric   if (T.isOSCygMing())
20230b57cec5SDimitry Andric     return nullptr;
20240b57cec5SDimitry Andric 
20250b57cec5SDimitry Andric   // Our symbols should exist in address space zero, cowardly no-op if
20260b57cec5SDimitry Andric   // otherwise.
20270b57cec5SDimitry Andric   if (LHS->getType()->getPointerAddressSpace() != 0 ||
20280b57cec5SDimitry Andric       RHS->getType()->getPointerAddressSpace() != 0)
20290b57cec5SDimitry Andric     return nullptr;
20300b57cec5SDimitry Andric 
20310b57cec5SDimitry Andric   // Both ptrtoint instructions must wrap global objects:
20320b57cec5SDimitry Andric   // - Only global variables are eligible for image relative relocations.
20330b57cec5SDimitry Andric   // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable.
20340b57cec5SDimitry Andric   // We expect __ImageBase to be a global variable without a section, externally
20350b57cec5SDimitry Andric   // defined.
20360b57cec5SDimitry Andric   //
20370b57cec5SDimitry Andric   // It should look something like this: @__ImageBase = external constant i8
20380b57cec5SDimitry Andric   if (!isa<GlobalObject>(LHS) || !isa<GlobalVariable>(RHS) ||
20390b57cec5SDimitry Andric       LHS->isThreadLocal() || RHS->isThreadLocal() ||
20400b57cec5SDimitry Andric       RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() ||
20410b57cec5SDimitry Andric       cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection())
20420b57cec5SDimitry Andric     return nullptr;
20430b57cec5SDimitry Andric 
20440b57cec5SDimitry Andric   return MCSymbolRefExpr::create(TM.getSymbol(LHS),
20450b57cec5SDimitry Andric                                  MCSymbolRefExpr::VK_COFF_IMGREL32,
20460b57cec5SDimitry Andric                                  getContext());
20470b57cec5SDimitry Andric }
20480b57cec5SDimitry Andric 
APIntToHexString(const APInt & AI)20490b57cec5SDimitry Andric static std::string APIntToHexString(const APInt &AI) {
20500b57cec5SDimitry Andric   unsigned Width = (AI.getBitWidth() / 8) * 2;
2051fe6060f1SDimitry Andric   std::string HexString = toString(AI, 16, /*Signed=*/false);
20525ffd83dbSDimitry Andric   llvm::transform(HexString, HexString.begin(), tolower);
20530b57cec5SDimitry Andric   unsigned Size = HexString.size();
20540b57cec5SDimitry Andric   assert(Width >= Size && "hex string is too large!");
20550b57cec5SDimitry Andric   HexString.insert(HexString.begin(), Width - Size, '0');
20560b57cec5SDimitry Andric 
20570b57cec5SDimitry Andric   return HexString;
20580b57cec5SDimitry Andric }
20590b57cec5SDimitry Andric 
scalarConstantToHexString(const Constant * C)20600b57cec5SDimitry Andric static std::string scalarConstantToHexString(const Constant *C) {
20610b57cec5SDimitry Andric   Type *Ty = C->getType();
20620b57cec5SDimitry Andric   if (isa<UndefValue>(C)) {
2063349cc55cSDimitry Andric     return APIntToHexString(APInt::getZero(Ty->getPrimitiveSizeInBits()));
20640b57cec5SDimitry Andric   } else if (const auto *CFP = dyn_cast<ConstantFP>(C)) {
20650b57cec5SDimitry Andric     return APIntToHexString(CFP->getValueAPF().bitcastToAPInt());
20660b57cec5SDimitry Andric   } else if (const auto *CI = dyn_cast<ConstantInt>(C)) {
20670b57cec5SDimitry Andric     return APIntToHexString(CI->getValue());
20680b57cec5SDimitry Andric   } else {
20690b57cec5SDimitry Andric     unsigned NumElements;
20705ffd83dbSDimitry Andric     if (auto *VTy = dyn_cast<VectorType>(Ty))
20715ffd83dbSDimitry Andric       NumElements = cast<FixedVectorType>(VTy)->getNumElements();
20720b57cec5SDimitry Andric     else
20730b57cec5SDimitry Andric       NumElements = Ty->getArrayNumElements();
20740b57cec5SDimitry Andric     std::string HexString;
20750b57cec5SDimitry Andric     for (int I = NumElements - 1, E = -1; I != E; --I)
20760b57cec5SDimitry Andric       HexString += scalarConstantToHexString(C->getAggregateElement(I));
20770b57cec5SDimitry Andric     return HexString;
20780b57cec5SDimitry Andric   }
20790b57cec5SDimitry Andric }
20800b57cec5SDimitry Andric 
getSectionForConstant(const DataLayout & DL,SectionKind Kind,const Constant * C,Align & Alignment) const20810b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant(
20820b57cec5SDimitry Andric     const DataLayout &DL, SectionKind Kind, const Constant *C,
20835ffd83dbSDimitry Andric     Align &Alignment) const {
20840b57cec5SDimitry Andric   if (Kind.isMergeableConst() && C &&
20850b57cec5SDimitry Andric       getContext().getAsmInfo()->hasCOFFComdatConstants()) {
20860b57cec5SDimitry Andric     // This creates comdat sections with the given symbol name, but unless
20870b57cec5SDimitry Andric     // AsmPrinter::GetCPISymbol actually makes the symbol global, the symbol
20880b57cec5SDimitry Andric     // will be created with a null storage class, which makes GNU binutils
20890b57cec5SDimitry Andric     // error out.
20900b57cec5SDimitry Andric     const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
20910b57cec5SDimitry Andric                                      COFF::IMAGE_SCN_MEM_READ |
20920b57cec5SDimitry Andric                                      COFF::IMAGE_SCN_LNK_COMDAT;
20930b57cec5SDimitry Andric     std::string COMDATSymName;
20940b57cec5SDimitry Andric     if (Kind.isMergeableConst4()) {
20955ffd83dbSDimitry Andric       if (Alignment <= 4) {
20960b57cec5SDimitry Andric         COMDATSymName = "__real@" + scalarConstantToHexString(C);
20975ffd83dbSDimitry Andric         Alignment = Align(4);
20980b57cec5SDimitry Andric       }
20990b57cec5SDimitry Andric     } else if (Kind.isMergeableConst8()) {
21005ffd83dbSDimitry Andric       if (Alignment <= 8) {
21010b57cec5SDimitry Andric         COMDATSymName = "__real@" + scalarConstantToHexString(C);
21025ffd83dbSDimitry Andric         Alignment = Align(8);
21030b57cec5SDimitry Andric       }
21040b57cec5SDimitry Andric     } else if (Kind.isMergeableConst16()) {
21050b57cec5SDimitry Andric       // FIXME: These may not be appropriate for non-x86 architectures.
21065ffd83dbSDimitry Andric       if (Alignment <= 16) {
21070b57cec5SDimitry Andric         COMDATSymName = "__xmm@" + scalarConstantToHexString(C);
21085ffd83dbSDimitry Andric         Alignment = Align(16);
21090b57cec5SDimitry Andric       }
21100b57cec5SDimitry Andric     } else if (Kind.isMergeableConst32()) {
21115ffd83dbSDimitry Andric       if (Alignment <= 32) {
21120b57cec5SDimitry Andric         COMDATSymName = "__ymm@" + scalarConstantToHexString(C);
21135ffd83dbSDimitry Andric         Alignment = Align(32);
21140b57cec5SDimitry Andric       }
21150b57cec5SDimitry Andric     }
21160b57cec5SDimitry Andric 
21170b57cec5SDimitry Andric     if (!COMDATSymName.empty())
21180b57cec5SDimitry Andric       return getContext().getCOFFSection(".rdata", Characteristics, Kind,
21190b57cec5SDimitry Andric                                          COMDATSymName,
21200b57cec5SDimitry Andric                                          COFF::IMAGE_COMDAT_SELECT_ANY);
21210b57cec5SDimitry Andric   }
21220b57cec5SDimitry Andric 
21235ffd83dbSDimitry Andric   return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C,
21245ffd83dbSDimitry Andric                                                          Alignment);
21250b57cec5SDimitry Andric }
21260b57cec5SDimitry Andric 
21270b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21280b57cec5SDimitry Andric //                                  Wasm
21290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21300b57cec5SDimitry Andric 
getWasmComdat(const GlobalValue * GV)21310b57cec5SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) {
21320b57cec5SDimitry Andric   const Comdat *C = GV->getComdat();
21330b57cec5SDimitry Andric   if (!C)
21340b57cec5SDimitry Andric     return nullptr;
21350b57cec5SDimitry Andric 
21360b57cec5SDimitry Andric   if (C->getSelectionKind() != Comdat::Any)
21370b57cec5SDimitry Andric     report_fatal_error("WebAssembly COMDATs only support "
21380b57cec5SDimitry Andric                        "SelectionKind::Any, '" + C->getName() + "' cannot be "
21390b57cec5SDimitry Andric                        "lowered.");
21400b57cec5SDimitry Andric 
21410b57cec5SDimitry Andric   return C;
21420b57cec5SDimitry Andric }
21430b57cec5SDimitry Andric 
getWasmSectionFlags(SectionKind K)2144fe6060f1SDimitry Andric static unsigned getWasmSectionFlags(SectionKind K) {
2145fe6060f1SDimitry Andric   unsigned Flags = 0;
2146fe6060f1SDimitry Andric 
2147fe6060f1SDimitry Andric   if (K.isThreadLocal())
2148fe6060f1SDimitry Andric     Flags |= wasm::WASM_SEG_FLAG_TLS;
2149fe6060f1SDimitry Andric 
2150fe6060f1SDimitry Andric   if (K.isMergeableCString())
2151fe6060f1SDimitry Andric     Flags |= wasm::WASM_SEG_FLAG_STRINGS;
2152fe6060f1SDimitry Andric 
2153fe6060f1SDimitry Andric   // TODO(sbc): Add suport for K.isMergeableConst()
2154fe6060f1SDimitry Andric 
2155fe6060f1SDimitry Andric   return Flags;
2156fe6060f1SDimitry Andric }
2157fe6060f1SDimitry Andric 
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const21580b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(
21590b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
21600b57cec5SDimitry Andric   // We don't support explict section names for functions in the wasm object
21610b57cec5SDimitry Andric   // format.  Each function has to be in its own unique section.
21620b57cec5SDimitry Andric   if (isa<Function>(GO)) {
21630b57cec5SDimitry Andric     return SelectSectionForGlobal(GO, Kind, TM);
21640b57cec5SDimitry Andric   }
21650b57cec5SDimitry Andric 
21660b57cec5SDimitry Andric   StringRef Name = GO->getSection();
21670b57cec5SDimitry Andric 
21685ffd83dbSDimitry Andric   // Certain data sections we treat as named custom sections rather than
21695ffd83dbSDimitry Andric   // segments within the data section.
21705ffd83dbSDimitry Andric   // This could be avoided if all data segements (the wasm sense) were
21715ffd83dbSDimitry Andric   // represented as their own sections (in the llvm sense).
21725ffd83dbSDimitry Andric   // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138
21735ffd83dbSDimitry Andric   if (Name == ".llvmcmd" || Name == ".llvmbc")
21745ffd83dbSDimitry Andric     Kind = SectionKind::getMetadata();
21750b57cec5SDimitry Andric 
21760b57cec5SDimitry Andric   StringRef Group = "";
21770b57cec5SDimitry Andric   if (const Comdat *C = getWasmComdat(GO)) {
21780b57cec5SDimitry Andric     Group = C->getName();
21790b57cec5SDimitry Andric   }
21800b57cec5SDimitry Andric 
2181fe6060f1SDimitry Andric   unsigned Flags = getWasmSectionFlags(Kind);
2182fe6060f1SDimitry Andric   MCSectionWasm *Section = getContext().getWasmSection(
2183fe6060f1SDimitry Andric       Name, Kind, Flags, Group, MCContext::GenericSectionID);
21840b57cec5SDimitry Andric 
21850b57cec5SDimitry Andric   return Section;
21860b57cec5SDimitry Andric }
21870b57cec5SDimitry Andric 
selectWasmSectionForGlobal(MCContext & Ctx,const GlobalObject * GO,SectionKind Kind,Mangler & Mang,const TargetMachine & TM,bool EmitUniqueSection,unsigned * NextUniqueID)21880b57cec5SDimitry Andric static MCSectionWasm *selectWasmSectionForGlobal(
21890b57cec5SDimitry Andric     MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
21900b57cec5SDimitry Andric     const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) {
21910b57cec5SDimitry Andric   StringRef Group = "";
21920b57cec5SDimitry Andric   if (const Comdat *C = getWasmComdat(GO)) {
21930b57cec5SDimitry Andric     Group = C->getName();
21940b57cec5SDimitry Andric   }
21950b57cec5SDimitry Andric 
21960b57cec5SDimitry Andric   bool UniqueSectionNames = TM.getUniqueSectionNames();
2197fe013be4SDimitry Andric   SmallString<128> Name = getSectionPrefixForGlobal(Kind, /*IsLarge=*/false);
21980b57cec5SDimitry Andric 
21990b57cec5SDimitry Andric   if (const auto *F = dyn_cast<Function>(GO)) {
22000b57cec5SDimitry Andric     const auto &OptionalPrefix = F->getSectionPrefix();
22010b57cec5SDimitry Andric     if (OptionalPrefix)
2202e8d8bef9SDimitry Andric       raw_svector_ostream(Name) << '.' << *OptionalPrefix;
22030b57cec5SDimitry Andric   }
22040b57cec5SDimitry Andric 
22050b57cec5SDimitry Andric   if (EmitUniqueSection && UniqueSectionNames) {
22060b57cec5SDimitry Andric     Name.push_back('.');
22070b57cec5SDimitry Andric     TM.getNameWithPrefix(Name, GO, Mang, true);
22080b57cec5SDimitry Andric   }
22090b57cec5SDimitry Andric   unsigned UniqueID = MCContext::GenericSectionID;
22100b57cec5SDimitry Andric   if (EmitUniqueSection && !UniqueSectionNames) {
22110b57cec5SDimitry Andric     UniqueID = *NextUniqueID;
22120b57cec5SDimitry Andric     (*NextUniqueID)++;
22130b57cec5SDimitry Andric   }
22140b57cec5SDimitry Andric 
2215fe6060f1SDimitry Andric   unsigned Flags = getWasmSectionFlags(Kind);
2216fe6060f1SDimitry Andric   return Ctx.getWasmSection(Name, Kind, Flags, Group, UniqueID);
22170b57cec5SDimitry Andric }
22180b57cec5SDimitry Andric 
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const22190b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal(
22200b57cec5SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
22210b57cec5SDimitry Andric 
22220b57cec5SDimitry Andric   if (Kind.isCommon())
22230b57cec5SDimitry Andric     report_fatal_error("mergable sections not supported yet on wasm");
22240b57cec5SDimitry Andric 
22250b57cec5SDimitry Andric   // If we have -ffunction-section or -fdata-section then we should emit the
22260b57cec5SDimitry Andric   // global value to a uniqued section specifically for it.
22270b57cec5SDimitry Andric   bool EmitUniqueSection = false;
22280b57cec5SDimitry Andric   if (Kind.isText())
22290b57cec5SDimitry Andric     EmitUniqueSection = TM.getFunctionSections();
22300b57cec5SDimitry Andric   else
22310b57cec5SDimitry Andric     EmitUniqueSection = TM.getDataSections();
22320b57cec5SDimitry Andric   EmitUniqueSection |= GO->hasComdat();
22330b57cec5SDimitry Andric 
22340b57cec5SDimitry Andric   return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
22350b57cec5SDimitry Andric                                     EmitUniqueSection, &NextUniqueID);
22360b57cec5SDimitry Andric }
22370b57cec5SDimitry Andric 
shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,const Function & F) const22380b57cec5SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection(
22390b57cec5SDimitry Andric     bool UsesLabelDifference, const Function &F) const {
22400b57cec5SDimitry Andric   // We can always create relative relocations, so use another section
22410b57cec5SDimitry Andric   // that can be marked non-executable.
22420b57cec5SDimitry Andric   return false;
22430b57cec5SDimitry Andric }
22440b57cec5SDimitry Andric 
lowerRelativeReference(const GlobalValue * LHS,const GlobalValue * RHS,const TargetMachine & TM) const22450b57cec5SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference(
22460b57cec5SDimitry Andric     const GlobalValue *LHS, const GlobalValue *RHS,
22470b57cec5SDimitry Andric     const TargetMachine &TM) const {
22480b57cec5SDimitry Andric   // We may only use a PLT-relative relocation to refer to unnamed_addr
22490b57cec5SDimitry Andric   // functions.
22500b57cec5SDimitry Andric   if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
22510b57cec5SDimitry Andric     return nullptr;
22520b57cec5SDimitry Andric 
22534824e7fdSDimitry Andric   // Basic correctness checks.
22540b57cec5SDimitry Andric   if (LHS->getType()->getPointerAddressSpace() != 0 ||
22550b57cec5SDimitry Andric       RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() ||
22560b57cec5SDimitry Andric       RHS->isThreadLocal())
22570b57cec5SDimitry Andric     return nullptr;
22580b57cec5SDimitry Andric 
22590b57cec5SDimitry Andric   return MCBinaryExpr::createSub(
22600b57cec5SDimitry Andric       MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None,
22610b57cec5SDimitry Andric                               getContext()),
22620b57cec5SDimitry Andric       MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
22630b57cec5SDimitry Andric }
22640b57cec5SDimitry Andric 
InitializeWasm()22650b57cec5SDimitry Andric void TargetLoweringObjectFileWasm::InitializeWasm() {
22660b57cec5SDimitry Andric   StaticCtorSection =
22670b57cec5SDimitry Andric       getContext().getWasmSection(".init_array", SectionKind::getData());
22680b57cec5SDimitry Andric 
22690b57cec5SDimitry Andric   // We don't use PersonalityEncoding and LSDAEncoding because we don't emit
22700b57cec5SDimitry Andric   // .cfi directives. We use TTypeEncoding to encode typeinfo global variables.
22710b57cec5SDimitry Andric   TTypeEncoding = dwarf::DW_EH_PE_absptr;
22720b57cec5SDimitry Andric }
22730b57cec5SDimitry Andric 
getStaticCtorSection(unsigned Priority,const MCSymbol * KeySym) const22740b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticCtorSection(
22750b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
22760b57cec5SDimitry Andric   return Priority == UINT16_MAX ?
22770b57cec5SDimitry Andric          StaticCtorSection :
22780b57cec5SDimitry Andric          getContext().getWasmSection(".init_array." + utostr(Priority),
22790b57cec5SDimitry Andric                                      SectionKind::getData());
22800b57cec5SDimitry Andric }
22810b57cec5SDimitry Andric 
getStaticDtorSection(unsigned Priority,const MCSymbol * KeySym) const22820b57cec5SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection(
22830b57cec5SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
228481ad6265SDimitry Andric   report_fatal_error("@llvm.global_dtors should have been lowered already");
22850b57cec5SDimitry Andric }
22868bcb0991SDimitry Andric 
22878bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
22888bcb0991SDimitry Andric //                                  XCOFF
22898bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
ShouldEmitEHBlock(const MachineFunction * MF)2290e8d8bef9SDimitry Andric bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(
2291e8d8bef9SDimitry Andric     const MachineFunction *MF) {
2292e8d8bef9SDimitry Andric   if (!MF->getLandingPads().empty())
2293e8d8bef9SDimitry Andric     return true;
2294e8d8bef9SDimitry Andric 
2295e8d8bef9SDimitry Andric   const Function &F = MF->getFunction();
2296e8d8bef9SDimitry Andric   if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry())
2297e8d8bef9SDimitry Andric     return false;
2298e8d8bef9SDimitry Andric 
2299fe6060f1SDimitry Andric   const GlobalValue *Per =
2300fe6060f1SDimitry Andric       dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
2301fe6060f1SDimitry Andric   assert(Per && "Personality routine is not a GlobalValue type.");
2302e8d8bef9SDimitry Andric   if (isNoOpWithoutInvoke(classifyEHPersonality(Per)))
2303e8d8bef9SDimitry Andric     return false;
2304e8d8bef9SDimitry Andric 
2305e8d8bef9SDimitry Andric   return true;
2306e8d8bef9SDimitry Andric }
2307e8d8bef9SDimitry Andric 
ShouldSetSSPCanaryBitInTB(const MachineFunction * MF)2308fe6060f1SDimitry Andric bool TargetLoweringObjectFileXCOFF::ShouldSetSSPCanaryBitInTB(
2309fe6060f1SDimitry Andric     const MachineFunction *MF) {
2310fe6060f1SDimitry Andric   const Function &F = MF->getFunction();
2311fe6060f1SDimitry Andric   if (!F.hasStackProtectorFnAttr())
2312fe6060f1SDimitry Andric     return false;
2313fe6060f1SDimitry Andric   // FIXME: check presence of canary word
2314fe6060f1SDimitry Andric   // There are cases that the stack protectors are not really inserted even if
2315fe6060f1SDimitry Andric   // the attributes are on.
2316fe6060f1SDimitry Andric   return true;
2317fe6060f1SDimitry Andric }
2318fe6060f1SDimitry Andric 
2319e8d8bef9SDimitry Andric MCSymbol *
getEHInfoTableSymbol(const MachineFunction * MF)2320e8d8bef9SDimitry Andric TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) {
2321c9157d92SDimitry Andric   MCSymbol *EHInfoSym = MF->getMMI().getContext().getOrCreateSymbol(
2322e8d8bef9SDimitry Andric       "__ehinfo." + Twine(MF->getFunctionNumber()));
2323c9157d92SDimitry Andric   cast<MCSymbolXCOFF>(EHInfoSym)->setEHInfo();
2324c9157d92SDimitry Andric   return EHInfoSym;
2325e8d8bef9SDimitry Andric }
2326e8d8bef9SDimitry Andric 
23275ffd83dbSDimitry Andric MCSymbol *
getTargetSymbol(const GlobalValue * GV,const TargetMachine & TM) const23285ffd83dbSDimitry Andric TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
23295ffd83dbSDimitry Andric                                                const TargetMachine &TM) const {
23305ffd83dbSDimitry Andric   // We always use a qualname symbol for a GV that represents
23315ffd83dbSDimitry Andric   // a declaration, a function descriptor, or a common symbol.
2332e8d8bef9SDimitry Andric   // If a GV represents a GlobalVariable and -fdata-sections is enabled, we
2333e8d8bef9SDimitry Andric   // also return a qualname so that a label symbol could be avoided.
23345ffd83dbSDimitry Andric   // It is inherently ambiguous when the GO represents the address of a
23355ffd83dbSDimitry Andric   // function, as the GO could either represent a function descriptor or a
23365ffd83dbSDimitry Andric   // function entry point. We choose to always return a function descriptor
23375ffd83dbSDimitry Andric   // here.
23385ffd83dbSDimitry Andric   if (const GlobalObject *GO = dyn_cast<GlobalObject>(GV)) {
2339bdd1243dSDimitry Andric     if (GO->isDeclarationForLinker())
2340bdd1243dSDimitry Andric       return cast<MCSectionXCOFF>(getSectionForExternalReference(GO, TM))
2341bdd1243dSDimitry Andric           ->getQualNameSymbol();
2342bdd1243dSDimitry Andric 
2343fe6060f1SDimitry Andric     if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
2344fe6060f1SDimitry Andric       if (GVar->hasAttribute("toc-data"))
2345fe6060f1SDimitry Andric         return cast<MCSectionXCOFF>(
2346fe6060f1SDimitry Andric                    SectionForGlobal(GVar, SectionKind::getData(), TM))
2347fe6060f1SDimitry Andric             ->getQualNameSymbol();
2348fe6060f1SDimitry Andric 
23495ffd83dbSDimitry Andric     SectionKind GOKind = getKindForGlobal(GO, TM);
23505ffd83dbSDimitry Andric     if (GOKind.isText())
23515ffd83dbSDimitry Andric       return cast<MCSectionXCOFF>(
23525ffd83dbSDimitry Andric                  getSectionForFunctionDescriptor(cast<Function>(GO), TM))
23535ffd83dbSDimitry Andric           ->getQualNameSymbol();
2354fe6060f1SDimitry Andric     if ((TM.getDataSections() && !GO->hasSection()) || GO->hasCommonLinkage() ||
2355fe6060f1SDimitry Andric         GOKind.isBSSLocal() || GOKind.isThreadBSSLocal())
23565ffd83dbSDimitry Andric       return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM))
23575ffd83dbSDimitry Andric           ->getQualNameSymbol();
23585ffd83dbSDimitry Andric   }
23595ffd83dbSDimitry Andric 
23605ffd83dbSDimitry Andric   // For all other cases, fall back to getSymbol to return the unqualified name.
23615ffd83dbSDimitry Andric   return nullptr;
23625ffd83dbSDimitry Andric }
23635ffd83dbSDimitry Andric 
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const23648bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
23658bcb0991SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2366e8d8bef9SDimitry Andric   if (!GO->hasSection())
2367e8d8bef9SDimitry Andric     report_fatal_error("#pragma clang section is not yet supported");
2368e8d8bef9SDimitry Andric 
2369e8d8bef9SDimitry Andric   StringRef SectionName = GO->getSection();
2370fe6060f1SDimitry Andric 
2371fe6060f1SDimitry Andric   // Handle the XCOFF::TD case first, then deal with the rest.
2372fe6060f1SDimitry Andric   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))
2373fe6060f1SDimitry Andric     if (GVar->hasAttribute("toc-data"))
2374fe6060f1SDimitry Andric       return getContext().getXCOFFSection(
2375fe6060f1SDimitry Andric           SectionName, Kind,
2376fe6060f1SDimitry Andric           XCOFF::CsectProperties(/*MappingClass*/ XCOFF::XMC_TD, XCOFF::XTY_SD),
2377fe6060f1SDimitry Andric           /* MultiSymbolsAllowed*/ true);
2378fe6060f1SDimitry Andric 
2379e8d8bef9SDimitry Andric   XCOFF::StorageMappingClass MappingClass;
2380e8d8bef9SDimitry Andric   if (Kind.isText())
2381e8d8bef9SDimitry Andric     MappingClass = XCOFF::XMC_PR;
2382fe013be4SDimitry Andric   else if (Kind.isData() || Kind.isBSS())
2383e8d8bef9SDimitry Andric     MappingClass = XCOFF::XMC_RW;
2384fe013be4SDimitry Andric   else if (Kind.isReadOnlyWithRel())
2385fe013be4SDimitry Andric     MappingClass =
2386fe013be4SDimitry Andric         TM.Options.XCOFFReadOnlyPointers ? XCOFF::XMC_RO : XCOFF::XMC_RW;
2387e8d8bef9SDimitry Andric   else if (Kind.isReadOnly())
2388e8d8bef9SDimitry Andric     MappingClass = XCOFF::XMC_RO;
2389e8d8bef9SDimitry Andric   else
2390e8d8bef9SDimitry Andric     report_fatal_error("XCOFF other section types not yet implemented.");
2391e8d8bef9SDimitry Andric 
2392fe6060f1SDimitry Andric   return getContext().getXCOFFSection(
2393fe6060f1SDimitry Andric       SectionName, Kind, XCOFF::CsectProperties(MappingClass, XCOFF::XTY_SD),
2394fe6060f1SDimitry Andric       /* MultiSymbolsAllowed*/ true);
23958bcb0991SDimitry Andric }
23968bcb0991SDimitry Andric 
getSectionForExternalReference(const GlobalObject * GO,const TargetMachine & TM) const23975ffd83dbSDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference(
23985ffd83dbSDimitry Andric     const GlobalObject *GO, const TargetMachine &TM) const {
23995ffd83dbSDimitry Andric   assert(GO->isDeclarationForLinker() &&
24005ffd83dbSDimitry Andric          "Tried to get ER section for a defined global.");
24015ffd83dbSDimitry Andric 
24025ffd83dbSDimitry Andric   SmallString<128> Name;
24035ffd83dbSDimitry Andric   getNameWithPrefix(Name, GO, TM);
24045ffd83dbSDimitry Andric 
2405fe6060f1SDimitry Andric   XCOFF::StorageMappingClass SMC =
2406fe6060f1SDimitry Andric       isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA;
2407fe6060f1SDimitry Andric   if (GO->isThreadLocal())
2408fe6060f1SDimitry Andric     SMC = XCOFF::XMC_UL;
2409fe6060f1SDimitry Andric 
2410bdd1243dSDimitry Andric   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))
2411bdd1243dSDimitry Andric     if (GVar->hasAttribute("toc-data"))
2412bdd1243dSDimitry Andric       SMC = XCOFF::XMC_TD;
2413bdd1243dSDimitry Andric 
24145ffd83dbSDimitry Andric   // Externals go into a csect of type ER.
24155ffd83dbSDimitry Andric   return getContext().getXCOFFSection(
2416fe6060f1SDimitry Andric       Name, SectionKind::getMetadata(),
2417fe6060f1SDimitry Andric       XCOFF::CsectProperties(SMC, XCOFF::XTY_ER));
24185ffd83dbSDimitry Andric }
24195ffd83dbSDimitry Andric 
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const24208bcb0991SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
24218bcb0991SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2422fe6060f1SDimitry Andric   // Handle the XCOFF::TD case first, then deal with the rest.
2423fe6060f1SDimitry Andric   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))
2424fe6060f1SDimitry Andric     if (GVar->hasAttribute("toc-data")) {
24258bcb0991SDimitry Andric       SmallString<128> Name;
24268bcb0991SDimitry Andric       getNameWithPrefix(Name, GO, TM);
24278bcb0991SDimitry Andric       return getContext().getXCOFFSection(
2428fe6060f1SDimitry Andric           Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TD, XCOFF::XTY_SD),
2429fe6060f1SDimitry Andric           /* MultiSymbolsAllowed*/ true);
2430fe6060f1SDimitry Andric     }
2431fe6060f1SDimitry Andric 
2432fe6060f1SDimitry Andric   // Common symbols go into a csect with matching name which will get mapped
2433fe6060f1SDimitry Andric   // into the .bss section.
2434fe6060f1SDimitry Andric   // Zero-initialized local TLS symbols go into a csect with matching name which
2435fe6060f1SDimitry Andric   // will get mapped into the .tbss section.
2436fe6060f1SDimitry Andric   if (Kind.isBSSLocal() || GO->hasCommonLinkage() || Kind.isThreadBSSLocal()) {
2437fe6060f1SDimitry Andric     SmallString<128> Name;
2438fe6060f1SDimitry Andric     getNameWithPrefix(Name, GO, TM);
2439fe6060f1SDimitry Andric     XCOFF::StorageMappingClass SMC = Kind.isBSSLocal() ? XCOFF::XMC_BS
2440fe6060f1SDimitry Andric                                      : Kind.isCommon() ? XCOFF::XMC_RW
2441fe6060f1SDimitry Andric                                                        : XCOFF::XMC_UL;
2442fe6060f1SDimitry Andric     return getContext().getXCOFFSection(
2443fe6060f1SDimitry Andric         Name, Kind, XCOFF::CsectProperties(SMC, XCOFF::XTY_CM));
24448bcb0991SDimitry Andric   }
24458bcb0991SDimitry 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 
2454fe013be4SDimitry Andric   if (TM.Options.XCOFFReadOnlyPointers && Kind.isReadOnlyWithRel()) {
2455fe013be4SDimitry Andric     if (!TM.getDataSections())
2456fe013be4SDimitry Andric       report_fatal_error(
2457fe013be4SDimitry Andric           "ReadOnlyPointers is supported only if data sections is turned on");
2458fe013be4SDimitry Andric 
2459fe013be4SDimitry Andric     SmallString<128> Name;
2460fe013be4SDimitry Andric     getNameWithPrefix(Name, GO, TM);
2461fe013be4SDimitry Andric     return getContext().getXCOFFSection(
2462fe013be4SDimitry Andric         Name, SectionKind::getReadOnly(),
2463fe013be4SDimitry Andric         XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));
2464fe013be4SDimitry Andric   }
2465fe013be4SDimitry 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 
getSectionForJumpTable(const Function & F,const TargetMachine & TM) const2509480093f4SDimitry 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 
shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,const Function & F) const25258bcb0991SDimitry 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.
getSectionForConstant(const DataLayout & DL,SectionKind Kind,const Constant * C,Align & Alignment) const2532480093f4SDimitry 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 
Initialize(MCContext & Ctx,const TargetMachine & TgtM)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 
getStaticCtorSection(unsigned Priority,const MCSymbol * KeySym) const25718bcb0991SDimitry 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 
getStaticDtorSection(unsigned Priority,const MCSymbol * KeySym) const25768bcb0991SDimitry 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 
lowerRelativeReference(const GlobalValue * LHS,const GlobalValue * RHS,const TargetMachine & TM) const25818bcb0991SDimitry 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
getStorageClassForGlobal(const GlobalValue * GV)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 
getFunctionEntryPointSymbol(const GlobalValue * Func,const TargetMachine & TM) const26135ffd83dbSDimitry 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()) ||
2631271697daSDimitry Andric        Func->isDeclarationForLinker()) &&
2632e8d8bef9SDimitry Andric       isa<Function>(Func)) {
2633e8d8bef9SDimitry Andric     return getContext()
2634fe6060f1SDimitry Andric         .getXCOFFSection(
2635fe6060f1SDimitry Andric             NameStr, SectionKind::getText(),
2636271697daSDimitry Andric             XCOFF::CsectProperties(XCOFF::XMC_PR, Func->isDeclarationForLinker()
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 
getSectionForFunctionDescriptor(const Function * F,const TargetMachine & TM) const26455ffd83dbSDimitry 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 
getSectionForTOCEntry(const MCSymbol * Sym,const TargetMachine & TM) const26545ffd83dbSDimitry 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
2657c9157d92SDimitry Andric   // the chance of needing -bbigtoc is decreased. Also, the toc-entry for
2658c9157d92SDimitry Andric   // EH info is never referenced directly using instructions so it can be
2659c9157d92SDimitry Andric   // allocated with TE storage-mapping class.
26605ffd83dbSDimitry Andric   return getContext().getXCOFFSection(
2661fe6060f1SDimitry Andric       cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(), SectionKind::getData(),
2662c9157d92SDimitry Andric       XCOFF::CsectProperties((TM.getCodeModel() == CodeModel::Large ||
2663c9157d92SDimitry Andric                               cast<MCSymbolXCOFF>(Sym)->isEHInfo())
2664c9157d92SDimitry Andric                                  ? XCOFF::XMC_TE
2665c9157d92SDimitry Andric                                  : XCOFF::XMC_TC,
2666fe6060f1SDimitry Andric                              XCOFF::XTY_SD));
2667fe6060f1SDimitry Andric }
2668fe6060f1SDimitry Andric 
getSectionForLSDA(const Function & F,const MCSymbol & FnSym,const TargetMachine & TM) const266981ad6265SDimitry Andric MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA(
267081ad6265SDimitry Andric     const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {
267181ad6265SDimitry Andric   auto *LSDA = cast<MCSectionXCOFF>(LSDASection);
267281ad6265SDimitry Andric   if (TM.getFunctionSections()) {
267381ad6265SDimitry Andric     // If option -ffunction-sections is on, append the function name to the
267481ad6265SDimitry Andric     // name of the LSDA csect so that each function has its own LSDA csect.
267581ad6265SDimitry Andric     // This helps the linker to garbage-collect EH info of unused functions.
267681ad6265SDimitry Andric     SmallString<128> NameStr = LSDA->getName();
267781ad6265SDimitry Andric     raw_svector_ostream(NameStr) << '.' << F.getName();
267881ad6265SDimitry Andric     LSDA = getContext().getXCOFFSection(NameStr, LSDA->getKind(),
267981ad6265SDimitry Andric                                         LSDA->getCsectProp());
268081ad6265SDimitry Andric   }
268181ad6265SDimitry Andric   return LSDA;
268281ad6265SDimitry Andric }
2683fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
2684fe6060f1SDimitry Andric //                                  GOFF
2685fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
268681ad6265SDimitry Andric TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default;
2687fe6060f1SDimitry Andric 
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const2688fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
2689fe6060f1SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2690fe6060f1SDimitry Andric   return SelectSectionForGlobal(GO, Kind, TM);
2691fe6060f1SDimitry Andric }
2692fe6060f1SDimitry Andric 
getSectionForLSDA(const Function & F,const MCSymbol & FnSym,const TargetMachine & TM) const2693e710425bSDimitry Andric MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
2694e710425bSDimitry Andric     const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {
2695e710425bSDimitry Andric   std::string Name = ".gcc_exception_table." + F.getName().str();
2696e710425bSDimitry Andric   return getContext().getGOFFSection(Name, SectionKind::getData(), nullptr,
2697e710425bSDimitry Andric                                      nullptr);
2698e710425bSDimitry Andric }
2699e710425bSDimitry Andric 
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const2700fe6060f1SDimitry Andric MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
2701fe6060f1SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2702fe6060f1SDimitry Andric   auto *Symbol = TM.getSymbol(GO);
2703fe6060f1SDimitry Andric   if (Kind.isBSS())
270481ad6265SDimitry Andric     return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(),
270581ad6265SDimitry Andric                                        nullptr, nullptr);
2706fe6060f1SDimitry Andric 
2707fe6060f1SDimitry Andric   return getContext().getObjectFileInfo()->getTextSection();
27088bcb0991SDimitry Andric }
2709