comparison lib/MC/MCMachOStreamer.cpp @ 77:54457678186b LLVM3.6

LLVM 3.6
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Mon, 08 Sep 2014 22:06:00 +0900
parents 95c75e76d11b
children 60c9769439b8
comparison
equal deleted inserted replaced
34:e874dbf0ad9d 77:54457678186b
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 9
10 #include "llvm/MC/MCStreamer.h" 10 #include "llvm/MC/MCStreamer.h"
11 #include "llvm/ADT/DenseMap.h"
12 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/MC/MCAsmBackend.h" 13 #include "llvm/MC/MCAsmBackend.h"
12 #include "llvm/MC/MCAssembler.h" 14 #include "llvm/MC/MCAssembler.h"
13 #include "llvm/MC/MCCodeEmitter.h" 15 #include "llvm/MC/MCCodeEmitter.h"
14 #include "llvm/MC/MCContext.h" 16 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCDwarf.h" 17 #include "llvm/MC/MCDwarf.h"
16 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCLinkerOptimizationHint.h"
18 #include "llvm/MC/MCMachOSymbolFlags.h" 21 #include "llvm/MC/MCMachOSymbolFlags.h"
22 #include "llvm/MC/MCObjectFileInfo.h"
19 #include "llvm/MC/MCObjectStreamer.h" 23 #include "llvm/MC/MCObjectStreamer.h"
20 #include "llvm/MC/MCSection.h" 24 #include "llvm/MC/MCSection.h"
21 #include "llvm/MC/MCSectionMachO.h" 25 #include "llvm/MC/MCSectionMachO.h"
22 #include "llvm/MC/MCSymbol.h" 26 #include "llvm/MC/MCSymbol.h"
23 #include "llvm/Support/Dwarf.h" 27 #include "llvm/Support/Dwarf.h"
28 32
29 namespace { 33 namespace {
30 34
31 class MCMachOStreamer : public MCObjectStreamer { 35 class MCMachOStreamer : public MCObjectStreamer {
32 private: 36 private:
33 virtual void EmitInstToData(const MCInst &Inst); 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 /// HasSectionLabel - map of which sections have already had a non-local
43 /// label emitted to them. Used so we don't emit extraneous linker local
44 /// labels in the middle of the section.
45 DenseMap<const MCSection*, bool> HasSectionLabel;
46
47 void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
34 48
35 void EmitDataRegion(DataRegionData::KindTy Kind); 49 void EmitDataRegion(DataRegionData::KindTy Kind);
36 void EmitDataRegionEnd(); 50 void EmitDataRegionEnd();
51
37 public: 52 public:
38 MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, 53 MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
39 MCCodeEmitter *Emitter) 54 MCCodeEmitter *Emitter, bool label)
40 : MCObjectStreamer(Context, 0, MAB, OS, Emitter) {} 55 : MCObjectStreamer(Context, MAB, OS, Emitter),
56 LabelSections(label) {}
41 57
42 /// @name MCStreamer Interface 58 /// @name MCStreamer Interface
43 /// @{ 59 /// @{
44 60
45 virtual void InitSections(); 61 void ChangeSection(const MCSection *Sect, const MCExpr *Subsect) override;
46 virtual void InitToTextSection(); 62 void EmitLabel(MCSymbol *Symbol) override;
47 virtual void EmitLabel(MCSymbol *Symbol); 63 void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
48 virtual void EmitDebugLabel(MCSymbol *Symbol); 64 void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
49 virtual void EmitEHSymAttributes(const MCSymbol *Symbol, 65 void EmitLinkerOptions(ArrayRef<std::string> Options) override;
50 MCSymbol *EHSymbol); 66 void EmitDataRegion(MCDataRegionType Kind) override;
51 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 67 void EmitVersionMin(MCVersionMinType Kind, unsigned Major,
52 virtual void EmitLinkerOptions(ArrayRef<std::string> Options); 68 unsigned Minor, unsigned Update) override;
53 virtual void EmitDataRegion(MCDataRegionType Kind); 69 void EmitThumbFunc(MCSymbol *Func) override;
54 virtual void EmitThumbFunc(MCSymbol *Func); 70 bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
55 virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 71 void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
56 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); 72 void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
57 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 73 unsigned ByteAlignment) override;
58 unsigned ByteAlignment); 74 void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {
59 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) { 75 llvm_unreachable("macho doesn't support this directive");
60 llvm_unreachable("macho doesn't support this directive"); 76 }
61 } 77 void EmitCOFFSymbolStorageClass(int StorageClass) override {
62 virtual void EmitCOFFSymbolStorageClass(int StorageClass) { 78 llvm_unreachable("macho doesn't support this directive");
63 llvm_unreachable("macho doesn't support this directive"); 79 }
64 } 80 void EmitCOFFSymbolType(int Type) override {
65 virtual void EmitCOFFSymbolType(int Type) { 81 llvm_unreachable("macho doesn't support this directive");
66 llvm_unreachable("macho doesn't support this directive"); 82 }
67 } 83 void EndCOFFSymbolDef() override {
68 virtual void EndCOFFSymbolDef() { 84 llvm_unreachable("macho doesn't support this directive");
69 llvm_unreachable("macho doesn't support this directive"); 85 }
70 } 86 void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override {
71 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 87 llvm_unreachable("macho doesn't support this directive");
72 llvm_unreachable("macho doesn't support this directive"); 88 }
73 } 89 void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
74 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 90 unsigned ByteAlignment) override;
75 unsigned ByteAlignment); 91 void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
76 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 92 uint64_t Size = 0, unsigned ByteAlignment = 0) override;
77 uint64_t Size = 0, unsigned ByteAlignment = 0); 93 void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
78 virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 94 unsigned ByteAlignment = 0) override;
79 uint64_t Size, unsigned ByteAlignment = 0); 95
80 96 void EmitFileDirective(StringRef Filename) override {
81 virtual void EmitFileDirective(StringRef Filename) {
82 // FIXME: Just ignore the .file; it isn't important enough to fail the 97 // FIXME: Just ignore the .file; it isn't important enough to fail the
83 // entire assembly. 98 // entire assembly.
84 99
85 // report_fatal_error("unsupported directive: '.file'"); 100 // report_fatal_error("unsupported directive: '.file'");
86 } 101 }
87 102
88 virtual void EmitIdent(StringRef IdentString) { 103 void EmitIdent(StringRef IdentString) override {
89 llvm_unreachable("macho doesn't support this directive"); 104 llvm_unreachable("macho doesn't support this directive");
90 } 105 }
91 106
92 virtual void FinishImpl(); 107 void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {
108 getAssembler().getLOHContainer().addDirective(Kind, Args);
109 }
110
111 void FinishImpl() override;
93 }; 112 };
94 113
95 } // end anonymous namespace. 114 } // end anonymous namespace.
96 115
97 void MCMachOStreamer::InitSections() { 116 void MCMachOStreamer::ChangeSection(const MCSection *Section,
98 InitToTextSection(); 117 const MCExpr *Subsection) {
99 } 118 // Change the section normally.
100 119 MCObjectStreamer::ChangeSection(Section, Subsection);
101 void MCMachOStreamer::InitToTextSection() { 120 // Output a linker-local symbol so we don't need section-relative local
102 SwitchSection(getContext().getMachOSection( 121 // relocations. The linker hates us when we do that.
103 "__TEXT", "__text", 122 if (LabelSections && !HasSectionLabel[Section]) {
104 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 123 MCSymbol *Label = getContext().CreateLinkerPrivateTempSymbol();
105 SectionKind::getText())); 124 EmitLabel(Label);
125 HasSectionLabel[Section] = true;
126 }
106 } 127 }
107 128
108 void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 129 void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
109 MCSymbol *EHSymbol) { 130 MCSymbol *EHSymbol) {
110 MCSymbolData &SD = 131 MCSymbolData &SD =
138 // FIXME: Cleanup this code, these bits should be emitted based on semantic 159 // FIXME: Cleanup this code, these bits should be emitted based on semantic
139 // properties, not on the order of definition, etc. 160 // properties, not on the order of definition, etc.
140 SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask); 161 SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask);
141 } 162 }
142 163
143 void MCMachOStreamer::EmitDebugLabel(MCSymbol *Symbol) {
144 EmitLabel(Symbol);
145 }
146 void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) { 164 void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
147 if (!getAssembler().getBackend().hasDataInCodeSupport()) 165 if (!getAssembler().getBackend().hasDataInCodeSupport())
148 return; 166 return;
149 // Create a temporary label to mark the start of the data region. 167 // Create a temporary label to mark the start of the data region.
150 MCSymbol *Start = getContext().CreateTempSymbol(); 168 MCSymbol *Start = getContext().CreateTempSymbol();
151 EmitLabel(Start); 169 EmitLabel(Start);
152 // Record the region for the object writer to use. 170 // Record the region for the object writer to use.
153 DataRegionData Data = { Kind, Start, NULL }; 171 DataRegionData Data = { Kind, Start, nullptr };
154 std::vector<DataRegionData> &Regions = getAssembler().getDataRegions(); 172 std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
155 Regions.push_back(Data); 173 Regions.push_back(Data);
156 } 174 }
157 175
158 void MCMachOStreamer::EmitDataRegionEnd() { 176 void MCMachOStreamer::EmitDataRegionEnd() {
159 if (!getAssembler().getBackend().hasDataInCodeSupport()) 177 if (!getAssembler().getBackend().hasDataInCodeSupport())
160 return; 178 return;
161 std::vector<DataRegionData> &Regions = getAssembler().getDataRegions(); 179 std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
162 assert(Regions.size() && "Mismatched .end_data_region!"); 180 assert(Regions.size() && "Mismatched .end_data_region!");
163 DataRegionData &Data = Regions.back(); 181 DataRegionData &Data = Regions.back();
164 assert(Data.End == NULL && "Mismatched .end_data_region!"); 182 assert(!Data.End && "Mismatched .end_data_region!");
165 // Create a temporary label to mark the end of the data region. 183 // Create a temporary label to mark the end of the data region.
166 Data.End = getContext().CreateTempSymbol(); 184 Data.End = getContext().CreateTempSymbol();
167 EmitLabel(Data.End); 185 EmitLabel(Data.End);
168 } 186 }
169 187
204 EmitDataRegionEnd(); 222 EmitDataRegionEnd();
205 return; 223 return;
206 } 224 }
207 } 225 }
208 226
227 void MCMachOStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
228 unsigned Minor, unsigned Update) {
229 getAssembler().setVersionMinInfo(Kind, Major, Minor, Update);
230 }
231
209 void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) { 232 void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {
210 // Remember that the function is a thumb function. Fixup and relocation 233 // Remember that the function is a thumb function. Fixup and relocation
211 // values will need adjusted. 234 // values will need adjusted.
212 getAssembler().setIsThumbFunc(Symbol); 235 getAssembler().setIsThumbFunc(Symbol);
213
214 // Mark the thumb bit on the symbol.
215 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
216 SD.setFlags(SD.getFlags() | SF_ThumbFunc);
217 } 236 }
218 237
219 bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 238 bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
220 MCSymbolAttr Attribute) { 239 MCSymbolAttr Attribute) {
221 // Indirect symbols are handled differently, to match how 'as' handles 240 // Indirect symbols are handled differently, to match how 'as' handles
323 void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 342 void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
324 unsigned ByteAlignment) { 343 unsigned ByteAlignment) {
325 // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself. 344 // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
326 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 345 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
327 346
328 AssignSection(Symbol, NULL); 347 AssignSection(Symbol, nullptr);
329 348
330 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 349 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
331 SD.setExternal(true); 350 SD.setExternal(true);
332 SD.setCommon(Size, ByteAlignment); 351 SD.setCommon(Size, ByteAlignment);
333 } 352 }
334 353
335 void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 354 void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
336 unsigned ByteAlignment) { 355 unsigned ByteAlignment) {
337 // '.lcomm' is equivalent to '.zerofill'. 356 // '.lcomm' is equivalent to '.zerofill'.
338 return EmitZerofill(getContext().getMachOSection("__DATA", "__bss", 357 return EmitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(),
339 MCSectionMachO::S_ZEROFILL,
340 0, SectionKind::getBSS()),
341 Symbol, Size, ByteAlignment); 358 Symbol, Size, ByteAlignment);
342 } 359 }
343 360
344 void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 361 void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
345 uint64_t Size, unsigned ByteAlignment) { 362 uint64_t Size, unsigned ByteAlignment) {
376 uint64_t Size, unsigned ByteAlignment) { 393 uint64_t Size, unsigned ByteAlignment) {
377 EmitZerofill(Section, Symbol, Size, ByteAlignment); 394 EmitZerofill(Section, Symbol, Size, ByteAlignment);
378 return; 395 return;
379 } 396 }
380 397
381 void MCMachOStreamer::EmitInstToData(const MCInst &Inst) { 398 void MCMachOStreamer::EmitInstToData(const MCInst &Inst,
399 const MCSubtargetInfo &STI) {
382 MCDataFragment *DF = getOrCreateDataFragment(); 400 MCDataFragment *DF = getOrCreateDataFragment();
383 401
384 SmallVector<MCFixup, 4> Fixups; 402 SmallVector<MCFixup, 4> Fixups;
385 SmallString<256> Code; 403 SmallString<256> Code;
386 raw_svector_ostream VecOS(Code); 404 raw_svector_ostream VecOS(Code);
387 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 405 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI);
388 VecOS.flush(); 406 VecOS.flush();
389 407
390 // Add the fixups and data. 408 // Add the fixups and data.
391 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 409 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
392 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 410 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
394 } 412 }
395 DF->getContents().append(Code.begin(), Code.end()); 413 DF->getContents().append(Code.begin(), Code.end());
396 } 414 }
397 415
398 void MCMachOStreamer::FinishImpl() { 416 void MCMachOStreamer::FinishImpl() {
399 EmitFrames(&getAssembler().getBackend(), true); 417 EmitFrames(&getAssembler().getBackend());
400 418
401 // We have to set the fragment atom associations so we can relax properly for 419 // We have to set the fragment atom associations so we can relax properly for
402 // Mach-O. 420 // Mach-O.
403 421
404 // First, scan the symbol table to build a lookup table from fragments to 422 // First, scan the symbol table to build a lookup table from fragments to
405 // defining symbols. 423 // defining symbols.
406 DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap; 424 DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap;
407 for (MCAssembler::symbol_iterator it = getAssembler().symbol_begin(), 425 for (MCSymbolData &SD : getAssembler().symbols()) {
408 ie = getAssembler().symbol_end(); it != ie; ++it) { 426 if (getAssembler().isSymbolLinkerVisible(SD.getSymbol()) &&
409 if (getAssembler().isSymbolLinkerVisible(it->getSymbol()) && 427 SD.getFragment()) {
410 it->getFragment()) {
411 // An atom defining symbol should never be internal to a fragment. 428 // An atom defining symbol should never be internal to a fragment.
412 assert(it->getOffset() == 0 && "Invalid offset in atom defining symbol!"); 429 assert(SD.getOffset() == 0 && "Invalid offset in atom defining symbol!");
413 DefiningSymbolMap[it->getFragment()] = it; 430 DefiningSymbolMap[SD.getFragment()] = &SD;
414 } 431 }
415 } 432 }
416 433
417 // Set the fragment atom associations by tracking the last seen atom defining 434 // Set the fragment atom associations by tracking the last seen atom defining
418 // symbol. 435 // symbol.
419 for (MCAssembler::iterator it = getAssembler().begin(), 436 for (MCAssembler::iterator it = getAssembler().begin(),
420 ie = getAssembler().end(); it != ie; ++it) { 437 ie = getAssembler().end(); it != ie; ++it) {
421 MCSymbolData *CurrentAtom = 0; 438 MCSymbolData *CurrentAtom = nullptr;
422 for (MCSectionData::iterator it2 = it->begin(), 439 for (MCSectionData::iterator it2 = it->begin(),
423 ie2 = it->end(); it2 != ie2; ++it2) { 440 ie2 = it->end(); it2 != ie2; ++it2) {
424 if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2)) 441 if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2))
425 CurrentAtom = SD; 442 CurrentAtom = SD;
426 it2->setAtom(CurrentAtom); 443 it2->setAtom(CurrentAtom);
430 this->MCObjectStreamer::FinishImpl(); 447 this->MCObjectStreamer::FinishImpl();
431 } 448 }
432 449
433 MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB, 450 MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
434 raw_ostream &OS, MCCodeEmitter *CE, 451 raw_ostream &OS, MCCodeEmitter *CE,
435 bool RelaxAll) { 452 bool RelaxAll,
436 MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE); 453 bool LabelSections) {
454 MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections);
437 if (RelaxAll) 455 if (RelaxAll)
438 S->getAssembler().setRelaxAll(true); 456 S->getAssembler().setRelaxAll(true);
439 return S; 457 return S;
440 } 458 }