LLVM: lib/MC/MCMachOStreamer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

34#include

35#include

36

37namespace llvm {

42}

43

44using namespace llvm;

45

46namespace {

47

48class MCMachOStreamer : public MCObjectStreamer {

49private:

50

51

52

53 bool LabelSections;

54

55

56

57

58 DenseMap<const MCSection*, bool> HasSectionLabel;

59

61 void emitDataRegionEnd();

62

63public:

64 MCMachOStreamer(MCContext &Context, std::unique_ptr MAB,

65 std::unique_ptr OW,

66 std::unique_ptr Emitter, bool label)

67 : MCObjectStreamer(Context, std::move(MAB), std::move(OW),

69 LabelSections(label) {}

70

71

72 void reset() override {

73 HasSectionLabel.clear();

75 }

76

77 MachObjectWriter &getWriter() {

78 return static_cast<MachObjectWriter &>(getAssembler().getWriter());

79 }

80

81

82

83

84 void changeSection(MCSection *Sect, uint32_t Subsection = 0) 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 emitSubsectionsViaSymbols() override;

89 void emitLinkerOptions(ArrayRefstd::string Options) 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 emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major,

96 unsigned Minor, unsigned Update,

97 VersionTuple SDKVersion) override;

99 void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;

100 void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,

101 Align ByteAlignment) override;

102

103 void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,

104 Align ByteAlignment) override;

105 void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,

106 uint64_t Size = 0, Align ByteAlignment = Align(1),

107 SMLoc Loc = SMLoc()) override;

108 void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,

109 Align ByteAlignment = Align(1)) override;

110

111 void emitIdent(StringRef IdentString) override {

113 }

114

115 void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {

116 getWriter().getLOHContainer().addDirective(Kind, Args);

117 }

118 void emitCGProfileEntry(const MCSymbolRefExpr *From,

119 const MCSymbolRefExpr *To, uint64_t Count) override {

121 getWriter().getCGProfile().push_back({From, To, Count});

122 }

123

124 void finishImpl() override;

125

126 void finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE);

127 void finalizeCGProfile();

128 void createAddrSigSection();

129};

130

131}

132

133void MCMachOStreamer::changeSection(MCSection *Section, uint32_t Subsection) {

135

136

137

138 if (LabelSections && !HasSectionLabel[Section] &&

139 Section->getBeginSymbol()) {

141 Section->setBeginSymbol(Label);

142 HasSectionLabel[Section] = true;

143 if (Label->isInSection())

144 emitLabel(Label);

145 }

146}

147

148void MCMachOStreamer::emitEHSymAttributes(const MCSymbol *Symbol,

149 MCSymbol *EHSymbol) {

150 auto *Sym = static_cast<const MCSymbolMachO *>(Symbol);

151 getAssembler().registerSymbol(*Symbol);

152 if (Sym->isExternal())

153 emitSymbolAttribute(EHSymbol, MCSA_Global);

154 if (Sym->isWeakDefinition())

156 if (Sym->isPrivateExtern())

158}

159

160void MCMachOStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {

161

162

164 newFragment();

165

167

168

169

170

171

172

173

174

175 static_cast<MCSymbolMachO *>(Symbol)->clearReferenceType();

176}

177

178void MCMachOStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {

179 MCValue Res;

180

181 if (Value->evaluateAsRelocatable(Res, nullptr)) {

182 if (const auto *SymA = Res.getAddSym()) {

184 (SymA->getName().empty() || Res.getConstant() != 0))

185 static_cast<MCSymbolMachO *>(Symbol)->setAltEntry();

186 }

187 }

189}

190

192

194 emitLabel(Start);

195

196 getWriter().getDataRegions().push_back({Kind, Start, nullptr});

197}

198

199void MCMachOStreamer::emitDataRegionEnd() {

200 auto &Regions = getWriter().getDataRegions();

201 assert(!Regions.empty() && "Mismatched .end_data_region!");

202 auto &Data = Regions.back();

203 assert(Data.End && "Mismatched .end_data_region!");

204

206 emitLabel(Data.End);

207}

208

209void MCMachOStreamer::emitSubsectionsViaSymbols() {

210 getWriter().setSubsectionsViaSymbols(true);

211}

212

213void MCMachOStreamer::emitLinkerOptions(ArrayRefstd::string Options) {

214 getWriter().getLinkerOptions().push_back(Options);

215}

216

218 switch (Kind) {

220 emitDataRegion(MachO::DataRegionType::DICE_KIND_DATA);

221 return;

223 emitDataRegion(MachO::DataRegionType::DICE_KIND_JUMP_TABLE8);

224 return;

226 emitDataRegion(MachO::DataRegionType::DICE_KIND_JUMP_TABLE16);

227 return;

229 emitDataRegion(MachO::DataRegionType::DICE_KIND_JUMP_TABLE32);

230 return;

232 emitDataRegionEnd();

233 return;

234 }

235}

236

237void MCMachOStreamer::emitVersionMin(MCVersionMinType Kind, unsigned Major,

238 unsigned Minor, unsigned Update,

239 VersionTuple SDKVersion) {

240 getWriter().setVersionMin(Kind, Major, Minor, Update, SDKVersion);

241}

