MCELFStreamer.cpp revision 212793
1//===- lib/MC/MCELFStreamer.cpp - ELF 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// This file assembles .s files and emits ELF .o object files.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/MC/MCStreamer.h"
15
16#include "llvm/MC/MCAssembler.h"
17#include "llvm/MC/MCContext.h"
18#include "llvm/MC/MCCodeEmitter.h"
19#include "llvm/MC/MCELFSymbolFlags.h"
20#include "llvm/MC/MCExpr.h"
21#include "llvm/MC/MCInst.h"
22#include "llvm/MC/MCObjectStreamer.h"
23#include "llvm/MC/MCSection.h"
24#include "llvm/MC/MCSectionELF.h"
25#include "llvm/MC/MCSymbol.h"
26#include "llvm/Support/Debug.h"
27#include "llvm/Support/ELF.h"
28#include "llvm/Support/ErrorHandling.h"
29#include "llvm/Support/raw_ostream.h"
30#include "llvm/Target/TargetAsmBackend.h"
31
32using namespace llvm;
33
34namespace {
35
36class MCELFStreamer : public MCObjectStreamer {
37  void EmitInstToFragment(const MCInst &Inst);
38  void EmitInstToData(const MCInst &Inst);
39public:
40  MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
41                  raw_ostream &OS, MCCodeEmitter *Emitter)
42    : MCObjectStreamer(Context, TAB, OS, Emitter) {}
43
44  ~MCELFStreamer() {}
45
46  /// @name MCStreamer Interface
47  /// @{
48
49  virtual void EmitLabel(MCSymbol *Symbol);
50  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
51  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
52  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
53  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
54    assert(0 && "ELF doesn't support this directive");
55  }
56  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
57                                unsigned ByteAlignment);
58  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
59    assert(0 && "ELF doesn't support this directive");
60  }
61
62  virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
63    assert(0 && "ELF doesn't support this directive");
64  }
65
66  virtual void EmitCOFFSymbolType(int Type) {
67    assert(0 && "ELF doesn't support this directive");
68  }
69
70  virtual void EndCOFFSymbolDef() {
71    assert(0 && "ELF doesn't support this directive");
72  }
73
74  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
75     MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
76     SD.setSize(Value);
77  }
78
79  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
80    assert(0 && "ELF doesn't support this directive");
81  }
82  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
83                            unsigned Size = 0, unsigned ByteAlignment = 0) {
84    assert(0 && "ELF doesn't support this directive");
85  }
86  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
87                              uint64_t Size, unsigned ByteAlignment = 0) {
88    assert(0 && "ELF doesn't support this directive");
89  }
90  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
91  virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
92  virtual void EmitGPRel32Value(const MCExpr *Value) {
93    assert(0 && "ELF doesn't support this directive");
94  }
95  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
96                                    unsigned ValueSize = 1,
97                                    unsigned MaxBytesToEmit = 0);
98  virtual void EmitCodeAlignment(unsigned ByteAlignment,
99                                 unsigned MaxBytesToEmit = 0);
100  virtual void EmitValueToOffset(const MCExpr *Offset,
101                                 unsigned char Value = 0);
102
103  virtual void EmitFileDirective(StringRef Filename);
104  virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
105    DEBUG(dbgs() << "FIXME: MCELFStreamer:EmitDwarfFileDirective not implemented\n");
106  }
107
108  virtual void EmitInstruction(const MCInst &Inst);
109  virtual void Finish();
110
111  /// @}
112};
113
114} // end anonymous namespace.
115
116void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
117  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
118
119  // FIXME: This is wasteful, we don't necessarily need to create a data
120  // fragment. Instead, we should mark the symbol as pointing into the data
121  // fragment if it exists, otherwise we should just queue the label and set its
122  // fragment pointer when we emit the next fragment.
123  MCDataFragment *F = getOrCreateDataFragment();
124  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
125  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
126  SD.setFragment(F);
127  SD.setOffset(F->getContents().size());
128
129  Symbol->setSection(*CurSection);
130}
131
132void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
133  switch (Flag) {
134  case MCAF_SubsectionsViaSymbols:
135    getAssembler().setSubsectionsViaSymbols(true);
136    return;
137  }
138
139  assert(0 && "invalid assembler flag!");
140}
141
142void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
143  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
144  // MCObjectStreamer.
145  // FIXME: Lift context changes into super class.
146  getAssembler().getOrCreateSymbolData(*Symbol);
147  Symbol->setVariableValue(AddValueSymbols(Value));
148}
149
150void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
151                                          MCSymbolAttr Attribute) {
152  // Indirect symbols are handled differently, to match how 'as' handles
153  // them. This makes writing matching .o files easier.
154  if (Attribute == MCSA_IndirectSymbol) {
155    // Note that we intentionally cannot use the symbol data here; this is
156    // important for matching the string table that 'as' generates.
157    IndirectSymbolData ISD;
158    ISD.Symbol = Symbol;
159    ISD.SectionData = getCurrentSectionData();
160    getAssembler().getIndirectSymbols().push_back(ISD);
161    return;
162  }
163
164  // Adding a symbol attribute always introduces the symbol, note that an
165  // important side effect of calling getOrCreateSymbolData here is to register
166  // the symbol with the assembler.
167  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
168
169  // The implementation of symbol attributes is designed to match 'as', but it
170  // leaves much to desired. It doesn't really make sense to arbitrarily add and
171  // remove flags, but 'as' allows this (in particular, see .desc).
172  //
173  // In the future it might be worth trying to make these operations more well
174  // defined.
175  switch (Attribute) {
176  case MCSA_LazyReference:
177  case MCSA_Reference:
178  case MCSA_NoDeadStrip:
179  case MCSA_PrivateExtern:
180  case MCSA_WeakDefinition:
181  case MCSA_WeakDefAutoPrivate:
182  case MCSA_Invalid:
183  case MCSA_ELF_TypeIndFunction:
184  case MCSA_IndirectSymbol:
185    assert(0 && "Invalid symbol attribute for ELF!");
186    break;
187
188  case MCSA_Global:
189    SD.setFlags(SD.getFlags() | ELF_STB_Global);
190    SD.setExternal(true);
191    break;
192
193  case MCSA_WeakReference:
194  case MCSA_Weak:
195    SD.setFlags(SD.getFlags() | ELF_STB_Weak);
196    break;
197
198  case MCSA_Local:
199    SD.setFlags(SD.getFlags() | ELF_STB_Local);
200    break;
201
202  case MCSA_ELF_TypeFunction:
203    SD.setFlags(SD.getFlags() | ELF_STT_Func);
204    break;
205
206  case MCSA_ELF_TypeObject:
207    SD.setFlags(SD.getFlags() | ELF_STT_Object);
208    break;
209
210  case MCSA_ELF_TypeTLS:
211    SD.setFlags(SD.getFlags() | ELF_STT_Tls);
212    break;
213
214  case MCSA_ELF_TypeCommon:
215    SD.setFlags(SD.getFlags() | ELF_STT_Common);
216    break;
217
218  case MCSA_ELF_TypeNoType:
219    SD.setFlags(SD.getFlags() | ELF_STT_Notype);
220    break;
221
222  case MCSA_Protected:
223    SD.setFlags(SD.getFlags() | ELF_STV_Protected);
224    break;
225
226  case MCSA_Hidden:
227    SD.setFlags(SD.getFlags() | ELF_STV_Hidden);
228    break;
229
230  case MCSA_Internal:
231    SD.setFlags(SD.getFlags() | ELF_STV_Internal);
232    break;
233  }
234}
235
236void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
237                                       unsigned ByteAlignment) {
238  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
239
240  if ((SD.getFlags() & (0xf << ELF_STB_Shift)) == ELF_STB_Local) {
241    const MCSection *Section = getAssembler().getContext().getELFSection(".bss",
242                                                                    MCSectionELF::SHT_NOBITS,
243                                                                    MCSectionELF::SHF_WRITE |
244                                                                    MCSectionELF::SHF_ALLOC,
245                                                                    SectionKind::getBSS());
246
247    MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section);
248    MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
249    SD.setFragment(F);
250    Symbol->setSection(*Section);
251    SD.setSize(MCConstantExpr::Create(Size, getContext()));
252  }
253
254  SD.setFlags(SD.getFlags() | ELF_STB_Global);
255  SD.setExternal(true);
256
257  SD.setCommon(Size, ByteAlignment);
258}
259
260void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
261  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
262  // MCObjectStreamer.
263  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
264}
265
266void MCELFStreamer::EmitValue(const MCExpr *Value, unsigned Size,
267                                unsigned AddrSpace) {
268  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
269  // MCObjectStreamer.
270  MCDataFragment *DF = getOrCreateDataFragment();
271
272  // Avoid fixups when possible.
273  int64_t AbsValue;
274  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
275    // FIXME: Endianness assumption.
276    for (unsigned i = 0; i != Size; ++i)
277      DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
278  } else {
279    DF->addFixup(MCFixup::Create(DF->getContents().size(), AddValueSymbols(Value),
280                                 MCFixup::getKindForSize(Size)));
281    DF->getContents().resize(DF->getContents().size() + Size, 0);
282  }
283}
284
285void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
286                                           int64_t Value, unsigned ValueSize,
287                                           unsigned MaxBytesToEmit) {
288  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
289  // MCObjectStreamer.
290  if (MaxBytesToEmit == 0)
291    MaxBytesToEmit = ByteAlignment;
292  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
293                      getCurrentSectionData());
294
295  // Update the maximum alignment on the current section if necessary.
296  if (ByteAlignment > getCurrentSectionData()->getAlignment())
297    getCurrentSectionData()->setAlignment(ByteAlignment);
298}
299
300void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
301                                        unsigned MaxBytesToEmit) {
302  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
303  // MCObjectStreamer.
304  if (MaxBytesToEmit == 0)
305    MaxBytesToEmit = ByteAlignment;
306  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
307                                           getCurrentSectionData());
308  F->setEmitNops(true);
309
310  // Update the maximum alignment on the current section if necessary.
311  if (ByteAlignment > getCurrentSectionData()->getAlignment())
312    getCurrentSectionData()->setAlignment(ByteAlignment);
313}
314
315void MCELFStreamer::EmitValueToOffset(const MCExpr *Offset,
316                                        unsigned char Value) {
317  // TODO: This is exactly the same as MCMachOStreamer. Consider merging into
318  // MCObjectStreamer.
319  new MCOrgFragment(*Offset, Value, getCurrentSectionData());
320}
321
322// Add a symbol for the file name of this module. This is the second
323// entry in the module's symbol table (the first being the null symbol).
324void MCELFStreamer::EmitFileDirective(StringRef Filename) {
325  MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename);
326  Symbol->setSection(*CurSection);
327  Symbol->setAbsolute();
328
329  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
330
331  SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default);
332}
333
334void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
335  MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
336
337  // Add the fixups and data.
338  //
339  // FIXME: Revisit this design decision when relaxation is done, we may be
340  // able to get away with not storing any extra data in the MCInst.
341  SmallVector<MCFixup, 4> Fixups;
342  SmallString<256> Code;
343  raw_svector_ostream VecOS(Code);
344  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
345  VecOS.flush();
346
347  IF->getCode() = Code;
348  IF->getFixups() = Fixups;
349}
350
351void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
352  MCDataFragment *DF = getOrCreateDataFragment();
353
354  SmallVector<MCFixup, 4> Fixups;
355  SmallString<256> Code;
356  raw_svector_ostream VecOS(Code);
357  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
358  VecOS.flush();
359
360  // Add the fixups and data.
361  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
362    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
363    DF->addFixup(Fixups[i]);
364  }
365  DF->getContents().append(Code.begin(), Code.end());
366}
367
368void MCELFStreamer::EmitInstruction(const MCInst &Inst) {
369  // Scan for values.
370  for (unsigned i = 0; i != Inst.getNumOperands(); ++i)
371    if (Inst.getOperand(i).isExpr())
372      AddValueSymbols(Inst.getOperand(i).getExpr());
373
374  getCurrentSectionData()->setHasInstructions(true);
375
376  // If this instruction doesn't need relaxation, just emit it as data.
377  if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
378    EmitInstToData(Inst);
379    return;
380  }
381
382  // Otherwise, if we are relaxing everything, relax the instruction as much as
383  // possible and emit it as data.
384  if (getAssembler().getRelaxAll()) {
385    MCInst Relaxed;
386    getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
387    while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
388      getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
389    EmitInstToData(Relaxed);
390    return;
391  }
392
393  // Otherwise emit to a separate fragment.
394  EmitInstToFragment(Inst);
395}
396
397void MCELFStreamer::Finish() {
398  getAssembler().Finish();
399}
400
401MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
402                                      raw_ostream &OS, MCCodeEmitter *CE,
403                                      bool RelaxAll) {
404  MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE);
405  if (RelaxAll)
406    S->getAssembler().setRelaxAll(true);
407  return S;
408}
409