Mercurial > hg > CbC > CbC_llvm
comparison lib/MC/MCELFStreamer.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 | e4204d083e25 |
children | 60c9769439b8 |
comparison
equal
deleted
inserted
replaced
34:e874dbf0ad9d | 77:54457678186b |
---|---|
10 // This file assembles .s files and emits ELF .o object files. | 10 // This file assembles .s files and emits ELF .o object files. |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 #include "llvm/MC/MCELFStreamer.h" | 14 #include "llvm/MC/MCELFStreamer.h" |
15 #include "llvm/ADT/STLExtras.h" | |
15 #include "llvm/ADT/SmallPtrSet.h" | 16 #include "llvm/ADT/SmallPtrSet.h" |
16 #include "llvm/ADT/STLExtras.h" | 17 #include "llvm/MC/MCAsmBackend.h" |
17 #include "llvm/MC/MCAssembler.h" | 18 #include "llvm/MC/MCAssembler.h" |
18 #include "llvm/MC/MCAsmBackend.h" | |
19 #include "llvm/MC/MCCodeEmitter.h" | 19 #include "llvm/MC/MCCodeEmitter.h" |
20 #include "llvm/MC/MCContext.h" | 20 #include "llvm/MC/MCContext.h" |
21 #include "llvm/MC/MCELF.h" | 21 #include "llvm/MC/MCELF.h" |
22 #include "llvm/MC/MCELFSymbolFlags.h" | 22 #include "llvm/MC/MCELFSymbolFlags.h" |
23 #include "llvm/MC/MCExpr.h" | 23 #include "llvm/MC/MCExpr.h" |
24 #include "llvm/MC/MCInst.h" | 24 #include "llvm/MC/MCInst.h" |
25 #include "llvm/MC/MCObjectFileInfo.h" | |
25 #include "llvm/MC/MCObjectStreamer.h" | 26 #include "llvm/MC/MCObjectStreamer.h" |
26 #include "llvm/MC/MCSection.h" | 27 #include "llvm/MC/MCSection.h" |
27 #include "llvm/MC/MCSectionELF.h" | 28 #include "llvm/MC/MCSectionELF.h" |
28 #include "llvm/MC/MCSymbol.h" | 29 #include "llvm/MC/MCSymbol.h" |
29 #include "llvm/MC/MCValue.h" | 30 #include "llvm/MC/MCValue.h" |
32 #include "llvm/Support/ErrorHandling.h" | 33 #include "llvm/Support/ErrorHandling.h" |
33 #include "llvm/Support/raw_ostream.h" | 34 #include "llvm/Support/raw_ostream.h" |
34 | 35 |
35 using namespace llvm; | 36 using namespace llvm; |
36 | 37 |
37 | |
38 inline void MCELFStreamer::SetSection(StringRef Section, unsigned Type, | |
39 unsigned Flags, SectionKind Kind) { | |
40 SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind)); | |
41 } | |
42 | |
43 inline void MCELFStreamer::SetSectionData() { | |
44 SetSection(".data", | |
45 ELF::SHT_PROGBITS, | |
46 ELF::SHF_WRITE | ELF::SHF_ALLOC, | |
47 SectionKind::getDataRel()); | |
48 EmitCodeAlignment(4, 0); | |
49 } | |
50 | |
51 inline void MCELFStreamer::SetSectionText() { | |
52 SetSection(".text", | |
53 ELF::SHT_PROGBITS, | |
54 ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, | |
55 SectionKind::getText()); | |
56 EmitCodeAlignment(4, 0); | |
57 } | |
58 | |
59 inline void MCELFStreamer::SetSectionBss() { | |
60 SetSection(".bss", | |
61 ELF::SHT_NOBITS, | |
62 ELF::SHF_WRITE | ELF::SHF_ALLOC, | |
63 SectionKind::getBSS()); | |
64 EmitCodeAlignment(4, 0); | |
65 } | |
66 | |
67 MCELFStreamer::~MCELFStreamer() { | 38 MCELFStreamer::~MCELFStreamer() { |
68 } | |
69 | |
70 void MCELFStreamer::InitToTextSection() { | |
71 SetSectionText(); | |
72 } | 39 } |
73 | 40 |
74 void MCELFStreamer::InitSections() { | 41 void MCELFStreamer::InitSections() { |
75 // This emulates the same behavior of GNU as. This makes it easier | 42 // This emulates the same behavior of GNU as. This makes it easier |
76 // to compare the output as the major sections are in the same order. | 43 // to compare the output as the major sections are in the same order. |
77 SetSectionText(); | 44 SwitchSection(getContext().getObjectFileInfo()->getTextSection()); |
78 SetSectionData(); | 45 EmitCodeAlignment(4); |
79 SetSectionBss(); | 46 |
80 SetSectionText(); | 47 SwitchSection(getContext().getObjectFileInfo()->getDataSection()); |
48 EmitCodeAlignment(4); | |
49 | |
50 SwitchSection(getContext().getObjectFileInfo()->getBSSSection()); | |
51 EmitCodeAlignment(4); | |
52 | |
53 SwitchSection(getContext().getObjectFileInfo()->getTextSection()); | |
81 } | 54 } |
82 | 55 |
83 void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { | 56 void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { |
84 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); | 57 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); |
85 | 58 |
88 const MCSectionELF &Section = | 61 const MCSectionELF &Section = |
89 static_cast<const MCSectionELF&>(Symbol->getSection()); | 62 static_cast<const MCSectionELF&>(Symbol->getSection()); |
90 MCSymbolData &SD = getAssembler().getSymbolData(*Symbol); | 63 MCSymbolData &SD = getAssembler().getSymbolData(*Symbol); |
91 if (Section.getFlags() & ELF::SHF_TLS) | 64 if (Section.getFlags() & ELF::SHF_TLS) |
92 MCELF::SetType(SD, ELF::STT_TLS); | 65 MCELF::SetType(SD, ELF::STT_TLS); |
93 } | |
94 | |
95 void MCELFStreamer::EmitDebugLabel(MCSymbol *Symbol) { | |
96 EmitLabel(Symbol); | |
97 } | 66 } |
98 | 67 |
99 void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { | 68 void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { |
100 // Let the target do whatever target specific stuff it needs to do. | 69 // Let the target do whatever target specific stuff it needs to do. |
101 getAssembler().getBackend().handleAssemblerFlag(Flag); | 70 getAssembler().getBackend().handleAssemblerFlag(Flag); |
124 this->MCObjectStreamer::ChangeSection(Section, Subsection); | 93 this->MCObjectStreamer::ChangeSection(Section, Subsection); |
125 } | 94 } |
126 | 95 |
127 void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { | 96 void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { |
128 getAssembler().getOrCreateSymbolData(*Symbol); | 97 getAssembler().getOrCreateSymbolData(*Symbol); |
129 MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias); | 98 const MCExpr *Value = MCSymbolRefExpr::Create( |
130 AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref); | 99 Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()); |
131 const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, getContext()); | |
132 Alias->setVariableValue(Value); | 100 Alias->setVariableValue(Value); |
133 } | 101 } |
134 | 102 |
135 // When GNU as encounters more than one .type declaration for an object it seems | 103 // When GNU as encounters more than one .type declaration for an object it seems |
136 // to use a mechanism similar to the one below to decide which type is actually | 104 // to use a mechanism similar to the one below to decide which type is actually |
301 SD.setExternal(false); | 269 SD.setExternal(false); |
302 BindingExplicitlySet.insert(Symbol); | 270 BindingExplicitlySet.insert(Symbol); |
303 EmitCommonSymbol(Symbol, Size, ByteAlignment); | 271 EmitCommonSymbol(Symbol, Size, ByteAlignment); |
304 } | 272 } |
305 | 273 |
306 void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { | 274 void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, |
275 const SMLoc &Loc) { | |
307 if (getCurrentSectionData()->isBundleLocked()) | 276 if (getCurrentSectionData()->isBundleLocked()) |
308 report_fatal_error("Emitting values inside a locked bundle is forbidden"); | 277 report_fatal_error("Emitting values inside a locked bundle is forbidden"); |
309 fixSymbolsInTLSFixups(Value); | 278 fixSymbolsInTLSFixups(Value); |
310 MCObjectStreamer::EmitValueImpl(Value, Size); | 279 MCObjectStreamer::EmitValueImpl(Value, Size, Loc); |
311 } | 280 } |
312 | 281 |
313 void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, | 282 void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, |
314 int64_t Value, | 283 int64_t Value, |
315 unsigned ValueSize, | 284 unsigned ValueSize, |
422 fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr()); | 391 fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr()); |
423 break; | 392 break; |
424 } | 393 } |
425 } | 394 } |
426 | 395 |
427 void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) { | 396 void MCELFStreamer::EmitInstToFragment(const MCInst &Inst, |
428 this->MCObjectStreamer::EmitInstToFragment(Inst); | 397 const MCSubtargetInfo &STI) { |
398 this->MCObjectStreamer::EmitInstToFragment(Inst, STI); | |
429 MCRelaxableFragment &F = *cast<MCRelaxableFragment>(getCurrentFragment()); | 399 MCRelaxableFragment &F = *cast<MCRelaxableFragment>(getCurrentFragment()); |
430 | 400 |
431 for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i) | 401 for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i) |
432 fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); | 402 fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); |
433 } | 403 } |
434 | 404 |
435 void MCELFStreamer::EmitInstToData(const MCInst &Inst) { | 405 void MCELFStreamer::EmitInstToData(const MCInst &Inst, |
406 const MCSubtargetInfo &STI) { | |
436 MCAssembler &Assembler = getAssembler(); | 407 MCAssembler &Assembler = getAssembler(); |
437 SmallVector<MCFixup, 4> Fixups; | 408 SmallVector<MCFixup, 4> Fixups; |
438 SmallString<256> Code; | 409 SmallString<256> Code; |
439 raw_svector_ostream VecOS(Code); | 410 raw_svector_ostream VecOS(Code); |
440 Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); | 411 Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI); |
441 VecOS.flush(); | 412 VecOS.flush(); |
442 | 413 |
443 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) | 414 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) |
444 fixSymbolsInTLSFixups(Fixups[i].getValue()); | 415 fixSymbolsInTLSFixups(Fixups[i].getValue()); |
445 | 416 |
561 | 532 |
562 LocalCommons.clear(); | 533 LocalCommons.clear(); |
563 } | 534 } |
564 | 535 |
565 void MCELFStreamer::FinishImpl() { | 536 void MCELFStreamer::FinishImpl() { |
566 EmitFrames(NULL, true); | 537 EmitFrames(nullptr); |
567 | 538 |
568 Flush(); | 539 Flush(); |
569 | 540 |
570 this->MCObjectStreamer::FinishImpl(); | 541 this->MCObjectStreamer::FinishImpl(); |
571 } | 542 } |
572 | 543 |
573 MCStreamer *llvm::createELFStreamer(MCContext &Context, | 544 MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, |
574 MCTargetStreamer *Streamer, | 545 raw_ostream &OS, MCCodeEmitter *CE, |
575 MCAsmBackend &MAB, raw_ostream &OS, | 546 bool RelaxAll, bool NoExecStack) { |
576 MCCodeEmitter *CE, bool RelaxAll, | 547 MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE); |
577 bool NoExecStack) { | |
578 MCELFStreamer *S = new MCELFStreamer(Context, Streamer, MAB, OS, CE); | |
579 if (RelaxAll) | 548 if (RelaxAll) |
580 S->getAssembler().setRelaxAll(true); | 549 S->getAssembler().setRelaxAll(true); |
581 if (NoExecStack) | 550 if (NoExecStack) |
582 S->getAssembler().setNoExecStack(true); | 551 S->getAssembler().setNoExecStack(true); |
583 return S; | 552 return S; |
585 | 554 |
586 void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { | 555 void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { |
587 llvm_unreachable("Generic ELF doesn't support this directive"); | 556 llvm_unreachable("Generic ELF doesn't support this directive"); |
588 } | 557 } |
589 | 558 |
590 MCSymbolData &MCELFStreamer::getOrCreateSymbolData(MCSymbol *Symbol) { | |
591 return getAssembler().getOrCreateSymbolData(*Symbol); | |
592 } | |
593 | |
594 void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { | 559 void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { |
595 llvm_unreachable("ELF doesn't support this directive"); | 560 llvm_unreachable("ELF doesn't support this directive"); |
596 } | 561 } |
597 | 562 |
598 void MCELFStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { | 563 void MCELFStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { |