]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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" | |
970d7e83 LB |
16 | #include "llvm/ADT/SmallString.h" |
17 | #include "llvm/ADT/StringExtras.h" | |
18 | #include "llvm/ADT/Triple.h" | |
223e47cc | 19 | #include "llvm/CodeGen/MachineModuleInfoImpls.h" |
970d7e83 LB |
20 | #include "llvm/IR/Constants.h" |
21 | #include "llvm/IR/DataLayout.h" | |
22 | #include "llvm/IR/DerivedTypes.h" | |
23 | #include "llvm/IR/Function.h" | |
24 | #include "llvm/IR/GlobalVariable.h" | |
1a4d82fc | 25 | #include "llvm/IR/Mangler.h" |
970d7e83 | 26 | #include "llvm/IR/Module.h" |
223e47cc LB |
27 | #include "llvm/MC/MCContext.h" |
28 | #include "llvm/MC/MCExpr.h" | |
223e47cc | 29 | #include "llvm/MC/MCSectionCOFF.h" |
970d7e83 LB |
30 | #include "llvm/MC/MCSectionELF.h" |
31 | #include "llvm/MC/MCSectionMachO.h" | |
223e47cc LB |
32 | #include "llvm/MC/MCStreamer.h" |
33 | #include "llvm/MC/MCSymbol.h" | |
223e47cc LB |
34 | #include "llvm/Support/Dwarf.h" |
35 | #include "llvm/Support/ELF.h" | |
36 | #include "llvm/Support/ErrorHandling.h" | |
37 | #include "llvm/Support/raw_ostream.h" | |
1a4d82fc | 38 | #include "llvm/Target/TargetLowering.h" |
970d7e83 | 39 | #include "llvm/Target/TargetMachine.h" |
1a4d82fc | 40 | #include "llvm/Target/TargetSubtargetInfo.h" |
223e47cc LB |
41 | using namespace llvm; |
42 | using namespace dwarf; | |
43 | ||
44 | //===----------------------------------------------------------------------===// | |
45 | // ELF | |
46 | //===----------------------------------------------------------------------===// | |
47 | ||
1a4d82fc JJ |
48 | MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( |
49 | const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM, | |
50 | MachineModuleInfo *MMI) const { | |
223e47cc | 51 | unsigned Encoding = getPersonalityEncoding(); |
1a4d82fc | 52 | if ((Encoding & 0x80) == dwarf::DW_EH_PE_indirect) |
223e47cc | 53 | return getContext().GetOrCreateSymbol(StringRef("DW.ref.") + |
1a4d82fc JJ |
54 | TM.getSymbol(GV, Mang)->getName()); |
55 | if ((Encoding & 0x70) == dwarf::DW_EH_PE_absptr) | |
56 | return TM.getSymbol(GV, Mang); | |
57 | report_fatal_error("We do not support this DWARF encoding yet!"); | |
223e47cc LB |
58 | } |
59 | ||
60 | void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, | |
61 | const TargetMachine &TM, | |
62 | const MCSymbol *Sym) const { | |
63 | SmallString<64> NameData("DW.ref."); | |
64 | NameData += Sym->getName(); | |
65 | MCSymbol *Label = getContext().GetOrCreateSymbol(NameData); | |
66 | Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); | |
67 | Streamer.EmitSymbolAttribute(Label, MCSA_Weak); | |
68 | StringRef Prefix = ".data."; | |
69 | NameData.insert(NameData.begin(), Prefix.begin(), Prefix.end()); | |
70 | unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; | |
71 | const MCSection *Sec = getContext().getELFSection(NameData, | |
72 | ELF::SHT_PROGBITS, | |
73 | Flags, | |
74 | SectionKind::getDataRel(), | |
75 | 0, Label->getName()); | |
1a4d82fc | 76 | unsigned Size = TM.getSubtargetImpl()->getDataLayout()->getPointerSize(); |
223e47cc | 77 | Streamer.SwitchSection(Sec); |
1a4d82fc JJ |
78 | Streamer.EmitValueToAlignment( |
79 | TM.getSubtargetImpl()->getDataLayout()->getPointerABIAlignment()); | |
223e47cc LB |
80 | Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); |
81 | const MCExpr *E = MCConstantExpr::Create(Size, getContext()); | |
82 | Streamer.EmitELFSize(Label, E); | |
83 | Streamer.EmitLabel(Label); | |
84 | ||
85 | Streamer.EmitSymbolValue(Sym, Size); | |
86 | } | |
87 | ||
1a4d82fc JJ |
88 | const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( |
89 | const GlobalValue *GV, unsigned Encoding, Mangler &Mang, | |
90 | const TargetMachine &TM, MachineModuleInfo *MMI, | |
91 | MCStreamer &Streamer) const { | |
970d7e83 LB |
92 | |
93 | if (Encoding & dwarf::DW_EH_PE_indirect) { | |
94 | MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); | |
95 | ||
1a4d82fc | 96 | MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang, TM); |
970d7e83 LB |
97 | |
98 | // Add information about the stub reference to ELFMMI so that the stub | |
99 | // gets emitted by the asmprinter. | |
970d7e83 | 100 | MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); |
1a4d82fc JJ |
101 | if (!StubSym.getPointer()) { |
102 | MCSymbol *Sym = TM.getSymbol(GV, Mang); | |
970d7e83 LB |
103 | StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); |
104 | } | |
105 | ||
106 | return TargetLoweringObjectFile:: | |
107 | getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()), | |
108 | Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); | |
109 | } | |
110 | ||
111 | return TargetLoweringObjectFile:: | |
1a4d82fc | 112 | getTTypeGlobalReference(GV, Encoding, Mang, TM, MMI, Streamer); |
970d7e83 LB |
113 | } |
114 | ||
223e47cc LB |
115 | static SectionKind |
116 | getELFKindForNamedSection(StringRef Name, SectionKind K) { | |
117 | // N.B.: The defaults used in here are no the same ones used in MC. | |
118 | // We follow gcc, MC follows gas. For example, given ".section .eh_frame", | |
119 | // both gas and MC will produce a section with no flags. Given | |
120 | // section(".eh_frame") gcc will produce: | |
121 | // | |
122 | // .section .eh_frame,"a",@progbits | |
123 | if (Name.empty() || Name[0] != '.') return K; | |
124 | ||
125 | // Some lame default implementation based on some magic section names. | |
126 | if (Name == ".bss" || | |
127 | Name.startswith(".bss.") || | |
128 | Name.startswith(".gnu.linkonce.b.") || | |
129 | Name.startswith(".llvm.linkonce.b.") || | |
130 | Name == ".sbss" || | |
131 | Name.startswith(".sbss.") || | |
132 | Name.startswith(".gnu.linkonce.sb.") || | |
133 | Name.startswith(".llvm.linkonce.sb.")) | |
134 | return SectionKind::getBSS(); | |
135 | ||
136 | if (Name == ".tdata" || | |
137 | Name.startswith(".tdata.") || | |
138 | Name.startswith(".gnu.linkonce.td.") || | |
139 | Name.startswith(".llvm.linkonce.td.")) | |
140 | return SectionKind::getThreadData(); | |
141 | ||
142 | if (Name == ".tbss" || | |
143 | Name.startswith(".tbss.") || | |
144 | Name.startswith(".gnu.linkonce.tb.") || | |
145 | Name.startswith(".llvm.linkonce.tb.")) | |
146 | return SectionKind::getThreadBSS(); | |
147 | ||
148 | return K; | |
149 | } | |
150 | ||
151 | ||
152 | static unsigned getELFSectionType(StringRef Name, SectionKind K) { | |
153 | ||
154 | if (Name == ".init_array") | |
155 | return ELF::SHT_INIT_ARRAY; | |
156 | ||
157 | if (Name == ".fini_array") | |
158 | return ELF::SHT_FINI_ARRAY; | |
159 | ||
160 | if (Name == ".preinit_array") | |
161 | return ELF::SHT_PREINIT_ARRAY; | |
162 | ||
163 | if (K.isBSS() || K.isThreadBSS()) | |
164 | return ELF::SHT_NOBITS; | |
165 | ||
166 | return ELF::SHT_PROGBITS; | |
167 | } | |
168 | ||
169 | ||
170 | static unsigned | |
171 | getELFSectionFlags(SectionKind K) { | |
172 | unsigned Flags = 0; | |
173 | ||
174 | if (!K.isMetadata()) | |
175 | Flags |= ELF::SHF_ALLOC; | |
176 | ||
177 | if (K.isText()) | |
178 | Flags |= ELF::SHF_EXECINSTR; | |
179 | ||
180 | if (K.isWriteable()) | |
181 | Flags |= ELF::SHF_WRITE; | |
182 | ||
183 | if (K.isThreadLocal()) | |
184 | Flags |= ELF::SHF_TLS; | |
185 | ||
186 | // K.isMergeableConst() is left out to honour PR4650 | |
187 | if (K.isMergeableCString() || K.isMergeableConst4() || | |
188 | K.isMergeableConst8() || K.isMergeableConst16()) | |
189 | Flags |= ELF::SHF_MERGE; | |
190 | ||
191 | if (K.isMergeableCString()) | |
192 | Flags |= ELF::SHF_STRINGS; | |
193 | ||
194 | return Flags; | |
195 | } | |
196 | ||
1a4d82fc JJ |
197 | static const Comdat *getELFComdat(const GlobalValue *GV) { |
198 | const Comdat *C = GV->getComdat(); | |
199 | if (!C) | |
200 | return nullptr; | |
223e47cc | 201 | |
1a4d82fc JJ |
202 | if (C->getSelectionKind() != Comdat::Any) |
203 | report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + | |
204 | C->getName() + "' cannot be lowered."); | |
205 | ||
206 | return C; | |
207 | } | |
208 | ||
209 | const MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( | |
210 | const GlobalValue *GV, SectionKind Kind, Mangler &Mang, | |
211 | const TargetMachine &TM) const { | |
223e47cc LB |
212 | StringRef SectionName = GV->getSection(); |
213 | ||
214 | // Infer section flags from the section name if we can. | |
215 | Kind = getELFKindForNamedSection(SectionName, Kind); | |
216 | ||
1a4d82fc JJ |
217 | StringRef Group = ""; |
218 | unsigned Flags = getELFSectionFlags(Kind); | |
219 | if (const Comdat *C = getELFComdat(GV)) { | |
220 | Group = C->getName(); | |
221 | Flags |= ELF::SHF_GROUP; | |
222 | } | |
223e47cc | 223 | return getContext().getELFSection(SectionName, |
1a4d82fc JJ |
224 | getELFSectionType(SectionName, Kind), Flags, |
225 | Kind, /*EntrySize=*/0, Group); | |
223e47cc LB |
226 | } |
227 | ||
228 | /// getSectionPrefixForGlobal - Return the section prefix name used by options | |
229 | /// FunctionsSections and DataSections. | |
1a4d82fc | 230 | static StringRef getSectionPrefixForGlobal(SectionKind Kind) { |
223e47cc LB |
231 | if (Kind.isText()) return ".text."; |
232 | if (Kind.isReadOnly()) return ".rodata."; | |
233 | if (Kind.isBSS()) return ".bss."; | |
234 | ||
235 | if (Kind.isThreadData()) return ".tdata."; | |
236 | if (Kind.isThreadBSS()) return ".tbss."; | |
237 | ||
238 | if (Kind.isDataNoRel()) return ".data."; | |
239 | if (Kind.isDataRelLocal()) return ".data.rel.local."; | |
240 | if (Kind.isDataRel()) return ".data.rel."; | |
241 | if (Kind.isReadOnlyWithRelLocal()) return ".data.rel.ro.local."; | |
242 | ||
243 | assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); | |
244 | return ".data.rel.ro."; | |
245 | } | |
246 | ||
223e47cc LB |
247 | const MCSection *TargetLoweringObjectFileELF:: |
248 | SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, | |
1a4d82fc | 249 | Mangler &Mang, const TargetMachine &TM) const { |
223e47cc LB |
250 | // If we have -ffunction-section or -fdata-section then we should emit the |
251 | // global value to a uniqued section specifically for it. | |
252 | bool EmitUniquedSection; | |
253 | if (Kind.isText()) | |
254 | EmitUniquedSection = TM.getFunctionSections(); | |
255 | else | |
256 | EmitUniquedSection = TM.getDataSections(); | |
257 | ||
258 | // If this global is linkonce/weak and the target handles this by emitting it | |
259 | // into a 'uniqued' section name, create and return the section now. | |
1a4d82fc | 260 | if ((GV->isWeakForLinker() || EmitUniquedSection || GV->hasComdat()) && |
223e47cc | 261 | !Kind.isCommon()) { |
1a4d82fc JJ |
262 | StringRef Prefix = getSectionPrefixForGlobal(Kind); |
263 | ||
264 | SmallString<128> Name(Prefix); | |
265 | TM.getNameWithPrefix(Name, GV, Mang, true); | |
223e47cc | 266 | |
223e47cc LB |
267 | StringRef Group = ""; |
268 | unsigned Flags = getELFSectionFlags(Kind); | |
1a4d82fc JJ |
269 | if (GV->isWeakForLinker() || GV->hasComdat()) { |
270 | if (const Comdat *C = getELFComdat(GV)) | |
271 | Group = C->getName(); | |
272 | else | |
273 | Group = Name.substr(Prefix.size()); | |
223e47cc LB |
274 | Flags |= ELF::SHF_GROUP; |
275 | } | |
276 | ||
277 | return getContext().getELFSection(Name.str(), | |
278 | getELFSectionType(Name.str(), Kind), | |
279 | Flags, Kind, 0, Group); | |
280 | } | |
281 | ||
282 | if (Kind.isText()) return TextSection; | |
283 | ||
284 | if (Kind.isMergeable1ByteCString() || | |
285 | Kind.isMergeable2ByteCString() || | |
286 | Kind.isMergeable4ByteCString()) { | |
287 | ||
288 | // We also need alignment here. | |
289 | // FIXME: this is getting the alignment of the character, not the | |
290 | // alignment of the global! | |
291 | unsigned Align = | |
1a4d82fc JJ |
292 | TM.getSubtargetImpl()->getDataLayout()->getPreferredAlignment( |
293 | cast<GlobalVariable>(GV)); | |
223e47cc LB |
294 | |
295 | const char *SizeSpec = ".rodata.str1."; | |
296 | if (Kind.isMergeable2ByteCString()) | |
297 | SizeSpec = ".rodata.str2."; | |
298 | else if (Kind.isMergeable4ByteCString()) | |
299 | SizeSpec = ".rodata.str4."; | |
300 | else | |
301 | assert(Kind.isMergeable1ByteCString() && "unknown string width"); | |
302 | ||
303 | ||
304 | std::string Name = SizeSpec + utostr(Align); | |
305 | return getContext().getELFSection(Name, ELF::SHT_PROGBITS, | |
306 | ELF::SHF_ALLOC | | |
307 | ELF::SHF_MERGE | | |
308 | ELF::SHF_STRINGS, | |
309 | Kind); | |
310 | } | |
311 | ||
312 | if (Kind.isMergeableConst()) { | |
313 | if (Kind.isMergeableConst4() && MergeableConst4Section) | |
314 | return MergeableConst4Section; | |
315 | if (Kind.isMergeableConst8() && MergeableConst8Section) | |
316 | return MergeableConst8Section; | |
317 | if (Kind.isMergeableConst16() && MergeableConst16Section) | |
318 | return MergeableConst16Section; | |
319 | return ReadOnlySection; // .const | |
320 | } | |
321 | ||
322 | if (Kind.isReadOnly()) return ReadOnlySection; | |
323 | ||
324 | if (Kind.isThreadData()) return TLSDataSection; | |
325 | if (Kind.isThreadBSS()) return TLSBSSSection; | |
326 | ||
327 | // Note: we claim that common symbols are put in BSSSection, but they are | |
328 | // really emitted with the magic .comm directive, which creates a symbol table | |
329 | // entry but not a section. | |
330 | if (Kind.isBSS() || Kind.isCommon()) return BSSSection; | |
331 | ||
332 | if (Kind.isDataNoRel()) return DataSection; | |
333 | if (Kind.isDataRelLocal()) return DataRelLocalSection; | |
334 | if (Kind.isDataRel()) return DataRelSection; | |
335 | if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection; | |
336 | ||
337 | assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); | |
338 | return DataRelROSection; | |
339 | } | |
340 | ||
341 | /// getSectionForConstant - Given a mergeable constant with the | |
342 | /// specified size and relocation information, return a section that it | |
343 | /// should be placed in. | |
1a4d82fc JJ |
344 | const MCSection * |
345 | TargetLoweringObjectFileELF::getSectionForConstant(SectionKind Kind, | |
346 | const Constant *C) const { | |
223e47cc LB |
347 | if (Kind.isMergeableConst4() && MergeableConst4Section) |
348 | return MergeableConst4Section; | |
349 | if (Kind.isMergeableConst8() && MergeableConst8Section) | |
350 | return MergeableConst8Section; | |
351 | if (Kind.isMergeableConst16() && MergeableConst16Section) | |
352 | return MergeableConst16Section; | |
353 | if (Kind.isReadOnly()) | |
354 | return ReadOnlySection; | |
355 | ||
356 | if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection; | |
357 | assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); | |
358 | return DataRelROSection; | |
359 | } | |
360 | ||
1a4d82fc JJ |
361 | static const MCSectionELF *getStaticStructorSection(MCContext &Ctx, |
362 | bool UseInitArray, | |
363 | bool IsCtor, | |
364 | unsigned Priority, | |
365 | const MCSymbol *KeySym) { | |
366 | std::string Name; | |
367 | unsigned Type; | |
368 | unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; | |
369 | SectionKind Kind = SectionKind::getDataRel(); | |
370 | StringRef COMDAT = KeySym ? KeySym->getName() : ""; | |
371 | ||
372 | if (KeySym) | |
373 | Flags |= ELF::SHF_GROUP; | |
223e47cc LB |
374 | |
375 | if (UseInitArray) { | |
1a4d82fc JJ |
376 | if (IsCtor) { |
377 | Type = ELF::SHT_INIT_ARRAY; | |
378 | Name = ".init_array"; | |
379 | } else { | |
380 | Type = ELF::SHT_FINI_ARRAY; | |
381 | Name = ".fini_array"; | |
382 | } | |
383 | if (Priority != 65535) { | |
384 | Name += '.'; | |
385 | Name += utostr(Priority); | |
386 | } | |
223e47cc | 387 | } else { |
1a4d82fc JJ |
388 | // The default scheme is .ctor / .dtor, so we have to invert the priority |
389 | // numbering. | |
390 | if (IsCtor) | |
391 | Name = ".ctors"; | |
392 | else | |
393 | Name = ".dtors"; | |
394 | if (Priority != 65535) { | |
395 | Name += '.'; | |
396 | Name += utostr(65535 - Priority); | |
397 | } | |
398 | Type = ELF::SHT_PROGBITS; | |
223e47cc | 399 | } |
1a4d82fc JJ |
400 | |
401 | return Ctx.getELFSection(Name, Type, Flags, Kind, 0, COMDAT); | |
223e47cc LB |
402 | } |
403 | ||
1a4d82fc JJ |
404 | const MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( |
405 | unsigned Priority, const MCSymbol *KeySym) const { | |
406 | return getStaticStructorSection(getContext(), UseInitArray, true, Priority, | |
407 | KeySym); | |
408 | } | |
223e47cc | 409 | |
1a4d82fc JJ |
410 | const MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( |
411 | unsigned Priority, const MCSymbol *KeySym) const { | |
412 | return getStaticStructorSection(getContext(), UseInitArray, false, Priority, | |
413 | KeySym); | |
223e47cc LB |
414 | } |
415 | ||
416 | void | |
417 | TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { | |
418 | UseInitArray = UseInitArray_; | |
419 | if (!UseInitArray) | |
420 | return; | |
421 | ||
422 | StaticCtorSection = | |
423 | getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY, | |
424 | ELF::SHF_WRITE | | |
425 | ELF::SHF_ALLOC, | |
426 | SectionKind::getDataRel()); | |
427 | StaticDtorSection = | |
428 | getContext().getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, | |
429 | ELF::SHF_WRITE | | |
430 | ELF::SHF_ALLOC, | |
431 | SectionKind::getDataRel()); | |
432 | } | |
433 | ||
434 | //===----------------------------------------------------------------------===// | |
435 | // MachO | |
436 | //===----------------------------------------------------------------------===// | |
437 | ||
1a4d82fc JJ |
438 | /// getDepLibFromLinkerOpt - Extract the dependent library name from a linker |
439 | /// option string. Returns StringRef() if the option does not specify a library. | |
440 | StringRef TargetLoweringObjectFileMachO:: | |
441 | getDepLibFromLinkerOpt(StringRef LinkerOption) const { | |
442 | const char *LibCmd = "-l"; | |
443 | if (LinkerOption.startswith(LibCmd)) | |
444 | return LinkerOption.substr(strlen(LibCmd)); | |
445 | return StringRef(); | |
446 | } | |
447 | ||
970d7e83 | 448 | /// emitModuleFlags - Perform code emission for module flags. |
223e47cc LB |
449 | void TargetLoweringObjectFileMachO:: |
450 | emitModuleFlags(MCStreamer &Streamer, | |
451 | ArrayRef<Module::ModuleFlagEntry> ModuleFlags, | |
1a4d82fc | 452 | Mangler &Mang, const TargetMachine &TM) const { |
223e47cc LB |
453 | unsigned VersionVal = 0; |
454 | unsigned ImageInfoFlags = 0; | |
1a4d82fc | 455 | MDNode *LinkerOptions = nullptr; |
223e47cc LB |
456 | StringRef SectionVal; |
457 | ||
458 | for (ArrayRef<Module::ModuleFlagEntry>::iterator | |
459 | i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) { | |
460 | const Module::ModuleFlagEntry &MFE = *i; | |
461 | ||
462 | // Ignore flags with 'Require' behavior. | |
463 | if (MFE.Behavior == Module::Require) | |
464 | continue; | |
465 | ||
466 | StringRef Key = MFE.Key->getString(); | |
85aaf69f | 467 | Metadata *Val = MFE.Val; |
223e47cc | 468 | |
970d7e83 | 469 | if (Key == "Objective-C Image Info Version") { |
85aaf69f | 470 | VersionVal = mdconst::extract<ConstantInt>(Val)->getZExtValue(); |
970d7e83 LB |
471 | } else if (Key == "Objective-C Garbage Collection" || |
472 | Key == "Objective-C GC Only" || | |
85aaf69f SL |
473 | Key == "Objective-C Is Simulated" || |
474 | Key == "Objective-C Image Swift Version") { | |
475 | ImageInfoFlags |= mdconst::extract<ConstantInt>(Val)->getZExtValue(); | |
970d7e83 | 476 | } else if (Key == "Objective-C Image Info Section") { |
223e47cc | 477 | SectionVal = cast<MDString>(Val)->getString(); |
970d7e83 LB |
478 | } else if (Key == "Linker Options") { |
479 | LinkerOptions = cast<MDNode>(Val); | |
480 | } | |
481 | } | |
482 | ||
483 | // Emit the linker options if present. | |
484 | if (LinkerOptions) { | |
485 | for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { | |
486 | MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i)); | |
487 | SmallVector<std::string, 4> StrOptions; | |
488 | ||
489 | // Convert to strings. | |
490 | for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) { | |
491 | MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii)); | |
492 | StrOptions.push_back(MDOption->getString()); | |
493 | } | |
494 | ||
495 | Streamer.EmitLinkerOptions(StrOptions); | |
496 | } | |
223e47cc LB |
497 | } |
498 | ||
499 | // The section is mandatory. If we don't have it, then we don't have GC info. | |
500 | if (SectionVal.empty()) return; | |
501 | ||
502 | StringRef Segment, Section; | |
503 | unsigned TAA = 0, StubSize = 0; | |
504 | bool TAAParsed; | |
505 | std::string ErrorCode = | |
506 | MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, | |
507 | TAA, TAAParsed, StubSize); | |
508 | if (!ErrorCode.empty()) | |
509 | // If invalid, report the error with report_fatal_error. | |
510 | report_fatal_error("Invalid section specifier '" + Section + "': " + | |
511 | ErrorCode + "."); | |
512 | ||
513 | // Get the section. | |
514 | const MCSectionMachO *S = | |
515 | getContext().getMachOSection(Segment, Section, TAA, StubSize, | |
516 | SectionKind::getDataNoRel()); | |
517 | Streamer.SwitchSection(S); | |
518 | Streamer.EmitLabel(getContext(). | |
519 | GetOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); | |
520 | Streamer.EmitIntValue(VersionVal, 4); | |
521 | Streamer.EmitIntValue(ImageInfoFlags, 4); | |
522 | Streamer.AddBlankLine(); | |
523 | } | |
524 | ||
1a4d82fc JJ |
525 | static void checkMachOComdat(const GlobalValue *GV) { |
526 | const Comdat *C = GV->getComdat(); | |
527 | if (!C) | |
528 | return; | |
529 | ||
530 | report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + | |
531 | "' cannot be lowered."); | |
532 | } | |
533 | ||
534 | const MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( | |
535 | const GlobalValue *GV, SectionKind Kind, Mangler &Mang, | |
536 | const TargetMachine &TM) const { | |
223e47cc LB |
537 | // Parse the section specifier and create it if valid. |
538 | StringRef Segment, Section; | |
539 | unsigned TAA = 0, StubSize = 0; | |
540 | bool TAAParsed; | |
1a4d82fc JJ |
541 | |
542 | checkMachOComdat(GV); | |
543 | ||
223e47cc LB |
544 | std::string ErrorCode = |
545 | MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section, | |
546 | TAA, TAAParsed, StubSize); | |
547 | if (!ErrorCode.empty()) { | |
548 | // If invalid, report the error with report_fatal_error. | |
549 | report_fatal_error("Global variable '" + GV->getName() + | |
550 | "' has an invalid section specifier '" + | |
551 | GV->getSection() + "': " + ErrorCode + "."); | |
552 | } | |
553 | ||
554 | // Get the section. | |
555 | const MCSectionMachO *S = | |
556 | getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); | |
557 | ||
558 | // If TAA wasn't set by ParseSectionSpecifier() above, | |
559 | // use the value returned by getMachOSection() as a default. | |
560 | if (!TAAParsed) | |
561 | TAA = S->getTypeAndAttributes(); | |
562 | ||
563 | // Okay, now that we got the section, verify that the TAA & StubSize agree. | |
564 | // If the user declared multiple globals with different section flags, we need | |
565 | // to reject it here. | |
566 | if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { | |
567 | // If invalid, report the error with report_fatal_error. | |
568 | report_fatal_error("Global variable '" + GV->getName() + | |
569 | "' section type or attributes does not match previous" | |
570 | " section specifier"); | |
571 | } | |
572 | ||
573 | return S; | |
574 | } | |
575 | ||
576 | const MCSection *TargetLoweringObjectFileMachO:: | |
577 | SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, | |
1a4d82fc JJ |
578 | Mangler &Mang, const TargetMachine &TM) const { |
579 | checkMachOComdat(GV); | |
223e47cc LB |
580 | |
581 | // Handle thread local data. | |
582 | if (Kind.isThreadBSS()) return TLSBSSSection; | |
583 | if (Kind.isThreadData()) return TLSDataSection; | |
584 | ||
585 | if (Kind.isText()) | |
586 | return GV->isWeakForLinker() ? TextCoalSection : TextSection; | |
587 | ||
588 | // If this is weak/linkonce, put this in a coalescable section, either in text | |
589 | // or data depending on if it is writable. | |
590 | if (GV->isWeakForLinker()) { | |
591 | if (Kind.isReadOnly()) | |
592 | return ConstTextCoalSection; | |
593 | return DataCoalSection; | |
594 | } | |
595 | ||
596 | // FIXME: Alignment check should be handled by section classifier. | |
597 | if (Kind.isMergeable1ByteCString() && | |
1a4d82fc JJ |
598 | TM.getSubtargetImpl()->getDataLayout()->getPreferredAlignment( |
599 | cast<GlobalVariable>(GV)) < 32) | |
223e47cc LB |
600 | return CStringSection; |
601 | ||
602 | // Do not put 16-bit arrays in the UString section if they have an | |
603 | // externally visible label, this runs into issues with certain linker | |
604 | // versions. | |
605 | if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() && | |
1a4d82fc JJ |
606 | TM.getSubtargetImpl()->getDataLayout()->getPreferredAlignment( |
607 | cast<GlobalVariable>(GV)) < 32) | |
223e47cc LB |
608 | return UStringSection; |
609 | ||
1a4d82fc JJ |
610 | // With MachO only variables whose corresponding symbol starts with 'l' or |
611 | // 'L' can be merged, so we only try merging GVs with private linkage. | |
612 | if (GV->hasPrivateLinkage() && Kind.isMergeableConst()) { | |
223e47cc LB |
613 | if (Kind.isMergeableConst4()) |
614 | return FourByteConstantSection; | |
615 | if (Kind.isMergeableConst8()) | |
616 | return EightByteConstantSection; | |
1a4d82fc | 617 | if (Kind.isMergeableConst16()) |
223e47cc LB |
618 | return SixteenByteConstantSection; |
619 | } | |
620 | ||
621 | // Otherwise, if it is readonly, but not something we can specially optimize, | |
622 | // just drop it in .const. | |
623 | if (Kind.isReadOnly()) | |
624 | return ReadOnlySection; | |
625 | ||
626 | // If this is marked const, put it into a const section. But if the dynamic | |
627 | // linker needs to write to it, put it in the data segment. | |
628 | if (Kind.isReadOnlyWithRel()) | |
629 | return ConstDataSection; | |
630 | ||
631 | // Put zero initialized globals with strong external linkage in the | |
632 | // DATA, __common section with the .zerofill directive. | |
633 | if (Kind.isBSSExtern()) | |
634 | return DataCommonSection; | |
635 | ||
636 | // Put zero initialized globals with local linkage in __DATA,__bss directive | |
637 | // with the .zerofill directive (aka .lcomm). | |
638 | if (Kind.isBSSLocal()) | |
639 | return DataBSSSection; | |
640 | ||
641 | // Otherwise, just drop the variable in the normal data section. | |
642 | return DataSection; | |
643 | } | |
644 | ||
645 | const MCSection * | |
1a4d82fc JJ |
646 | TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind, |
647 | const Constant *C) const { | |
223e47cc LB |
648 | // If this constant requires a relocation, we have to put it in the data |
649 | // segment, not in the text segment. | |
650 | if (Kind.isDataRel() || Kind.isReadOnlyWithRel()) | |
651 | return ConstDataSection; | |
652 | ||
653 | if (Kind.isMergeableConst4()) | |
654 | return FourByteConstantSection; | |
655 | if (Kind.isMergeableConst8()) | |
656 | return EightByteConstantSection; | |
1a4d82fc | 657 | if (Kind.isMergeableConst16()) |
223e47cc LB |
658 | return SixteenByteConstantSection; |
659 | return ReadOnlySection; // .const | |
660 | } | |
661 | ||
1a4d82fc JJ |
662 | const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( |
663 | const GlobalValue *GV, unsigned Encoding, Mangler &Mang, | |
664 | const TargetMachine &TM, MachineModuleInfo *MMI, | |
665 | MCStreamer &Streamer) const { | |
223e47cc LB |
666 | // The mach-o version of this method defaults to returning a stub reference. |
667 | ||
668 | if (Encoding & DW_EH_PE_indirect) { | |
669 | MachineModuleInfoMachO &MachOMMI = | |
670 | MMI->getObjFileInfo<MachineModuleInfoMachO>(); | |
671 | ||
1a4d82fc JJ |
672 | MCSymbol *SSym = |
673 | getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang, TM); | |
223e47cc LB |
674 | |
675 | // Add information about the stub reference to MachOMMI so that the stub | |
676 | // gets emitted by the asmprinter. | |
223e47cc LB |
677 | MachineModuleInfoImpl::StubValueTy &StubSym = |
678 | GV->hasHiddenVisibility() ? MachOMMI.getHiddenGVStubEntry(SSym) : | |
679 | MachOMMI.getGVStubEntry(SSym); | |
1a4d82fc JJ |
680 | if (!StubSym.getPointer()) { |
681 | MCSymbol *Sym = TM.getSymbol(GV, Mang); | |
223e47cc LB |
682 | StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); |
683 | } | |
684 | ||
685 | return TargetLoweringObjectFile:: | |
970d7e83 LB |
686 | getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()), |
687 | Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); | |
223e47cc LB |
688 | } |
689 | ||
1a4d82fc JJ |
690 | return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, Mang, |
691 | TM, MMI, Streamer); | |
223e47cc LB |
692 | } |
693 | ||
1a4d82fc JJ |
694 | MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( |
695 | const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM, | |
696 | MachineModuleInfo *MMI) const { | |
223e47cc LB |
697 | // The mach-o version of this method defaults to returning a stub reference. |
698 | MachineModuleInfoMachO &MachOMMI = | |
699 | MMI->getObjFileInfo<MachineModuleInfoMachO>(); | |
700 | ||
1a4d82fc | 701 | MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang, TM); |
223e47cc LB |
702 | |
703 | // Add information about the stub reference to MachOMMI so that the stub | |
704 | // gets emitted by the asmprinter. | |
223e47cc | 705 | MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); |
1a4d82fc JJ |
706 | if (!StubSym.getPointer()) { |
707 | MCSymbol *Sym = TM.getSymbol(GV, Mang); | |
223e47cc LB |
708 | StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); |
709 | } | |
710 | ||
711 | return SSym; | |
712 | } | |
713 | ||
714 | //===----------------------------------------------------------------------===// | |
715 | // COFF | |
716 | //===----------------------------------------------------------------------===// | |
717 | ||
718 | static unsigned | |
719 | getCOFFSectionFlags(SectionKind K) { | |
720 | unsigned Flags = 0; | |
721 | ||
722 | if (K.isMetadata()) | |
723 | Flags |= | |
724 | COFF::IMAGE_SCN_MEM_DISCARDABLE; | |
725 | else if (K.isText()) | |
726 | Flags |= | |
727 | COFF::IMAGE_SCN_MEM_EXECUTE | | |
728 | COFF::IMAGE_SCN_MEM_READ | | |
729 | COFF::IMAGE_SCN_CNT_CODE; | |
1a4d82fc | 730 | else if (K.isBSS()) |
223e47cc LB |
731 | Flags |= |
732 | COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | | |
733 | COFF::IMAGE_SCN_MEM_READ | | |
734 | COFF::IMAGE_SCN_MEM_WRITE; | |
735 | else if (K.isThreadLocal()) | |
736 | Flags |= | |
737 | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | | |
738 | COFF::IMAGE_SCN_MEM_READ | | |
739 | COFF::IMAGE_SCN_MEM_WRITE; | |
1a4d82fc | 740 | else if (K.isReadOnly() || K.isReadOnlyWithRel()) |
223e47cc LB |
741 | Flags |= |
742 | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | | |
743 | COFF::IMAGE_SCN_MEM_READ; | |
744 | else if (K.isWriteable()) | |
745 | Flags |= | |
746 | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | | |
747 | COFF::IMAGE_SCN_MEM_READ | | |
748 | COFF::IMAGE_SCN_MEM_WRITE; | |
749 | ||
750 | return Flags; | |
751 | } | |
752 | ||
1a4d82fc JJ |
753 | static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { |
754 | const Comdat *C = GV->getComdat(); | |
755 | assert(C && "expected GV to have a Comdat!"); | |
756 | ||
757 | StringRef ComdatGVName = C->getName(); | |
758 | const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); | |
759 | if (!ComdatGV) | |
760 | report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + | |
761 | "' does not exist."); | |
762 | ||
763 | if (ComdatGV->getComdat() != C) | |
764 | report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + | |
765 | "' is not a key for its COMDAT."); | |
766 | ||
767 | return ComdatGV; | |
768 | } | |
769 | ||
770 | static int getSelectionForCOFF(const GlobalValue *GV) { | |
771 | if (const Comdat *C = GV->getComdat()) { | |
772 | const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); | |
773 | if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) | |
774 | ComdatKey = GA->getBaseObject(); | |
775 | if (ComdatKey == GV) { | |
776 | switch (C->getSelectionKind()) { | |
777 | case Comdat::Any: | |
778 | return COFF::IMAGE_COMDAT_SELECT_ANY; | |
779 | case Comdat::ExactMatch: | |
780 | return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; | |
781 | case Comdat::Largest: | |
782 | return COFF::IMAGE_COMDAT_SELECT_LARGEST; | |
783 | case Comdat::NoDuplicates: | |
784 | return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; | |
785 | case Comdat::SameSize: | |
786 | return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; | |
787 | } | |
788 | } else { | |
789 | return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; | |
790 | } | |
791 | } else if (GV->isWeakForLinker()) { | |
792 | return COFF::IMAGE_COMDAT_SELECT_ANY; | |
793 | } | |
794 | return 0; | |
795 | } | |
796 | ||
797 | const MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( | |
798 | const GlobalValue *GV, SectionKind Kind, Mangler &Mang, | |
799 | const TargetMachine &TM) const { | |
970d7e83 LB |
800 | int Selection = 0; |
801 | unsigned Characteristics = getCOFFSectionFlags(Kind); | |
1a4d82fc JJ |
802 | StringRef Name = GV->getSection(); |
803 | StringRef COMDATSymName = ""; | |
804 | if ((GV->isWeakForLinker() || GV->hasComdat()) && !Kind.isCommon()) { | |
805 | Selection = getSelectionForCOFF(GV); | |
806 | const GlobalValue *ComdatGV; | |
807 | if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) | |
808 | ComdatGV = getComdatGVForCOFF(GV); | |
809 | else | |
810 | ComdatGV = GV; | |
811 | ||
812 | if (!ComdatGV->hasPrivateLinkage()) { | |
813 | MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang); | |
814 | COMDATSymName = Sym->getName(); | |
815 | Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; | |
816 | } else { | |
817 | Selection = 0; | |
818 | } | |
970d7e83 LB |
819 | } |
820 | return getContext().getCOFFSection(Name, | |
821 | Characteristics, | |
1a4d82fc JJ |
822 | Kind, |
823 | COMDATSymName, | |
824 | Selection); | |
223e47cc LB |
825 | } |
826 | ||
1a4d82fc | 827 | static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { |
223e47cc | 828 | if (Kind.isText()) |
1a4d82fc JJ |
829 | return ".text"; |
830 | if (Kind.isBSS()) | |
831 | return ".bss"; | |
832 | if (Kind.isThreadLocal()) | |
833 | return ".tls$"; | |
834 | if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) | |
835 | return ".rdata"; | |
836 | return ".data"; | |
223e47cc LB |
837 | } |
838 | ||
839 | ||
840 | const MCSection *TargetLoweringObjectFileCOFF:: | |
841 | SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, | |
1a4d82fc JJ |
842 | Mangler &Mang, const TargetMachine &TM) const { |
843 | // If we have -ffunction-sections then we should emit the global value to a | |
844 | // uniqued section specifically for it. | |
845 | bool EmitUniquedSection; | |
846 | if (Kind.isText()) | |
847 | EmitUniquedSection = TM.getFunctionSections(); | |
848 | else | |
849 | EmitUniquedSection = TM.getDataSections(); | |
223e47cc LB |
850 | |
851 | // If this global is linkonce/weak and the target handles this by emitting it | |
852 | // into a 'uniqued' section name, create and return the section now. | |
1a4d82fc JJ |
853 | // Section names depend on the name of the symbol which is not feasible if the |
854 | // symbol has private linkage. | |
855 | if ((GV->isWeakForLinker() || EmitUniquedSection || GV->hasComdat()) && | |
856 | !Kind.isCommon()) { | |
857 | const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); | |
223e47cc LB |
858 | unsigned Characteristics = getCOFFSectionFlags(Kind); |
859 | ||
860 | Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; | |
1a4d82fc JJ |
861 | int Selection = getSelectionForCOFF(GV); |
862 | if (!Selection) | |
863 | Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; | |
864 | const GlobalValue *ComdatGV; | |
865 | if (GV->hasComdat()) | |
866 | ComdatGV = getComdatGVForCOFF(GV); | |
867 | else | |
868 | ComdatGV = GV; | |
223e47cc | 869 | |
1a4d82fc JJ |
870 | if (!ComdatGV->hasPrivateLinkage()) { |
871 | MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang); | |
872 | StringRef COMDATSymName = Sym->getName(); | |
873 | return getContext().getCOFFSection(Name, Characteristics, Kind, | |
874 | COMDATSymName, Selection); | |
875 | } | |
223e47cc LB |
876 | } |
877 | ||
878 | if (Kind.isText()) | |
1a4d82fc | 879 | return TextSection; |
223e47cc LB |
880 | |
881 | if (Kind.isThreadLocal()) | |
1a4d82fc JJ |
882 | return TLSDataSection; |
883 | ||
884 | if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) | |
885 | return ReadOnlySection; | |
223e47cc | 886 | |
1a4d82fc JJ |
887 | // Note: we claim that common symbols are put in BSSSection, but they are |
888 | // really emitted with the magic .comm directive, which creates a symbol table | |
889 | // entry but not a section. | |
890 | if (Kind.isBSS() || Kind.isCommon()) | |
891 | return BSSSection; | |
892 | ||
893 | return DataSection; | |
894 | } | |
895 | ||
896 | StringRef TargetLoweringObjectFileCOFF:: | |
897 | getDepLibFromLinkerOpt(StringRef LinkerOption) const { | |
898 | const char *LibCmd = "/DEFAULTLIB:"; | |
899 | if (LinkerOption.startswith(LibCmd)) | |
900 | return LinkerOption.substr(strlen(LibCmd)); | |
901 | return StringRef(); | |
902 | } | |
903 | ||
904 | void TargetLoweringObjectFileCOFF:: | |
905 | emitModuleFlags(MCStreamer &Streamer, | |
906 | ArrayRef<Module::ModuleFlagEntry> ModuleFlags, | |
907 | Mangler &Mang, const TargetMachine &TM) const { | |
908 | MDNode *LinkerOptions = nullptr; | |
909 | ||
910 | // Look for the "Linker Options" flag, since it's the only one we support. | |
911 | for (ArrayRef<Module::ModuleFlagEntry>::iterator | |
912 | i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) { | |
913 | const Module::ModuleFlagEntry &MFE = *i; | |
914 | StringRef Key = MFE.Key->getString(); | |
85aaf69f | 915 | Metadata *Val = MFE.Val; |
1a4d82fc JJ |
916 | if (Key == "Linker Options") { |
917 | LinkerOptions = cast<MDNode>(Val); | |
918 | break; | |
919 | } | |
920 | } | |
921 | if (!LinkerOptions) | |
922 | return; | |
923 | ||
924 | // Emit the linker options to the linker .drectve section. According to the | |
925 | // spec, this section is a space-separated string containing flags for linker. | |
926 | const MCSection *Sec = getDrectveSection(); | |
927 | Streamer.SwitchSection(Sec); | |
928 | for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { | |
929 | MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i)); | |
930 | for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) { | |
931 | MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii)); | |
932 | StringRef Op = MDOption->getString(); | |
933 | // Lead with a space for consistency with our dllexport implementation. | |
934 | std::string Escaped(" "); | |
85aaf69f | 935 | if (!Op.startswith("\"") && (Op.find(" ") != StringRef::npos)) { |
1a4d82fc JJ |
936 | // The PE-COFF spec says args with spaces must be quoted. It doesn't say |
937 | // how to escape quotes, but it probably uses this algorithm: | |
938 | // http://msdn.microsoft.com/en-us/library/17w5ykft(v=vs.85).aspx | |
939 | // FIXME: Reuse escaping code from Support/Windows/Program.inc | |
940 | Escaped.push_back('\"'); | |
941 | Escaped.append(Op); | |
942 | Escaped.push_back('\"'); | |
943 | } else { | |
944 | Escaped.append(Op); | |
945 | } | |
946 | Streamer.EmitBytes(Escaped); | |
947 | } | |
948 | } | |
223e47cc LB |
949 | } |
950 | ||
1a4d82fc JJ |
951 | const MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( |
952 | unsigned Priority, const MCSymbol *KeySym) const { | |
953 | return getContext().getAssociativeCOFFSection( | |
954 | cast<MCSectionCOFF>(StaticCtorSection), KeySym); | |
955 | } | |
956 | ||
957 | const MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( | |
958 | unsigned Priority, const MCSymbol *KeySym) const { | |
959 | return getContext().getAssociativeCOFFSection( | |
960 | cast<MCSectionCOFF>(StaticDtorSection), KeySym); | |
961 | } |