Mercurial > hg > CbC > CbC_llvm
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 } |