242

243void MCMachOStreamer::emitBuildVersion(unsigned Platform, unsigned Major,

244 unsigned Minor, unsigned Update,

245 VersionTuple SDKVersion) {

247 Update, SDKVersion);

248}

249

250void MCMachOStreamer::emitDarwinTargetVariantBuildVersion(

251 unsigned Platform, unsigned Major, unsigned Minor, unsigned Update,

252 VersionTuple SDKVersion) {

253 getWriter().setTargetVariantBuildVersion((MachO::PlatformType)Platform, Major,

254 Minor, Update, SDKVersion);

255}

256

257bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,

259 auto *Symbol = static_cast<MCSymbolMachO *>(Sym);

260

261

262

264

265

266 getWriter().getIndirectSymbols().push_back(

267 {Symbol, getCurrentSectionOnly()});

268 return true;

269 }

270

271

272

273

274 getAssembler().registerSymbol(*Symbol);

275

276

277

278

279

280

281

302 return false;

303

305 Symbol->setExternal(true);

306

307

308

309

310

311

312 Symbol->setReferenceTypeUndefinedLazy(false);

313 break;

314

316

317 Symbol->setNoDeadStrip();

318 if (Symbol->isUndefined())

319 Symbol->setReferenceTypeUndefinedLazy(true);

320 break;

321

322

323

326 Symbol->setNoDeadStrip();

327 break;

328

330 Symbol->setSymbolResolver();

331 break;

332

334 Symbol->setAltEntry();

335 break;

336

338 Symbol->setExternal(true);

339 Symbol->setPrivateExtern(true);

340 break;

341

343

344 if (Symbol->isUndefined())

345 Symbol->setWeakReference();

346 break;

347

349

350

351 Symbol->setWeakDefinition();

352 break;

353

355 Symbol->setWeakDefinition();

356 Symbol->setWeakReference();

357 break;

358

361 break;

362 }

363

364 return true;

365}

366

367void MCMachOStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {

368

369 getAssembler().registerSymbol(*Symbol);

370 static_cast<MCSymbolMachO *>(Symbol)->setDesc(DescValue);

371}

372

373void MCMachOStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,

374 Align ByteAlignment) {

375 auto &Sym = static_cast<MCSymbolMachO &>(*Symbol);

376

377 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");

378

379 getAssembler().registerSymbol(Sym);

380 Sym.setExternal(true);

382}

383

384void MCMachOStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,

385 Align ByteAlignment) {

386

387 return emitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(),

388 Symbol, Size, ByteAlignment);

389}

390

391void MCMachOStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,

392 uint64_t Size, Align ByteAlignment,

393 SMLoc Loc) {

394

395

396

397 if (Section->isBssSection()) {

399 Loc, "The usage of .zerofill is restricted to sections of "

400 "ZEROFILL type. Use .zero or .space instead.");

401 return;

402

403 }

404

405 pushSection();

406 switchSection(Section);

407

408

409 if (Symbol) {

410 emitValueToAlignment(ByteAlignment, 0, 1, 0);

411 emitLabel(Symbol);

412 emitZeros(Size);

413 }

414 popSection();

415}

416

417

418

419void MCMachOStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,

420 uint64_t Size, Align ByteAlignment) {

421 emitZerofill(Section, Symbol, Size, ByteAlignment);

422}

423

424void MCMachOStreamer::finishImpl() {

425 emitFrames();

426

427

428

429

430

431

432 DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap;

433 for (const MCSymbol &Symbol : getAssembler().symbols()) {

434 auto &Sym = static_cast<const MCSymbolMachO &>(Symbol);

436 !Sym.isAltEntry()) {

437

439 "Invalid offset in atom defining symbol!");

440 DefiningSymbolMap[Symbol.getFragment()] = &Symbol;

441 }

442 }

443

444

445

446 for (MCSection &Sec : getAssembler()) {

447 static_cast<MCSectionMachO &>(Sec).allocAtoms();

448 const MCSymbol *CurrentAtom = nullptr;

449 size_t I = 0;

450 for (MCFragment &Frag : Sec) {

451 if (const MCSymbol *Symbol = DefiningSymbolMap.lookup(&Frag))

452 CurrentAtom = Symbol;

453 static_cast<MCSectionMachO &>(Sec).setAtom(I++, CurrentAtom);

454 }

455 }

456

457 finalizeCGProfile();

458

459 createAddrSigSection();

461}

462

463void MCMachOStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {

464 auto *S =

465 static_cast<MCSymbolMachO *>(const_cast<MCSymbol *>(&SRE->getSymbol()));

466 if (getAssembler().registerSymbol(*S))

467 S->setExternal(true);

468}

469

