LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MCPureStreamer.cpp
Go to the documentation of this file.
1 //===- lib/MC/MCPureStreamer.cpp - MC "Pure" Object Output ----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/MC/MCStreamer.h"
11 #include "llvm/MC/MCAssembler.h"
12 #include "llvm/MC/MCCodeEmitter.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCSymbol.h"
19 
20 using namespace llvm;
21 
22 namespace {
23 
24 class MCPureStreamer : public MCObjectStreamer {
25 private:
26  virtual void EmitInstToFragment(const MCInst &Inst);
27  virtual void EmitInstToData(const MCInst &Inst);
28 
29 public:
30  MCPureStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
31  MCCodeEmitter *Emitter)
32  : MCObjectStreamer(Context, 0, TAB, OS, Emitter) {}
33 
34  /// @name MCStreamer Interface
35  /// @{
36 
37  virtual void InitSections();
38  virtual void InitToTextSection();
39  virtual void EmitLabel(MCSymbol *Symbol);
40  virtual void EmitDebugLabel(MCSymbol *Symbol);
41  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
42  uint64_t Size = 0, unsigned ByteAlignment = 0);
43  virtual void EmitBytes(StringRef Data);
44  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
45  unsigned ValueSize = 1,
46  unsigned MaxBytesToEmit = 0);
47  virtual void EmitCodeAlignment(unsigned ByteAlignment,
48  unsigned MaxBytesToEmit = 0);
49  virtual bool EmitValueToOffset(const MCExpr *Offset,
50  unsigned char Value = 0);
51  virtual void FinishImpl();
52 
53 
54  virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) {
55  report_fatal_error("unsupported directive in pure streamer");
56  return false;
57  }
58  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {
59  report_fatal_error("unsupported directive in pure streamer");
60  }
61  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
62  uint64_t Size, unsigned ByteAlignment = 0) {
63  report_fatal_error("unsupported directive in pure streamer");
64  }
65  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
66  report_fatal_error("unsupported directive in pure streamer");
67  }
68  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
69  unsigned ByteAlignment) {
70  report_fatal_error("unsupported directive in pure streamer");
71  }
72  virtual void EmitThumbFunc(MCSymbol *Func) {
73  report_fatal_error("unsupported directive in pure streamer");
74  }
75  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
76  report_fatal_error("unsupported directive in pure streamer");
77  }
78  virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
79  report_fatal_error("unsupported directive in pure streamer");
80  }
81  virtual void EmitCOFFSymbolType(int Type) {
82  report_fatal_error("unsupported directive in pure streamer");
83  }
84  virtual void EndCOFFSymbolDef() {
85  report_fatal_error("unsupported directive in pure streamer");
86  }
87  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
88  report_fatal_error("unsupported directive in pure streamer");
89  }
90  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
91  unsigned ByteAlignment) {
92  report_fatal_error("unsupported directive in pure streamer");
93  }
94  virtual void EmitFileDirective(StringRef Filename) {
95  report_fatal_error("unsupported directive in pure streamer");
96  }
97  virtual void EmitIdent(StringRef IdentString) {
98  report_fatal_error("unsupported directive in pure streamer");
99  }
100  virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
101  StringRef Filename, unsigned CUID = 0) {
102  report_fatal_error("unsupported directive in pure streamer");
103  }
104 };
105 
106 } // end anonymous namespace.
107 
108 void MCPureStreamer::InitSections() {
109  InitToTextSection();
110 }
111 
112 void MCPureStreamer::InitToTextSection() {
113  SwitchSection(getContext().getObjectFileInfo()->getTextSection());
114 }
115 
116 void MCPureStreamer::EmitLabel(MCSymbol *Symbol) {
117  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
118  assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
119  assert(getCurrentSection().first && "Cannot emit before setting section!");
120 
121  AssignSection(Symbol, getCurrentSection().first);
122 
123  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
124 
125  // We have to create a new fragment if this is an atom defining symbol,
126  // fragments cannot span atoms.
127  if (getAssembler().isSymbolLinkerVisible(SD.getSymbol()))
128  insert(new MCDataFragment());
129 
130  // FIXME: This is wasteful, we don't necessarily need to create a data
131  // fragment. Instead, we should mark the symbol as pointing into the data
132  // fragment if it exists, otherwise we should just queue the label and set its
133  // fragment pointer when we emit the next fragment.
134  MCDataFragment *F = getOrCreateDataFragment();
135  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
136  SD.setFragment(F);
137  SD.setOffset(F->getContents().size());
138 }
139 
140 
141 void MCPureStreamer::EmitDebugLabel(MCSymbol *Symbol) {
142  EmitLabel(Symbol);
143 }
144 
145 void MCPureStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
146  uint64_t Size, unsigned ByteAlignment) {
147  report_fatal_error("not yet implemented in pure streamer");
148 }
149 
150 void MCPureStreamer::EmitBytes(StringRef Data) {
151  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
152  // MCObjectStreamer.
153  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
154 }
155 
156 void MCPureStreamer::EmitValueToAlignment(unsigned ByteAlignment,
157  int64_t Value, unsigned ValueSize,
158  unsigned MaxBytesToEmit) {
159  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
160  // MCObjectStreamer.
161  if (MaxBytesToEmit == 0)
162  MaxBytesToEmit = ByteAlignment;
163  insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
164 
165  // Update the maximum alignment on the current section if necessary.
166  if (ByteAlignment > getCurrentSectionData()->getAlignment())
167  getCurrentSectionData()->setAlignment(ByteAlignment);
168 }
169 
170 void MCPureStreamer::EmitCodeAlignment(unsigned ByteAlignment,
171  unsigned MaxBytesToEmit) {
172  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
173  // MCObjectStreamer.
174  if (MaxBytesToEmit == 0)
175  MaxBytesToEmit = ByteAlignment;
176  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit);
177  insert(F);
178  F->setEmitNops(true);
179 
180  // Update the maximum alignment on the current section if necessary.
181  if (ByteAlignment > getCurrentSectionData()->getAlignment())
182  getCurrentSectionData()->setAlignment(ByteAlignment);
183 }
184 
185 bool MCPureStreamer::EmitValueToOffset(const MCExpr *Offset,
186  unsigned char Value) {
187  insert(new MCOrgFragment(*Offset, Value));
188  return false;
189 }
190 
191 void MCPureStreamer::EmitInstToFragment(const MCInst &Inst) {
193  insert(IF);
194 
195  // Add the fixups and data.
196  //
197  // FIXME: Revisit this design decision when relaxation is done, we may be
198  // able to get away with not storing any extra data in the MCInst.
201  raw_svector_ostream VecOS(Code);
202  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
203  VecOS.flush();
204 
205  IF->getContents() = Code;
206  IF->getFixups() = Fixups;
207 }
208 
209 void MCPureStreamer::EmitInstToData(const MCInst &Inst) {
210  MCDataFragment *DF = getOrCreateDataFragment();
211 
214  raw_svector_ostream VecOS(Code);
215  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
216  VecOS.flush();
217 
218  // Add the fixups and data.
219  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
220  Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
221  DF->getFixups().push_back(Fixups[i]);
222  }
223  DF->getContents().append(Code.begin(), Code.end());
224 }
225 
226 void MCPureStreamer::FinishImpl() {
227  // FIXME: Handle DWARF tables?
228 
230 }
231 
233  raw_ostream &OS, MCCodeEmitter *CE) {
234  return new MCPureStreamer(Context, MAB, OS, CE);
235 }
MCStreamer * createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE)
F(f)
virtual SmallVectorImpl< char > & getContents()
Definition: MCAssembler.h:221
COFF::SymbolStorageClass StorageClass
Definition: COFFYAML.cpp:204
const MCSymbol & getSymbol() const
Definition: MCAssembler.h:718
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCAssembler.h:224
void setEmitNops(bool Value)
Definition: MCAssembler.h:369
Streaming object file generation interface.
MCFragment * getFragment() const
Definition: MCAssembler.h:720
iterator begin() const
Definition: StringRef.h:97
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:22
void append(in_iter in_start, in_iter in_end)
Definition: SmallVector.h:445
virtual SmallVectorImpl< char > & getContents()
Definition: MCAssembler.h:302
void setOffset(uint64_t Value)
Definition: MCAssembler.h:724
MCSymbolAttr
Definition: MCDirectives.h:19
virtual void FinishImpl()
FinishImpl - Streamer specific finalization.
MCAssemblerFlag
Definition: MCDirectives.h:47
void setFragment(MCFragment *Value)
Definition: MCAssembler.h:721
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:132
LLVM Value Representation.
Definition: Value.h:66
MCAsmBackend - Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:34
iterator end() const
Definition: StringRef.h:99
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:100
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCAssembler.h:308