MCELFStreamer.cpp revision c70a1d985aca40b33b3e4b046b179f0d5e5e238b
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/ADT/SmallPtrSet.h"
17#include "llvm/MC/MCAssembler.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCCodeEmitter.h"
20#include "llvm/MC/MCELFSymbolFlags.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCObjectStreamer.h"
24#include "llvm/MC/MCSection.h"
25#include "llvm/MC/MCSectionELF.h"
26#include "llvm/MC/MCSymbol.h"
27#include "llvm/MC/MCValue.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/ELF.h"
30#include "llvm/Support/ErrorHandling.h"
31#include "llvm/Support/raw_ostream.h"
32#include "llvm/Target/TargetAsmBackend.h"
33
34using namespace llvm;
35
36namespace {
37
38class MCELFStreamer : public MCObjectStreamer {
39public:
40  MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
41                  raw_ostream &OS, MCCodeEmitter *Emitter)
42    : MCObjectStreamer(Context, TAB, OS, Emitter, false) {}
43
44  ~MCELFStreamer() {}
45
46  /// @name MCStreamer Interface
47  /// @{
48
49  virtual void InitSections();
50  virtual void EmitLabel(MCSymbol *Symbol);
51  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
52  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
53  virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
54  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
55  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
56    assert(0 && "ELF doesn't support this directive");
57  }
58  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
59                                unsigned ByteAlignment);
60  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
61    assert(0 && "ELF doesn't support this directive");
62  }
63
64  virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
65    assert(0 && "ELF doesn't support this directive");
66  }
67
68  virtual void EmitCOFFSymbolType(int Type) {
69    assert(0 && "ELF doesn't support this directive");
70  }
71
72  virtual void EndCOFFSymbolDef() {
73    assert(0 && "ELF doesn't support this directive");
74  }
75
76  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
77     MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
78     SD.setSize(Value);
79  }
80
81  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
82    assert(0 && "ELF doesn't support this directive");
83  }
84  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
85                            unsigned Size = 0, unsigned ByteAlignment = 0) {
86    assert(0 && "ELF doesn't support this directive");
87  }
88  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
89                              uint64_t Size, unsigned ByteAlignment = 0) {
90    assert(0 && "ELF doesn't support this directive");
91  }
92  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
93  virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
94  virtual void EmitGPRel32Value(const MCExpr *Value) {
95    assert(0 && "ELF doesn't support this directive");
96  }
97  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
98                                    unsigned ValueSize = 1,
99                                    unsigned MaxBytesToEmit = 0);
100  virtual void EmitCodeAlignment(unsigned ByteAlignment,
101                                 unsigned MaxBytesToEmit = 0);
102  virtual void EmitValueToOffset(const MCExpr *Offset,
103                                 unsigned char Value = 0);
104
105  virtual void EmitFileDirective(StringRef Filename);
106  virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
107    DEBUG(dbgs() << "FIXME: MCELFStreamer:EmitDwarfFileDirective not implemented\n");
108  }
109
110  virtual void Finish();
111
112private:
113  virtual void EmitInstToFragment(const MCInst &Inst);
114  virtual void EmitInstToData(const MCInst &Inst);
115
116  struct LocalCommon {
117    MCSymbolData *SD;
118    uint64_t Size;
119    unsigned ByteAlignment;
120  };
121  std::vector<LocalCommon> LocalCommons;
122
123  SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
124  /// @}
125  void SetSection(StringRef Section, unsigned Type, unsigned Flags,
126                  SectionKind Kind) {
127    SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind));
128  }
129
130  void SetSectionData() {
131    SetSection(".data", MCSectionELF::SHT_PROGBITS,
132               MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
133               SectionKind::getDataRel());
134    EmitCodeAlignment(4, 0);
135  }
136  void SetSectionText() {
137    SetSection(".text", MCSectionELF::SHT_PROGBITS,
138               MCSectionELF::SHF_EXECINSTR |
139               MCSectionELF::SHF_ALLOC, SectionKind::getText());
140    EmitCodeAlignment(4, 0);
141  }
142  void SetSectionBss() {
143    SetSection(".bss", MCSectionELF::SHT_NOBITS,
144               MCSectionELF::SHF_WRITE |
145               MCSectionELF::SHF_ALLOC, SectionKind::getBSS());
146    EmitCodeAlignment(4, 0);
147  }
148};
149
150} // end anonymous namespace.
151
152void MCELFStreamer::InitSections() {
153  // This emulates the same behavior of GNU as. This makes it easier
154  // to compare the output as the major sections are in the same order.
155  SetSectionText();
156  SetSectionData();
157  SetSectionBss();
158  SetSectionText();
159}
160
161void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
162  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
163
164  Symbol->setSection(*CurSection);
165
166  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
167
168  // FIXME: This is wasteful, we don't necessarily need to create a data
169  // fragment. Instead, we should mark the symbol as pointing into the data
170  // fragment if it exists, otherwise we should just queue the label and set its
171  // fragment pointer when we emit the next fragment.
172  MCDataFragment *F = getOrCreateDataFragment();
173
174  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
175  SD.setFragment(F);
176  SD.setOffset(F->getContents().size());
177}
178
179void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
180  switch (Flag) {
181  case MCAF_SyntaxUnified:  return; // no-op here?
182  case MCAF_SubsectionsViaSymbols:
183    getAssembler().setSubsectionsViaSymbols(true);
184    return;
185  }
186
187  assert(0 && "invalid assembler flag!");
188}
189
190void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
191  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
192  // MCObjectStreamer.
193  // FIXME: Lift context changes into super class.
194  getAssembler().getOrCreateSymbolData(*Symbol);
195  Symbol->setVariableValue(AddValueSymbols(Value));
196}
197
198// This is a hack. To be able to implement weakrefs the writer has to be able
199// to distinguish
200//    .weakref foo, bar
201//    .long foo
202// from
203//   .weakref foo, bar
204//   .long bar
205// since the first case should produce a weak undefined reference and the second
206// one a strong one.
207// If we created foo as a regular alias pointing to bar (foo = bar), then
208// MCExpr::EvaluateAsRelocatable would recurse on foo and the writer would
209// never see it used in a relocation.
210// What we do is create a MCTargetExpr that when evaluated produces a symbol
211// ref to a temporary symbol. This temporary symbol in turn is a variable
212// that equals the original symbol (tmp = bar). With this hack the writer
213// gets a relocation with tmp and can correctly implement weak references.
214
215class WeakRefExpr : public MCTargetExpr {
216private:
217  const MCSymbolRefExpr *Alias;
218
219  explicit WeakRefExpr(const MCSymbolRefExpr *Alias_)
220    : MCTargetExpr(), Alias(Alias_) {}
221
222public:
223  virtual void PrintImpl(raw_ostream &OS) const {
224    llvm_unreachable("Unimplemented");
225  }
226
227  virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
228                                         const MCAsmLayout *Layout) const {
229    Res = MCValue::get(Alias, 0, 0);
230    return true;
231  }
232
233  static const WeakRefExpr *Create(const MCSymbol *Alias, MCContext &Ctx) {
234    const MCSymbolRefExpr *A = MCSymbolRefExpr::Create(Alias, Ctx);
235    return new (Ctx) WeakRefExpr(A);
236  }
237};
238
239void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
240  getAssembler().getOrCreateSymbolData(*Symbol);
241  MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias);
242  AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref);
243
244  // Create the alias that actually points to Symbol
245  const MCSymbolRefExpr *SymRef = MCSymbolRefExpr::Create(Symbol, getContext());
246  MCSymbol *RealAlias = getContext().CreateTempSymbol();
247  RealAlias->setVariableValue(SymRef);
248
249  MCSymbolData &RealAliasSD = getAssembler().getOrCreateSymbolData(*RealAlias);
250  RealAliasSD.setFlags(RealAliasSD.getFlags() | ELF_Other_Weakref);
251
252  const MCExpr *Value = WeakRefExpr::Create(RealAlias, getContext());
253  Alias->setVariableValue(Value);
254}
255
256static void SetBinding(MCSymbolData &SD, unsigned Binding) {
257  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
258         Binding == ELF::STB_WEAK);
259  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift);
260  SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift));
261}
262
263static unsigned GetBinding(const MCSymbolData &SD) {
264  uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift;
265  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
266         Binding == ELF::STB_WEAK);
267  return Binding;
268}
269
270static void SetType(MCSymbolData &SD, unsigned Type) {
271  assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT ||
272         Type == ELF::STT_FUNC || Type == ELF::STT_SECTION ||
273         Type == ELF::STT_FILE || Type == ELF::STT_COMMON ||
274         Type == ELF::STT_TLS);
275
276  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift);
277  SD.setFlags(OtherFlags | (Type << ELF_STT_Shift));
278}
279
280static void SetVisibility(MCSymbolData &SD, unsigned Visibility) {
281  assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
282         Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
283
284  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STV_Shift);
285  SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
286}
287
288void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
289                                          MCSymbolAttr Attribute) {
290  // Indirect symbols are handled differently, to match how 'as' handles
291  // them. This makes writing matching .o files easier.
292  if (Attribute == MCSA_IndirectSymbol) {
293    // Note that we intentionally cannot use the symbol data here; this is
294    // important for matching the string table that 'as' generates.
295    IndirectSymbolData ISD;
296    ISD.Symbol = Symbol;
297    ISD.SectionData = getCurrentSectionData();
298    getAssembler().getIndirectSymbols().push_back(ISD);
299    return;
300  }
301
302  // Adding a symbol attribute always introduces the symbol, note that an
303  // important side effect of calling getOrCreateSymbolData here is to register
304  // the symbol with the assembler.
305  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
306
307  // The implementation of symbol attributes is designed to match 'as', but it
308  // leaves much to desired. It doesn't really make sense to arbitrarily add and
309  // remove flags, but 'as' allows this (in particular, see .desc).
310  //
311  // In the future it might be worth trying to make these operations more well
312  // defined.
313  switch (Attribute) {
314  case MCSA_LazyReference:
315  case MCSA_Reference:
316  case MCSA_NoDeadStrip:
317  case MCSA_PrivateExtern:
318  case MCSA_WeakDefinition:
319  case MCSA_WeakDefAutoPrivate:
320  case MCSA_Invalid:
321  case MCSA_ELF_TypeIndFunction:
322  case MCSA_IndirectSymbol:
323    assert(0 && "Invalid symbol attribute for ELF!");
324    break;
325
326  case MCSA_Global:
327    SetBinding(SD, ELF::STB_GLOBAL);
328    SD.setExternal(true);
329    BindingExplicitlySet.insert(Symbol);
330    break;
331
332  case MCSA_WeakReference:
333  case MCSA_Weak:
334    SetBinding(SD, ELF::STB_WEAK);
335    SD.setExternal(true);
336    BindingExplicitlySet.insert(Symbol);
337    break;
338
339  case MCSA_Local:
340    SetBinding(SD, ELF::STB_LOCAL);
341    SD.setExternal(false);
342    BindingExplicitlySet.insert(Symbol);
343    break;
344
345  case MCSA_ELF_TypeFunction:
346    SetType(SD, ELF::STT_FUNC);
347    break;
348
349  case MCSA_ELF_TypeObject:
350    SetType(SD, ELF::STT_OBJECT);
351    break;
352
353  case MCSA_ELF_TypeTLS:
354    SetType(SD, ELF::STT_TLS);
355    break;
356
357  case MCSA_ELF_TypeCommon:
358    SetType(SD, ELF::STT_COMMON);
359    break;
360
361  case MCSA_ELF_TypeNoType:
362    SetType(SD, ELF::STT_NOTYPE);
363    break;
364
365  case MCSA_Protected:
366    SetVisibility(SD, ELF::STV_PROTECTED);
367    break;
368
369  case MCSA_Hidden:
370    SetVisibility(SD, ELF::STV_HIDDEN);
371    break;
372
373  case MCSA_Internal:
374    SetVisibility(SD, ELF::STV_INTERNAL);
375    break;
376  }
377}
378
379void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
380                                       unsigned ByteAlignment) {
381  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
382
383  if (!BindingExplicitlySet.count(Symbol)) {
384    SetBinding(SD, ELF::STB_GLOBAL);
385    SD.setExternal(true);
386  }
387
388  if (GetBinding(SD) == ELF_STB_Local) {
389    const MCSection *Section = getAssembler().getContext().getELFSection(".bss",
390                                                                    MCSectionELF::SHT_NOBITS,
391                                                                    MCSectionELF::SHF_WRITE |
392                                                                    MCSectionELF::SHF_ALLOC,
393                                                                    SectionKind::getBSS());
394    Symbol->setSection(*Section);
395
396    struct LocalCommon L = {&SD, Size, ByteAlignment};
397    LocalCommons.push_back(L);
398  } else {
399    SD.setCommon(Size, ByteAlignment);
400  }
401
402  SD.setSize(MCConstantExpr::Create(Size, getContext()));
403}
404
405void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
406  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
407  // MCObjectStreamer.
408  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
409}
410
411void MCELFStreamer::EmitValue(const MCExpr *Value, unsigned Size,
412                                unsigned AddrSpace) {
413  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
414  // MCObjectStreamer.
415  MCDataFragment *DF = getOrCreateDataFragment();
416
417  // Avoid fixups when possible.
418  int64_t AbsValue;
419  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
420    // FIXME: Endianness assumption.
421    for (unsigned i = 0; i != Size; ++i)
422      DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
423  } else {
424    DF->addFixup(MCFixup::Create(DF->getContents().size(), AddValueSymbols(Value),
425                                 MCFixup::getKindForSize(Size)));
426    DF->getContents().resize(DF->getContents().size() + Size, 0);
427  }
428}
429
430void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
431                                           int64_t Value, unsigned ValueSize,
432                                           unsigned MaxBytesToEmit) {
433  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
434  // MCObjectStreamer.
435  if (MaxBytesToEmit == 0)
436    MaxBytesToEmit = ByteAlignment;
437  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
438                      getCurrentSectionData());
439
440  // Update the maximum alignment on the current section if necessary.
441  if (ByteAlignment > getCurrentSectionData()->getAlignment())
442    getCurrentSectionData()->setAlignment(ByteAlignment);
443}
444
445void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
446                                        unsigned MaxBytesToEmit) {
447  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
448  // MCObjectStreamer.
449  if (MaxBytesToEmit == 0)
450    MaxBytesToEmit = ByteAlignment;
451  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
452                                           getCurrentSectionData());
453  F->setEmitNops(true);
454
455  // Update the maximum alignment on the current section if necessary.
456  if (ByteAlignment > getCurrentSectionData()->getAlignment())
457    getCurrentSectionData()->setAlignment(ByteAlignment);
458}
459
460void MCELFStreamer::EmitValueToOffset(const MCExpr *Offset,
461                                        unsigned char Value) {
462  // TODO: This is exactly the same as MCMachOStreamer. Consider merging into
463  // MCObjectStreamer.
464  new MCOrgFragment(*Offset, Value, getCurrentSectionData());
465}
466
467// Add a symbol for the file name of this module. This is the second
468// entry in the module's symbol table (the first being the null symbol).
469void MCELFStreamer::EmitFileDirective(StringRef Filename) {
470  MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename);
471  Symbol->setSection(*CurSection);
472  Symbol->setAbsolute();
473
474  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
475
476  SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default);
477}
478
479void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
480  MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
481
482  // Add the fixups and data.
483  //
484  // FIXME: Revisit this design decision when relaxation is done, we may be
485  // able to get away with not storing any extra data in the MCInst.
486  SmallVector<MCFixup, 4> Fixups;
487  SmallString<256> Code;
488  raw_svector_ostream VecOS(Code);
489  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
490  VecOS.flush();
491
492  IF->getCode() = Code;
493  IF->getFixups() = Fixups;
494}
495
496void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
497  MCDataFragment *DF = getOrCreateDataFragment();
498
499  SmallVector<MCFixup, 4> Fixups;
500  SmallString<256> Code;
501  raw_svector_ostream VecOS(Code);
502  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
503  VecOS.flush();
504
505  // Add the fixups and data.
506  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
507    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
508    DF->addFixup(Fixups[i]);
509  }
510  DF->getContents().append(Code.begin(), Code.end());
511}
512
513void MCELFStreamer::Finish() {
514  // FIXME: duplicated code with the MachO streamer.
515  // Dump out the dwarf file & directory tables and line tables.
516  if (getContext().hasDwarfFiles()) {
517    const MCSection *DwarfLineSection =
518      getContext().getELFSection(".debug_line", 0, 0,
519                                 SectionKind::getDataRelLocal());
520    MCDwarfFileTable::Emit(this, DwarfLineSection);
521  }
522
523  for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),
524                                                e = LocalCommons.end();
525       i != e; ++i) {
526    MCSymbolData *SD = i->SD;
527    uint64_t Size = i->Size;
528    unsigned ByteAlignment = i->ByteAlignment;
529    const MCSymbol &Symbol = SD->getSymbol();
530    const MCSection &Section = Symbol.getSection();
531
532    MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section);
533    new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData);
534
535    MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
536    SD->setFragment(F);
537
538    // Update the maximum alignment of the section if necessary.
539    if (ByteAlignment > SectData.getAlignment())
540      SectData.setAlignment(ByteAlignment);
541  }
542
543  this->MCObjectStreamer::Finish();
544}
545
546MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
547                                      raw_ostream &OS, MCCodeEmitter *CE,
548                                      bool RelaxAll) {
549  MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE);
550  if (RelaxAll)
551    S->getAssembler().setRelaxAll(true);
552  return S;
553}
554