470void MCMachOStreamer::finalizeCGProfile() {

471 MCAssembler &Asm = getAssembler();

472 MCObjectWriter &W = getWriter();

473 if (W.getCGProfile().empty())

474 return;

475 for (auto &E : W.getCGProfile()) {

476 finalizeCGProfileEntry(E.From);

477 finalizeCGProfileEntry(E.To);

478 }

479

480

481

482 MCSection *CGProfileSection = Asm.getContext().getMachOSection(

484

486

487 size_t SectionBytes =

488 W.getCGProfile().size() * (2 * sizeof(uint32_t) + sizeof(uint64_t));

489 (*CGProfileSection->begin())

490 .setVarContents(std::vector(SectionBytes, 0));

491}

492

494 std::unique_ptr &&MAB,

495 std::unique_ptr &&OW,

496 std::unique_ptr &&CE,

497 bool DWARFMustBeAtTheEnd,

498 bool LabelSections) {

499 return new MCMachOStreamer(Context, std::move(MAB), std::move(OW),

500 std::move(CE), LabelSections);

501}

502

503

504

505

506

507

508

509void MCMachOStreamer::createAddrSigSection() {

513 return;

514

515

517 Asm.getContext().getObjectFileInfo()->getAddrSigSection();

518

521

522

523

524

525

526 constexpr char zero[8] = {};

527 Frag->setVarContents(zero);

528}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

dxil DXContainer Global Emitter

This file defines the DenseMap class.

static bool isSymbolLinkerVisible(const MCSymbol &Symbol)

This file defines the SmallVector class.

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

Context object for machine code objects.

Instances of this class represent a single low-level machine instruction.

void reset() override

state management

void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override

Emit an assignment of Value to Symbol.

void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override

Emit a label for Symbol into the current section.

void finishImpl() override

Streamer specific finalization.

void changeSection(MCSection *Section, uint32_t Subsection=0) override

This is called by popSection and switchSection, if the current section changes.

Defines the object file and target independent interfaces used by the assembler backend to write nati...

bool getEmitAddrsigSection()

Instances of this class represent a uniqued identifier for a section in the current translation unit.

FragList * curFragList() const

Streaming machine code generation interface.

Generic base class for all target subtargets.

const MCSymbol & getSymbol() const

void setCommon(uint64_t Size, Align Alignment)

Mark this symbol as being 'common'.

bool isInSection() const

isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).

bool isVariable() const

isVariable - Check if this is a variable symbol.

bool isTemporary() const

isTemporary - Check if this is an assembler temporary symbol.

const MCSymbol * getAddSym() const

int64_t getConstant() const

const MCSymbol * getSubSym() const

static SectionKind getMetadata()

Triple - Helper class for working with autoconf configuration names.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

Context & getContext() const

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

@ MCDR_DataRegionEnd

.end_data_region

@ MCDR_DataRegion

.data_region

@ MCDR_DataRegionJT8

.data_region jt8

@ MCDR_DataRegionJT32

.data_region jt32

@ MCDR_DataRegionJT16

.data_region jt16

LLVM_ABI MCStreamer * createMachOStreamer(MCContext &Ctx, std::unique_ptr< MCAsmBackend > &&TAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&CE, bool DWARFMustBeAtTheEnd, bool LabelSections=false)

Definition MCMachOStreamer.cpp:493

MCLOHDirective::LOHArgs MCLOHArgs

FunctionAddr VTableAddr Count

FunctionAddr VTableAddr uintptr_t uintptr_t Data

MCLOHType

Linker Optimization Hint Type.

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

@ MCSA_WeakDefAutoPrivate

.weak_def_can_be_hidden (MachO)

@ MCSA_Memtag

.memtag (ELF)

@ MCSA_Protected

.protected (ELF)

@ MCSA_Exported

.globl _foo, exported (XCOFF)

@ MCSA_PrivateExtern

.private_extern (MachO)

@ MCSA_Internal

.internal (ELF)

@ MCSA_WeakReference

.weak_reference (MachO)

@ MCSA_AltEntry

.alt_entry (MachO)

@ MCSA_ELF_TypeIndFunction

.type _foo, STT_GNU_IFUNC

@ MCSA_LazyReference

.lazy_reference (MachO)

@ MCSA_ELF_TypeNoType

.type _foo, STT_NOTYPE # aka @notype

@ MCSA_Reference

.reference (MachO)

@ MCSA_SymbolResolver

.symbol_resolver (MachO)

@ MCSA_ELF_TypeTLS

.type _foo, STT_TLS # aka @tls_object

@ MCSA_IndirectSymbol

.indirect_symbol (MachO)

@ MCSA_WeakDefinition

.weak_definition (MachO)

@ MCSA_ELF_TypeCommon

.type _foo, STT_COMMON # aka @common

@ MCSA_Global

.type _foo, @gnu_unique_object

@ MCSA_WeakAntiDep

.weak_anti_dep (COFF)

@ MCSA_Extern

.extern (XCOFF)

@ MCSA_ELF_TypeObject

.type _foo, STT_OBJECT # aka @object

@ MCSA_ELF_TypeGnuUniqueObject

@ MCSA_ELF_TypeFunction

.type _foo, STT_FUNC # aka @function

@ MCSA_Hidden

.hidden (ELF)

@ MCSA_LGlobal

.lglobl (XCOFF)

@ MCSA_Invalid

Not a valid directive.

@ MCSA_NoDeadStrip

.no_dead_strip (MachO)