17a7e6055SDimitry Andric //===- llvm/CodeGen/TargetLoweringObjectFileImpl.cpp - Object File Info ---===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements classes used to handle lowerings specific to common
11f22ef01cSRoman Divacky // object file formats.
12f22ef01cSRoman Divacky //
13f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
14f22ef01cSRoman Divacky
15db17bf38SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
16139f7f9bSDimitry Andric #include "llvm/ADT/SmallString.h"
177a7e6055SDimitry Andric #include "llvm/ADT/SmallVector.h"
18139f7f9bSDimitry Andric #include "llvm/ADT/StringExtras.h"
197a7e6055SDimitry Andric #include "llvm/ADT/StringRef.h"
20139f7f9bSDimitry Andric #include "llvm/ADT/Triple.h"
21db17bf38SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
22db17bf38SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
23db17bf38SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
24db17bf38SDimitry Andric #include "llvm/BinaryFormat/MachO.h"
257a7e6055SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
26f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfoImpls.h"
277a7e6055SDimitry Andric #include "llvm/IR/Comdat.h"
28139f7f9bSDimitry Andric #include "llvm/IR/Constants.h"
29139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h"
30139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h"
31139f7f9bSDimitry Andric #include "llvm/IR/Function.h"
327a7e6055SDimitry Andric #include "llvm/IR/GlobalAlias.h"
337a7e6055SDimitry Andric #include "llvm/IR/GlobalObject.h"
347a7e6055SDimitry Andric #include "llvm/IR/GlobalValue.h"
35139f7f9bSDimitry Andric #include "llvm/IR/GlobalVariable.h"
3691bc56edSDimitry Andric #include "llvm/IR/Mangler.h"
377a7e6055SDimitry Andric #include "llvm/IR/Metadata.h"
38139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
397a7e6055SDimitry Andric #include "llvm/IR/Type.h"
407d523365SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
41f22ef01cSRoman Divacky #include "llvm/MC/MCContext.h"
42f22ef01cSRoman Divacky #include "llvm/MC/MCExpr.h"
43f22ef01cSRoman Divacky #include "llvm/MC/MCSectionCOFF.h"
44139f7f9bSDimitry Andric #include "llvm/MC/MCSectionELF.h"
45139f7f9bSDimitry Andric #include "llvm/MC/MCSectionMachO.h"
467a7e6055SDimitry Andric #include "llvm/MC/MCSectionWasm.h"
473b0f4066SDimitry Andric #include "llvm/MC/MCStreamer.h"
487a7e6055SDimitry Andric #include "llvm/MC/MCSymbol.h"
4997bc6c73SDimitry Andric #include "llvm/MC/MCSymbolELF.h"
50ff0cc061SDimitry Andric #include "llvm/MC/MCValue.h"
517a7e6055SDimitry Andric #include "llvm/MC/SectionKind.h"
523ca95b02SDimitry Andric #include "llvm/ProfileData/InstrProf.h"
537a7e6055SDimitry Andric #include "llvm/Support/Casting.h"
547a7e6055SDimitry Andric #include "llvm/Support/CodeGen.h"
552cab237bSDimitry Andric #include "llvm/Support/Format.h"
56f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
57f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h"
58139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h"
597a7e6055SDimitry Andric #include <cassert>
607a7e6055SDimitry Andric #include <string>
617a7e6055SDimitry Andric
62f22ef01cSRoman Divacky using namespace llvm;
63f22ef01cSRoman Divacky using namespace dwarf;
64f22ef01cSRoman Divacky
GetObjCImageInfo(Module & M,unsigned & Version,unsigned & Flags,StringRef & Section)6524d58133SDimitry Andric static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
66db17bf38SDimitry Andric StringRef &Section) {
6724d58133SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
6824d58133SDimitry Andric M.getModuleFlagsMetadata(ModuleFlags);
6924d58133SDimitry Andric
70db17bf38SDimitry Andric for (const auto &MFE: ModuleFlags) {
71db17bf38SDimitry Andric // Ignore flags with 'Require' behaviour.
72db17bf38SDimitry Andric if (MFE.Behavior == Module::Require)
73db17bf38SDimitry Andric continue;
74db17bf38SDimitry Andric
75db17bf38SDimitry Andric StringRef Key = MFE.Key->getString();
76db17bf38SDimitry Andric if (Key == "Objective-C Image Info Version") {
77db17bf38SDimitry Andric Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue();
78db17bf38SDimitry Andric } else if (Key == "Objective-C Garbage Collection" ||
79db17bf38SDimitry Andric Key == "Objective-C GC Only" ||
80db17bf38SDimitry Andric Key == "Objective-C Is Simulated" ||
81db17bf38SDimitry Andric Key == "Objective-C Class Properties" ||
82db17bf38SDimitry Andric Key == "Objective-C Image Swift Version") {
83db17bf38SDimitry Andric Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue();
84db17bf38SDimitry Andric } else if (Key == "Objective-C Image Info Section") {
85db17bf38SDimitry Andric Section = cast<MDString>(MFE.Val)->getString();
86db17bf38SDimitry Andric }
87db17bf38SDimitry Andric }
88db17bf38SDimitry Andric }
89db17bf38SDimitry Andric
90f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
91f22ef01cSRoman Divacky // ELF
92f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
93f22ef01cSRoman Divacky
Initialize(MCContext & Ctx,const TargetMachine & TgtM)944ba319b5SDimitry Andric void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
954ba319b5SDimitry Andric const TargetMachine &TgtM) {
964ba319b5SDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TgtM);
974ba319b5SDimitry Andric TM = &TgtM;
98*b5893f02SDimitry Andric
99*b5893f02SDimitry Andric CodeModel::Model CM = TgtM.getCodeModel();
100*b5893f02SDimitry Andric
101*b5893f02SDimitry Andric switch (TgtM.getTargetTriple().getArch()) {
102*b5893f02SDimitry Andric case Triple::arm:
103*b5893f02SDimitry Andric case Triple::armeb:
104*b5893f02SDimitry Andric case Triple::thumb:
105*b5893f02SDimitry Andric case Triple::thumbeb:
106*b5893f02SDimitry Andric if (Ctx.getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM)
107*b5893f02SDimitry Andric break;
108*b5893f02SDimitry Andric // Fallthrough if not using EHABI
109*b5893f02SDimitry Andric LLVM_FALLTHROUGH;
110*b5893f02SDimitry Andric case Triple::ppc:
111*b5893f02SDimitry Andric case Triple::x86:
112*b5893f02SDimitry Andric PersonalityEncoding = isPositionIndependent()
113*b5893f02SDimitry Andric ? dwarf::DW_EH_PE_indirect |
114*b5893f02SDimitry Andric dwarf::DW_EH_PE_pcrel |
115*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata4
116*b5893f02SDimitry Andric : dwarf::DW_EH_PE_absptr;
117*b5893f02SDimitry Andric LSDAEncoding = isPositionIndependent()
118*b5893f02SDimitry Andric ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
119*b5893f02SDimitry Andric : dwarf::DW_EH_PE_absptr;
120*b5893f02SDimitry Andric TTypeEncoding = isPositionIndependent()
121*b5893f02SDimitry Andric ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
122*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata4
123*b5893f02SDimitry Andric : dwarf::DW_EH_PE_absptr;
124*b5893f02SDimitry Andric break;
125*b5893f02SDimitry Andric case Triple::x86_64:
126*b5893f02SDimitry Andric if (isPositionIndependent()) {
127*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
128*b5893f02SDimitry Andric ((CM == CodeModel::Small || CM == CodeModel::Medium)
129*b5893f02SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
130*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel |
131*b5893f02SDimitry Andric (CM == CodeModel::Small
132*b5893f02SDimitry Andric ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
133*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
134*b5893f02SDimitry Andric ((CM == CodeModel::Small || CM == CodeModel::Medium)
135*b5893f02SDimitry Andric ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4);
136*b5893f02SDimitry Andric } else {
137*b5893f02SDimitry Andric PersonalityEncoding =
138*b5893f02SDimitry Andric (CM == CodeModel::Small || CM == CodeModel::Medium)
139*b5893f02SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
140*b5893f02SDimitry Andric LSDAEncoding = (CM == CodeModel::Small)
141*b5893f02SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
142*b5893f02SDimitry Andric TTypeEncoding = (CM == CodeModel::Small)
143*b5893f02SDimitry Andric ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
144*b5893f02SDimitry Andric }
145*b5893f02SDimitry Andric break;
146*b5893f02SDimitry Andric case Triple::hexagon:
147*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr;
148*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr;
149*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr;
150*b5893f02SDimitry Andric if (isPositionIndependent()) {
151*b5893f02SDimitry Andric PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel;
152*b5893f02SDimitry Andric LSDAEncoding |= dwarf::DW_EH_PE_pcrel;
153*b5893f02SDimitry Andric TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel;
154*b5893f02SDimitry Andric }
155*b5893f02SDimitry Andric break;
156*b5893f02SDimitry Andric case Triple::aarch64:
157*b5893f02SDimitry Andric case Triple::aarch64_be:
158*b5893f02SDimitry Andric // The small model guarantees static code/data size < 4GB, but not where it
159*b5893f02SDimitry Andric // will be in memory. Most of these could end up >2GB away so even a signed
160*b5893f02SDimitry Andric // pc-relative 32-bit address is insufficient, theoretically.
161*b5893f02SDimitry Andric if (isPositionIndependent()) {
162*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
163*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata8;
164*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
165*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
166*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata8;
167*b5893f02SDimitry Andric } else {
168*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr;
169*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr;
170*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr;
171*b5893f02SDimitry Andric }
172*b5893f02SDimitry Andric break;
173*b5893f02SDimitry Andric case Triple::lanai:
174*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr;
175*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr;
176*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr;
177*b5893f02SDimitry Andric break;
178*b5893f02SDimitry Andric case Triple::mips:
179*b5893f02SDimitry Andric case Triple::mipsel:
180*b5893f02SDimitry Andric case Triple::mips64:
181*b5893f02SDimitry Andric case Triple::mips64el:
182*b5893f02SDimitry Andric // MIPS uses indirect pointer to refer personality functions and types, so
183*b5893f02SDimitry Andric // that the eh_frame section can be read-only. DW.ref.personality will be
184*b5893f02SDimitry Andric // generated for relocation.
185*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect;
186*b5893f02SDimitry Andric // FIXME: The N64 ABI probably ought to use DW_EH_PE_sdata8 but we can't
187*b5893f02SDimitry Andric // identify N64 from just a triple.
188*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
189*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata4;
190*b5893f02SDimitry Andric // We don't support PC-relative LSDA references in GAS so we use the default
191*b5893f02SDimitry Andric // DW_EH_PE_absptr for those.
192*b5893f02SDimitry Andric
193*b5893f02SDimitry Andric // FreeBSD must be explicit about the data size and using pcrel since it's
194*b5893f02SDimitry Andric // assembler/linker won't do the automatic conversion that the Linux tools
195*b5893f02SDimitry Andric // do.
196*b5893f02SDimitry Andric if (TgtM.getTargetTriple().isOSFreeBSD()) {
197*b5893f02SDimitry Andric PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
198*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
199*b5893f02SDimitry Andric }
200*b5893f02SDimitry Andric break;
201*b5893f02SDimitry Andric case Triple::ppc64:
202*b5893f02SDimitry Andric case Triple::ppc64le:
203*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
204*b5893f02SDimitry Andric dwarf::DW_EH_PE_udata8;
205*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
206*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
207*b5893f02SDimitry Andric dwarf::DW_EH_PE_udata8;
208*b5893f02SDimitry Andric break;
209*b5893f02SDimitry Andric case Triple::sparcel:
210*b5893f02SDimitry Andric case Triple::sparc:
211*b5893f02SDimitry Andric if (isPositionIndependent()) {
212*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
213*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
214*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata4;
215*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
216*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata4;
217*b5893f02SDimitry Andric } else {
218*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr;
219*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr;
220*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr;
221*b5893f02SDimitry Andric }
222*b5893f02SDimitry Andric break;
223*b5893f02SDimitry Andric case Triple::sparcv9:
224*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
225*b5893f02SDimitry Andric if (isPositionIndependent()) {
226*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
227*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata4;
228*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
229*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata4;
230*b5893f02SDimitry Andric } else {
231*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr;
232*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr;
233*b5893f02SDimitry Andric }
234*b5893f02SDimitry Andric break;
235*b5893f02SDimitry Andric case Triple::systemz:
236*b5893f02SDimitry Andric // All currently-defined code models guarantee that 4-byte PC-relative
237*b5893f02SDimitry Andric // values will be in range.
238*b5893f02SDimitry Andric if (isPositionIndependent()) {
239*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
240*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata4;
241*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
242*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
243*b5893f02SDimitry Andric dwarf::DW_EH_PE_sdata4;
244*b5893f02SDimitry Andric } else {
245*b5893f02SDimitry Andric PersonalityEncoding = dwarf::DW_EH_PE_absptr;
246*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_absptr;
247*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr;
248*b5893f02SDimitry Andric }
249*b5893f02SDimitry Andric break;
250*b5893f02SDimitry Andric default:
251*b5893f02SDimitry Andric break;
252*b5893f02SDimitry Andric }
2534ba319b5SDimitry Andric }
2544ba319b5SDimitry Andric
emitModuleMetadata(MCStreamer & Streamer,Module & M) const2554ba319b5SDimitry Andric void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
2564ba319b5SDimitry Andric Module &M) const {
2574ba319b5SDimitry Andric auto &C = getContext();
2584ba319b5SDimitry Andric
2594ba319b5SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
2604ba319b5SDimitry Andric auto *S = C.getELFSection(".linker-options", ELF::SHT_LLVM_LINKER_OPTIONS,
2614ba319b5SDimitry Andric ELF::SHF_EXCLUDE);
2624ba319b5SDimitry Andric
2634ba319b5SDimitry Andric Streamer.SwitchSection(S);
2644ba319b5SDimitry Andric
2654ba319b5SDimitry Andric for (const auto &Operand : LinkerOptions->operands()) {
2664ba319b5SDimitry Andric if (cast<MDNode>(Operand)->getNumOperands() != 2)
2674ba319b5SDimitry Andric report_fatal_error("invalid llvm.linker.options");
2684ba319b5SDimitry Andric for (const auto &Option : cast<MDNode>(Operand)->operands()) {
2694ba319b5SDimitry Andric Streamer.EmitBytes(cast<MDString>(Option)->getString());
2704ba319b5SDimitry Andric Streamer.EmitIntValue(0, 1);
2714ba319b5SDimitry Andric }
2724ba319b5SDimitry Andric }
2734ba319b5SDimitry Andric }
2744ba319b5SDimitry Andric
275db17bf38SDimitry Andric unsigned Version = 0;
276db17bf38SDimitry Andric unsigned Flags = 0;
277db17bf38SDimitry Andric StringRef Section;
278db17bf38SDimitry Andric
27924d58133SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section);
2804ba319b5SDimitry Andric if (!Section.empty()) {
281db17bf38SDimitry Andric auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
282db17bf38SDimitry Andric Streamer.SwitchSection(S);
283db17bf38SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
284db17bf38SDimitry Andric Streamer.EmitIntValue(Version, 4);
285db17bf38SDimitry Andric Streamer.EmitIntValue(Flags, 4);
286db17bf38SDimitry Andric Streamer.AddBlankLine();
287db17bf38SDimitry Andric }
288db17bf38SDimitry Andric
2894ba319b5SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
2904ba319b5SDimitry Andric M.getModuleFlagsMetadata(ModuleFlags);
2914ba319b5SDimitry Andric
2924ba319b5SDimitry Andric MDNode *CFGProfile = nullptr;
2934ba319b5SDimitry Andric
2944ba319b5SDimitry Andric for (const auto &MFE : ModuleFlags) {
2954ba319b5SDimitry Andric StringRef Key = MFE.Key->getString();
2964ba319b5SDimitry Andric if (Key == "CG Profile") {
2974ba319b5SDimitry Andric CFGProfile = cast<MDNode>(MFE.Val);
2984ba319b5SDimitry Andric break;
2994ba319b5SDimitry Andric }
3004ba319b5SDimitry Andric }
3014ba319b5SDimitry Andric
3024ba319b5SDimitry Andric if (!CFGProfile)
3034ba319b5SDimitry Andric return;
3044ba319b5SDimitry Andric
3054ba319b5SDimitry Andric auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * {
3064ba319b5SDimitry Andric if (!MDO)
3074ba319b5SDimitry Andric return nullptr;
3084ba319b5SDimitry Andric auto V = cast<ValueAsMetadata>(MDO);
3094ba319b5SDimitry Andric const Function *F = cast<Function>(V->getValue());
3104ba319b5SDimitry Andric return TM->getSymbol(F);
3114ba319b5SDimitry Andric };
3124ba319b5SDimitry Andric
3134ba319b5SDimitry Andric for (const auto &Edge : CFGProfile->operands()) {
3144ba319b5SDimitry Andric MDNode *E = cast<MDNode>(Edge);
3154ba319b5SDimitry Andric const MCSymbol *From = GetSym(E->getOperand(0));
3164ba319b5SDimitry Andric const MCSymbol *To = GetSym(E->getOperand(1));
3174ba319b5SDimitry Andric // Skip null functions. This can happen if functions are dead stripped after
3184ba319b5SDimitry Andric // the CGProfile pass has been run.
3194ba319b5SDimitry Andric if (!From || !To)
3204ba319b5SDimitry Andric continue;
3214ba319b5SDimitry Andric uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2))
3224ba319b5SDimitry Andric ->getValue()
3234ba319b5SDimitry Andric ->getUniqueInteger()
3244ba319b5SDimitry Andric .getZExtValue();
3254ba319b5SDimitry Andric Streamer.emitCGProfileEntry(
3264ba319b5SDimitry Andric MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C),
3274ba319b5SDimitry Andric MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count);
3284ba319b5SDimitry Andric }
3294ba319b5SDimitry Andric }
3304ba319b5SDimitry Andric
getCFIPersonalitySymbol(const GlobalValue * GV,const TargetMachine & TM,MachineModuleInfo * MMI) const33191bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
332d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM,
3333b0f4066SDimitry Andric MachineModuleInfo *MMI) const {
3343b0f4066SDimitry Andric unsigned Encoding = getPersonalityEncoding();
3357a7e6055SDimitry Andric if ((Encoding & 0x80) == DW_EH_PE_indirect)
336ff0cc061SDimitry Andric return getContext().getOrCreateSymbol(StringRef("DW.ref.") +
337d88c1a5aSDimitry Andric TM.getSymbol(GV)->getName());
3387a7e6055SDimitry Andric if ((Encoding & 0x70) == DW_EH_PE_absptr)
339d88c1a5aSDimitry Andric return TM.getSymbol(GV);
34091bc56edSDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!");
3413b0f4066SDimitry Andric }
3423b0f4066SDimitry Andric
emitPersonalityValue(MCStreamer & Streamer,const DataLayout & DL,const MCSymbol * Sym) const3437d523365SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue(
3447d523365SDimitry Andric MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const {
34517a519f9SDimitry Andric SmallString<64> NameData("DW.ref.");
34617a519f9SDimitry Andric NameData += Sym->getName();
34797bc6c73SDimitry Andric MCSymbolELF *Label =
34897bc6c73SDimitry Andric cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData));
3493b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Hidden);
3503b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Weak);
3513b0f4066SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP;
3523ca95b02SDimitry Andric MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(),
3533ca95b02SDimitry Andric ELF::SHT_PROGBITS, Flags, 0);
3547d523365SDimitry Andric unsigned Size = DL.getPointerSize();
3553b0f4066SDimitry Andric Streamer.SwitchSection(Sec);
3562cab237bSDimitry Andric Streamer.EmitValueToAlignment(DL.getPointerABIAlignment(0));
3573b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject);
35897bc6c73SDimitry Andric const MCExpr *E = MCConstantExpr::create(Size, getContext());
35997bc6c73SDimitry Andric Streamer.emitELFSize(Label, E);
3603b0f4066SDimitry Andric Streamer.EmitLabel(Label);
3613b0f4066SDimitry Andric
3623b0f4066SDimitry Andric Streamer.EmitSymbolValue(Sym, Size);
3633b0f4066SDimitry Andric }
3643b0f4066SDimitry Andric
getTTypeGlobalReference(const GlobalValue * GV,unsigned Encoding,const TargetMachine & TM,MachineModuleInfo * MMI,MCStreamer & Streamer) const36591bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(
366d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,
367d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const {
3687a7e6055SDimitry Andric if (Encoding & DW_EH_PE_indirect) {
369139f7f9bSDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
370139f7f9bSDimitry Andric
371d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM);
372139f7f9bSDimitry Andric
373139f7f9bSDimitry Andric // Add information about the stub reference to ELFMMI so that the stub
374139f7f9bSDimitry Andric // gets emitted by the asmprinter.
375139f7f9bSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
37691bc56edSDimitry Andric if (!StubSym.getPointer()) {
377d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV);
378139f7f9bSDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
379139f7f9bSDimitry Andric }
380139f7f9bSDimitry Andric
381139f7f9bSDimitry Andric return TargetLoweringObjectFile::
38297bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()),
3837a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer);
384139f7f9bSDimitry Andric }
385139f7f9bSDimitry Andric
386d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM,
387d88c1a5aSDimitry Andric MMI, Streamer);
388139f7f9bSDimitry Andric }
389139f7f9bSDimitry Andric
getELFKindForNamedSection(StringRef Name,SectionKind K)3902cab237bSDimitry Andric static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
3914ba319b5SDimitry Andric // N.B.: The defaults used in here are not the same ones used in MC.
392bd5abe19SDimitry Andric // We follow gcc, MC follows gas. For example, given ".section .eh_frame",
393bd5abe19SDimitry Andric // both gas and MC will produce a section with no flags. Given
3947ae0e2c9SDimitry Andric // section(".eh_frame") gcc will produce:
3957ae0e2c9SDimitry Andric //
396bd5abe19SDimitry Andric // .section .eh_frame,"a",@progbits
3973ca95b02SDimitry Andric
3987a7e6055SDimitry Andric if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF,
3997a7e6055SDimitry Andric /*AddSegmentInfo=*/false))
4003ca95b02SDimitry Andric return SectionKind::getMetadata();
4013ca95b02SDimitry Andric
402f22ef01cSRoman Divacky if (Name.empty() || Name[0] != '.') return K;
403f22ef01cSRoman Divacky
4044ba319b5SDimitry Andric // Default implementation based on some magic section names.
405f22ef01cSRoman Divacky if (Name == ".bss" ||
406f22ef01cSRoman Divacky Name.startswith(".bss.") ||
407f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.b.") ||
408f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.b.") ||
409f22ef01cSRoman Divacky Name == ".sbss" ||
410f22ef01cSRoman Divacky Name.startswith(".sbss.") ||
411f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.sb.") ||
412f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.sb."))
413f22ef01cSRoman Divacky return SectionKind::getBSS();
414f22ef01cSRoman Divacky
415f22ef01cSRoman Divacky if (Name == ".tdata" ||
416f22ef01cSRoman Divacky Name.startswith(".tdata.") ||
417f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.td.") ||
418f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.td."))
419f22ef01cSRoman Divacky return SectionKind::getThreadData();
420f22ef01cSRoman Divacky
421f22ef01cSRoman Divacky if (Name == ".tbss" ||
422f22ef01cSRoman Divacky Name.startswith(".tbss.") ||
423f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.tb.") ||
424f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.tb."))
425f22ef01cSRoman Divacky return SectionKind::getThreadBSS();
426f22ef01cSRoman Divacky
427f22ef01cSRoman Divacky return K;
428f22ef01cSRoman Divacky }
429f22ef01cSRoman Divacky
getELFSectionType(StringRef Name,SectionKind K)430f22ef01cSRoman Divacky static unsigned getELFSectionType(StringRef Name, SectionKind K) {
431d88c1a5aSDimitry Andric // Use SHT_NOTE for section whose name starts with ".note" to allow
432d88c1a5aSDimitry Andric // emitting ELF notes from C variable declaration.
433d88c1a5aSDimitry Andric // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609
434d88c1a5aSDimitry Andric if (Name.startswith(".note"))
435d88c1a5aSDimitry Andric return ELF::SHT_NOTE;
436f22ef01cSRoman Divacky
437f22ef01cSRoman Divacky if (Name == ".init_array")
4382754fe60SDimitry Andric return ELF::SHT_INIT_ARRAY;
439f22ef01cSRoman Divacky
440f22ef01cSRoman Divacky if (Name == ".fini_array")
4412754fe60SDimitry Andric return ELF::SHT_FINI_ARRAY;
442f22ef01cSRoman Divacky
443f22ef01cSRoman Divacky if (Name == ".preinit_array")
4442754fe60SDimitry Andric return ELF::SHT_PREINIT_ARRAY;
445f22ef01cSRoman Divacky
446f22ef01cSRoman Divacky if (K.isBSS() || K.isThreadBSS())
4472754fe60SDimitry Andric return ELF::SHT_NOBITS;
448f22ef01cSRoman Divacky
4492754fe60SDimitry Andric return ELF::SHT_PROGBITS;
450f22ef01cSRoman Divacky }
451f22ef01cSRoman Divacky
getELFSectionFlags(SectionKind K)452ff0cc061SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) {
453f22ef01cSRoman Divacky unsigned Flags = 0;
454f22ef01cSRoman Divacky
455f22ef01cSRoman Divacky if (!K.isMetadata())
4562754fe60SDimitry Andric Flags |= ELF::SHF_ALLOC;
457f22ef01cSRoman Divacky
458f22ef01cSRoman Divacky if (K.isText())
4592754fe60SDimitry Andric Flags |= ELF::SHF_EXECINSTR;
460f22ef01cSRoman Divacky
461d88c1a5aSDimitry Andric if (K.isExecuteOnly())
462d88c1a5aSDimitry Andric Flags |= ELF::SHF_ARM_PURECODE;
463d88c1a5aSDimitry Andric
464f22ef01cSRoman Divacky if (K.isWriteable())
4652754fe60SDimitry Andric Flags |= ELF::SHF_WRITE;
466f22ef01cSRoman Divacky
467f22ef01cSRoman Divacky if (K.isThreadLocal())
4682754fe60SDimitry Andric Flags |= ELF::SHF_TLS;
469f22ef01cSRoman Divacky
470ff0cc061SDimitry Andric if (K.isMergeableCString() || K.isMergeableConst())
4712754fe60SDimitry Andric Flags |= ELF::SHF_MERGE;
472f22ef01cSRoman Divacky
473f22ef01cSRoman Divacky if (K.isMergeableCString())
4742754fe60SDimitry Andric Flags |= ELF::SHF_STRINGS;
475f22ef01cSRoman Divacky
476f22ef01cSRoman Divacky return Flags;
477f22ef01cSRoman Divacky }
478f22ef01cSRoman Divacky
getELFComdat(const GlobalValue * GV)47991bc56edSDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) {
48091bc56edSDimitry Andric const Comdat *C = GV->getComdat();
48191bc56edSDimitry Andric if (!C)
48291bc56edSDimitry Andric return nullptr;
483f22ef01cSRoman Divacky
48491bc56edSDimitry Andric if (C->getSelectionKind() != Comdat::Any)
48591bc56edSDimitry Andric report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" +
48691bc56edSDimitry Andric C->getName() + "' cannot be lowered.");
48791bc56edSDimitry Andric
48891bc56edSDimitry Andric return C;
48991bc56edSDimitry Andric }
49091bc56edSDimitry Andric
getAssociatedSymbol(const GlobalObject * GO,const TargetMachine & TM)4917a7e6055SDimitry Andric static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO,
4927a7e6055SDimitry Andric const TargetMachine &TM) {
4937a7e6055SDimitry Andric MDNode *MD = GO->getMetadata(LLVMContext::MD_associated);
4947a7e6055SDimitry Andric if (!MD)
4957a7e6055SDimitry Andric return nullptr;
4967a7e6055SDimitry Andric
4975517e702SDimitry Andric const MDOperand &Op = MD->getOperand(0);
4985517e702SDimitry Andric if (!Op.get())
4995517e702SDimitry Andric return nullptr;
5005517e702SDimitry Andric
5015517e702SDimitry Andric auto *VM = dyn_cast<ValueAsMetadata>(Op);
5027a7e6055SDimitry Andric if (!VM)
5037a7e6055SDimitry Andric report_fatal_error("MD_associated operand is not ValueAsMetadata");
5047a7e6055SDimitry Andric
5057a7e6055SDimitry Andric GlobalObject *OtherGO = dyn_cast<GlobalObject>(VM->getValue());
5067a7e6055SDimitry Andric return OtherGO ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGO)) : nullptr;
5077a7e6055SDimitry Andric }
5087a7e6055SDimitry Andric
getEntrySizeForKind(SectionKind Kind)509*b5893f02SDimitry Andric static unsigned getEntrySizeForKind(SectionKind Kind) {
510*b5893f02SDimitry Andric if (Kind.isMergeable1ByteCString())
511*b5893f02SDimitry Andric return 1;
512*b5893f02SDimitry Andric else if (Kind.isMergeable2ByteCString())
513*b5893f02SDimitry Andric return 2;
514*b5893f02SDimitry Andric else if (Kind.isMergeable4ByteCString())
515*b5893f02SDimitry Andric return 4;
516*b5893f02SDimitry Andric else if (Kind.isMergeableConst4())
517*b5893f02SDimitry Andric return 4;
518*b5893f02SDimitry Andric else if (Kind.isMergeableConst8())
519*b5893f02SDimitry Andric return 8;
520*b5893f02SDimitry Andric else if (Kind.isMergeableConst16())
521*b5893f02SDimitry Andric return 16;
522*b5893f02SDimitry Andric else if (Kind.isMergeableConst32())
523*b5893f02SDimitry Andric return 32;
524*b5893f02SDimitry Andric else {
525*b5893f02SDimitry Andric // We shouldn't have mergeable C strings or mergeable constants that we
526*b5893f02SDimitry Andric // didn't handle above.
527*b5893f02SDimitry Andric assert(!Kind.isMergeableCString() && "unknown string width");
528*b5893f02SDimitry Andric assert(!Kind.isMergeableConst() && "unknown data width");
529*b5893f02SDimitry Andric return 0;
530*b5893f02SDimitry Andric }
531*b5893f02SDimitry Andric }
532*b5893f02SDimitry Andric
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const533ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
534d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
535d88c1a5aSDimitry Andric StringRef SectionName = GO->getSection();
536f22ef01cSRoman Divacky
537db17bf38SDimitry Andric // Check if '#pragma clang section' name is applicable.
538db17bf38SDimitry Andric // Note that pragma directive overrides -ffunction-section, -fdata-section
539db17bf38SDimitry Andric // and so section name is exactly as user specified and not uniqued.
540db17bf38SDimitry Andric const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO);
541db17bf38SDimitry Andric if (GV && GV->hasImplicitSection()) {
542db17bf38SDimitry Andric auto Attrs = GV->getAttributes();
543db17bf38SDimitry Andric if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) {
544db17bf38SDimitry Andric SectionName = Attrs.getAttribute("bss-section").getValueAsString();
545db17bf38SDimitry Andric } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
546db17bf38SDimitry Andric SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
547db17bf38SDimitry Andric } else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
548db17bf38SDimitry Andric SectionName = Attrs.getAttribute("data-section").getValueAsString();
549db17bf38SDimitry Andric }
550db17bf38SDimitry Andric }
551db17bf38SDimitry Andric const Function *F = dyn_cast<Function>(GO);
552db17bf38SDimitry Andric if (F && F->hasFnAttribute("implicit-section-name")) {
553db17bf38SDimitry Andric SectionName = F->getFnAttribute("implicit-section-name").getValueAsString();
554db17bf38SDimitry Andric }
555db17bf38SDimitry Andric
556f22ef01cSRoman Divacky // Infer section flags from the section name if we can.
557f22ef01cSRoman Divacky Kind = getELFKindForNamedSection(SectionName, Kind);
558f22ef01cSRoman Divacky
55991bc56edSDimitry Andric StringRef Group = "";
56091bc56edSDimitry Andric unsigned Flags = getELFSectionFlags(Kind);
561d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) {
56291bc56edSDimitry Andric Group = C->getName();
56391bc56edSDimitry Andric Flags |= ELF::SHF_GROUP;
56491bc56edSDimitry Andric }
5657a7e6055SDimitry Andric
5667a7e6055SDimitry Andric // A section can have at most one associated section. Put each global with
5677a7e6055SDimitry Andric // MD_associated in a unique section.
5687a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID;
5697a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM);
5707a7e6055SDimitry Andric if (AssociatedSymbol) {
5717a7e6055SDimitry Andric UniqueID = NextUniqueID++;
5727a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER;
5737a7e6055SDimitry Andric }
5747a7e6055SDimitry Andric
5757a7e6055SDimitry Andric MCSectionELF *Section = getContext().getELFSection(
5767a7e6055SDimitry Andric SectionName, getELFSectionType(SectionName, Kind), Flags,
577*b5893f02SDimitry Andric getEntrySizeForKind(Kind), Group, UniqueID, AssociatedSymbol);
5787a7e6055SDimitry Andric // Make sure that we did not get some other section with incompatible sh_link.
5797a7e6055SDimitry Andric // This should not be possible due to UniqueID code above.
5804ba319b5SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol &&
5814ba319b5SDimitry Andric "Associated symbol mismatch between sections");
5827a7e6055SDimitry Andric return Section;
583f22ef01cSRoman Divacky }
584f22ef01cSRoman Divacky
585ff0cc061SDimitry Andric /// Return the section prefix name used by options FunctionsSections and
586ff0cc061SDimitry Andric /// DataSections.
getSectionPrefixForGlobal(SectionKind Kind)58791bc56edSDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind) {
588ff0cc061SDimitry Andric if (Kind.isText())
589ff0cc061SDimitry Andric return ".text";
590ff0cc061SDimitry Andric if (Kind.isReadOnly())
591ff0cc061SDimitry Andric return ".rodata";
592ff0cc061SDimitry Andric if (Kind.isBSS())
593ff0cc061SDimitry Andric return ".bss";
594ff0cc061SDimitry Andric if (Kind.isThreadData())
595ff0cc061SDimitry Andric return ".tdata";
596ff0cc061SDimitry Andric if (Kind.isThreadBSS())
597ff0cc061SDimitry Andric return ".tbss";
5987d523365SDimitry Andric if (Kind.isData())
599ff0cc061SDimitry Andric return ".data";
600f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
601ff0cc061SDimitry Andric return ".data.rel.ro";
602f22ef01cSRoman Divacky }
603f22ef01cSRoman Divacky
selectELFSectionForGlobal(MCContext & Ctx,const GlobalObject * GO,SectionKind Kind,Mangler & Mang,const TargetMachine & TM,bool EmitUniqueSection,unsigned Flags,unsigned * NextUniqueID,const MCSymbolELF * AssociatedSymbol)6047a7e6055SDimitry Andric static MCSectionELF *selectELFSectionForGlobal(
6057a7e6055SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
6067a7e6055SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags,
6077a7e6055SDimitry Andric unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) {
60891bc56edSDimitry Andric
6092754fe60SDimitry Andric StringRef Group = "";
610d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) {
6112754fe60SDimitry Andric Flags |= ELF::SHF_GROUP;
612ff0cc061SDimitry Andric Group = C->getName();
6132754fe60SDimitry Andric }
6142754fe60SDimitry Andric
6154ba319b5SDimitry Andric // Get the section entry size based on the kind.
6164ba319b5SDimitry Andric unsigned EntrySize = getEntrySizeForKind(Kind);
6174ba319b5SDimitry Andric
618ff0cc061SDimitry Andric SmallString<128> Name;
619ff0cc061SDimitry Andric if (Kind.isMergeableCString()) {
620f22ef01cSRoman Divacky // We also need alignment here.
621f22ef01cSRoman Divacky // FIXME: this is getting the alignment of the character, not the
622f22ef01cSRoman Divacky // alignment of the global!
623d88c1a5aSDimitry Andric unsigned Align = GO->getParent()->getDataLayout().getPreferredAlignment(
624d88c1a5aSDimitry Andric cast<GlobalVariable>(GO));
625f22ef01cSRoman Divacky
626ff0cc061SDimitry Andric std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + ".";
627ff0cc061SDimitry Andric Name = SizeSpec + utostr(Align);
628ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) {
629ff0cc061SDimitry Andric Name = ".rodata.cst";
630ff0cc061SDimitry Andric Name += utostr(EntrySize);
631ff0cc061SDimitry Andric } else {
632ff0cc061SDimitry Andric Name = getSectionPrefixForGlobal(Kind);
633ff0cc061SDimitry Andric }
634d88c1a5aSDimitry Andric
635d88c1a5aSDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) {
636d88c1a5aSDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix();
637d88c1a5aSDimitry Andric if (OptionalPrefix)
638d88c1a5aSDimitry Andric Name += *OptionalPrefix;
639d88c1a5aSDimitry Andric }
640ff0cc061SDimitry Andric
6413ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID;
6424ba319b5SDimitry Andric if (EmitUniqueSection) {
6434ba319b5SDimitry Andric if (TM.getUniqueSectionNames()) {
6444ba319b5SDimitry Andric Name.push_back('.');
6454ba319b5SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true /*MayAlwaysUsePrivate*/);
6464ba319b5SDimitry Andric } else {
647ff0cc061SDimitry Andric UniqueID = *NextUniqueID;
648ff0cc061SDimitry Andric (*NextUniqueID)++;
649ff0cc061SDimitry Andric }
6504ba319b5SDimitry Andric }
6514ba319b5SDimitry Andric // Use 0 as the unique ID for execute-only text.
652d88c1a5aSDimitry Andric if (Kind.isExecuteOnly())
653d88c1a5aSDimitry Andric UniqueID = 0;
654ff0cc061SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
6557a7e6055SDimitry Andric EntrySize, Group, UniqueID, AssociatedSymbol);
656ff0cc061SDimitry Andric }
657ff0cc061SDimitry Andric
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const658ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
659d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
660ff0cc061SDimitry Andric unsigned Flags = getELFSectionFlags(Kind);
661ff0cc061SDimitry Andric
662ff0cc061SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the
663ff0cc061SDimitry Andric // global value to a uniqued section specifically for it.
664ff0cc061SDimitry Andric bool EmitUniqueSection = false;
665ff0cc061SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) {
666ff0cc061SDimitry Andric if (Kind.isText())
667ff0cc061SDimitry Andric EmitUniqueSection = TM.getFunctionSections();
668f22ef01cSRoman Divacky else
669ff0cc061SDimitry Andric EmitUniqueSection = TM.getDataSections();
670ff0cc061SDimitry Andric }
671d88c1a5aSDimitry Andric EmitUniqueSection |= GO->hasComdat();
672f22ef01cSRoman Divacky
6737a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM);
6747a7e6055SDimitry Andric if (AssociatedSymbol) {
6757a7e6055SDimitry Andric EmitUniqueSection = true;
6767a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER;
6777a7e6055SDimitry Andric }
6787a7e6055SDimitry Andric
6797a7e6055SDimitry Andric MCSectionELF *Section = selectELFSectionForGlobal(
6807a7e6055SDimitry Andric getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags,
6817a7e6055SDimitry Andric &NextUniqueID, AssociatedSymbol);
6827a7e6055SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol);
6837a7e6055SDimitry Andric return Section;
684f22ef01cSRoman Divacky }
685f22ef01cSRoman Divacky
getSectionForJumpTable(const Function & F,const TargetMachine & TM) const686ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
687d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const {
688ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that
689ff0cc061SDimitry Andric // the table doesn't prevent the removal.
690ff0cc061SDimitry Andric const Comdat *C = F.getComdat();
691ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C;
692ff0cc061SDimitry Andric if (!EmitUniqueSection)
693ff0cc061SDimitry Andric return ReadOnlySection;
694ff0cc061SDimitry Andric
695ff0cc061SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(),
6967a7e6055SDimitry Andric getMangler(), TM, EmitUniqueSection,
6977a7e6055SDimitry Andric ELF::SHF_ALLOC, &NextUniqueID,
6987a7e6055SDimitry Andric /* AssociatedSymbol */ nullptr);
699f22ef01cSRoman Divacky }
700f22ef01cSRoman Divacky
shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,const Function & F) const701ff0cc061SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
702ff0cc061SDimitry Andric bool UsesLabelDifference, const Function &F) const {
703ff0cc061SDimitry Andric // We can always create relative relocations, so use another section
704ff0cc061SDimitry Andric // that can be marked non-executable.
705ff0cc061SDimitry Andric return false;
706f22ef01cSRoman Divacky }
707f22ef01cSRoman Divacky
708ff0cc061SDimitry Andric /// Given a mergeable constant with the specified size and relocation
709ff0cc061SDimitry Andric /// information, return a section that it should be placed in.
getSectionForConstant(const DataLayout & DL,SectionKind Kind,const Constant * C,unsigned & Align) const7107d523365SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant(
7113ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C,
7123ca95b02SDimitry Andric unsigned &Align) const {
713f22ef01cSRoman Divacky if (Kind.isMergeableConst4() && MergeableConst4Section)
714f22ef01cSRoman Divacky return MergeableConst4Section;
715f22ef01cSRoman Divacky if (Kind.isMergeableConst8() && MergeableConst8Section)
716f22ef01cSRoman Divacky return MergeableConst8Section;
717f22ef01cSRoman Divacky if (Kind.isMergeableConst16() && MergeableConst16Section)
718f22ef01cSRoman Divacky return MergeableConst16Section;
7193ca95b02SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section)
7203ca95b02SDimitry Andric return MergeableConst32Section;
721f22ef01cSRoman Divacky if (Kind.isReadOnly())
722f22ef01cSRoman Divacky return ReadOnlySection;
723f22ef01cSRoman Divacky
724f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
725f22ef01cSRoman Divacky return DataRelROSection;
726f22ef01cSRoman Divacky }
727f22ef01cSRoman Divacky
getStaticStructorSection(MCContext & Ctx,bool UseInitArray,bool IsCtor,unsigned Priority,const MCSymbol * KeySym)728ff0cc061SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
729ff0cc061SDimitry Andric bool IsCtor, unsigned Priority,
73039d628a0SDimitry Andric const MCSymbol *KeySym) {
73139d628a0SDimitry Andric std::string Name;
73239d628a0SDimitry Andric unsigned Type;
73339d628a0SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE;
73439d628a0SDimitry Andric StringRef COMDAT = KeySym ? KeySym->getName() : "";
73539d628a0SDimitry Andric
73639d628a0SDimitry Andric if (KeySym)
73739d628a0SDimitry Andric Flags |= ELF::SHF_GROUP;
738dff0c46cSDimitry Andric
7397ae0e2c9SDimitry Andric if (UseInitArray) {
74039d628a0SDimitry Andric if (IsCtor) {
74139d628a0SDimitry Andric Type = ELF::SHT_INIT_ARRAY;
74239d628a0SDimitry Andric Name = ".init_array";
7437ae0e2c9SDimitry Andric } else {
74439d628a0SDimitry Andric Type = ELF::SHT_FINI_ARRAY;
74539d628a0SDimitry Andric Name = ".fini_array";
746dff0c46cSDimitry Andric }
74739d628a0SDimitry Andric if (Priority != 65535) {
74839d628a0SDimitry Andric Name += '.';
74939d628a0SDimitry Andric Name += utostr(Priority);
75039d628a0SDimitry Andric }
75139d628a0SDimitry Andric } else {
75239d628a0SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority
75339d628a0SDimitry Andric // numbering.
75439d628a0SDimitry Andric if (IsCtor)
75539d628a0SDimitry Andric Name = ".ctors";
75639d628a0SDimitry Andric else
75739d628a0SDimitry Andric Name = ".dtors";
7582cab237bSDimitry Andric if (Priority != 65535)
7592cab237bSDimitry Andric raw_string_ostream(Name) << format(".%05u", 65535 - Priority);
76039d628a0SDimitry Andric Type = ELF::SHT_PROGBITS;
76139d628a0SDimitry Andric }
76239d628a0SDimitry Andric
763ff0cc061SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT);
76439d628a0SDimitry Andric }
76539d628a0SDimitry Andric
getStaticCtorSection(unsigned Priority,const MCSymbol * KeySym) const766ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection(
76739d628a0SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const {
76839d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority,
76939d628a0SDimitry Andric KeySym);
7707ae0e2c9SDimitry Andric }
771dff0c46cSDimitry Andric
getStaticDtorSection(unsigned Priority,const MCSymbol * KeySym) const772ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection(
77391bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const {
77439d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority,
77539d628a0SDimitry Andric KeySym);
7767ae0e2c9SDimitry Andric }
7777ae0e2c9SDimitry Andric
lowerRelativeReference(const GlobalValue * LHS,const GlobalValue * RHS,const TargetMachine & TM) const7783ca95b02SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
779d88c1a5aSDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS,
7803ca95b02SDimitry Andric const TargetMachine &TM) const {
7813ca95b02SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr
7823ca95b02SDimitry Andric // functions.
7833ca95b02SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
7843ca95b02SDimitry Andric return nullptr;
7853ca95b02SDimitry Andric
7863ca95b02SDimitry Andric // Basic sanity checks.
7873ca95b02SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 ||
7883ca95b02SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() ||
7893ca95b02SDimitry Andric RHS->isThreadLocal())
7903ca95b02SDimitry Andric return nullptr;
7913ca95b02SDimitry Andric
7923ca95b02SDimitry Andric return MCBinaryExpr::createSub(
793d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind,
7943ca95b02SDimitry Andric getContext()),
795d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
7963ca95b02SDimitry Andric }
7973ca95b02SDimitry Andric
getSectionForCommandLines() const798*b5893f02SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
799*b5893f02SDimitry Andric // Use ".GCC.command.line" since this feature is to support clang's
800*b5893f02SDimitry Andric // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the
801*b5893f02SDimitry Andric // same name.
802*b5893f02SDimitry Andric return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS,
803*b5893f02SDimitry Andric ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
804*b5893f02SDimitry Andric }
805*b5893f02SDimitry Andric
8067ae0e2c9SDimitry Andric void
InitializeELF(bool UseInitArray_)8077ae0e2c9SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) {
8087ae0e2c9SDimitry Andric UseInitArray = UseInitArray_;
809d88c1a5aSDimitry Andric MCContext &Ctx = getContext();
810d88c1a5aSDimitry Andric if (!UseInitArray) {
811d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS,
812d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE);
8137ae0e2c9SDimitry Andric
814d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS,
815d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE);
816d88c1a5aSDimitry Andric return;
817d88c1a5aSDimitry Andric }
818d88c1a5aSDimitry Andric
819d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY,
820d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC);
821d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY,
822d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC);
8237ae0e2c9SDimitry Andric }
824dff0c46cSDimitry Andric
825f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
826f22ef01cSRoman Divacky // MachO
827f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
828f22ef01cSRoman Divacky
TargetLoweringObjectFileMachO()829ff0cc061SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO()
830ff0cc061SDimitry Andric : TargetLoweringObjectFile() {
831ff0cc061SDimitry Andric SupportIndirectSymViaGOTPCRel = true;
832ff0cc061SDimitry Andric }
833ff0cc061SDimitry Andric
Initialize(MCContext & Ctx,const TargetMachine & TM)834d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
835d88c1a5aSDimitry Andric const TargetMachine &TM) {
836d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM);
837d88c1a5aSDimitry Andric if (TM.getRelocationModel() == Reloc::Static) {
838d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0,
839d88c1a5aSDimitry Andric SectionKind::getData());
840d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0,
841d88c1a5aSDimitry Andric SectionKind::getData());
842d88c1a5aSDimitry Andric } else {
843d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func",
844d88c1a5aSDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS,
845d88c1a5aSDimitry Andric SectionKind::getData());
846d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func",
847d88c1a5aSDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS,
848d88c1a5aSDimitry Andric SectionKind::getData());
849d88c1a5aSDimitry Andric }
850*b5893f02SDimitry Andric
851*b5893f02SDimitry Andric PersonalityEncoding =
852*b5893f02SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
853*b5893f02SDimitry Andric LSDAEncoding = dwarf::DW_EH_PE_pcrel;
854*b5893f02SDimitry Andric TTypeEncoding =
855*b5893f02SDimitry Andric dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
856d88c1a5aSDimitry Andric }
857d88c1a5aSDimitry Andric
emitModuleMetadata(MCStreamer & Streamer,Module & M) const8584ba319b5SDimitry Andric void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer,
8594ba319b5SDimitry Andric Module &M) const {
860139f7f9bSDimitry Andric // Emit the linker options if present.
86124d58133SDimitry Andric if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
8623ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) {
863139f7f9bSDimitry Andric SmallVector<std::string, 4> StrOptions;
8643ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands())
8653ca95b02SDimitry Andric StrOptions.push_back(cast<MDString>(Piece)->getString());
866139f7f9bSDimitry Andric Streamer.EmitLinkerOptions(StrOptions);
867139f7f9bSDimitry Andric }
868dff0c46cSDimitry Andric }
869dff0c46cSDimitry Andric
870db17bf38SDimitry Andric unsigned VersionVal = 0;
871db17bf38SDimitry Andric unsigned ImageInfoFlags = 0;
872db17bf38SDimitry Andric StringRef SectionVal;
87324d58133SDimitry Andric
87424d58133SDimitry Andric GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal);
875db17bf38SDimitry Andric
876dff0c46cSDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info.
877db17bf38SDimitry Andric if (SectionVal.empty())
878db17bf38SDimitry Andric return;
879dff0c46cSDimitry Andric
880dff0c46cSDimitry Andric StringRef Segment, Section;
881dff0c46cSDimitry Andric unsigned TAA = 0, StubSize = 0;
882dff0c46cSDimitry Andric bool TAAParsed;
883dff0c46cSDimitry Andric std::string ErrorCode =
884dff0c46cSDimitry Andric MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section,
885dff0c46cSDimitry Andric TAA, TAAParsed, StubSize);
886dff0c46cSDimitry Andric if (!ErrorCode.empty())
887dff0c46cSDimitry Andric // If invalid, report the error with report_fatal_error.
888dff0c46cSDimitry Andric report_fatal_error("Invalid section specifier '" + Section + "': " +
889dff0c46cSDimitry Andric ErrorCode + ".");
890dff0c46cSDimitry Andric
891dff0c46cSDimitry Andric // Get the section.
892ff0cc061SDimitry Andric MCSectionMachO *S = getContext().getMachOSection(
8937d523365SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData());
894dff0c46cSDimitry Andric Streamer.SwitchSection(S);
895dff0c46cSDimitry Andric Streamer.EmitLabel(getContext().
896ff0cc061SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO")));
897dff0c46cSDimitry Andric Streamer.EmitIntValue(VersionVal, 4);
8987ae0e2c9SDimitry Andric Streamer.EmitIntValue(ImageInfoFlags, 4);
899dff0c46cSDimitry Andric Streamer.AddBlankLine();
900dff0c46cSDimitry Andric }
901dff0c46cSDimitry Andric
checkMachOComdat(const GlobalValue * GV)90291bc56edSDimitry Andric static void checkMachOComdat(const GlobalValue *GV) {
90391bc56edSDimitry Andric const Comdat *C = GV->getComdat();
90491bc56edSDimitry Andric if (!C)
90591bc56edSDimitry Andric return;
90691bc56edSDimitry Andric
90791bc56edSDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() +
90891bc56edSDimitry Andric "' cannot be lowered.");
90991bc56edSDimitry Andric }
91091bc56edSDimitry Andric
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const911ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
912d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
913f22ef01cSRoman Divacky // Parse the section specifier and create it if valid.
914f22ef01cSRoman Divacky StringRef Segment, Section;
9153b0f4066SDimitry Andric unsigned TAA = 0, StubSize = 0;
9163b0f4066SDimitry Andric bool TAAParsed;
91791bc56edSDimitry Andric
918d88c1a5aSDimitry Andric checkMachOComdat(GO);
91991bc56edSDimitry Andric
920f22ef01cSRoman Divacky std::string ErrorCode =
921d88c1a5aSDimitry Andric MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section,
9223b0f4066SDimitry Andric TAA, TAAParsed, StubSize);
923f22ef01cSRoman Divacky if (!ErrorCode.empty()) {
924f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error.
925d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() +
926dff0c46cSDimitry Andric "' has an invalid section specifier '" +
927d88c1a5aSDimitry Andric GO->getSection() + "': " + ErrorCode + ".");
928f22ef01cSRoman Divacky }
929f22ef01cSRoman Divacky
930f22ef01cSRoman Divacky // Get the section.
931ff0cc061SDimitry Andric MCSectionMachO *S =
932f22ef01cSRoman Divacky getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind);
933f22ef01cSRoman Divacky
934dd6029ffSDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above,
935dd6029ffSDimitry Andric // use the value returned by getMachOSection() as a default.
9363b0f4066SDimitry Andric if (!TAAParsed)
937dd6029ffSDimitry Andric TAA = S->getTypeAndAttributes();
938dd6029ffSDimitry Andric
939f22ef01cSRoman Divacky // Okay, now that we got the section, verify that the TAA & StubSize agree.
940f22ef01cSRoman Divacky // If the user declared multiple globals with different section flags, we need
941f22ef01cSRoman Divacky // to reject it here.
942f22ef01cSRoman Divacky if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {
943f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error.
944d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() +
945f22ef01cSRoman Divacky "' section type or attributes does not match previous"
946f22ef01cSRoman Divacky " section specifier");
947f22ef01cSRoman Divacky }
948f22ef01cSRoman Divacky
949f22ef01cSRoman Divacky return S;
950f22ef01cSRoman Divacky }
951f22ef01cSRoman Divacky
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const952ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal(
953d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
954d88c1a5aSDimitry Andric checkMachOComdat(GO);
955f785676fSDimitry Andric
956f785676fSDimitry Andric // Handle thread local data.
957f785676fSDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection;
958f785676fSDimitry Andric if (Kind.isThreadData()) return TLSDataSection;
959f785676fSDimitry Andric
960f22ef01cSRoman Divacky if (Kind.isText())
961d88c1a5aSDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection;
962f22ef01cSRoman Divacky
963f22ef01cSRoman Divacky // If this is weak/linkonce, put this in a coalescable section, either in text
964f22ef01cSRoman Divacky // or data depending on if it is writable.
965d88c1a5aSDimitry Andric if (GO->isWeakForLinker()) {
966f22ef01cSRoman Divacky if (Kind.isReadOnly())
967f22ef01cSRoman Divacky return ConstTextCoalSection;
9684ba319b5SDimitry Andric if (Kind.isReadOnlyWithRel())
9694ba319b5SDimitry Andric return ConstDataCoalSection;
970f22ef01cSRoman Divacky return DataCoalSection;
971f22ef01cSRoman Divacky }
972f22ef01cSRoman Divacky
973f22ef01cSRoman Divacky // FIXME: Alignment check should be handled by section classifier.
974f22ef01cSRoman Divacky if (Kind.isMergeable1ByteCString() &&
975d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment(
976d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32)
977f22ef01cSRoman Divacky return CStringSection;
978f22ef01cSRoman Divacky
979f22ef01cSRoman Divacky // Do not put 16-bit arrays in the UString section if they have an
980f22ef01cSRoman Divacky // externally visible label, this runs into issues with certain linker
981f22ef01cSRoman Divacky // versions.
982d88c1a5aSDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() &&
983d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment(
984d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32)
985f22ef01cSRoman Divacky return UStringSection;
986f22ef01cSRoman Divacky
98739d628a0SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or
98839d628a0SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage.
989d88c1a5aSDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) {
990f22ef01cSRoman Divacky if (Kind.isMergeableConst4())
991f22ef01cSRoman Divacky return FourByteConstantSection;
992f22ef01cSRoman Divacky if (Kind.isMergeableConst8())
993f22ef01cSRoman Divacky return EightByteConstantSection;
99491bc56edSDimitry Andric if (Kind.isMergeableConst16())
995f22ef01cSRoman Divacky return SixteenByteConstantSection;
996f22ef01cSRoman Divacky }
997f22ef01cSRoman Divacky
998f22ef01cSRoman Divacky // Otherwise, if it is readonly, but not something we can specially optimize,
999f22ef01cSRoman Divacky // just drop it in .const.
1000f22ef01cSRoman Divacky if (Kind.isReadOnly())
1001f22ef01cSRoman Divacky return ReadOnlySection;
1002f22ef01cSRoman Divacky
1003f22ef01cSRoman Divacky // If this is marked const, put it into a const section. But if the dynamic
1004f22ef01cSRoman Divacky // linker needs to write to it, put it in the data segment.
1005f22ef01cSRoman Divacky if (Kind.isReadOnlyWithRel())
1006f22ef01cSRoman Divacky return ConstDataSection;
1007f22ef01cSRoman Divacky
1008f22ef01cSRoman Divacky // Put zero initialized globals with strong external linkage in the
1009f22ef01cSRoman Divacky // DATA, __common section with the .zerofill directive.
1010f22ef01cSRoman Divacky if (Kind.isBSSExtern())
1011f22ef01cSRoman Divacky return DataCommonSection;
1012f22ef01cSRoman Divacky
1013f22ef01cSRoman Divacky // Put zero initialized globals with local linkage in __DATA,__bss directive
1014f22ef01cSRoman Divacky // with the .zerofill directive (aka .lcomm).
1015f22ef01cSRoman Divacky if (Kind.isBSSLocal())
1016f22ef01cSRoman Divacky return DataBSSSection;
1017f22ef01cSRoman Divacky
1018f22ef01cSRoman Divacky // Otherwise, just drop the variable in the normal data section.
1019f22ef01cSRoman Divacky return DataSection;
1020f22ef01cSRoman Divacky }
1021f22ef01cSRoman Divacky
getSectionForConstant(const DataLayout & DL,SectionKind Kind,const Constant * C,unsigned & Align) const10227d523365SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant(
10233ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C,
10243ca95b02SDimitry Andric unsigned &Align) const {
1025f22ef01cSRoman Divacky // If this constant requires a relocation, we have to put it in the data
1026f22ef01cSRoman Divacky // segment, not in the text segment.
10277d523365SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel())
1028f22ef01cSRoman Divacky return ConstDataSection;
1029f22ef01cSRoman Divacky
1030f22ef01cSRoman Divacky if (Kind.isMergeableConst4())
1031f22ef01cSRoman Divacky return FourByteConstantSection;
1032f22ef01cSRoman Divacky if (Kind.isMergeableConst8())
1033f22ef01cSRoman Divacky return EightByteConstantSection;
103491bc56edSDimitry Andric if (Kind.isMergeableConst16())
1035f22ef01cSRoman Divacky return SixteenByteConstantSection;
1036f22ef01cSRoman Divacky return ReadOnlySection; // .const
1037f22ef01cSRoman Divacky }
1038f22ef01cSRoman Divacky
getTTypeGlobalReference(const GlobalValue * GV,unsigned Encoding,const TargetMachine & TM,MachineModuleInfo * MMI,MCStreamer & Streamer) const103991bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference(
1040d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,
1041d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const {
1042f22ef01cSRoman Divacky // The mach-o version of this method defaults to returning a stub reference.
1043f22ef01cSRoman Divacky
1044f22ef01cSRoman Divacky if (Encoding & DW_EH_PE_indirect) {
1045f22ef01cSRoman Divacky MachineModuleInfoMachO &MachOMMI =
1046f22ef01cSRoman Divacky MMI->getObjFileInfo<MachineModuleInfoMachO>();
1047f22ef01cSRoman Divacky
1048d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM);
1049f22ef01cSRoman Divacky
1050f22ef01cSRoman Divacky // Add information about the stub reference to MachOMMI so that the stub
1051f22ef01cSRoman Divacky // gets emitted by the asmprinter.
10523ca95b02SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
105391bc56edSDimitry Andric if (!StubSym.getPointer()) {
1054d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV);
1055f22ef01cSRoman Divacky StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
1056f22ef01cSRoman Divacky }
1057f22ef01cSRoman Divacky
1058f22ef01cSRoman Divacky return TargetLoweringObjectFile::
105997bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()),
10607a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer);
1061f22ef01cSRoman Divacky }
1062f22ef01cSRoman Divacky
1063d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM,
1064d88c1a5aSDimitry Andric MMI, Streamer);
1065f22ef01cSRoman Divacky }
1066f22ef01cSRoman Divacky
getCFIPersonalitySymbol(const GlobalValue * GV,const TargetMachine & TM,MachineModuleInfo * MMI) const106791bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol(
1068d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM,
10693b0f4066SDimitry Andric MachineModuleInfo *MMI) const {
10703b0f4066SDimitry Andric // The mach-o version of this method defaults to returning a stub reference.
10713b0f4066SDimitry Andric MachineModuleInfoMachO &MachOMMI =
10723b0f4066SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>();
10733b0f4066SDimitry Andric
1074d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM);
10753b0f4066SDimitry Andric
10763b0f4066SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub
10773b0f4066SDimitry Andric // gets emitted by the asmprinter.
1078dff0c46cSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
107991bc56edSDimitry Andric if (!StubSym.getPointer()) {
1080d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV);
10813b0f4066SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
10823b0f4066SDimitry Andric }
10833b0f4066SDimitry Andric
10843b0f4066SDimitry Andric return SSym;
10853b0f4066SDimitry Andric }
10863b0f4066SDimitry Andric
getIndirectSymViaGOTPCRel(const MCSymbol * Sym,const MCValue & MV,int64_t Offset,MachineModuleInfo * MMI,MCStreamer & Streamer) const1087ff0cc061SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel(
1088ff0cc061SDimitry Andric const MCSymbol *Sym, const MCValue &MV, int64_t Offset,
1089ff0cc061SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const {
10907d523365SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation
1091ff0cc061SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol
1092ff0cc061SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the
1093ff0cc061SDimitry Andric // computation of deltas to final external symbols. Example:
1094ff0cc061SDimitry Andric //
1095ff0cc061SDimitry Andric // _extgotequiv:
1096ff0cc061SDimitry Andric // .long _extfoo
1097ff0cc061SDimitry Andric //
1098ff0cc061SDimitry Andric // _delta:
1099ff0cc061SDimitry Andric // .long _extgotequiv-_delta
1100ff0cc061SDimitry Andric //
1101ff0cc061SDimitry Andric // is transformed to:
1102ff0cc061SDimitry Andric //
1103ff0cc061SDimitry Andric // _delta:
1104ff0cc061SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0)
1105ff0cc061SDimitry Andric //
1106ff0cc061SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers
1107ff0cc061SDimitry Andric // L_extfoo$non_lazy_ptr:
1108ff0cc061SDimitry Andric // .indirect_symbol _extfoo
1109ff0cc061SDimitry Andric // .long 0
1110ff0cc061SDimitry Andric //
1111*b5893f02SDimitry Andric // The indirect symbol table (and sections of non_lazy_symbol_pointers type)
1112*b5893f02SDimitry Andric // may point to both local (same translation unit) and global (other
1113*b5893f02SDimitry Andric // translation units) symbols. Example:
1114*b5893f02SDimitry Andric //
1115*b5893f02SDimitry Andric // .section __DATA,__pointers,non_lazy_symbol_pointers
1116*b5893f02SDimitry Andric // L1:
1117*b5893f02SDimitry Andric // .indirect_symbol _myGlobal
1118*b5893f02SDimitry Andric // .long 0
1119*b5893f02SDimitry Andric // L2:
1120*b5893f02SDimitry Andric // .indirect_symbol _myLocal
1121*b5893f02SDimitry Andric // .long _myLocal
1122*b5893f02SDimitry Andric //
1123*b5893f02SDimitry Andric // If the symbol is local, instead of the symbol's index, the assembler
1124*b5893f02SDimitry Andric // places the constant INDIRECT_SYMBOL_LOCAL into the indirect symbol table.
1125*b5893f02SDimitry Andric // Then the linker will notice the constant in the table and will look at the
1126*b5893f02SDimitry Andric // content of the symbol.
1127ff0cc061SDimitry Andric MachineModuleInfoMachO &MachOMMI =
1128ff0cc061SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>();
1129ff0cc061SDimitry Andric MCContext &Ctx = getContext();
1130ff0cc061SDimitry Andric
1131ff0cc061SDimitry Andric // The offset must consider the original displacement from the base symbol
1132ff0cc061SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement.
1133ff0cc061SDimitry Andric Offset = -MV.getConstant();
1134ff0cc061SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol();
1135ff0cc061SDimitry Andric
1136ff0cc061SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated
1137ff0cc061SDimitry Andric // non_lazy_ptr stubs.
1138ff0cc061SDimitry Andric SmallString<128> Name;
1139ff0cc061SDimitry Andric StringRef Suffix = "$non_lazy_ptr";
11407d523365SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix();
1141ff0cc061SDimitry Andric Name += Sym->getName();
1142ff0cc061SDimitry Andric Name += Suffix;
1143ff0cc061SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name);
1144ff0cc061SDimitry Andric
1145ff0cc061SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub);
1146*b5893f02SDimitry Andric if (!StubSym.getPointer()) {
1147*b5893f02SDimitry Andric bool IsIndirectLocal = Sym->isDefined() && !Sym->isExternal();
1148*b5893f02SDimitry Andric // With the assumption that IsIndirectLocal == GV->hasLocalLinkage().
1149*b5893f02SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym),
1150*b5893f02SDimitry Andric !IsIndirectLocal);
1151*b5893f02SDimitry Andric }
1152ff0cc061SDimitry Andric
1153ff0cc061SDimitry Andric const MCExpr *BSymExpr =
115497bc6c73SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx);
1155ff0cc061SDimitry Andric const MCExpr *LHS =
115697bc6c73SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx);
1157ff0cc061SDimitry Andric
1158ff0cc061SDimitry Andric if (!Offset)
115997bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx);
1160ff0cc061SDimitry Andric
1161ff0cc061SDimitry Andric const MCExpr *RHS =
116297bc6c73SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx);
116397bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx);
1164ff0cc061SDimitry Andric }
1165ff0cc061SDimitry Andric
canUsePrivateLabel(const MCAsmInfo & AsmInfo,const MCSection & Section)11667d523365SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo,
11677d523365SDimitry Andric const MCSection &Section) {
11687d523365SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section))
11697d523365SDimitry Andric return true;
11707d523365SDimitry Andric
11717d523365SDimitry Andric // If it is not dead stripped, it is safe to use private labels.
11727d523365SDimitry Andric const MCSectionMachO &SMO = cast<MCSectionMachO>(Section);
11737d523365SDimitry Andric if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP))
11747d523365SDimitry Andric return true;
11757d523365SDimitry Andric
11767d523365SDimitry Andric return false;
11777d523365SDimitry Andric }
11787d523365SDimitry Andric
getNameWithPrefix(SmallVectorImpl<char> & OutName,const GlobalValue * GV,const TargetMachine & TM) const11797d523365SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix(
1180d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV,
11817d523365SDimitry Andric const TargetMachine &TM) const {
1182d88c1a5aSDimitry Andric bool CannotUsePrivateLabel = true;
1183d88c1a5aSDimitry Andric if (auto *GO = GV->getBaseObject()) {
1184d88c1a5aSDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM);
1185d88c1a5aSDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM);
1186d88c1a5aSDimitry Andric CannotUsePrivateLabel =
11877d523365SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection);
1188d88c1a5aSDimitry Andric }
1189d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);
11907d523365SDimitry Andric }
11917d523365SDimitry Andric
1192f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
1193f22ef01cSRoman Divacky // COFF
1194f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
1195f22ef01cSRoman Divacky
1196f22ef01cSRoman Divacky static unsigned
getCOFFSectionFlags(SectionKind K,const TargetMachine & TM)11973ca95b02SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) {
1198f22ef01cSRoman Divacky unsigned Flags = 0;
11993ca95b02SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb;
1200f22ef01cSRoman Divacky
1201ffd1746dSEd Schouten if (K.isMetadata())
1202f22ef01cSRoman Divacky Flags |=
1203ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_DISCARDABLE;
1204f22ef01cSRoman Divacky else if (K.isText())
1205f22ef01cSRoman Divacky Flags |=
1206ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_EXECUTE |
12072754fe60SDimitry Andric COFF::IMAGE_SCN_MEM_READ |
12083ca95b02SDimitry Andric COFF::IMAGE_SCN_CNT_CODE |
12093ca95b02SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0);
1210f22ef01cSRoman Divacky else if (K.isBSS())
1211f22ef01cSRoman Divacky Flags |=
1212ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
1213ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ |
1214ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE;
1215dff0c46cSDimitry Andric else if (K.isThreadLocal())
1216dff0c46cSDimitry Andric Flags |=
1217dff0c46cSDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1218dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_READ |
1219dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE;
122039d628a0SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel())
1221f22ef01cSRoman Divacky Flags |=
1222ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1223ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ;
1224f22ef01cSRoman Divacky else if (K.isWriteable())
1225f22ef01cSRoman Divacky Flags |=
1226ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1227ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ |
1228ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE;
1229f22ef01cSRoman Divacky
1230f22ef01cSRoman Divacky return Flags;
1231f22ef01cSRoman Divacky }
1232f22ef01cSRoman Divacky
getComdatGVForCOFF(const GlobalValue * GV)123391bc56edSDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) {
123491bc56edSDimitry Andric const Comdat *C = GV->getComdat();
123591bc56edSDimitry Andric assert(C && "expected GV to have a Comdat!");
123691bc56edSDimitry Andric
123791bc56edSDimitry Andric StringRef ComdatGVName = C->getName();
123891bc56edSDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName);
123991bc56edSDimitry Andric if (!ComdatGV)
124091bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +
124191bc56edSDimitry Andric "' does not exist.");
124291bc56edSDimitry Andric
124391bc56edSDimitry Andric if (ComdatGV->getComdat() != C)
124491bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +
124539d628a0SDimitry Andric "' is not a key for its COMDAT.");
124691bc56edSDimitry Andric
124791bc56edSDimitry Andric return ComdatGV;
124891bc56edSDimitry Andric }
124991bc56edSDimitry Andric
getSelectionForCOFF(const GlobalValue * GV)125091bc56edSDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) {
125191bc56edSDimitry Andric if (const Comdat *C = GV->getComdat()) {
125291bc56edSDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV);
125391bc56edSDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey))
125491bc56edSDimitry Andric ComdatKey = GA->getBaseObject();
125591bc56edSDimitry Andric if (ComdatKey == GV) {
125691bc56edSDimitry Andric switch (C->getSelectionKind()) {
125791bc56edSDimitry Andric case Comdat::Any:
125891bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY;
125991bc56edSDimitry Andric case Comdat::ExactMatch:
126091bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH;
126191bc56edSDimitry Andric case Comdat::Largest:
126291bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST;
126391bc56edSDimitry Andric case Comdat::NoDuplicates:
126491bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;
126591bc56edSDimitry Andric case Comdat::SameSize:
126691bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE;
126791bc56edSDimitry Andric }
126891bc56edSDimitry Andric } else {
126991bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
127091bc56edSDimitry Andric }
127191bc56edSDimitry Andric }
127291bc56edSDimitry Andric return 0;
127391bc56edSDimitry Andric }
127491bc56edSDimitry Andric
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const1275ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
1276d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
1277139f7f9bSDimitry Andric int Selection = 0;
12783ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
1279d88c1a5aSDimitry Andric StringRef Name = GO->getSection();
128091bc56edSDimitry Andric StringRef COMDATSymName = "";
1281d88c1a5aSDimitry Andric if (GO->hasComdat()) {
1282d88c1a5aSDimitry Andric Selection = getSelectionForCOFF(GO);
128391bc56edSDimitry Andric const GlobalValue *ComdatGV;
128491bc56edSDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
1285d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO);
128691bc56edSDimitry Andric else
1287d88c1a5aSDimitry Andric ComdatGV = GO;
128891bc56edSDimitry Andric
128991bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) {
1290d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV);
129191bc56edSDimitry Andric COMDATSymName = Sym->getName();
1292139f7f9bSDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
129391bc56edSDimitry Andric } else {
129491bc56edSDimitry Andric Selection = 0;
129591bc56edSDimitry Andric }
1296139f7f9bSDimitry Andric }
12973ca95b02SDimitry Andric
12983ca95b02SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
1299f785676fSDimitry Andric Selection);
1300f22ef01cSRoman Divacky }
1301f22ef01cSRoman Divacky
getCOFFSectionNameForUniqueGlobal(SectionKind Kind)13024ba319b5SDimitry Andric static StringRef getCOFFSectionNameForUniqueGlobal(SectionKind Kind) {
1303f22ef01cSRoman Divacky if (Kind.isText())
130491bc56edSDimitry Andric return ".text";
1305f22ef01cSRoman Divacky if (Kind.isBSS())
130691bc56edSDimitry Andric return ".bss";
130791bc56edSDimitry Andric if (Kind.isThreadLocal())
130891bc56edSDimitry Andric return ".tls$";
130939d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())
131091bc56edSDimitry Andric return ".rdata";
131139d628a0SDimitry Andric return ".data";
1312f22ef01cSRoman Divacky }
1313f22ef01cSRoman Divacky
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const1314ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
1315d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
131691bc56edSDimitry Andric // If we have -ffunction-sections then we should emit the global value to a
131791bc56edSDimitry Andric // uniqued section specifically for it.
131891bc56edSDimitry Andric bool EmitUniquedSection;
131991bc56edSDimitry Andric if (Kind.isText())
132091bc56edSDimitry Andric EmitUniquedSection = TM.getFunctionSections();
132191bc56edSDimitry Andric else
132291bc56edSDimitry Andric EmitUniquedSection = TM.getDataSections();
1323f22ef01cSRoman Divacky
1324d88c1a5aSDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) {
13254ba319b5SDimitry Andric SmallString<256> Name = getCOFFSectionNameForUniqueGlobal(Kind);
13264ba319b5SDimitry Andric
13273ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
1328f22ef01cSRoman Divacky
1329ffd1746dSEd Schouten Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
1330d88c1a5aSDimitry Andric int Selection = getSelectionForCOFF(GO);
133191bc56edSDimitry Andric if (!Selection)
133291bc56edSDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;
133391bc56edSDimitry Andric const GlobalValue *ComdatGV;
1334d88c1a5aSDimitry Andric if (GO->hasComdat())
1335d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO);
133691bc56edSDimitry Andric else
1337d88c1a5aSDimitry Andric ComdatGV = GO;
1338f22ef01cSRoman Divacky
13393ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID;
13403ca95b02SDimitry Andric if (EmitUniquedSection)
13413ca95b02SDimitry Andric UniqueID = NextUniqueID++;
13423ca95b02SDimitry Andric
134391bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) {
1344d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV);
134591bc56edSDimitry Andric StringRef COMDATSymName = Sym->getName();
13464ba319b5SDimitry Andric
13474ba319b5SDimitry Andric // Append "$symbol" to the section name *before* IR-level mangling is
13484ba319b5SDimitry Andric // applied when targetting mingw. This is what GCC does, and the ld.bfd
13494ba319b5SDimitry Andric // COFF linker will not properly handle comdats otherwise.
13504ba319b5SDimitry Andric if (getTargetTriple().isWindowsGNUEnvironment())
13514ba319b5SDimitry Andric raw_svector_ostream(Name) << '$' << ComdatGV->getName();
13524ba319b5SDimitry Andric
135391bc56edSDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind,
13543ca95b02SDimitry Andric COMDATSymName, Selection, UniqueID);
1355ff0cc061SDimitry Andric } else {
1356ff0cc061SDimitry Andric SmallString<256> TmpData;
1357d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true);
1358ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData,
13593ca95b02SDimitry Andric Selection, UniqueID);
136091bc56edSDimitry Andric }
1361f22ef01cSRoman Divacky }
1362f22ef01cSRoman Divacky
1363f22ef01cSRoman Divacky if (Kind.isText())
1364f785676fSDimitry Andric return TextSection;
1365f22ef01cSRoman Divacky
1366dff0c46cSDimitry Andric if (Kind.isThreadLocal())
1367f785676fSDimitry Andric return TLSDataSection;
1368dff0c46cSDimitry Andric
136939d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())
1370f785676fSDimitry Andric return ReadOnlySection;
1371f785676fSDimitry Andric
137291bc56edSDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are
137391bc56edSDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table
137491bc56edSDimitry Andric // entry but not a section.
137591bc56edSDimitry Andric if (Kind.isBSS() || Kind.isCommon())
1376f785676fSDimitry Andric return BSSSection;
1377f785676fSDimitry Andric
1378f785676fSDimitry Andric return DataSection;
1379f22ef01cSRoman Divacky }
1380f22ef01cSRoman Divacky
getNameWithPrefix(SmallVectorImpl<char> & OutName,const GlobalValue * GV,const TargetMachine & TM) const1381ff0cc061SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix(
1382d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV,
13837d523365SDimitry Andric const TargetMachine &TM) const {
13847d523365SDimitry Andric bool CannotUsePrivateLabel = false;
1385ff0cc061SDimitry Andric if (GV->hasPrivateLinkage() &&
1386ff0cc061SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) ||
1387ff0cc061SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections())))
1388ff0cc061SDimitry Andric CannotUsePrivateLabel = true;
1389ff0cc061SDimitry Andric
1390d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);
1391ff0cc061SDimitry Andric }
1392ff0cc061SDimitry Andric
getSectionForJumpTable(const Function & F,const TargetMachine & TM) const1393ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
1394d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const {
1395ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that
1396ff0cc061SDimitry Andric // the table doesn't prevent the removal.
1397ff0cc061SDimitry Andric const Comdat *C = F.getComdat();
1398ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C;
1399ff0cc061SDimitry Andric if (!EmitUniqueSection)
1400ff0cc061SDimitry Andric return ReadOnlySection;
1401ff0cc061SDimitry Andric
1402ff0cc061SDimitry Andric // FIXME: we should produce a symbol for F instead.
1403ff0cc061SDimitry Andric if (F.hasPrivateLinkage())
1404ff0cc061SDimitry Andric return ReadOnlySection;
1405ff0cc061SDimitry Andric
1406d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(&F);
1407ff0cc061SDimitry Andric StringRef COMDATSymName = Sym->getName();
1408ff0cc061SDimitry Andric
1409ff0cc061SDimitry Andric SectionKind Kind = SectionKind::getReadOnly();
14104ba319b5SDimitry Andric StringRef SecName = getCOFFSectionNameForUniqueGlobal(Kind);
14113ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM);
1412ff0cc061SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
14133ca95b02SDimitry Andric unsigned UniqueID = NextUniqueID++;
1414ff0cc061SDimitry Andric
14154ba319b5SDimitry Andric return getContext().getCOFFSection(
14164ba319b5SDimitry Andric SecName, Characteristics, Kind, COMDATSymName,
14173ca95b02SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
1418ff0cc061SDimitry Andric }
1419ff0cc061SDimitry Andric
emitModuleMetadata(MCStreamer & Streamer,Module & M) const14204ba319b5SDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
14214ba319b5SDimitry Andric Module &M) const {
142224d58133SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
1423284c1978SDimitry Andric // Emit the linker options to the linker .drectve section. According to the
14243ca95b02SDimitry Andric // spec, this section is a space-separated string containing flags for
14253ca95b02SDimitry Andric // linker.
1426ff0cc061SDimitry Andric MCSection *Sec = getDrectveSection();
1427284c1978SDimitry Andric Streamer.SwitchSection(Sec);
14283ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) {
14293ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) {
1430284c1978SDimitry Andric // Lead with a space for consistency with our dllexport implementation.
1431ff0cc061SDimitry Andric std::string Directive(" ");
14323ca95b02SDimitry Andric Directive.append(cast<MDString>(Piece)->getString());
1433ff0cc061SDimitry Andric Streamer.EmitBytes(Directive);
1434284c1978SDimitry Andric }
1435284c1978SDimitry Andric }
1436284c1978SDimitry Andric }
1437db17bf38SDimitry Andric
1438db17bf38SDimitry Andric unsigned Version = 0;
1439db17bf38SDimitry Andric unsigned Flags = 0;
1440db17bf38SDimitry Andric StringRef Section;
1441db17bf38SDimitry Andric
144224d58133SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section);
1443db17bf38SDimitry Andric if (Section.empty())
1444db17bf38SDimitry Andric return;
1445db17bf38SDimitry Andric
1446db17bf38SDimitry Andric auto &C = getContext();
1447db17bf38SDimitry Andric auto *S = C.getCOFFSection(
1448db17bf38SDimitry Andric Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
1449db17bf38SDimitry Andric SectionKind::getReadOnly());
1450db17bf38SDimitry Andric Streamer.SwitchSection(S);
1451db17bf38SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
1452db17bf38SDimitry Andric Streamer.EmitIntValue(Version, 4);
1453db17bf38SDimitry Andric Streamer.EmitIntValue(Flags, 4);
1454db17bf38SDimitry Andric Streamer.AddBlankLine();
14553ca95b02SDimitry Andric }
145691bc56edSDimitry Andric
Initialize(MCContext & Ctx,const TargetMachine & TM)1457d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
1458d88c1a5aSDimitry Andric const TargetMachine &TM) {
1459d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM);
1460d88c1a5aSDimitry Andric const Triple &T = TM.getTargetTriple();
1461d88c1a5aSDimitry Andric if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
1462d88c1a5aSDimitry Andric StaticCtorSection =
1463d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1464d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ,
1465d88c1a5aSDimitry Andric SectionKind::getReadOnly());
1466d88c1a5aSDimitry Andric StaticDtorSection =
1467d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1468d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ,
1469d88c1a5aSDimitry Andric SectionKind::getReadOnly());
1470d88c1a5aSDimitry Andric } else {
1471d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getCOFFSection(
1472d88c1a5aSDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1473d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE,
1474d88c1a5aSDimitry Andric SectionKind::getData());
1475d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getCOFFSection(
1476d88c1a5aSDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1477d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE,
1478d88c1a5aSDimitry Andric SectionKind::getData());
1479d88c1a5aSDimitry Andric }
1480d88c1a5aSDimitry Andric }
1481d88c1a5aSDimitry Andric
getCOFFStaticStructorSection(MCContext & Ctx,const Triple & T,bool IsCtor,unsigned Priority,const MCSymbol * KeySym,MCSectionCOFF * Default)14822cab237bSDimitry Andric static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx,
14832cab237bSDimitry Andric const Triple &T, bool IsCtor,
14842cab237bSDimitry Andric unsigned Priority,
14852cab237bSDimitry Andric const MCSymbol *KeySym,
14862cab237bSDimitry Andric MCSectionCOFF *Default) {
1487*b5893f02SDimitry Andric if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
1488*b5893f02SDimitry Andric // If the priority is the default, use .CRT$XCU, possibly associative.
1489*b5893f02SDimitry Andric if (Priority == 65535)
14902cab237bSDimitry Andric return Ctx.getAssociativeCOFFSection(Default, KeySym, 0);
14912cab237bSDimitry Andric
1492*b5893f02SDimitry Andric // Otherwise, we need to compute a new section name. Low priorities should
1493*b5893f02SDimitry Andric // run earlier. The linker will sort sections ASCII-betically, and we need a
1494*b5893f02SDimitry Andric // string that sorts between .CRT$XCA and .CRT$XCU. In the general case, we
1495*b5893f02SDimitry Andric // make a name like ".CRT$XCT12345", since that runs before .CRT$XCU. Really
1496*b5893f02SDimitry Andric // low priorities need to sort before 'L', since the CRT uses that
1497*b5893f02SDimitry Andric // internally, so we use ".CRT$XCA00001" for them.
1498*b5893f02SDimitry Andric SmallString<24> Name;
1499*b5893f02SDimitry Andric raw_svector_ostream OS(Name);
1500*b5893f02SDimitry Andric OS << ".CRT$XC" << (Priority < 200 ? 'A' : 'T') << format("%05u", Priority);
1501*b5893f02SDimitry Andric MCSectionCOFF *Sec = Ctx.getCOFFSection(
1502*b5893f02SDimitry Andric Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
1503*b5893f02SDimitry Andric SectionKind::getReadOnly());
1504*b5893f02SDimitry Andric return Ctx.getAssociativeCOFFSection(Sec, KeySym, 0);
1505*b5893f02SDimitry Andric }
1506*b5893f02SDimitry Andric
15072cab237bSDimitry Andric std::string Name = IsCtor ? ".ctors" : ".dtors";
15082cab237bSDimitry Andric if (Priority != 65535)
15092cab237bSDimitry Andric raw_string_ostream(Name) << format(".%05u", 65535 - Priority);
15102cab237bSDimitry Andric
15112cab237bSDimitry Andric return Ctx.getAssociativeCOFFSection(
15122cab237bSDimitry Andric Ctx.getCOFFSection(Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
15132cab237bSDimitry Andric COFF::IMAGE_SCN_MEM_READ |
15142cab237bSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE,
15152cab237bSDimitry Andric SectionKind::getData()),
15162cab237bSDimitry Andric KeySym, 0);
15172cab237bSDimitry Andric }
15182cab237bSDimitry Andric
getStaticCtorSection(unsigned Priority,const MCSymbol * KeySym) const1519ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
152091bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const {
15212cab237bSDimitry Andric return getCOFFStaticStructorSection(getContext(), getTargetTriple(), true,
15222cab237bSDimitry Andric Priority, KeySym,
15232cab237bSDimitry Andric cast<MCSectionCOFF>(StaticCtorSection));
152491bc56edSDimitry Andric }
152591bc56edSDimitry Andric
getStaticDtorSection(unsigned Priority,const MCSymbol * KeySym) const1526ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
152791bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const {
15282cab237bSDimitry Andric return getCOFFStaticStructorSection(getContext(), getTargetTriple(), false,
15292cab237bSDimitry Andric Priority, KeySym,
15302cab237bSDimitry Andric cast<MCSectionCOFF>(StaticDtorSection));
153191bc56edSDimitry Andric }
15323dac3a9bSDimitry Andric
emitLinkerFlagsForGlobal(raw_ostream & OS,const GlobalValue * GV) const15333dac3a9bSDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
1534d88c1a5aSDimitry Andric raw_ostream &OS, const GlobalValue *GV) const {
15357a7e6055SDimitry Andric emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler());
15363dac3a9bSDimitry Andric }
15373dac3a9bSDimitry Andric
emitLinkerFlagsForUsed(raw_ostream & OS,const GlobalValue * GV) const15384ba319b5SDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForUsed(
15394ba319b5SDimitry Andric raw_ostream &OS, const GlobalValue *GV) const {
15404ba319b5SDimitry Andric emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
15414ba319b5SDimitry Andric }
15424ba319b5SDimitry Andric
lowerRelativeReference(const GlobalValue * LHS,const GlobalValue * RHS,const TargetMachine & TM) const15434ba319b5SDimitry Andric const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
15444ba319b5SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS,
15454ba319b5SDimitry Andric const TargetMachine &TM) const {
15464ba319b5SDimitry Andric const Triple &T = TM.getTargetTriple();
15474ba319b5SDimitry Andric if (!T.isKnownWindowsMSVCEnvironment() &&
15484ba319b5SDimitry Andric !T.isWindowsItaniumEnvironment() &&
15494ba319b5SDimitry Andric !T.isWindowsCoreCLREnvironment())
15504ba319b5SDimitry Andric return nullptr;
15514ba319b5SDimitry Andric
15524ba319b5SDimitry Andric // Our symbols should exist in address space zero, cowardly no-op if
15534ba319b5SDimitry Andric // otherwise.
15544ba319b5SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 ||
15554ba319b5SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0)
15564ba319b5SDimitry Andric return nullptr;
15574ba319b5SDimitry Andric
15584ba319b5SDimitry Andric // Both ptrtoint instructions must wrap global objects:
15594ba319b5SDimitry Andric // - Only global variables are eligible for image relative relocations.
15604ba319b5SDimitry Andric // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable.
15614ba319b5SDimitry Andric // We expect __ImageBase to be a global variable without a section, externally
15624ba319b5SDimitry Andric // defined.
15634ba319b5SDimitry Andric //
15644ba319b5SDimitry Andric // It should look something like this: @__ImageBase = external constant i8
15654ba319b5SDimitry Andric if (!isa<GlobalObject>(LHS) || !isa<GlobalVariable>(RHS) ||
15664ba319b5SDimitry Andric LHS->isThreadLocal() || RHS->isThreadLocal() ||
15674ba319b5SDimitry Andric RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() ||
15684ba319b5SDimitry Andric cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection())
15694ba319b5SDimitry Andric return nullptr;
15704ba319b5SDimitry Andric
15714ba319b5SDimitry Andric return MCSymbolRefExpr::create(TM.getSymbol(LHS),
15724ba319b5SDimitry Andric MCSymbolRefExpr::VK_COFF_IMGREL32,
15734ba319b5SDimitry Andric getContext());
15744ba319b5SDimitry Andric }
15754ba319b5SDimitry Andric
APIntToHexString(const APInt & AI)15764ba319b5SDimitry Andric static std::string APIntToHexString(const APInt &AI) {
15774ba319b5SDimitry Andric unsigned Width = (AI.getBitWidth() / 8) * 2;
15784ba319b5SDimitry Andric std::string HexString = utohexstr(AI.getLimitedValue(), /*LowerCase=*/true);
15794ba319b5SDimitry Andric unsigned Size = HexString.size();
15804ba319b5SDimitry Andric assert(Width >= Size && "hex string is too large!");
15814ba319b5SDimitry Andric HexString.insert(HexString.begin(), Width - Size, '0');
15824ba319b5SDimitry Andric
15834ba319b5SDimitry Andric return HexString;
15844ba319b5SDimitry Andric }
15854ba319b5SDimitry Andric
scalarConstantToHexString(const Constant * C)15864ba319b5SDimitry Andric static std::string scalarConstantToHexString(const Constant *C) {
15874ba319b5SDimitry Andric Type *Ty = C->getType();
15884ba319b5SDimitry Andric if (isa<UndefValue>(C)) {
15894ba319b5SDimitry Andric return APIntToHexString(APInt::getNullValue(Ty->getPrimitiveSizeInBits()));
15904ba319b5SDimitry Andric } else if (const auto *CFP = dyn_cast<ConstantFP>(C)) {
15914ba319b5SDimitry Andric return APIntToHexString(CFP->getValueAPF().bitcastToAPInt());
15924ba319b5SDimitry Andric } else if (const auto *CI = dyn_cast<ConstantInt>(C)) {
15934ba319b5SDimitry Andric return APIntToHexString(CI->getValue());
15944ba319b5SDimitry Andric } else {
15954ba319b5SDimitry Andric unsigned NumElements;
15964ba319b5SDimitry Andric if (isa<VectorType>(Ty))
15974ba319b5SDimitry Andric NumElements = Ty->getVectorNumElements();
15984ba319b5SDimitry Andric else
15994ba319b5SDimitry Andric NumElements = Ty->getArrayNumElements();
16004ba319b5SDimitry Andric std::string HexString;
16014ba319b5SDimitry Andric for (int I = NumElements - 1, E = -1; I != E; --I)
16024ba319b5SDimitry Andric HexString += scalarConstantToHexString(C->getAggregateElement(I));
16034ba319b5SDimitry Andric return HexString;
16044ba319b5SDimitry Andric }
16054ba319b5SDimitry Andric }
16064ba319b5SDimitry Andric
getSectionForConstant(const DataLayout & DL,SectionKind Kind,const Constant * C,unsigned & Align) const16074ba319b5SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant(
16084ba319b5SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C,
16094ba319b5SDimitry Andric unsigned &Align) const {
16104ba319b5SDimitry Andric if (Kind.isMergeableConst() && C &&
16114ba319b5SDimitry Andric getContext().getAsmInfo()->hasCOFFComdatConstants()) {
16124ba319b5SDimitry Andric // This creates comdat sections with the given symbol name, but unless
16134ba319b5SDimitry Andric // AsmPrinter::GetCPISymbol actually makes the symbol global, the symbol
16144ba319b5SDimitry Andric // will be created with a null storage class, which makes GNU binutils
16154ba319b5SDimitry Andric // error out.
16164ba319b5SDimitry Andric const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
16174ba319b5SDimitry Andric COFF::IMAGE_SCN_MEM_READ |
16184ba319b5SDimitry Andric COFF::IMAGE_SCN_LNK_COMDAT;
16194ba319b5SDimitry Andric std::string COMDATSymName;
16204ba319b5SDimitry Andric if (Kind.isMergeableConst4()) {
16214ba319b5SDimitry Andric if (Align <= 4) {
16224ba319b5SDimitry Andric COMDATSymName = "__real@" + scalarConstantToHexString(C);
16234ba319b5SDimitry Andric Align = 4;
16244ba319b5SDimitry Andric }
16254ba319b5SDimitry Andric } else if (Kind.isMergeableConst8()) {
16264ba319b5SDimitry Andric if (Align <= 8) {
16274ba319b5SDimitry Andric COMDATSymName = "__real@" + scalarConstantToHexString(C);
16284ba319b5SDimitry Andric Align = 8;
16294ba319b5SDimitry Andric }
16304ba319b5SDimitry Andric } else if (Kind.isMergeableConst16()) {
16314ba319b5SDimitry Andric // FIXME: These may not be appropriate for non-x86 architectures.
16324ba319b5SDimitry Andric if (Align <= 16) {
16334ba319b5SDimitry Andric COMDATSymName = "__xmm@" + scalarConstantToHexString(C);
16344ba319b5SDimitry Andric Align = 16;
16354ba319b5SDimitry Andric }
16364ba319b5SDimitry Andric } else if (Kind.isMergeableConst32()) {
16374ba319b5SDimitry Andric if (Align <= 32) {
16384ba319b5SDimitry Andric COMDATSymName = "__ymm@" + scalarConstantToHexString(C);
16394ba319b5SDimitry Andric Align = 32;
16404ba319b5SDimitry Andric }
16414ba319b5SDimitry Andric }
16424ba319b5SDimitry Andric
16434ba319b5SDimitry Andric if (!COMDATSymName.empty())
16444ba319b5SDimitry Andric return getContext().getCOFFSection(".rdata", Characteristics, Kind,
16454ba319b5SDimitry Andric COMDATSymName,
16464ba319b5SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ANY);
16474ba319b5SDimitry Andric }
16484ba319b5SDimitry Andric
16494ba319b5SDimitry Andric return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, Align);
16504ba319b5SDimitry Andric }
16514ba319b5SDimitry Andric
16524ba319b5SDimitry Andric
16537a7e6055SDimitry Andric //===----------------------------------------------------------------------===//
16547a7e6055SDimitry Andric // Wasm
16557a7e6055SDimitry Andric //===----------------------------------------------------------------------===//
16567a7e6055SDimitry Andric
getWasmComdat(const GlobalValue * GV)16574ba319b5SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) {
16587a7e6055SDimitry Andric const Comdat *C = GV->getComdat();
16597a7e6055SDimitry Andric if (!C)
16604ba319b5SDimitry Andric return nullptr;
16617a7e6055SDimitry Andric
16624ba319b5SDimitry Andric if (C->getSelectionKind() != Comdat::Any)
16634ba319b5SDimitry Andric report_fatal_error("WebAssembly COMDATs only support "
16644ba319b5SDimitry Andric "SelectionKind::Any, '" + C->getName() + "' cannot be "
16654ba319b5SDimitry Andric "lowered.");
16664ba319b5SDimitry Andric
16674ba319b5SDimitry Andric return C;
16682cab237bSDimitry Andric }
16697a7e6055SDimitry Andric
getWasmKindForNamedSection(StringRef Name,SectionKind K)16702cab237bSDimitry Andric static SectionKind getWasmKindForNamedSection(StringRef Name, SectionKind K) {
16712cab237bSDimitry Andric // If we're told we have function data, then use that.
16722cab237bSDimitry Andric if (K.isText())
16732cab237bSDimitry Andric return SectionKind::getText();
16742cab237bSDimitry Andric
16752cab237bSDimitry Andric // Otherwise, ignore whatever section type the generic impl detected and use
16762cab237bSDimitry Andric // a plain data section.
16772cab237bSDimitry Andric return SectionKind::getData();
16783dac3a9bSDimitry Andric }
16797a7e6055SDimitry Andric
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const16807a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(
16817a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
16824ba319b5SDimitry Andric // We don't support explict section names for functions in the wasm object
16834ba319b5SDimitry Andric // format. Each function has to be in its own unique section.
16844ba319b5SDimitry Andric if (isa<Function>(GO)) {
16854ba319b5SDimitry Andric return SelectSectionForGlobal(GO, Kind, TM);
16864ba319b5SDimitry Andric }
16874ba319b5SDimitry Andric
16882cab237bSDimitry Andric StringRef Name = GO->getSection();
16894ba319b5SDimitry Andric
16902cab237bSDimitry Andric Kind = getWasmKindForNamedSection(Name, Kind);
16914ba319b5SDimitry Andric
16924ba319b5SDimitry Andric StringRef Group = "";
16934ba319b5SDimitry Andric if (const Comdat *C = getWasmComdat(GO)) {
16944ba319b5SDimitry Andric Group = C->getName();
16954ba319b5SDimitry Andric }
16964ba319b5SDimitry Andric
16974ba319b5SDimitry Andric return getContext().getWasmSection(Name, Kind, Group,
16984ba319b5SDimitry Andric MCContext::GenericSectionID);
16997a7e6055SDimitry Andric }
17007a7e6055SDimitry Andric
selectWasmSectionForGlobal(MCContext & Ctx,const GlobalObject * GO,SectionKind Kind,Mangler & Mang,const TargetMachine & TM,bool EmitUniqueSection,unsigned * NextUniqueID)17012cab237bSDimitry Andric static MCSectionWasm *selectWasmSectionForGlobal(
17022cab237bSDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
17032cab237bSDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) {
17047a7e6055SDimitry Andric StringRef Group = "";
17054ba319b5SDimitry Andric if (const Comdat *C = getWasmComdat(GO)) {
17064ba319b5SDimitry Andric Group = C->getName();
17074ba319b5SDimitry Andric }
17087a7e6055SDimitry Andric
17097a7e6055SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames();
17107a7e6055SDimitry Andric SmallString<128> Name = getSectionPrefixForGlobal(Kind);
17117a7e6055SDimitry Andric
17127a7e6055SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) {
17137a7e6055SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix();
17147a7e6055SDimitry Andric if (OptionalPrefix)
17157a7e6055SDimitry Andric Name += *OptionalPrefix;
17167a7e6055SDimitry Andric }
17177a7e6055SDimitry Andric
17187a7e6055SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) {
17197a7e6055SDimitry Andric Name.push_back('.');
17207a7e6055SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true);
17217a7e6055SDimitry Andric }
17227a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID;
17237a7e6055SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) {
17247a7e6055SDimitry Andric UniqueID = *NextUniqueID;
17257a7e6055SDimitry Andric (*NextUniqueID)++;
17267a7e6055SDimitry Andric }
17272cab237bSDimitry Andric return Ctx.getWasmSection(Name, Kind, Group, UniqueID);
17287a7e6055SDimitry Andric }
17297a7e6055SDimitry Andric
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const17307a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal(
17317a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
17327a7e6055SDimitry Andric
17337a7e6055SDimitry Andric if (Kind.isCommon())
17347a7e6055SDimitry Andric report_fatal_error("mergable sections not supported yet on wasm");
17357a7e6055SDimitry Andric
17367a7e6055SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the
17377a7e6055SDimitry Andric // global value to a uniqued section specifically for it.
17387a7e6055SDimitry Andric bool EmitUniqueSection = false;
17397a7e6055SDimitry Andric if (Kind.isText())
17407a7e6055SDimitry Andric EmitUniqueSection = TM.getFunctionSections();
17417a7e6055SDimitry Andric else
17427a7e6055SDimitry Andric EmitUniqueSection = TM.getDataSections();
17437a7e6055SDimitry Andric EmitUniqueSection |= GO->hasComdat();
17447a7e6055SDimitry Andric
17457a7e6055SDimitry Andric return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
17462cab237bSDimitry Andric EmitUniqueSection, &NextUniqueID);
17477a7e6055SDimitry Andric }
17487a7e6055SDimitry Andric
shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,const Function & F) const17497a7e6055SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection(
17507a7e6055SDimitry Andric bool UsesLabelDifference, const Function &F) const {
17517a7e6055SDimitry Andric // We can always create relative relocations, so use another section
17527a7e6055SDimitry Andric // that can be marked non-executable.
17537a7e6055SDimitry Andric return false;
17547a7e6055SDimitry Andric }
17557a7e6055SDimitry Andric
lowerRelativeReference(const GlobalValue * LHS,const GlobalValue * RHS,const TargetMachine & TM) const17567a7e6055SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference(
17577a7e6055SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS,
17587a7e6055SDimitry Andric const TargetMachine &TM) const {
17597a7e6055SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr
17607a7e6055SDimitry Andric // functions.
17617a7e6055SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
17627a7e6055SDimitry Andric return nullptr;
17637a7e6055SDimitry Andric
17647a7e6055SDimitry Andric // Basic sanity checks.
17657a7e6055SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 ||
17667a7e6055SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() ||
17677a7e6055SDimitry Andric RHS->isThreadLocal())
17687a7e6055SDimitry Andric return nullptr;
17697a7e6055SDimitry Andric
17707a7e6055SDimitry Andric return MCBinaryExpr::createSub(
17717a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None,
17727a7e6055SDimitry Andric getContext()),
17737a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
17747a7e6055SDimitry Andric }
17757a7e6055SDimitry Andric
InitializeWasm()17762cab237bSDimitry Andric void TargetLoweringObjectFileWasm::InitializeWasm() {
17772cab237bSDimitry Andric StaticCtorSection =
17782cab237bSDimitry Andric getContext().getWasmSection(".init_array", SectionKind::getData());
1779*b5893f02SDimitry Andric
1780*b5893f02SDimitry Andric // We don't use PersonalityEncoding and LSDAEncoding because we don't emit
1781*b5893f02SDimitry Andric // .cfi directives. We use TTypeEncoding to encode typeinfo global variables.
1782*b5893f02SDimitry Andric TTypeEncoding = dwarf::DW_EH_PE_absptr;
17832cab237bSDimitry Andric }
17842cab237bSDimitry Andric
getStaticCtorSection(unsigned Priority,const MCSymbol * KeySym) const17852cab237bSDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticCtorSection(
17862cab237bSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const {
17872cab237bSDimitry Andric return Priority == UINT16_MAX ?
17882cab237bSDimitry Andric StaticCtorSection :
17892cab237bSDimitry Andric getContext().getWasmSection(".init_array." + utostr(Priority),
17902cab237bSDimitry Andric SectionKind::getData());
17912cab237bSDimitry Andric }
17922cab237bSDimitry Andric
getStaticDtorSection(unsigned Priority,const MCSymbol * KeySym) const17932cab237bSDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection(
17942cab237bSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const {
17952cab237bSDimitry Andric llvm_unreachable("@llvm.global_dtors should have been lowered already");
17962cab237bSDimitry Andric return nullptr;
17973dac3a9bSDimitry Andric }
1798