/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/CodeGen/TargetLoweringObjectFileImpl.cpp - Object File Info ---===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file implements classes used to handle lowerings specific to common |
11 | | // object file formats. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" |
16 | | #include "llvm/ADT/SmallString.h" |
17 | | #include "llvm/ADT/SmallVector.h" |
18 | | #include "llvm/ADT/StringExtras.h" |
19 | | #include "llvm/ADT/StringRef.h" |
20 | | #include "llvm/ADT/Triple.h" |
21 | | #include "llvm/BinaryFormat/COFF.h" |
22 | | #include "llvm/BinaryFormat/Dwarf.h" |
23 | | #include "llvm/BinaryFormat/ELF.h" |
24 | | #include "llvm/BinaryFormat/MachO.h" |
25 | | #include "llvm/CodeGen/MachineModuleInfo.h" |
26 | | #include "llvm/CodeGen/MachineModuleInfoImpls.h" |
27 | | #include "llvm/IR/Comdat.h" |
28 | | #include "llvm/IR/Constants.h" |
29 | | #include "llvm/IR/DataLayout.h" |
30 | | #include "llvm/IR/DerivedTypes.h" |
31 | | #include "llvm/IR/Function.h" |
32 | | #include "llvm/IR/GlobalAlias.h" |
33 | | #include "llvm/IR/GlobalObject.h" |
34 | | #include "llvm/IR/GlobalValue.h" |
35 | | #include "llvm/IR/GlobalVariable.h" |
36 | | #include "llvm/IR/Mangler.h" |
37 | | #include "llvm/IR/Metadata.h" |
38 | | #include "llvm/IR/Module.h" |
39 | | #include "llvm/IR/Type.h" |
40 | | #include "llvm/MC/MCAsmInfo.h" |
41 | | #include "llvm/MC/MCContext.h" |
42 | | #include "llvm/MC/MCExpr.h" |
43 | | #include "llvm/MC/MCSectionCOFF.h" |
44 | | #include "llvm/MC/MCSectionELF.h" |
45 | | #include "llvm/MC/MCSectionMachO.h" |
46 | | #include "llvm/MC/MCSectionWasm.h" |
47 | | #include "llvm/MC/MCStreamer.h" |
48 | | #include "llvm/MC/MCSymbol.h" |
49 | | #include "llvm/MC/MCSymbolELF.h" |
50 | | #include "llvm/MC/MCValue.h" |
51 | | #include "llvm/MC/SectionKind.h" |
52 | | #include "llvm/ProfileData/InstrProf.h" |
53 | | #include "llvm/Support/Casting.h" |
54 | | #include "llvm/Support/CodeGen.h" |
55 | | #include "llvm/Support/ErrorHandling.h" |
56 | | #include "llvm/Support/raw_ostream.h" |
57 | | #include "llvm/Target/TargetMachine.h" |
58 | | #include <cassert> |
59 | | #include <string> |
60 | | |
61 | | using namespace llvm; |
62 | | using namespace dwarf; |
63 | | |
64 | | static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, |
65 | 33.1k | StringRef &Section) { |
66 | 33.1k | SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; |
67 | 33.1k | M.getModuleFlagsMetadata(ModuleFlags); |
68 | 33.1k | |
69 | 47.2k | for (const auto &MFE: ModuleFlags) { |
70 | 47.2k | // Ignore flags with 'Require' behaviour. |
71 | 47.2k | if (MFE.Behavior == Module::Require) |
72 | 0 | continue; |
73 | 47.2k | |
74 | 47.2k | StringRef Key = MFE.Key->getString(); |
75 | 47.2k | if (Key == "Objective-C Image Info Version"47.2k ) { |
76 | 110 | Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); |
77 | 47.2k | } else if (47.1k Key == "Objective-C Garbage Collection" || |
78 | 47.0k | Key == "Objective-C GC Only" || |
79 | 47.0k | Key == "Objective-C Is Simulated" || |
80 | 47.0k | Key == "Objective-C Class Properties" || |
81 | 47.1k | Key == "Objective-C Image Swift Version"46.9k ) { |
82 | 220 | Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); |
83 | 47.1k | } else if (46.9k Key == "Objective-C Image Info Section"46.9k ) { |
84 | 110 | Section = cast<MDString>(MFE.Val)->getString(); |
85 | 110 | } |
86 | 47.2k | } |
87 | 33.1k | } |
88 | | |
89 | | //===----------------------------------------------------------------------===// |
90 | | // ELF |
91 | | //===----------------------------------------------------------------------===// |
92 | | |
93 | | void TargetLoweringObjectFileELF::emitModuleMetadata( |
94 | 12.8k | MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { |
95 | 12.8k | unsigned Version = 0; |
96 | 12.8k | unsigned Flags = 0; |
97 | 12.8k | StringRef Section; |
98 | 12.8k | |
99 | 12.8k | GetObjCImageInfo(M, Version, Flags, Section); |
100 | 12.8k | if (Section.empty()) |
101 | 12.8k | return; |
102 | 5 | |
103 | 5 | auto &C = getContext(); |
104 | 5 | auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); |
105 | 5 | Streamer.SwitchSection(S); |
106 | 5 | Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); |
107 | 5 | Streamer.EmitIntValue(Version, 4); |
108 | 5 | Streamer.EmitIntValue(Flags, 4); |
109 | 5 | Streamer.AddBlankLine(); |
110 | 5 | } |
111 | | |
112 | | MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( |
113 | | const GlobalValue *GV, const TargetMachine &TM, |
114 | 131 | MachineModuleInfo *MMI) const { |
115 | 131 | unsigned Encoding = getPersonalityEncoding(); |
116 | 131 | if ((Encoding & 0x80) == DW_EH_PE_indirect) |
117 | 32 | return getContext().getOrCreateSymbol(StringRef("DW.ref.") + |
118 | 32 | TM.getSymbol(GV)->getName()); |
119 | 99 | if (99 (Encoding & 0x70) == DW_EH_PE_absptr99 ) |
120 | 99 | return TM.getSymbol(GV); |
121 | 0 | report_fatal_error("We do not support this DWARF encoding yet!"); |
122 | 0 | } |
123 | | |
124 | | void TargetLoweringObjectFileELF::emitPersonalityValue( |
125 | 32 | MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { |
126 | 32 | SmallString<64> NameData("DW.ref."); |
127 | 32 | NameData += Sym->getName(); |
128 | 32 | MCSymbolELF *Label = |
129 | 32 | cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); |
130 | 32 | Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); |
131 | 32 | Streamer.EmitSymbolAttribute(Label, MCSA_Weak); |
132 | 32 | unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; |
133 | 32 | MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), |
134 | 32 | ELF::SHT_PROGBITS, Flags, 0); |
135 | 32 | unsigned Size = DL.getPointerSize(); |
136 | 32 | Streamer.SwitchSection(Sec); |
137 | 32 | Streamer.EmitValueToAlignment(DL.getPointerABIAlignment()); |
138 | 32 | Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); |
139 | 32 | const MCExpr *E = MCConstantExpr::create(Size, getContext()); |
140 | 32 | Streamer.emitELFSize(Label, E); |
141 | 32 | Streamer.EmitLabel(Label); |
142 | 32 | |
143 | 32 | Streamer.EmitSymbolValue(Sym, Size); |
144 | 32 | } |
145 | | |
146 | | const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( |
147 | | const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, |
148 | 29 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
149 | 29 | if (Encoding & DW_EH_PE_indirect29 ) { |
150 | 15 | MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); |
151 | 15 | |
152 | 15 | MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM); |
153 | 15 | |
154 | 15 | // Add information about the stub reference to ELFMMI so that the stub |
155 | 15 | // gets emitted by the asmprinter. |
156 | 15 | MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); |
157 | 15 | if (!StubSym.getPointer()15 ) { |
158 | 15 | MCSymbol *Sym = TM.getSymbol(GV); |
159 | 15 | StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); |
160 | 15 | } |
161 | 15 | |
162 | 15 | return TargetLoweringObjectFile:: |
163 | 15 | getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), |
164 | 15 | Encoding & ~DW_EH_PE_indirect, Streamer); |
165 | 15 | } |
166 | 14 | |
167 | 14 | return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, |
168 | 14 | MMI, Streamer); |
169 | 14 | } |
170 | | |
171 | | static SectionKind |
172 | 250 | getELFKindForNamedSection(StringRef Name, SectionKind K) { |
173 | 250 | // N.B.: The defaults used in here are no the same ones used in MC. |
174 | 250 | // We follow gcc, MC follows gas. For example, given ".section .eh_frame", |
175 | 250 | // both gas and MC will produce a section with no flags. Given |
176 | 250 | // section(".eh_frame") gcc will produce: |
177 | 250 | // |
178 | 250 | // .section .eh_frame,"a",@progbits |
179 | 250 | |
180 | 250 | if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF, |
181 | 250 | /*AddSegmentInfo=*/false)) |
182 | 1 | return SectionKind::getMetadata(); |
183 | 249 | |
184 | 249 | if (249 Name.empty() || 249 Name[0] != '.'249 ) return K137 ; |
185 | 112 | |
186 | 112 | // Some lame default implementation based on some magic section names. |
187 | 112 | if (112 Name == ".bss" || |
188 | 111 | Name.startswith(".bss.") || |
189 | 110 | Name.startswith(".gnu.linkonce.b.") || |
190 | 110 | Name.startswith(".llvm.linkonce.b.") || |
191 | 110 | Name == ".sbss" || |
192 | 109 | Name.startswith(".sbss.") || |
193 | 109 | Name.startswith(".gnu.linkonce.sb.") || |
194 | 109 | Name.startswith(".llvm.linkonce.sb.")) |
195 | 3 | return SectionKind::getBSS(); |
196 | 109 | |
197 | 109 | if (109 Name == ".tdata" || |
198 | 109 | Name.startswith(".tdata.") || |
199 | 109 | Name.startswith(".gnu.linkonce.td.") || |
200 | 109 | Name.startswith(".llvm.linkonce.td.")) |
201 | 0 | return SectionKind::getThreadData(); |
202 | 109 | |
203 | 109 | if (109 Name == ".tbss" || |
204 | 109 | Name.startswith(".tbss.") || |
205 | 109 | Name.startswith(".gnu.linkonce.tb.") || |
206 | 109 | Name.startswith(".llvm.linkonce.tb.")) |
207 | 0 | return SectionKind::getThreadBSS(); |
208 | 109 | |
209 | 109 | return K; |
210 | 109 | } |
211 | | |
212 | 123k | static unsigned getELFSectionType(StringRef Name, SectionKind K) { |
213 | 123k | // Use SHT_NOTE for section whose name starts with ".note" to allow |
214 | 123k | // emitting ELF notes from C variable declaration. |
215 | 123k | // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609 |
216 | 123k | if (Name.startswith(".note")) |
217 | 1 | return ELF::SHT_NOTE; |
218 | 123k | |
219 | 123k | if (123k Name == ".init_array"123k ) |
220 | 1 | return ELF::SHT_INIT_ARRAY; |
221 | 123k | |
222 | 123k | if (123k Name == ".fini_array"123k ) |
223 | 1 | return ELF::SHT_FINI_ARRAY; |
224 | 123k | |
225 | 123k | if (123k Name == ".preinit_array"123k ) |
226 | 1 | return ELF::SHT_PREINIT_ARRAY; |
227 | 123k | |
228 | 123k | if (123k K.isBSS() || 123k K.isThreadBSS()120k ) |
229 | 2.82k | return ELF::SHT_NOBITS; |
230 | 120k | |
231 | 120k | return ELF::SHT_PROGBITS; |
232 | 120k | } |
233 | | |
234 | 123k | static unsigned getELFSectionFlags(SectionKind K) { |
235 | 123k | unsigned Flags = 0; |
236 | 123k | |
237 | 123k | if (!K.isMetadata()) |
238 | 123k | Flags |= ELF::SHF_ALLOC; |
239 | 123k | |
240 | 123k | if (K.isText()) |
241 | 116k | Flags |= ELF::SHF_EXECINSTR; |
242 | 123k | |
243 | 123k | if (K.isExecuteOnly()) |
244 | 78 | Flags |= ELF::SHF_ARM_PURECODE; |
245 | 123k | |
246 | 123k | if (K.isWriteable()) |
247 | 6.25k | Flags |= ELF::SHF_WRITE; |
248 | 123k | |
249 | 123k | if (K.isThreadLocal()) |
250 | 159 | Flags |= ELF::SHF_TLS; |
251 | 123k | |
252 | 123k | if (K.isMergeableCString() || 123k K.isMergeableConst()122k ) |
253 | 501 | Flags |= ELF::SHF_MERGE; |
254 | 123k | |
255 | 123k | if (K.isMergeableCString()) |
256 | 387 | Flags |= ELF::SHF_STRINGS; |
257 | 123k | |
258 | 123k | return Flags; |
259 | 123k | } |
260 | | |
261 | 123k | static const Comdat *getELFComdat(const GlobalValue *GV) { |
262 | 123k | const Comdat *C = GV->getComdat(); |
263 | 123k | if (!C) |
264 | 123k | return nullptr; |
265 | 81 | |
266 | 81 | if (81 C->getSelectionKind() != Comdat::Any81 ) |
267 | 0 | report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + |
268 | 0 | C->getName() + "' cannot be lowered."); |
269 | 81 | |
270 | 81 | return C; |
271 | 81 | } |
272 | | |
273 | | static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO, |
274 | 123k | const TargetMachine &TM) { |
275 | 123k | MDNode *MD = GO->getMetadata(LLVMContext::MD_associated); |
276 | 123k | if (!MD) |
277 | 123k | return nullptr; |
278 | 23 | |
279 | 23 | const MDOperand &Op = MD->getOperand(0); |
280 | 23 | if (!Op.get()) |
281 | 2 | return nullptr; |
282 | 21 | |
283 | 21 | auto *VM = dyn_cast<ValueAsMetadata>(Op); |
284 | 21 | if (!VM) |
285 | 0 | report_fatal_error("MD_associated operand is not ValueAsMetadata"); |
286 | 21 | |
287 | 21 | GlobalObject *OtherGO = dyn_cast<GlobalObject>(VM->getValue()); |
288 | 21 | return OtherGO ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGO))18 : nullptr3 ; |
289 | 123k | } |
290 | | |
291 | | MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( |
292 | 250 | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
293 | 250 | StringRef SectionName = GO->getSection(); |
294 | 250 | |
295 | 250 | // Check if '#pragma clang section' name is applicable. |
296 | 250 | // Note that pragma directive overrides -ffunction-section, -fdata-section |
297 | 250 | // and so section name is exactly as user specified and not uniqued. |
298 | 250 | const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); |
299 | 250 | if (GV && 250 GV->hasImplicitSection()118 ) { |
300 | 13 | auto Attrs = GV->getAttributes(); |
301 | 13 | if (Attrs.hasAttribute("bss-section") && 13 Kind.isBSS()13 ) { |
302 | 7 | SectionName = Attrs.getAttribute("bss-section").getValueAsString(); |
303 | 13 | } else if (6 Attrs.hasAttribute("rodata-section") && 6 Kind.isReadOnly()6 ) { |
304 | 3 | SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); |
305 | 6 | } else if (3 Attrs.hasAttribute("data-section") && 3 Kind.isData()3 ) { |
306 | 3 | SectionName = Attrs.getAttribute("data-section").getValueAsString(); |
307 | 3 | } |
308 | 13 | } |
309 | 250 | const Function *F = dyn_cast<Function>(GO); |
310 | 250 | if (F && 250 F->hasFnAttribute("implicit-section-name")132 ) { |
311 | 2 | SectionName = F->getFnAttribute("implicit-section-name").getValueAsString(); |
312 | 2 | } |
313 | 250 | |
314 | 250 | // Infer section flags from the section name if we can. |
315 | 250 | Kind = getELFKindForNamedSection(SectionName, Kind); |
316 | 250 | |
317 | 250 | StringRef Group = ""; |
318 | 250 | unsigned Flags = getELFSectionFlags(Kind); |
319 | 250 | if (const Comdat *C250 = getELFComdat(GO)) { |
320 | 3 | Group = C->getName(); |
321 | 3 | Flags |= ELF::SHF_GROUP; |
322 | 3 | } |
323 | 250 | |
324 | 250 | // A section can have at most one associated section. Put each global with |
325 | 250 | // MD_associated in a unique section. |
326 | 250 | unsigned UniqueID = MCContext::GenericSectionID; |
327 | 250 | const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); |
328 | 250 | if (AssociatedSymbol250 ) { |
329 | 6 | UniqueID = NextUniqueID++; |
330 | 6 | Flags |= ELF::SHF_LINK_ORDER; |
331 | 6 | } |
332 | 250 | |
333 | 250 | MCSectionELF *Section = getContext().getELFSection( |
334 | 250 | SectionName, getELFSectionType(SectionName, Kind), Flags, |
335 | 250 | /*EntrySize=*/0, Group, UniqueID, AssociatedSymbol); |
336 | 250 | // Make sure that we did not get some other section with incompatible sh_link. |
337 | 250 | // This should not be possible due to UniqueID code above. |
338 | 250 | assert(Section->getAssociatedSymbol() == AssociatedSymbol); |
339 | 250 | return Section; |
340 | 250 | } |
341 | | |
342 | | /// Return the section prefix name used by options FunctionsSections and |
343 | | /// DataSections. |
344 | 122k | static StringRef getSectionPrefixForGlobal(SectionKind Kind) { |
345 | 122k | if (Kind.isText()) |
346 | 116k | return ".text"; |
347 | 6.48k | if (6.48k Kind.isReadOnly()6.48k ) |
348 | 339 | return ".rodata"; |
349 | 6.14k | if (6.14k Kind.isBSS()6.14k ) |
350 | 2.73k | return ".bss"; |
351 | 3.41k | if (3.41k Kind.isThreadData()3.41k ) |
352 | 76 | return ".tdata"; |
353 | 3.33k | if (3.33k Kind.isThreadBSS()3.33k ) |
354 | 83 | return ".tbss"; |
355 | 3.25k | if (3.25k Kind.isData()3.25k ) |
356 | 3.23k | return ".data"; |
357 | 3.25k | assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); |
358 | 23 | return ".data.rel.ro"; |
359 | 23 | } |
360 | | |
361 | | static MCSectionELF *selectELFSectionForGlobal( |
362 | | MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, |
363 | | const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, |
364 | 123k | unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { |
365 | 123k | unsigned EntrySize = 0; |
366 | 123k | if (Kind.isMergeableCString()123k ) { |
367 | 387 | if (Kind.isMergeable2ByteCString()387 ) { |
368 | 6 | EntrySize = 2; |
369 | 387 | } else if (381 Kind.isMergeable4ByteCString()381 ) { |
370 | 4 | EntrySize = 4; |
371 | 381 | } else { |
372 | 377 | EntrySize = 1; |
373 | 377 | assert(Kind.isMergeable1ByteCString() && "unknown string width"); |
374 | 377 | } |
375 | 123k | } else if (122k Kind.isMergeableConst()122k ) { |
376 | 114 | if (Kind.isMergeableConst4()114 ) { |
377 | 41 | EntrySize = 4; |
378 | 114 | } else if (73 Kind.isMergeableConst8()73 ) { |
379 | 50 | EntrySize = 8; |
380 | 73 | } else if (23 Kind.isMergeableConst16()23 ) { |
381 | 16 | EntrySize = 16; |
382 | 23 | } else { |
383 | 7 | assert(Kind.isMergeableConst32() && "unknown data width"); |
384 | 7 | EntrySize = 32; |
385 | 7 | } |
386 | 122k | } |
387 | 123k | |
388 | 123k | StringRef Group = ""; |
389 | 123k | if (const Comdat *C123k = getELFComdat(GO)) { |
390 | 80 | Flags |= ELF::SHF_GROUP; |
391 | 80 | Group = C->getName(); |
392 | 80 | } |
393 | 123k | |
394 | 123k | bool UniqueSectionNames = TM.getUniqueSectionNames(); |
395 | 123k | SmallString<128> Name; |
396 | 123k | if (Kind.isMergeableCString()123k ) { |
397 | 387 | // We also need alignment here. |
398 | 387 | // FIXME: this is getting the alignment of the character, not the |
399 | 387 | // alignment of the global! |
400 | 387 | unsigned Align = GO->getParent()->getDataLayout().getPreferredAlignment( |
401 | 387 | cast<GlobalVariable>(GO)); |
402 | 387 | |
403 | 387 | std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; |
404 | 387 | Name = SizeSpec + utostr(Align); |
405 | 123k | } else if (122k Kind.isMergeableConst()122k ) { |
406 | 114 | Name = ".rodata.cst"; |
407 | 114 | Name += utostr(EntrySize); |
408 | 122k | } else { |
409 | 122k | Name = getSectionPrefixForGlobal(Kind); |
410 | 122k | } |
411 | 123k | |
412 | 123k | if (const auto *F123k = dyn_cast<Function>(GO)) { |
413 | 116k | const auto &OptionalPrefix = F->getSectionPrefix(); |
414 | 116k | if (OptionalPrefix) |
415 | 7 | Name += *OptionalPrefix; |
416 | 116k | } |
417 | 123k | |
418 | 123k | if (EmitUniqueSection && 123k UniqueSectionNames351 ) { |
419 | 344 | Name.push_back('.'); |
420 | 344 | TM.getNameWithPrefix(Name, GO, Mang, true); |
421 | 344 | } |
422 | 123k | unsigned UniqueID = MCContext::GenericSectionID; |
423 | 123k | if (EmitUniqueSection && 123k !UniqueSectionNames352 ) { |
424 | 7 | UniqueID = *NextUniqueID; |
425 | 7 | (*NextUniqueID)++; |
426 | 7 | } |
427 | 123k | // Use 0 as the unique ID for execute-only text |
428 | 123k | if (Kind.isExecuteOnly()) |
429 | 75 | UniqueID = 0; |
430 | 123k | return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, |
431 | 123k | EntrySize, Group, UniqueID, AssociatedSymbol); |
432 | 123k | } |
433 | | |
434 | | MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( |
435 | 123k | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
436 | 123k | unsigned Flags = getELFSectionFlags(Kind); |
437 | 123k | |
438 | 123k | // If we have -ffunction-section or -fdata-section then we should emit the |
439 | 123k | // global value to a uniqued section specifically for it. |
440 | 123k | bool EmitUniqueSection = false; |
441 | 123k | if (!(Flags & ELF::SHF_MERGE) && 123k !Kind.isCommon()122k ) { |
442 | 122k | if (Kind.isText()) |
443 | 116k | EmitUniqueSection = TM.getFunctionSections(); |
444 | 122k | else |
445 | 6.47k | EmitUniqueSection = TM.getDataSections(); |
446 | 122k | } |
447 | 123k | EmitUniqueSection |= GO->hasComdat(); |
448 | 123k | |
449 | 123k | const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); |
450 | 123k | if (AssociatedSymbol123k ) { |
451 | 12 | EmitUniqueSection = true; |
452 | 12 | Flags |= ELF::SHF_LINK_ORDER; |
453 | 12 | } |
454 | 123k | |
455 | 123k | MCSectionELF *Section = selectELFSectionForGlobal( |
456 | 123k | getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, |
457 | 123k | &NextUniqueID, AssociatedSymbol); |
458 | 123k | assert(Section->getAssociatedSymbol() == AssociatedSymbol); |
459 | 123k | return Section; |
460 | 123k | } |
461 | | |
462 | | MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( |
463 | 94 | const Function &F, const TargetMachine &TM) const { |
464 | 94 | // If the function can be removed, produce a unique section so that |
465 | 94 | // the table doesn't prevent the removal. |
466 | 94 | const Comdat *C = F.getComdat(); |
467 | 86 | bool EmitUniqueSection = TM.getFunctionSections() || C; |
468 | 94 | if (!EmitUniqueSection) |
469 | 85 | return ReadOnlySection; |
470 | 9 | |
471 | 9 | return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), |
472 | 9 | getMangler(), TM, EmitUniqueSection, |
473 | 9 | ELF::SHF_ALLOC, &NextUniqueID, |
474 | 9 | /* AssociatedSymbol */ nullptr); |
475 | 9 | } |
476 | | |
477 | | bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( |
478 | 91 | bool UsesLabelDifference, const Function &F) const { |
479 | 91 | // We can always create relative relocations, so use another section |
480 | 91 | // that can be marked non-executable. |
481 | 91 | return false; |
482 | 91 | } |
483 | | |
484 | | /// Given a mergeable constant with the specified size and relocation |
485 | | /// information, return a section that it should be placed in. |
486 | | MCSection *TargetLoweringObjectFileELF::getSectionForConstant( |
487 | | const DataLayout &DL, SectionKind Kind, const Constant *C, |
488 | 13.7k | unsigned &Align) const { |
489 | 13.7k | if (Kind.isMergeableConst4() && 13.7k MergeableConst4Section1.54k ) |
490 | 1.54k | return MergeableConst4Section; |
491 | 12.1k | if (12.1k Kind.isMergeableConst8() && 12.1k MergeableConst8Section991 ) |
492 | 991 | return MergeableConst8Section; |
493 | 11.1k | if (11.1k Kind.isMergeableConst16() && 11.1k MergeableConst16Section7.06k ) |
494 | 7.06k | return MergeableConst16Section; |
495 | 4.13k | if (4.13k Kind.isMergeableConst32() && 4.13k MergeableConst32Section2.91k ) |
496 | 2.91k | return MergeableConst32Section; |
497 | 1.22k | if (1.22k Kind.isReadOnly()1.22k ) |
498 | 1.20k | return ReadOnlySection; |
499 | 17 | |
500 | 1.22k | assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); |
501 | 17 | return DataRelROSection; |
502 | 17 | } |
503 | | |
504 | | static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, |
505 | | bool IsCtor, unsigned Priority, |
506 | 58 | const MCSymbol *KeySym) { |
507 | 58 | std::string Name; |
508 | 58 | unsigned Type; |
509 | 58 | unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; |
510 | 58 | StringRef COMDAT = KeySym ? KeySym->getName()13 : ""45 ; |
511 | 58 | |
512 | 58 | if (KeySym) |
513 | 13 | Flags |= ELF::SHF_GROUP; |
514 | 58 | |
515 | 58 | if (UseInitArray58 ) { |
516 | 35 | if (IsCtor35 ) { |
517 | 33 | Type = ELF::SHT_INIT_ARRAY; |
518 | 33 | Name = ".init_array"; |
519 | 35 | } else { |
520 | 2 | Type = ELF::SHT_FINI_ARRAY; |
521 | 2 | Name = ".fini_array"; |
522 | 2 | } |
523 | 35 | if (Priority != 6553535 ) { |
524 | 14 | Name += '.'; |
525 | 14 | Name += utostr(Priority); |
526 | 14 | } |
527 | 58 | } else { |
528 | 23 | // The default scheme is .ctor / .dtor, so we have to invert the priority |
529 | 23 | // numbering. |
530 | 23 | if (IsCtor) |
531 | 19 | Name = ".ctors"; |
532 | 23 | else |
533 | 4 | Name = ".dtors"; |
534 | 23 | if (Priority != 6553523 ) { |
535 | 14 | Name += '.'; |
536 | 14 | Name += utostr(65535 - Priority); |
537 | 14 | } |
538 | 23 | Type = ELF::SHT_PROGBITS; |
539 | 23 | } |
540 | 58 | |
541 | 58 | return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); |
542 | 58 | } |
543 | | |
544 | | MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( |
545 | 52 | unsigned Priority, const MCSymbol *KeySym) const { |
546 | 52 | return getStaticStructorSection(getContext(), UseInitArray, true, Priority, |
547 | 52 | KeySym); |
548 | 52 | } |
549 | | |
550 | | MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( |
551 | 6 | unsigned Priority, const MCSymbol *KeySym) const { |
552 | 6 | return getStaticStructorSection(getContext(), UseInitArray, false, Priority, |
553 | 6 | KeySym); |
554 | 6 | } |
555 | | |
556 | | const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( |
557 | | const GlobalValue *LHS, const GlobalValue *RHS, |
558 | 11 | const TargetMachine &TM) const { |
559 | 11 | // We may only use a PLT-relative relocation to refer to unnamed_addr |
560 | 11 | // functions. |
561 | 11 | if (!LHS->hasGlobalUnnamedAddr() || 11 !LHS->getValueType()->isFunctionTy()7 ) |
562 | 5 | return nullptr; |
563 | 6 | |
564 | 6 | // Basic sanity checks. |
565 | 6 | if (6 LHS->getType()->getPointerAddressSpace() != 0 || |
566 | 6 | RHS->getType()->getPointerAddressSpace() != 06 || LHS->isThreadLocal()6 || |
567 | 6 | RHS->isThreadLocal()) |
568 | 0 | return nullptr; |
569 | 6 | |
570 | 6 | return MCBinaryExpr::createSub( |
571 | 6 | MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, |
572 | 6 | getContext()), |
573 | 6 | MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); |
574 | 6 | } |
575 | | |
576 | | void |
577 | 7.54k | TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { |
578 | 7.54k | UseInitArray = UseInitArray_; |
579 | 7.54k | MCContext &Ctx = getContext(); |
580 | 7.54k | if (!UseInitArray7.54k ) { |
581 | 60 | StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, |
582 | 60 | ELF::SHF_ALLOC | ELF::SHF_WRITE); |
583 | 60 | |
584 | 60 | StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, |
585 | 60 | ELF::SHF_ALLOC | ELF::SHF_WRITE); |
586 | 60 | return; |
587 | 60 | } |
588 | 7.48k | |
589 | 7.48k | StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, |
590 | 7.48k | ELF::SHF_WRITE | ELF::SHF_ALLOC); |
591 | 7.48k | StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, |
592 | 7.48k | ELF::SHF_WRITE | ELF::SHF_ALLOC); |
593 | 7.48k | } |
594 | | |
595 | | //===----------------------------------------------------------------------===// |
596 | | // MachO |
597 | | //===----------------------------------------------------------------------===// |
598 | | |
599 | | TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() |
600 | 23.3k | : TargetLoweringObjectFile() { |
601 | 23.3k | SupportIndirectSymViaGOTPCRel = true; |
602 | 23.3k | } |
603 | | |
604 | | void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, |
605 | 19.7k | const TargetMachine &TM) { |
606 | 19.7k | TargetLoweringObjectFile::Initialize(Ctx, TM); |
607 | 19.7k | if (TM.getRelocationModel() == Reloc::Static19.7k ) { |
608 | 684 | StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, |
609 | 684 | SectionKind::getData()); |
610 | 684 | StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, |
611 | 684 | SectionKind::getData()); |
612 | 19.7k | } else { |
613 | 19.0k | StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", |
614 | 19.0k | MachO::S_MOD_INIT_FUNC_POINTERS, |
615 | 19.0k | SectionKind::getData()); |
616 | 19.0k | StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", |
617 | 19.0k | MachO::S_MOD_TERM_FUNC_POINTERS, |
618 | 19.0k | SectionKind::getData()); |
619 | 19.0k | } |
620 | 19.7k | } |
621 | | |
622 | | void TargetLoweringObjectFileMachO::emitModuleMetadata( |
623 | 19.6k | MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { |
624 | 19.6k | // Emit the linker options if present. |
625 | 19.6k | if (auto *LinkerOptions19.6k = M.getNamedMetadata("llvm.linker.options")) { |
626 | 6 | for (const auto &Option : LinkerOptions->operands()) { |
627 | 6 | SmallVector<std::string, 4> StrOptions; |
628 | 6 | for (const auto &Piece : cast<MDNode>(Option)->operands()) |
629 | 8 | StrOptions.push_back(cast<MDString>(Piece)->getString()); |
630 | 6 | Streamer.EmitLinkerOptions(StrOptions); |
631 | 6 | } |
632 | 20 | } |
633 | 19.6k | |
634 | 19.6k | unsigned VersionVal = 0; |
635 | 19.6k | unsigned ImageInfoFlags = 0; |
636 | 19.6k | StringRef SectionVal; |
637 | 19.6k | |
638 | 19.6k | GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal); |
639 | 19.6k | |
640 | 19.6k | // The section is mandatory. If we don't have it, then we don't have GC info. |
641 | 19.6k | if (SectionVal.empty()) |
642 | 19.5k | return; |
643 | 103 | |
644 | 103 | StringRef Segment, Section; |
645 | 103 | unsigned TAA = 0, StubSize = 0; |
646 | 103 | bool TAAParsed; |
647 | 103 | std::string ErrorCode = |
648 | 103 | MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, |
649 | 103 | TAA, TAAParsed, StubSize); |
650 | 103 | if (!ErrorCode.empty()) |
651 | 103 | // If invalid, report the error with report_fatal_error. |
652 | 0 | report_fatal_error("Invalid section specifier '" + Section + "': " + |
653 | 0 | ErrorCode + "."); |
654 | 103 | |
655 | 103 | // Get the section. |
656 | 103 | MCSectionMachO *S = getContext().getMachOSection( |
657 | 103 | Segment, Section, TAA, StubSize, SectionKind::getData()); |
658 | 103 | Streamer.SwitchSection(S); |
659 | 103 | Streamer.EmitLabel(getContext(). |
660 | 103 | getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); |
661 | 103 | Streamer.EmitIntValue(VersionVal, 4); |
662 | 103 | Streamer.EmitIntValue(ImageInfoFlags, 4); |
663 | 103 | Streamer.AddBlankLine(); |
664 | 103 | } |
665 | | |
666 | 1.22M | static void checkMachOComdat(const GlobalValue *GV) { |
667 | 1.22M | const Comdat *C = GV->getComdat(); |
668 | 1.22M | if (!C) |
669 | 1.22M | return; |
670 | 1 | |
671 | 1 | report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + |
672 | 1 | "' cannot be lowered."); |
673 | 1 | } |
674 | | |
675 | | MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( |
676 | 3.88k | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
677 | 3.88k | // Parse the section specifier and create it if valid. |
678 | 3.88k | StringRef Segment, Section; |
679 | 3.88k | unsigned TAA = 0, StubSize = 0; |
680 | 3.88k | bool TAAParsed; |
681 | 3.88k | |
682 | 3.88k | checkMachOComdat(GO); |
683 | 3.88k | |
684 | 3.88k | std::string ErrorCode = |
685 | 3.88k | MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, |
686 | 3.88k | TAA, TAAParsed, StubSize); |
687 | 3.88k | if (!ErrorCode.empty()3.88k ) { |
688 | 2 | // If invalid, report the error with report_fatal_error. |
689 | 2 | report_fatal_error("Global variable '" + GO->getName() + |
690 | 2 | "' has an invalid section specifier '" + |
691 | 2 | GO->getSection() + "': " + ErrorCode + "."); |
692 | 2 | } |
693 | 3.88k | |
694 | 3.88k | // Get the section. |
695 | 3.88k | MCSectionMachO *S = |
696 | 3.88k | getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); |
697 | 3.88k | |
698 | 3.88k | // If TAA wasn't set by ParseSectionSpecifier() above, |
699 | 3.88k | // use the value returned by getMachOSection() as a default. |
700 | 3.88k | if (!TAAParsed) |
701 | 1.23k | TAA = S->getTypeAndAttributes(); |
702 | 3.88k | |
703 | 3.88k | // Okay, now that we got the section, verify that the TAA & StubSize agree. |
704 | 3.88k | // If the user declared multiple globals with different section flags, we need |
705 | 3.88k | // to reject it here. |
706 | 3.88k | if (S->getTypeAndAttributes() != TAA || 3.88k S->getStubSize() != StubSize3.88k ) { |
707 | 0 | // If invalid, report the error with report_fatal_error. |
708 | 0 | report_fatal_error("Global variable '" + GO->getName() + |
709 | 0 | "' section type or attributes does not match previous" |
710 | 0 | " section specifier"); |
711 | 0 | } |
712 | 3.88k | |
713 | 3.88k | return S; |
714 | 3.88k | } |
715 | | |
716 | | MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( |
717 | 1.21M | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
718 | 1.21M | checkMachOComdat(GO); |
719 | 1.21M | |
720 | 1.21M | // Handle thread local data. |
721 | 1.21M | if (Kind.isThreadBSS()1.21M ) return TLSBSSSection72 ; |
722 | 1.21M | if (1.21M Kind.isThreadData()1.21M ) return TLSDataSection12 ; |
723 | 1.21M | |
724 | 1.21M | if (1.21M Kind.isText()1.21M ) |
725 | 475k | return GO->isWeakForLinker() ? 475k TextCoalSection384k : TextSection90.6k ; |
726 | 741k | |
727 | 741k | // If this is weak/linkonce, put this in a coalescable section, either in text |
728 | 741k | // or data depending on if it is writable. |
729 | 741k | if (741k GO->isWeakForLinker()741k ) { |
730 | 78.8k | if (Kind.isReadOnly()) |
731 | 1.46k | return ConstTextCoalSection; |
732 | 77.3k | return DataCoalSection; |
733 | 77.3k | } |
734 | 663k | |
735 | 663k | // FIXME: Alignment check should be handled by section classifier. |
736 | 663k | if (663k Kind.isMergeable1ByteCString() && |
737 | 491k | GO->getParent()->getDataLayout().getPreferredAlignment( |
738 | 491k | cast<GlobalVariable>(GO)) < 32) |
739 | 491k | return CStringSection; |
740 | 171k | |
741 | 171k | // Do not put 16-bit arrays in the UString section if they have an |
742 | 171k | // externally visible label, this runs into issues with certain linker |
743 | 171k | // versions. |
744 | 171k | if (171k Kind.isMergeable2ByteCString() && 171k !GO->hasExternalLinkage()7 && |
745 | 4 | GO->getParent()->getDataLayout().getPreferredAlignment( |
746 | 4 | cast<GlobalVariable>(GO)) < 32) |
747 | 4 | return UStringSection; |
748 | 171k | |
749 | 171k | // With MachO only variables whose corresponding symbol starts with 'l' or |
750 | 171k | // 'L' can be merged, so we only try merging GVs with private linkage. |
751 | 171k | if (171k GO->hasPrivateLinkage() && 171k Kind.isMergeableConst()143k ) { |
752 | 646 | if (Kind.isMergeableConst4()) |
753 | 5 | return FourByteConstantSection; |
754 | 641 | if (641 Kind.isMergeableConst8()641 ) |
755 | 6 | return EightByteConstantSection; |
756 | 635 | if (635 Kind.isMergeableConst16()635 ) |
757 | 621 | return SixteenByteConstantSection; |
758 | 171k | } |
759 | 171k | |
760 | 171k | // Otherwise, if it is readonly, but not something we can specially optimize, |
761 | 171k | // just drop it in .const. |
762 | 171k | if (171k Kind.isReadOnly()171k ) |
763 | 131k | return ReadOnlySection; |
764 | 40.1k | |
765 | 40.1k | // If this is marked const, put it into a const section. But if the dynamic |
766 | 40.1k | // linker needs to write to it, put it in the data segment. |
767 | 40.1k | if (40.1k Kind.isReadOnlyWithRel()40.1k ) |
768 | 15.8k | return ConstDataSection; |
769 | 24.2k | |
770 | 24.2k | // Put zero initialized globals with strong external linkage in the |
771 | 24.2k | // DATA, __common section with the .zerofill directive. |
772 | 24.2k | if (24.2k Kind.isBSSExtern()24.2k ) |
773 | 1.72k | return DataCommonSection; |
774 | 22.5k | |
775 | 22.5k | // Put zero initialized globals with local linkage in __DATA,__bss directive |
776 | 22.5k | // with the .zerofill directive (aka .lcomm). |
777 | 22.5k | if (22.5k Kind.isBSSLocal()22.5k ) |
778 | 5.00k | return DataBSSSection; |
779 | 17.5k | |
780 | 17.5k | // Otherwise, just drop the variable in the normal data section. |
781 | 17.5k | return DataSection; |
782 | 17.5k | } |
783 | | |
784 | | MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( |
785 | | const DataLayout &DL, SectionKind Kind, const Constant *C, |
786 | 57.1k | unsigned &Align) const { |
787 | 57.1k | // If this constant requires a relocation, we have to put it in the data |
788 | 57.1k | // segment, not in the text segment. |
789 | 57.1k | if (Kind.isData() || 57.1k Kind.isReadOnlyWithRel()57.1k ) |
790 | 0 | return ConstDataSection; |
791 | 57.1k | |
792 | 57.1k | if (57.1k Kind.isMergeableConst4()57.1k ) |
793 | 5.24k | return FourByteConstantSection; |
794 | 51.9k | if (51.9k Kind.isMergeableConst8()51.9k ) |
795 | 41.6k | return EightByteConstantSection; |
796 | 10.2k | if (10.2k Kind.isMergeableConst16()10.2k ) |
797 | 10.0k | return SixteenByteConstantSection; |
798 | 235 | return ReadOnlySection; // .const |
799 | 235 | } |
800 | | |
801 | | const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( |
802 | | const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, |
803 | 8 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
804 | 8 | // The mach-o version of this method defaults to returning a stub reference. |
805 | 8 | |
806 | 8 | if (Encoding & DW_EH_PE_indirect8 ) { |
807 | 8 | MachineModuleInfoMachO &MachOMMI = |
808 | 8 | MMI->getObjFileInfo<MachineModuleInfoMachO>(); |
809 | 8 | |
810 | 8 | MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); |
811 | 8 | |
812 | 8 | // Add information about the stub reference to MachOMMI so that the stub |
813 | 8 | // gets emitted by the asmprinter. |
814 | 8 | MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); |
815 | 8 | if (!StubSym.getPointer()8 ) { |
816 | 7 | MCSymbol *Sym = TM.getSymbol(GV); |
817 | 7 | StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); |
818 | 7 | } |
819 | 8 | |
820 | 8 | return TargetLoweringObjectFile:: |
821 | 8 | getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), |
822 | 8 | Encoding & ~DW_EH_PE_indirect, Streamer); |
823 | 8 | } |
824 | 0 |
|
825 | 0 | return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, |
826 | 0 | MMI, Streamer); |
827 | 0 | } |
828 | | |
829 | | MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( |
830 | | const GlobalValue *GV, const TargetMachine &TM, |
831 | 24 | MachineModuleInfo *MMI) const { |
832 | 24 | // The mach-o version of this method defaults to returning a stub reference. |
833 | 24 | MachineModuleInfoMachO &MachOMMI = |
834 | 24 | MMI->getObjFileInfo<MachineModuleInfoMachO>(); |
835 | 24 | |
836 | 24 | MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); |
837 | 24 | |
838 | 24 | // Add information about the stub reference to MachOMMI so that the stub |
839 | 24 | // gets emitted by the asmprinter. |
840 | 24 | MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); |
841 | 24 | if (!StubSym.getPointer()24 ) { |
842 | 15 | MCSymbol *Sym = TM.getSymbol(GV); |
843 | 15 | StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); |
844 | 15 | } |
845 | 24 | |
846 | 24 | return SSym; |
847 | 24 | } |
848 | | |
849 | | const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( |
850 | | const MCSymbol *Sym, const MCValue &MV, int64_t Offset, |
851 | 10 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
852 | 10 | // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation |
853 | 10 | // as 64-bit do, we replace the GOT equivalent by accessing the final symbol |
854 | 10 | // through a non_lazy_ptr stub instead. One advantage is that it allows the |
855 | 10 | // computation of deltas to final external symbols. Example: |
856 | 10 | // |
857 | 10 | // _extgotequiv: |
858 | 10 | // .long _extfoo |
859 | 10 | // |
860 | 10 | // _delta: |
861 | 10 | // .long _extgotequiv-_delta |
862 | 10 | // |
863 | 10 | // is transformed to: |
864 | 10 | // |
865 | 10 | // _delta: |
866 | 10 | // .long L_extfoo$non_lazy_ptr-(_delta+0) |
867 | 10 | // |
868 | 10 | // .section __IMPORT,__pointers,non_lazy_symbol_pointers |
869 | 10 | // L_extfoo$non_lazy_ptr: |
870 | 10 | // .indirect_symbol _extfoo |
871 | 10 | // .long 0 |
872 | 10 | // |
873 | 10 | MachineModuleInfoMachO &MachOMMI = |
874 | 10 | MMI->getObjFileInfo<MachineModuleInfoMachO>(); |
875 | 10 | MCContext &Ctx = getContext(); |
876 | 10 | |
877 | 10 | // The offset must consider the original displacement from the base symbol |
878 | 10 | // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. |
879 | 10 | Offset = -MV.getConstant(); |
880 | 10 | const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); |
881 | 10 | |
882 | 10 | // Access the final symbol via sym$non_lazy_ptr and generate the appropriated |
883 | 10 | // non_lazy_ptr stubs. |
884 | 10 | SmallString<128> Name; |
885 | 10 | StringRef Suffix = "$non_lazy_ptr"; |
886 | 10 | Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); |
887 | 10 | Name += Sym->getName(); |
888 | 10 | Name += Suffix; |
889 | 10 | MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); |
890 | 10 | |
891 | 10 | MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); |
892 | 10 | if (!StubSym.getPointer()) |
893 | 4 | StubSym = MachineModuleInfoImpl:: |
894 | 4 | StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */); |
895 | 10 | |
896 | 10 | const MCExpr *BSymExpr = |
897 | 10 | MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); |
898 | 10 | const MCExpr *LHS = |
899 | 10 | MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); |
900 | 10 | |
901 | 10 | if (!Offset) |
902 | 2 | return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); |
903 | 8 | |
904 | 8 | const MCExpr *RHS = |
905 | 8 | MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); |
906 | 8 | return MCBinaryExpr::createSub(LHS, RHS, Ctx); |
907 | 8 | } |
908 | | |
909 | | static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, |
910 | 49.5k | const MCSection &Section) { |
911 | 49.5k | if (!AsmInfo.isSectionAtomizableBySymbols(Section)) |
912 | 48.5k | return true; |
913 | 972 | |
914 | 972 | // If it is not dead stripped, it is safe to use private labels. |
915 | 972 | const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); |
916 | 972 | if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) |
917 | 130 | return true; |
918 | 842 | |
919 | 842 | return false; |
920 | 842 | } |
921 | | |
922 | | void TargetLoweringObjectFileMachO::getNameWithPrefix( |
923 | | SmallVectorImpl<char> &OutName, const GlobalValue *GV, |
924 | 49.5k | const TargetMachine &TM) const { |
925 | 49.5k | bool CannotUsePrivateLabel = true; |
926 | 49.5k | if (auto *GO49.5k = GV->getBaseObject()) { |
927 | 49.5k | SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); |
928 | 49.5k | const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); |
929 | 49.5k | CannotUsePrivateLabel = |
930 | 49.5k | !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); |
931 | 49.5k | } |
932 | 49.5k | getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); |
933 | 49.5k | } |
934 | | |
935 | | //===----------------------------------------------------------------------===// |
936 | | // COFF |
937 | | //===----------------------------------------------------------------------===// |
938 | | |
939 | | static unsigned |
940 | 173 | getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { |
941 | 173 | unsigned Flags = 0; |
942 | 173 | bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; |
943 | 173 | |
944 | 173 | if (K.isMetadata()) |
945 | 0 | Flags |= |
946 | 0 | COFF::IMAGE_SCN_MEM_DISCARDABLE; |
947 | 173 | else if (173 K.isText()173 ) |
948 | 47 | Flags |= |
949 | 47 | COFF::IMAGE_SCN_MEM_EXECUTE | |
950 | 47 | COFF::IMAGE_SCN_MEM_READ | |
951 | 47 | COFF::IMAGE_SCN_CNT_CODE | |
952 | 47 | (isThumb ? COFF::IMAGE_SCN_MEM_16BIT0 : (COFF::SectionCharacteristics)047 ); |
953 | 126 | else if (126 K.isBSS()126 ) |
954 | 15 | Flags |= |
955 | 15 | COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | |
956 | 15 | COFF::IMAGE_SCN_MEM_READ | |
957 | 15 | COFF::IMAGE_SCN_MEM_WRITE; |
958 | 111 | else if (111 K.isThreadLocal()111 ) |
959 | 0 | Flags |= |
960 | 0 | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | |
961 | 0 | COFF::IMAGE_SCN_MEM_READ | |
962 | 0 | COFF::IMAGE_SCN_MEM_WRITE; |
963 | 111 | else if (111 K.isReadOnly() || 111 K.isReadOnlyWithRel()80 ) |
964 | 78 | Flags |= |
965 | 78 | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | |
966 | 78 | COFF::IMAGE_SCN_MEM_READ; |
967 | 33 | else if (33 K.isWriteable()33 ) |
968 | 33 | Flags |= |
969 | 33 | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | |
970 | 33 | COFF::IMAGE_SCN_MEM_READ | |
971 | 33 | COFF::IMAGE_SCN_MEM_WRITE; |
972 | 173 | |
973 | 173 | return Flags; |
974 | 173 | } |
975 | | |
976 | 249 | static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { |
977 | 249 | const Comdat *C = GV->getComdat(); |
978 | 249 | assert(C && "expected GV to have a Comdat!"); |
979 | 249 | |
980 | 249 | StringRef ComdatGVName = C->getName(); |
981 | 249 | const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); |
982 | 249 | if (!ComdatGV) |
983 | 1 | report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + |
984 | 1 | "' does not exist."); |
985 | 248 | |
986 | 248 | if (248 ComdatGV->getComdat() != C248 ) |
987 | 1 | report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + |
988 | 1 | "' is not a key for its COMDAT."); |
989 | 247 | |
990 | 247 | return ComdatGV; |
991 | 247 | } |
992 | | |
993 | 151 | static int getSelectionForCOFF(const GlobalValue *GV) { |
994 | 151 | if (const Comdat *C151 = GV->getComdat()) { |
995 | 127 | const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); |
996 | 127 | if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) |
997 | 10 | ComdatKey = GA->getBaseObject(); |
998 | 127 | if (ComdatKey == GV127 ) { |
999 | 116 | switch (C->getSelectionKind()) { |
1000 | 101 | case Comdat::Any: |
1001 | 101 | return COFF::IMAGE_COMDAT_SELECT_ANY; |
1002 | 1 | case Comdat::ExactMatch: |
1003 | 1 | return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; |
1004 | 11 | case Comdat::Largest: |
1005 | 11 | return COFF::IMAGE_COMDAT_SELECT_LARGEST; |
1006 | 1 | case Comdat::NoDuplicates: |
1007 | 1 | return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; |
1008 | 2 | case Comdat::SameSize: |
1009 | 2 | return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; |
1010 | 127 | } |
1011 | 11 | } else { |
1012 | 11 | return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; |
1013 | 11 | } |
1014 | 24 | } |
1015 | 24 | return 0; |
1016 | 24 | } |
1017 | | |
1018 | | MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( |
1019 | 21 | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
1020 | 21 | int Selection = 0; |
1021 | 21 | unsigned Characteristics = getCOFFSectionFlags(Kind, TM); |
1022 | 21 | StringRef Name = GO->getSection(); |
1023 | 21 | StringRef COMDATSymName = ""; |
1024 | 21 | if (GO->hasComdat()21 ) { |
1025 | 3 | Selection = getSelectionForCOFF(GO); |
1026 | 3 | const GlobalValue *ComdatGV; |
1027 | 3 | if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) |
1028 | 0 | ComdatGV = getComdatGVForCOFF(GO); |
1029 | 3 | else |
1030 | 3 | ComdatGV = GO; |
1031 | 3 | |
1032 | 3 | if (!ComdatGV->hasPrivateLinkage()3 ) { |
1033 | 3 | MCSymbol *Sym = TM.getSymbol(ComdatGV); |
1034 | 3 | COMDATSymName = Sym->getName(); |
1035 | 3 | Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; |
1036 | 3 | } else { |
1037 | 0 | Selection = 0; |
1038 | 0 | } |
1039 | 3 | } |
1040 | 21 | |
1041 | 21 | return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, |
1042 | 21 | Selection); |
1043 | 21 | } |
1044 | | |
1045 | 152 | static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { |
1046 | 152 | if (Kind.isText()) |
1047 | 45 | return ".text"; |
1048 | 107 | if (107 Kind.isBSS()107 ) |
1049 | 15 | return ".bss"; |
1050 | 92 | if (92 Kind.isThreadLocal()92 ) |
1051 | 0 | return ".tls$"; |
1052 | 92 | if (92 Kind.isReadOnly() || 92 Kind.isReadOnlyWithRel()66 ) |
1053 | 72 | return ".rdata"; |
1054 | 20 | return ".data"; |
1055 | 20 | } |
1056 | | |
1057 | | MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( |
1058 | 2.53k | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
1059 | 2.53k | // If we have -ffunction-sections then we should emit the global value to a |
1060 | 2.53k | // uniqued section specifically for it. |
1061 | 2.53k | bool EmitUniquedSection; |
1062 | 2.53k | if (Kind.isText()) |
1063 | 2.16k | EmitUniquedSection = TM.getFunctionSections(); |
1064 | 2.53k | else |
1065 | 366 | EmitUniquedSection = TM.getDataSections(); |
1066 | 2.53k | |
1067 | 2.53k | if ((EmitUniquedSection && 2.53k !Kind.isCommon()24 ) || GO->hasComdat()2.50k ) { |
1068 | 148 | const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); |
1069 | 148 | unsigned Characteristics = getCOFFSectionFlags(Kind, TM); |
1070 | 148 | |
1071 | 148 | Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; |
1072 | 148 | int Selection = getSelectionForCOFF(GO); |
1073 | 148 | if (!Selection) |
1074 | 24 | Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; |
1075 | 148 | const GlobalValue *ComdatGV; |
1076 | 148 | if (GO->hasComdat()) |
1077 | 122 | ComdatGV = getComdatGVForCOFF(GO); |
1078 | 148 | else |
1079 | 26 | ComdatGV = GO; |
1080 | 148 | |
1081 | 148 | unsigned UniqueID = MCContext::GenericSectionID; |
1082 | 148 | if (EmitUniquedSection) |
1083 | 24 | UniqueID = NextUniqueID++; |
1084 | 148 | |
1085 | 148 | if (!ComdatGV->hasPrivateLinkage()148 ) { |
1086 | 144 | MCSymbol *Sym = TM.getSymbol(ComdatGV); |
1087 | 144 | StringRef COMDATSymName = Sym->getName(); |
1088 | 144 | return getContext().getCOFFSection(Name, Characteristics, Kind, |
1089 | 144 | COMDATSymName, Selection, UniqueID); |
1090 | 0 | } else { |
1091 | 4 | SmallString<256> TmpData; |
1092 | 4 | getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); |
1093 | 4 | return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, |
1094 | 4 | Selection, UniqueID); |
1095 | 4 | } |
1096 | 2.38k | } |
1097 | 2.38k | |
1098 | 2.38k | if (2.38k Kind.isText()2.38k ) |
1099 | 2.12k | return TextSection; |
1100 | 262 | |
1101 | 262 | if (262 Kind.isThreadLocal()262 ) |
1102 | 34 | return TLSDataSection; |
1103 | 228 | |
1104 | 228 | if (228 Kind.isReadOnly() || 228 Kind.isReadOnlyWithRel()125 ) |
1105 | 107 | return ReadOnlySection; |
1106 | 121 | |
1107 | 121 | // Note: we claim that common symbols are put in BSSSection, but they are |
1108 | 121 | // really emitted with the magic .comm directive, which creates a symbol table |
1109 | 121 | // entry but not a section. |
1110 | 121 | if (121 Kind.isBSS() || 121 Kind.isCommon()37 ) |
1111 | 85 | return BSSSection; |
1112 | 36 | |
1113 | 36 | return DataSection; |
1114 | 36 | } |
1115 | | |
1116 | | void TargetLoweringObjectFileCOFF::getNameWithPrefix( |
1117 | | SmallVectorImpl<char> &OutName, const GlobalValue *GV, |
1118 | 205 | const TargetMachine &TM) const { |
1119 | 205 | bool CannotUsePrivateLabel = false; |
1120 | 205 | if (GV->hasPrivateLinkage() && |
1121 | 205 | ((isa<Function>(GV) && 205 TM.getFunctionSections()4 ) || |
1122 | 205 | (isa<GlobalVariable>(GV) && 205 TM.getDataSections()201 ))) |
1123 | 4 | CannotUsePrivateLabel = true; |
1124 | 205 | |
1125 | 205 | getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); |
1126 | 205 | } |
1127 | | |
1128 | | MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( |
1129 | 7 | const Function &F, const TargetMachine &TM) const { |
1130 | 7 | // If the function can be removed, produce a unique section so that |
1131 | 7 | // the table doesn't prevent the removal. |
1132 | 7 | const Comdat *C = F.getComdat(); |
1133 | 3 | bool EmitUniqueSection = TM.getFunctionSections() || C; |
1134 | 7 | if (!EmitUniqueSection) |
1135 | 3 | return ReadOnlySection; |
1136 | 4 | |
1137 | 4 | // FIXME: we should produce a symbol for F instead. |
1138 | 4 | if (4 F.hasPrivateLinkage()4 ) |
1139 | 0 | return ReadOnlySection; |
1140 | 4 | |
1141 | 4 | MCSymbol *Sym = TM.getSymbol(&F); |
1142 | 4 | StringRef COMDATSymName = Sym->getName(); |
1143 | 4 | |
1144 | 4 | SectionKind Kind = SectionKind::getReadOnly(); |
1145 | 4 | const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); |
1146 | 4 | unsigned Characteristics = getCOFFSectionFlags(Kind, TM); |
1147 | 4 | Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; |
1148 | 4 | unsigned UniqueID = NextUniqueID++; |
1149 | 4 | |
1150 | 4 | return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, |
1151 | 4 | COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); |
1152 | 4 | } |
1153 | | |
1154 | | void TargetLoweringObjectFileCOFF::emitModuleMetadata( |
1155 | 598 | MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { |
1156 | 598 | if (NamedMDNode *LinkerOptions598 = M.getNamedMetadata("llvm.linker.options")) { |
1157 | 7 | // Emit the linker options to the linker .drectve section. According to the |
1158 | 7 | // spec, this section is a space-separated string containing flags for |
1159 | 7 | // linker. |
1160 | 7 | MCSection *Sec = getDrectveSection(); |
1161 | 7 | Streamer.SwitchSection(Sec); |
1162 | 9 | for (const auto &Option : LinkerOptions->operands()) { |
1163 | 10 | for (const auto &Piece : cast<MDNode>(Option)->operands()) { |
1164 | 10 | // Lead with a space for consistency with our dllexport implementation. |
1165 | 10 | std::string Directive(" "); |
1166 | 10 | Directive.append(cast<MDString>(Piece)->getString()); |
1167 | 10 | Streamer.EmitBytes(Directive); |
1168 | 10 | } |
1169 | 9 | } |
1170 | 7 | } |
1171 | 598 | |
1172 | 598 | unsigned Version = 0; |
1173 | 598 | unsigned Flags = 0; |
1174 | 598 | StringRef Section; |
1175 | 598 | |
1176 | 598 | GetObjCImageInfo(M, Version, Flags, Section); |
1177 | 598 | if (Section.empty()) |
1178 | 595 | return; |
1179 | 3 | |
1180 | 3 | auto &C = getContext(); |
1181 | 3 | auto *S = C.getCOFFSection( |
1182 | 3 | Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, |
1183 | 3 | SectionKind::getReadOnly()); |
1184 | 3 | Streamer.SwitchSection(S); |
1185 | 3 | Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); |
1186 | 3 | Streamer.EmitIntValue(Version, 4); |
1187 | 3 | Streamer.EmitIntValue(Flags, 4); |
1188 | 3 | Streamer.AddBlankLine(); |
1189 | 3 | } |
1190 | | |
1191 | | void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, |
1192 | 603 | const TargetMachine &TM) { |
1193 | 603 | TargetLoweringObjectFile::Initialize(Ctx, TM); |
1194 | 603 | const Triple &T = TM.getTargetTriple(); |
1195 | 603 | if (T.isKnownWindowsMSVCEnvironment() || 603 T.isWindowsItaniumEnvironment()142 ) { |
1196 | 506 | StaticCtorSection = |
1197 | 506 | Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | |
1198 | 506 | COFF::IMAGE_SCN_MEM_READ, |
1199 | 506 | SectionKind::getReadOnly()); |
1200 | 506 | StaticDtorSection = |
1201 | 506 | Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | |
1202 | 506 | COFF::IMAGE_SCN_MEM_READ, |
1203 | 506 | SectionKind::getReadOnly()); |
1204 | 603 | } else { |
1205 | 97 | StaticCtorSection = Ctx.getCOFFSection( |
1206 | 97 | ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | |
1207 | 97 | COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, |
1208 | 97 | SectionKind::getData()); |
1209 | 97 | StaticDtorSection = Ctx.getCOFFSection( |
1210 | 97 | ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | |
1211 | 97 | COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, |
1212 | 97 | SectionKind::getData()); |
1213 | 97 | } |
1214 | 603 | } |
1215 | | |
1216 | | MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( |
1217 | 16 | unsigned Priority, const MCSymbol *KeySym) const { |
1218 | 16 | return getContext().getAssociativeCOFFSection( |
1219 | 16 | cast<MCSectionCOFF>(StaticCtorSection), KeySym, 0); |
1220 | 16 | } |
1221 | | |
1222 | | MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( |
1223 | 5 | unsigned Priority, const MCSymbol *KeySym) const { |
1224 | 5 | return getContext().getAssociativeCOFFSection( |
1225 | 5 | cast<MCSectionCOFF>(StaticDtorSection), KeySym, 0); |
1226 | 5 | } |
1227 | | |
1228 | | void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( |
1229 | 4.44k | raw_ostream &OS, const GlobalValue *GV) const { |
1230 | 4.44k | emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); |
1231 | 4.44k | } |
1232 | | |
1233 | | //===----------------------------------------------------------------------===// |
1234 | | // Wasm |
1235 | | //===----------------------------------------------------------------------===// |
1236 | | |
1237 | 0 | static const Comdat *getWasmComdat(const GlobalValue *GV) { |
1238 | 0 | const Comdat *C = GV->getComdat(); |
1239 | 0 | if (!C) |
1240 | 0 | return nullptr; |
1241 | 0 |
|
1242 | 0 | if (0 C->getSelectionKind() != Comdat::Any0 ) |
1243 | 0 | report_fatal_error("Wasm COMDATs only support SelectionKind::Any, '" + |
1244 | 0 | C->getName() + "' cannot be lowered."); |
1245 | 0 |
|
1246 | 0 | return C; |
1247 | 0 | } |
1248 | | |
1249 | | MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( |
1250 | 0 | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
1251 | 0 | StringRef Name = GO->getSection(); |
1252 | 0 | return getContext().getWasmSection(Name, wasm::WASM_SEC_DATA); |
1253 | 0 | } |
1254 | | |
1255 | | static MCSectionWasm *selectWasmSectionForGlobal( |
1256 | | MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, |
1257 | 0 | const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) { |
1258 | 0 | StringRef Group = ""; |
1259 | 0 | if (getWasmComdat(GO)) |
1260 | 0 | llvm_unreachable("comdat not yet supported for wasm"); |
1261 | 0 |
|
1262 | 0 | bool UniqueSectionNames = TM.getUniqueSectionNames(); |
1263 | 0 | SmallString<128> Name = getSectionPrefixForGlobal(Kind); |
1264 | 0 |
|
1265 | 0 | uint32_t Type = wasm::WASM_SEC_DATA; |
1266 | 0 | if (const auto *F0 = dyn_cast<Function>(GO)) { |
1267 | 0 | const auto &OptionalPrefix = F->getSectionPrefix(); |
1268 | 0 | if (OptionalPrefix) |
1269 | 0 | Name += *OptionalPrefix; |
1270 | 0 | Type = wasm::WASM_SEC_CODE; |
1271 | 0 | } |
1272 | 0 |
|
1273 | 0 | if (EmitUniqueSection && 0 UniqueSectionNames0 ) { |
1274 | 0 | Name.push_back('.'); |
1275 | 0 | TM.getNameWithPrefix(Name, GO, Mang, true); |
1276 | 0 | } |
1277 | 0 | unsigned UniqueID = MCContext::GenericSectionID; |
1278 | 0 | if (EmitUniqueSection && 0 !UniqueSectionNames0 ) { |
1279 | 0 | UniqueID = *NextUniqueID; |
1280 | 0 | (*NextUniqueID)++; |
1281 | 0 | } |
1282 | 0 | return Ctx.getWasmSection(Name, Type, Group, UniqueID); |
1283 | 0 | } |
1284 | | |
1285 | | MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( |
1286 | 0 | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { |
1287 | 0 |
|
1288 | 0 | if (Kind.isCommon()) |
1289 | 0 | report_fatal_error("mergable sections not supported yet on wasm"); |
1290 | 0 |
|
1291 | 0 | // If we have -ffunction-section or -fdata-section then we should emit the |
1292 | 0 | // global value to a uniqued section specifically for it. |
1293 | 0 | bool EmitUniqueSection = false; |
1294 | 0 | if (Kind.isText()) |
1295 | 0 | EmitUniqueSection = TM.getFunctionSections(); |
1296 | 0 | else |
1297 | 0 | EmitUniqueSection = TM.getDataSections(); |
1298 | 0 | EmitUniqueSection |= GO->hasComdat(); |
1299 | 0 |
|
1300 | 0 | return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, |
1301 | 0 | EmitUniqueSection, &NextUniqueID); |
1302 | 0 | } |
1303 | | |
1304 | | bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( |
1305 | 0 | bool UsesLabelDifference, const Function &F) const { |
1306 | 0 | // We can always create relative relocations, so use another section |
1307 | 0 | // that can be marked non-executable. |
1308 | 0 | return false; |
1309 | 0 | } |
1310 | | |
1311 | | const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( |
1312 | | const GlobalValue *LHS, const GlobalValue *RHS, |
1313 | 0 | const TargetMachine &TM) const { |
1314 | 0 | // We may only use a PLT-relative relocation to refer to unnamed_addr |
1315 | 0 | // functions. |
1316 | 0 | if (!LHS->hasGlobalUnnamedAddr() || 0 !LHS->getValueType()->isFunctionTy()0 ) |
1317 | 0 | return nullptr; |
1318 | 0 |
|
1319 | 0 | // Basic sanity checks. |
1320 | 0 | if (0 LHS->getType()->getPointerAddressSpace() != 0 || |
1321 | 0 | RHS->getType()->getPointerAddressSpace() != 00 || LHS->isThreadLocal()0 || |
1322 | 0 | RHS->isThreadLocal()) |
1323 | 0 | return nullptr; |
1324 | 0 |
|
1325 | 0 | return MCBinaryExpr::createSub( |
1326 | 0 | MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, |
1327 | 0 | getContext()), |
1328 | 0 | MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); |
1329 | 0 | } |
1330 | | |
1331 | | void |
1332 | 0 | TargetLoweringObjectFileWasm::InitializeWasm() { |
1333 | 0 | // TODO: Initialize StaticCtorSection and StaticDtorSection. |
1334 | 0 | } |