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