Coverage Report

Created: 2019-07-24 05:18

/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
}