File: | lib/MC/MCMachOStreamer.cpp |
Location: | line 426, column 23 |
Description: | Potential leak of memory pointed to by 'F' |
1 | //===-- MCMachOStreamer.cpp - MachO Streamer ------------------------------===// | |||
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 | #include "llvm/MC/MCStreamer.h" | |||
11 | #include "llvm/ADT/DenseMap.h" | |||
12 | #include "llvm/ADT/SmallVector.h" | |||
13 | #include "llvm/MC/MCAsmBackend.h" | |||
14 | #include "llvm/MC/MCAssembler.h" | |||
15 | #include "llvm/MC/MCCodeEmitter.h" | |||
16 | #include "llvm/MC/MCContext.h" | |||
17 | #include "llvm/MC/MCDwarf.h" | |||
18 | #include "llvm/MC/MCExpr.h" | |||
19 | #include "llvm/MC/MCInst.h" | |||
20 | #include "llvm/MC/MCLinkerOptimizationHint.h" | |||
21 | #include "llvm/MC/MCObjectFileInfo.h" | |||
22 | #include "llvm/MC/MCObjectStreamer.h" | |||
23 | #include "llvm/MC/MCSection.h" | |||
24 | #include "llvm/MC/MCSectionMachO.h" | |||
25 | #include "llvm/MC/MCSymbolMachO.h" | |||
26 | #include "llvm/Support/Dwarf.h" | |||
27 | #include "llvm/Support/ErrorHandling.h" | |||
28 | #include "llvm/Support/TargetRegistry.h" | |||
29 | #include "llvm/Support/raw_ostream.h" | |||
30 | ||||
31 | using namespace llvm; | |||
32 | ||||
33 | namespace { | |||
34 | ||||
35 | class MCMachOStreamer : public MCObjectStreamer { | |||
36 | private: | |||
37 | /// LabelSections - true if each section change should emit a linker local | |||
38 | /// label for use in relocations for assembler local references. Obviates the | |||
39 | /// need for local relocations. False by default. | |||
40 | bool LabelSections; | |||
41 | ||||
42 | bool DWARFMustBeAtTheEnd; | |||
43 | bool CreatedADWARFSection; | |||
44 | ||||
45 | /// HasSectionLabel - map of which sections have already had a non-local | |||
46 | /// label emitted to them. Used so we don't emit extraneous linker local | |||
47 | /// labels in the middle of the section. | |||
48 | DenseMap<const MCSection*, bool> HasSectionLabel; | |||
49 | ||||
50 | void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override; | |||
51 | ||||
52 | void EmitDataRegion(DataRegionData::KindTy Kind); | |||
53 | void EmitDataRegionEnd(); | |||
54 | ||||
55 | public: | |||
56 | MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS, | |||
57 | MCCodeEmitter *Emitter, bool DWARFMustBeAtTheEnd, bool label) | |||
58 | : MCObjectStreamer(Context, MAB, OS, Emitter), LabelSections(label), | |||
59 | DWARFMustBeAtTheEnd(DWARFMustBeAtTheEnd), CreatedADWARFSection(false) {} | |||
60 | ||||
61 | /// state management | |||
62 | void reset() override { | |||
63 | HasSectionLabel.clear(); | |||
64 | MCObjectStreamer::reset(); | |||
65 | } | |||
66 | ||||
67 | /// @name MCStreamer Interface | |||
68 | /// @{ | |||
69 | ||||
70 | void ChangeSection(MCSection *Sect, const MCExpr *Subsect) override; | |||
71 | void EmitLabel(MCSymbol *Symbol) override; | |||
72 | void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override; | |||
73 | void EmitAssemblerFlag(MCAssemblerFlag Flag) override; | |||
74 | void EmitLinkerOptions(ArrayRef<std::string> Options) override; | |||
75 | void EmitDataRegion(MCDataRegionType Kind) override; | |||
76 | void EmitVersionMin(MCVersionMinType Kind, unsigned Major, | |||
77 | unsigned Minor, unsigned Update) override; | |||
78 | void EmitThumbFunc(MCSymbol *Func) override; | |||
79 | bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; | |||
80 | void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; | |||
81 | void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, | |||
82 | unsigned ByteAlignment) override; | |||
83 | void BeginCOFFSymbolDef(const MCSymbol *Symbol) override { | |||
84 | llvm_unreachable("macho doesn't support this directive")::llvm::llvm_unreachable_internal("macho doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 84); | |||
85 | } | |||
86 | void EmitCOFFSymbolStorageClass(int StorageClass) override { | |||
87 | llvm_unreachable("macho doesn't support this directive")::llvm::llvm_unreachable_internal("macho doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 87); | |||
88 | } | |||
89 | void EmitCOFFSymbolType(int Type) override { | |||
90 | llvm_unreachable("macho doesn't support this directive")::llvm::llvm_unreachable_internal("macho doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 90); | |||
91 | } | |||
92 | void EndCOFFSymbolDef() override { | |||
93 | llvm_unreachable("macho doesn't support this directive")::llvm::llvm_unreachable_internal("macho doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 93); | |||
94 | } | |||
95 | void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, | |||
96 | unsigned ByteAlignment) override; | |||
97 | void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, | |||
98 | uint64_t Size = 0, unsigned ByteAlignment = 0) override; | |||
99 | void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, | |||
100 | unsigned ByteAlignment = 0) override; | |||
101 | ||||
102 | void EmitFileDirective(StringRef Filename) override { | |||
103 | // FIXME: Just ignore the .file; it isn't important enough to fail the | |||
104 | // entire assembly. | |||
105 | ||||
106 | // report_fatal_error("unsupported directive: '.file'"); | |||
107 | } | |||
108 | ||||
109 | void EmitIdent(StringRef IdentString) override { | |||
110 | llvm_unreachable("macho doesn't support this directive")::llvm::llvm_unreachable_internal("macho doesn't support this directive" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 110); | |||
111 | } | |||
112 | ||||
113 | void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override { | |||
114 | getAssembler().getLOHContainer().addDirective(Kind, Args); | |||
115 | } | |||
116 | ||||
117 | void FinishImpl() override; | |||
118 | }; | |||
119 | ||||
120 | } // end anonymous namespace. | |||
121 | ||||
122 | static bool canGoAfterDWARF(const MCSectionMachO &MSec) { | |||
123 | // These sections are created by the assembler itself after the end of | |||
124 | // the .s file. | |||
125 | StringRef SegName = MSec.getSegmentName(); | |||
126 | StringRef SecName = MSec.getSectionName(); | |||
127 | ||||
128 | if (SegName == "__LD" && SecName == "__compact_unwind") | |||
129 | return true; | |||
130 | ||||
131 | if (SegName == "__IMPORT") { | |||
132 | if (SecName == "__jump_table") | |||
133 | return true; | |||
134 | ||||
135 | if (SecName == "__pointers") | |||
136 | return true; | |||
137 | } | |||
138 | ||||
139 | if (SegName == "__TEXT" && SecName == "__eh_frame") | |||
140 | return true; | |||
141 | ||||
142 | if (SegName == "__DATA" && SecName == "__nl_symbol_ptr") | |||
143 | return true; | |||
144 | ||||
145 | return false; | |||
146 | } | |||
147 | ||||
148 | void MCMachOStreamer::ChangeSection(MCSection *Section, | |||
149 | const MCExpr *Subsection) { | |||
150 | // Change the section normally. | |||
151 | bool Created = MCObjectStreamer::changeSectionImpl(Section, Subsection); | |||
152 | const MCSectionMachO &MSec = *cast<MCSectionMachO>(Section); | |||
153 | StringRef SegName = MSec.getSegmentName(); | |||
154 | if (SegName == "__DWARF") | |||
155 | CreatedADWARFSection = true; | |||
156 | else if (Created && DWARFMustBeAtTheEnd && !canGoAfterDWARF(MSec)) | |||
157 | assert(!CreatedADWARFSection && "Creating regular section after DWARF")((!CreatedADWARFSection && "Creating regular section after DWARF" ) ? static_cast<void> (0) : __assert_fail ("!CreatedADWARFSection && \"Creating regular section after DWARF\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 157, __PRETTY_FUNCTION__)); | |||
158 | ||||
159 | // Output a linker-local symbol so we don't need section-relative local | |||
160 | // relocations. The linker hates us when we do that. | |||
161 | if (LabelSections && !HasSectionLabel[Section] && | |||
162 | !Section->getBeginSymbol()) { | |||
163 | MCSymbol *Label = getContext().createLinkerPrivateTempSymbol(); | |||
164 | Section->setBeginSymbol(Label); | |||
165 | HasSectionLabel[Section] = true; | |||
166 | } | |||
167 | } | |||
168 | ||||
169 | void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, | |||
170 | MCSymbol *EHSymbol) { | |||
171 | getAssembler().registerSymbol(*Symbol); | |||
172 | if (Symbol->isExternal()) | |||
173 | EmitSymbolAttribute(EHSymbol, MCSA_Global); | |||
174 | if (cast<MCSymbolMachO>(Symbol)->isWeakDefinition()) | |||
175 | EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition); | |||
176 | if (Symbol->isPrivateExtern()) | |||
177 | EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern); | |||
178 | } | |||
179 | ||||
180 | void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { | |||
181 | assert(Symbol->isUndefined() && "Cannot define a symbol twice!")((Symbol->isUndefined() && "Cannot define a symbol twice!" ) ? static_cast<void> (0) : __assert_fail ("Symbol->isUndefined() && \"Cannot define a symbol twice!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 181, __PRETTY_FUNCTION__)); | |||
182 | ||||
183 | // isSymbolLinkerVisible uses the section. | |||
184 | AssignSection(Symbol, getCurrentSection().first); | |||
185 | // We have to create a new fragment if this is an atom defining symbol, | |||
186 | // fragments cannot span atoms. | |||
187 | if (getAssembler().isSymbolLinkerVisible(*Symbol)) | |||
188 | insert(new MCDataFragment()); | |||
189 | ||||
190 | MCObjectStreamer::EmitLabel(Symbol); | |||
191 | ||||
192 | // This causes the reference type flag to be cleared. Darwin 'as' was "trying" | |||
193 | // to clear the weak reference and weak definition bits too, but the | |||
194 | // implementation was buggy. For now we just try to match 'as', for | |||
195 | // diffability. | |||
196 | // | |||
197 | // FIXME: Cleanup this code, these bits should be emitted based on semantic | |||
198 | // properties, not on the order of definition, etc. | |||
199 | cast<MCSymbolMachO>(Symbol)->clearReferenceType(); | |||
200 | } | |||
201 | ||||
202 | void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) { | |||
203 | if (!getAssembler().getBackend().hasDataInCodeSupport()) | |||
204 | return; | |||
205 | // Create a temporary label to mark the start of the data region. | |||
206 | MCSymbol *Start = getContext().createTempSymbol(); | |||
207 | EmitLabel(Start); | |||
208 | // Record the region for the object writer to use. | |||
209 | DataRegionData Data = { Kind, Start, nullptr }; | |||
210 | std::vector<DataRegionData> &Regions = getAssembler().getDataRegions(); | |||
211 | Regions.push_back(Data); | |||
212 | } | |||
213 | ||||
214 | void MCMachOStreamer::EmitDataRegionEnd() { | |||
215 | if (!getAssembler().getBackend().hasDataInCodeSupport()) | |||
216 | return; | |||
217 | std::vector<DataRegionData> &Regions = getAssembler().getDataRegions(); | |||
218 | assert(!Regions.empty() && "Mismatched .end_data_region!")((!Regions.empty() && "Mismatched .end_data_region!") ? static_cast<void> (0) : __assert_fail ("!Regions.empty() && \"Mismatched .end_data_region!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 218, __PRETTY_FUNCTION__)); | |||
219 | DataRegionData &Data = Regions.back(); | |||
220 | assert(!Data.End && "Mismatched .end_data_region!")((!Data.End && "Mismatched .end_data_region!") ? static_cast <void> (0) : __assert_fail ("!Data.End && \"Mismatched .end_data_region!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 220, __PRETTY_FUNCTION__)); | |||
221 | // Create a temporary label to mark the end of the data region. | |||
222 | Data.End = getContext().createTempSymbol(); | |||
223 | EmitLabel(Data.End); | |||
224 | } | |||
225 | ||||
226 | void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { | |||
227 | // Let the target do whatever target specific stuff it needs to do. | |||
228 | getAssembler().getBackend().handleAssemblerFlag(Flag); | |||
229 | // Do any generic stuff we need to do. | |||
230 | switch (Flag) { | |||
231 | case MCAF_SyntaxUnified: return; // no-op here. | |||
232 | case MCAF_Code16: return; // Change parsing mode; no-op here. | |||
233 | case MCAF_Code32: return; // Change parsing mode; no-op here. | |||
234 | case MCAF_Code64: return; // Change parsing mode; no-op here. | |||
235 | case MCAF_SubsectionsViaSymbols: | |||
236 | getAssembler().setSubsectionsViaSymbols(true); | |||
237 | return; | |||
238 | } | |||
239 | } | |||
240 | ||||
241 | void MCMachOStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) { | |||
242 | getAssembler().getLinkerOptions().push_back(Options); | |||
243 | } | |||
244 | ||||
245 | void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) { | |||
246 | switch (Kind) { | |||
247 | case MCDR_DataRegion: | |||
248 | EmitDataRegion(DataRegionData::Data); | |||
249 | return; | |||
250 | case MCDR_DataRegionJT8: | |||
251 | EmitDataRegion(DataRegionData::JumpTable8); | |||
252 | return; | |||
253 | case MCDR_DataRegionJT16: | |||
254 | EmitDataRegion(DataRegionData::JumpTable16); | |||
255 | return; | |||
256 | case MCDR_DataRegionJT32: | |||
257 | EmitDataRegion(DataRegionData::JumpTable32); | |||
258 | return; | |||
259 | case MCDR_DataRegionEnd: | |||
260 | EmitDataRegionEnd(); | |||
261 | return; | |||
262 | } | |||
263 | } | |||
264 | ||||
265 | void MCMachOStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major, | |||
266 | unsigned Minor, unsigned Update) { | |||
267 | getAssembler().setVersionMinInfo(Kind, Major, Minor, Update); | |||
268 | } | |||
269 | ||||
270 | void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) { | |||
271 | // Remember that the function is a thumb function. Fixup and relocation | |||
272 | // values will need adjusted. | |||
273 | getAssembler().setIsThumbFunc(Symbol); | |||
274 | cast<MCSymbolMachO>(Symbol)->setThumbFunc(); | |||
275 | } | |||
276 | ||||
277 | bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Sym, | |||
278 | MCSymbolAttr Attribute) { | |||
279 | MCSymbolMachO *Symbol = cast<MCSymbolMachO>(Sym); | |||
280 | ||||
281 | // Indirect symbols are handled differently, to match how 'as' handles | |||
282 | // them. This makes writing matching .o files easier. | |||
283 | if (Attribute == MCSA_IndirectSymbol) { | |||
284 | // Note that we intentionally cannot use the symbol data here; this is | |||
285 | // important for matching the string table that 'as' generates. | |||
286 | IndirectSymbolData ISD; | |||
287 | ISD.Symbol = Symbol; | |||
288 | ISD.Section = getCurrentSectionOnly(); | |||
289 | getAssembler().getIndirectSymbols().push_back(ISD); | |||
290 | return true; | |||
291 | } | |||
292 | ||||
293 | // Adding a symbol attribute always introduces the symbol, note that an | |||
294 | // important side effect of calling registerSymbol here is to register | |||
295 | // the symbol with the assembler. | |||
296 | getAssembler().registerSymbol(*Symbol); | |||
297 | ||||
298 | // The implementation of symbol attributes is designed to match 'as', but it | |||
299 | // leaves much to desired. It doesn't really make sense to arbitrarily add and | |||
300 | // remove flags, but 'as' allows this (in particular, see .desc). | |||
301 | // | |||
302 | // In the future it might be worth trying to make these operations more well | |||
303 | // defined. | |||
304 | switch (Attribute) { | |||
305 | case MCSA_Invalid: | |||
306 | case MCSA_ELF_TypeFunction: | |||
307 | case MCSA_ELF_TypeIndFunction: | |||
308 | case MCSA_ELF_TypeObject: | |||
309 | case MCSA_ELF_TypeTLS: | |||
310 | case MCSA_ELF_TypeCommon: | |||
311 | case MCSA_ELF_TypeNoType: | |||
312 | case MCSA_ELF_TypeGnuUniqueObject: | |||
313 | case MCSA_Hidden: | |||
314 | case MCSA_IndirectSymbol: | |||
315 | case MCSA_Internal: | |||
316 | case MCSA_Protected: | |||
317 | case MCSA_Weak: | |||
318 | case MCSA_Local: | |||
319 | return false; | |||
320 | ||||
321 | case MCSA_Global: | |||
322 | Symbol->setExternal(true); | |||
323 | // This effectively clears the undefined lazy bit, in Darwin 'as', although | |||
324 | // it isn't very consistent because it implements this as part of symbol | |||
325 | // lookup. | |||
326 | // | |||
327 | // FIXME: Cleanup this code, these bits should be emitted based on semantic | |||
328 | // properties, not on the order of definition, etc. | |||
329 | Symbol->setReferenceTypeUndefinedLazy(false); | |||
330 | break; | |||
331 | ||||
332 | case MCSA_LazyReference: | |||
333 | // FIXME: This requires -dynamic. | |||
334 | Symbol->setNoDeadStrip(); | |||
335 | if (Symbol->isUndefined()) | |||
336 | Symbol->setReferenceTypeUndefinedLazy(true); | |||
337 | break; | |||
338 | ||||
339 | // Since .reference sets the no dead strip bit, it is equivalent to | |||
340 | // .no_dead_strip in practice. | |||
341 | case MCSA_Reference: | |||
342 | case MCSA_NoDeadStrip: | |||
343 | Symbol->setNoDeadStrip(); | |||
344 | break; | |||
345 | ||||
346 | case MCSA_SymbolResolver: | |||
347 | Symbol->setSymbolResolver(); | |||
348 | break; | |||
349 | ||||
350 | case MCSA_PrivateExtern: | |||
351 | Symbol->setExternal(true); | |||
352 | Symbol->setPrivateExtern(true); | |||
353 | break; | |||
354 | ||||
355 | case MCSA_WeakReference: | |||
356 | // FIXME: This requires -dynamic. | |||
357 | if (Symbol->isUndefined()) | |||
358 | Symbol->setWeakReference(); | |||
359 | break; | |||
360 | ||||
361 | case MCSA_WeakDefinition: | |||
362 | // FIXME: 'as' enforces that this is defined and global. The manual claims | |||
363 | // it has to be in a coalesced section, but this isn't enforced. | |||
364 | Symbol->setWeakDefinition(); | |||
365 | break; | |||
366 | ||||
367 | case MCSA_WeakDefAutoPrivate: | |||
368 | Symbol->setWeakDefinition(); | |||
369 | Symbol->setWeakReference(); | |||
370 | break; | |||
371 | } | |||
372 | ||||
373 | return true; | |||
374 | } | |||
375 | ||||
376 | void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { | |||
377 | // Encode the 'desc' value into the lowest implementation defined bits. | |||
378 | getAssembler().registerSymbol(*Symbol); | |||
379 | cast<MCSymbolMachO>(Symbol)->setDesc(DescValue); | |||
380 | } | |||
381 | ||||
382 | void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, | |||
383 | unsigned ByteAlignment) { | |||
384 | // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself. | |||
385 | assert(Symbol->isUndefined() && "Cannot define a symbol twice!")((Symbol->isUndefined() && "Cannot define a symbol twice!" ) ? static_cast<void> (0) : __assert_fail ("Symbol->isUndefined() && \"Cannot define a symbol twice!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 385, __PRETTY_FUNCTION__)); | |||
386 | ||||
387 | AssignSection(Symbol, nullptr); | |||
388 | ||||
389 | getAssembler().registerSymbol(*Symbol); | |||
390 | Symbol->setExternal(true); | |||
391 | Symbol->setCommon(Size, ByteAlignment); | |||
392 | } | |||
393 | ||||
394 | void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, | |||
395 | unsigned ByteAlignment) { | |||
396 | // '.lcomm' is equivalent to '.zerofill'. | |||
397 | return EmitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(), | |||
398 | Symbol, Size, ByteAlignment); | |||
399 | } | |||
400 | ||||
401 | void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, | |||
402 | uint64_t Size, unsigned ByteAlignment) { | |||
403 | getAssembler().registerSection(*Section); | |||
404 | ||||
405 | // The symbol may not be present, which only creates the section. | |||
406 | if (!Symbol) | |||
407 | return; | |||
408 | ||||
409 | // On darwin all virtual sections have zerofill type. | |||
410 | assert(Section->isVirtualSection() && "Section does not have zerofill type!")((Section->isVirtualSection() && "Section does not have zerofill type!" ) ? static_cast<void> (0) : __assert_fail ("Section->isVirtualSection() && \"Section does not have zerofill type!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 410, __PRETTY_FUNCTION__)); | |||
411 | ||||
412 | assert(Symbol->isUndefined() && "Cannot define a symbol twice!")((Symbol->isUndefined() && "Cannot define a symbol twice!" ) ? static_cast<void> (0) : __assert_fail ("Symbol->isUndefined() && \"Cannot define a symbol twice!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 412, __PRETTY_FUNCTION__)); | |||
413 | ||||
414 | getAssembler().registerSymbol(*Symbol); | |||
415 | ||||
416 | // Emit an align fragment if necessary. | |||
417 | if (ByteAlignment != 1) | |||
418 | new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, Section); | |||
419 | ||||
420 | AssignSection(Symbol, Section); | |||
421 | ||||
422 | MCFragment *F = new MCFillFragment(0, 0, Size, Section); | |||
423 | Symbol->setFragment(F); | |||
424 | ||||
425 | // Update the maximum alignment on the zero fill section if necessary. | |||
426 | if (ByteAlignment > Section->getAlignment()) | |||
| ||||
427 | Section->setAlignment(ByteAlignment); | |||
428 | } | |||
429 | ||||
430 | // This should always be called with the thread local bss section. Like the | |||
431 | // .zerofill directive this doesn't actually switch sections on us. | |||
432 | void MCMachOStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, | |||
433 | uint64_t Size, unsigned ByteAlignment) { | |||
434 | EmitZerofill(Section, Symbol, Size, ByteAlignment); | |||
| ||||
435 | return; | |||
436 | } | |||
437 | ||||
438 | void MCMachOStreamer::EmitInstToData(const MCInst &Inst, | |||
439 | const MCSubtargetInfo &STI) { | |||
440 | MCDataFragment *DF = getOrCreateDataFragment(); | |||
441 | ||||
442 | SmallVector<MCFixup, 4> Fixups; | |||
443 | SmallString<256> Code; | |||
444 | raw_svector_ostream VecOS(Code); | |||
445 | getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); | |||
446 | ||||
447 | // Add the fixups and data. | |||
448 | for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { | |||
449 | Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); | |||
450 | DF->getFixups().push_back(Fixups[i]); | |||
451 | } | |||
452 | DF->getContents().append(Code.begin(), Code.end()); | |||
453 | } | |||
454 | ||||
455 | void MCMachOStreamer::FinishImpl() { | |||
456 | EmitFrames(&getAssembler().getBackend()); | |||
457 | ||||
458 | // We have to set the fragment atom associations so we can relax properly for | |||
459 | // Mach-O. | |||
460 | ||||
461 | // First, scan the symbol table to build a lookup table from fragments to | |||
462 | // defining symbols. | |||
463 | DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap; | |||
464 | for (const MCSymbol &Symbol : getAssembler().symbols()) { | |||
465 | if (getAssembler().isSymbolLinkerVisible(Symbol) && Symbol.getFragment()) { | |||
466 | // An atom defining symbol should never be internal to a fragment. | |||
467 | assert(Symbol.getOffset() == 0 &&((Symbol.getOffset() == 0 && "Invalid offset in atom defining symbol!" ) ? static_cast<void> (0) : __assert_fail ("Symbol.getOffset() == 0 && \"Invalid offset in atom defining symbol!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 468, __PRETTY_FUNCTION__)) | |||
468 | "Invalid offset in atom defining symbol!")((Symbol.getOffset() == 0 && "Invalid offset in atom defining symbol!" ) ? static_cast<void> (0) : __assert_fail ("Symbol.getOffset() == 0 && \"Invalid offset in atom defining symbol!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/MCMachOStreamer.cpp" , 468, __PRETTY_FUNCTION__)); | |||
469 | DefiningSymbolMap[Symbol.getFragment()] = &Symbol; | |||
470 | } | |||
471 | } | |||
472 | ||||
473 | // Set the fragment atom associations by tracking the last seen atom defining | |||
474 | // symbol. | |||
475 | for (MCAssembler::iterator it = getAssembler().begin(), | |||
476 | ie = getAssembler().end(); it != ie; ++it) { | |||
477 | const MCSymbol *CurrentAtom = nullptr; | |||
478 | for (MCSection::iterator it2 = it->begin(), ie2 = it->end(); it2 != ie2; | |||
479 | ++it2) { | |||
480 | if (const MCSymbol *Symbol = DefiningSymbolMap.lookup(it2)) | |||
481 | CurrentAtom = Symbol; | |||
482 | it2->setAtom(CurrentAtom); | |||
483 | } | |||
484 | } | |||
485 | ||||
486 | this->MCObjectStreamer::FinishImpl(); | |||
487 | } | |||
488 | ||||
489 | MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB, | |||
490 | raw_pwrite_stream &OS, MCCodeEmitter *CE, | |||
491 | bool RelaxAll, bool DWARFMustBeAtTheEnd, | |||
492 | bool LabelSections) { | |||
493 | MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, | |||
494 | DWARFMustBeAtTheEnd, LabelSections); | |||
495 | const Triple &TT = Context.getObjectFileInfo()->getTargetTriple(); | |||
496 | if (TT.isOSDarwin()) { | |||
497 | unsigned Major, Minor, Update; | |||
498 | TT.getOSVersion(Major, Minor, Update); | |||
499 | // If there is a version specified, Major will be non-zero. | |||
500 | if (Major) | |||
501 | S->EmitVersionMin((TT.isMacOSX() ? | |||
502 | MCVM_OSXVersionMin : MCVM_IOSVersionMin), | |||
503 | Major, Minor, Update); | |||
504 | } | |||
505 | if (RelaxAll) | |||
506 | S->getAssembler().setRelaxAll(true); | |||
507 | return S; | |||
508 | } |