MCELFStreamer.cpp revision 59ff3c913449402ad5447bbe3ae6338402fb84b0
13565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===- lib/MC/MCELFStreamer.cpp - ELF Object Output ------------===//
23565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
33565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//                     The LLVM Compiler Infrastructure
43565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
53565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file is distributed under the University of Illinois Open Source
63565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// License. See LICENSE.TXT for details.
73565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
83565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
93565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file assembles .s files and emits ELF .o object files.
113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCStreamer.h"
153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
16f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola#include "llvm/ADT/SmallPtrSet.h"
173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAssembler.h"
183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h"
193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCCodeEmitter.h"
203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCELFSymbolFlags.h"
213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h"
223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCInst.h"
233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCObjectStreamer.h"
243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSection.h"
253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h"
263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSymbol.h"
273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h"
283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h"
293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h"
303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/raw_ostream.h"
313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Target/TargetAsmBackend.h"
323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
333565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm;
343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
353565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingnamespace {
363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
373565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingclass MCELFStreamer : public MCObjectStreamer {
3893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  void EmitInstToFragment(const MCInst &Inst);
3993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  void EmitInstToData(const MCInst &Inst);
403565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingpublic:
413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                  raw_ostream &OS, MCCodeEmitter *Emitter)
4359ff3c913449402ad5447bbe3ae6338402fb84b0Rafael Espindola    : MCObjectStreamer(Context, TAB, OS, Emitter, false) {}
443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  ~MCELFStreamer() {}
463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  /// @name MCStreamer Interface
483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  /// @{
493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
50d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  virtual void InitSections();
513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitLabel(MCSymbol *Symbol);
523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                unsigned ByteAlignment);
603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitCOFFSymbolType(int Type) {
693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EndCOFFSymbolDef() {
733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming     MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming     SD.setSize(Value);
793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                            unsigned Size = 0, unsigned ByteAlignment = 0) {
863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                              uint64_t Size, unsigned ByteAlignment = 0) {
903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitGPRel32Value(const MCExpr *Value) {
953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                    unsigned ValueSize = 1,
993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                    unsigned MaxBytesToEmit = 0);
1003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitCodeAlignment(unsigned ByteAlignment,
1013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                 unsigned MaxBytesToEmit = 0);
1023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitValueToOffset(const MCExpr *Offset,
1033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                 unsigned char Value = 0);
1043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitFileDirective(StringRef Filename);
1063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
1073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DEBUG(dbgs() << "FIXME: MCELFStreamer:EmitDwarfFileDirective not implemented\n");
1083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitInstruction(const MCInst &Inst);
1113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void Finish();
1123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
113f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindolaprivate:
114f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
1153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  /// @}
116d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSection(StringRef Section, unsigned Type, unsigned Flags,
117d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola                  SectionKind Kind) {
118d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind));
119d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
120d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola
121d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSectionData() {
122d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SetSection(".data", MCSectionELF::SHT_PROGBITS,
123d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
124d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               SectionKind::getDataRel());
125d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    EmitCodeAlignment(4, 0);
126d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
127d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSectionText() {
128d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SetSection(".text", MCSectionELF::SHT_PROGBITS,
129d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_EXECINSTR |
130d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_ALLOC, SectionKind::getText());
131d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    EmitCodeAlignment(4, 0);
132d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
133d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSectionBss() {
134d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SetSection(".bss", MCSectionELF::SHT_NOBITS,
135d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_WRITE |
136d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_ALLOC, SectionKind::getBSS());
137d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    EmitCodeAlignment(4, 0);
138d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
1393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming};
1403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} // end anonymous namespace.
1423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
143d80781b98b771d370730ab7c630018f23e202b57Rafael Espindolavoid MCELFStreamer::InitSections() {
144d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  // This emulates the same behavior of GNU as. This makes it easier
145d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  // to compare the output as the major sections are in the same order.
146d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionText();
147d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionData();
148d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionBss();
149d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionText();
150d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola}
151d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola
1523565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
1533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
1543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: This is wasteful, we don't necessarily need to create a data
1563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // fragment. Instead, we should mark the symbol as pointing into the data
1573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // fragment if it exists, otherwise we should just queue the label and set its
1583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // fragment pointer when we emit the next fragment.
1593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *F = getOrCreateDataFragment();
1603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
1613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
1623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SD.setFragment(F);
1633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SD.setOffset(F->getContents().size());
1643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setSection(*CurSection);
1663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1683565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
1693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  switch (Flag) {
1703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCAF_SubsectionsViaSymbols:
1713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getAssembler().setSubsectionsViaSymbols(true);
1723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    return;
1733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(0 && "invalid assembler flag!");
1763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1783565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
1793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
1803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
1813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Lift context changes into super class.
1823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getAssembler().getOrCreateSymbolData(*Symbol);
1833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setVariableValue(AddValueSymbols(Value));
1843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
186f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindolastatic void SetBinding(MCSymbolData &SD, unsigned Binding) {
187f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
188f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Binding == ELF::STB_WEAK);
189f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift);
190f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift));
191f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola}
192f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
193f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindolastatic unsigned GetBinding(const MCSymbolData &SD) {
194f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift;
195f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
196f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola         Binding == ELF::STB_WEAK);
197f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  return Binding;
198f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola}
199f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
200f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindolastatic void SetType(MCSymbolData &SD, unsigned Type) {
201f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT ||
202f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Type == ELF::STT_FUNC || Type == ELF::STT_SECTION ||
203f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Type == ELF::STT_FILE || Type == ELF::STT_COMMON ||
204f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Type == ELF::STT_TLS);
205f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
206f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift);
207f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  SD.setFlags(OtherFlags | (Type << ELF_STT_Shift));
208f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola}
209f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
210f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindolastatic void SetVisibility(MCSymbolData &SD, unsigned Visibility) {
211f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
212f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
213f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
214f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STV_Shift);
215f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
216f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola}
217f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
2183565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
2193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                          MCSymbolAttr Attribute) {
2203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Indirect symbols are handled differently, to match how 'as' handles
2213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // them. This makes writing matching .o files easier.
2223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (Attribute == MCSA_IndirectSymbol) {
2233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Note that we intentionally cannot use the symbol data here; this is
2243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // important for matching the string table that 'as' generates.
2253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    IndirectSymbolData ISD;
2263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ISD.Symbol = Symbol;
2273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ISD.SectionData = getCurrentSectionData();
2283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getAssembler().getIndirectSymbols().push_back(ISD);
2293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    return;
2303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
2313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Adding a symbol attribute always introduces the symbol, note that an
2333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // important side effect of calling getOrCreateSymbolData here is to register
2343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // the symbol with the assembler.
2353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
2363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The implementation of symbol attributes is designed to match 'as', but it
2383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // leaves much to desired. It doesn't really make sense to arbitrarily add and
2393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // remove flags, but 'as' allows this (in particular, see .desc).
2403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
2413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // In the future it might be worth trying to make these operations more well
2423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // defined.
2433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  switch (Attribute) {
2443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_LazyReference:
2453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Reference:
2463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_NoDeadStrip:
2473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_PrivateExtern:
2483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_WeakDefinition:
249f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman  case MCSA_WeakDefAutoPrivate:
2503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Invalid:
2513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeIndFunction:
2523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_IndirectSymbol:
2533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "Invalid symbol attribute for ELF!");
2543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Global:
257f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetBinding(SD, ELF::STB_GLOBAL);
2583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    SD.setExternal(true);
259f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    BindingExplicitlySet.insert(Symbol);
2603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
262230c27472458d5f1f52f96347b655d1b5c531f33Benjamin Kramer  case MCSA_WeakReference:
2633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Weak:
264f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetBinding(SD, ELF::STB_WEAK);
265f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    BindingExplicitlySet.insert(Symbol);
2663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Local:
269f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetBinding(SD, ELF::STB_LOCAL);
270f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SD.setExternal(false);
271f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    BindingExplicitlySet.insert(Symbol);
2723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeFunction:
275f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_FUNC);
2763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeObject:
279f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_OBJECT);
2803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeTLS:
283f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_TLS);
2843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeCommon:
287f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_COMMON);
2883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeNoType:
291f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_NOTYPE);
2923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Protected:
295f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetVisibility(SD, ELF::STV_PROTECTED);
2963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
2973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Hidden:
299f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetVisibility(SD, ELF::STV_HIDDEN);
3003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Internal:
303f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetVisibility(SD, ELF::STV_INTERNAL);
3043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3083565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
3093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                       unsigned ByteAlignment) {
3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
312f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  if (!BindingExplicitlySet.count(Symbol)) {
313f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SetBinding(SD, ELF::STB_GLOBAL);
314f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SD.setExternal(true);
315f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  }
316f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
317f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  if (GetBinding(SD) == ELF_STB_Local) {
3183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSection *Section = getAssembler().getContext().getELFSection(".bss",
3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    MCSectionELF::SHT_NOBITS,
3203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    MCSectionELF::SHF_WRITE |
3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    MCSectionELF::SHF_ALLOC,
3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    SectionKind::getBSS());
3233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section);
3251963572f9de87cd1ac5f16e504e27c3c26267e6fRafael Espindola    new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData);
3261963572f9de87cd1ac5f16e504e27c3c26267e6fRafael Espindola
3273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
3283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    SD.setFragment(F);
3293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    Symbol->setSection(*Section);
3301963572f9de87cd1ac5f16e504e27c3c26267e6fRafael Espindola
3311963572f9de87cd1ac5f16e504e27c3c26267e6fRafael Espindola    // Update the maximum alignment of the section if necessary.
3321963572f9de87cd1ac5f16e504e27c3c26267e6fRafael Espindola    if (ByteAlignment > SectData.getAlignment())
3331963572f9de87cd1ac5f16e504e27c3c26267e6fRafael Espindola      SectData.setAlignment(ByteAlignment);
334f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  } else {
335f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SD.setCommon(Size, ByteAlignment);
3363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
338f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  SD.setSize(MCConstantExpr::Create(Size, getContext()));
3393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3413565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
3423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
3433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
3443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
3453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3473565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitValue(const MCExpr *Value, unsigned Size,
3483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                unsigned AddrSpace) {
3493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
3503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
3513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *DF = getOrCreateDataFragment();
3523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Avoid fixups when possible.
3543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  int64_t AbsValue;
3553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
3563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // FIXME: Endianness assumption.
3573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    for (unsigned i = 0; i != Size; ++i)
3583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
3593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  } else {
3603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DF->addFixup(MCFixup::Create(DF->getContents().size(), AddValueSymbols(Value),
3613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                 MCFixup::getKindForSize(Size)));
3623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DF->getContents().resize(DF->getContents().size() + Size, 0);
3633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3663565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
3673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                           int64_t Value, unsigned ValueSize,
3683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                           unsigned MaxBytesToEmit) {
3693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
3703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
3713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (MaxBytesToEmit == 0)
3723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MaxBytesToEmit = ByteAlignment;
3733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
3743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                      getCurrentSectionData());
3753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Update the maximum alignment on the current section if necessary.
3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (ByteAlignment > getCurrentSectionData()->getAlignment())
3783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getCurrentSectionData()->setAlignment(ByteAlignment);
3793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3813565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
3823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                        unsigned MaxBytesToEmit) {
3833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
3843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
3853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (MaxBytesToEmit == 0)
3863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MaxBytesToEmit = ByteAlignment;
3873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
3883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                           getCurrentSectionData());
3893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->setEmitNops(true);
3903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Update the maximum alignment on the current section if necessary.
3923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (ByteAlignment > getCurrentSectionData()->getAlignment())
3933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getCurrentSectionData()->setAlignment(ByteAlignment);
3943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3963565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitValueToOffset(const MCExpr *Offset,
3973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                        unsigned char Value) {
3983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as MCMachOStreamer. Consider merging into
3993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  new MCOrgFragment(*Offset, Value, getCurrentSectionData());
4013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Add a symbol for the file name of this module. This is the second
4043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// entry in the module's symbol table (the first being the null symbol).
4053565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitFileDirective(StringRef Filename) {
4063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename);
4073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setSection(*CurSection);
4083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setAbsolute();
4093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
4113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default);
4133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
41593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramervoid MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
41693ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
4173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
41893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // Add the fixups and data.
41993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  //
42093ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // FIXME: Revisit this design decision when relaxation is done, we may be
42193ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // able to get away with not storing any extra data in the MCInst.
42293ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  SmallVector<MCFixup, 4> Fixups;
42393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  SmallString<256> Code;
42493ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  raw_svector_ostream VecOS(Code);
42593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
42693ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  VecOS.flush();
4273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
42893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  IF->getCode() = Code;
42993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  IF->getFixups() = Fixups;
43093ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer}
43193ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer
43293ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramervoid MCELFStreamer::EmitInstToData(const MCInst &Inst) {
43393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  MCDataFragment *DF = getOrCreateDataFragment();
4343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SmallVector<MCFixup, 4> Fixups;
4363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SmallString<256> Code;
4373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  raw_svector_ostream VecOS(Code);
4383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
4393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  VecOS.flush();
4403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
44193ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // Add the fixups and data.
4423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
44393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
44493ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    DF->addFixup(Fixups[i]);
4453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
44693ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  DF->getContents().append(Code.begin(), Code.end());
44793ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer}
4483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
44993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramervoid MCELFStreamer::EmitInstruction(const MCInst &Inst) {
45093ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // Scan for values.
45193ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  for (unsigned i = 0; i != Inst.getNumOperands(); ++i)
45293ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    if (Inst.getOperand(i).isExpr())
45393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer      AddValueSymbols(Inst.getOperand(i).getExpr());
45493ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer
45593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  getCurrentSectionData()->setHasInstructions(true);
4563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
45793ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // If this instruction doesn't need relaxation, just emit it as data.
45893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
45993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    EmitInstToData(Inst);
4603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    return;
4613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
4623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
46393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // Otherwise, if we are relaxing everything, relax the instruction as much as
46493ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // possible and emit it as data.
46593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  if (getAssembler().getRelaxAll()) {
46693ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    MCInst Relaxed;
46793ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
46893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
46993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer      getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
47093ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    EmitInstToData(Relaxed);
47193ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    return;
4723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
47393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer
47493ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // Otherwise emit to a separate fragment.
47593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  EmitInstToFragment(Inst);
4763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4783565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::Finish() {
4793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getAssembler().Finish();
4803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4823565a06ebf44a193a8b333cbeff2ee154298d450Matt FlemingMCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
4833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                      raw_ostream &OS, MCCodeEmitter *CE,
4843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                      bool RelaxAll) {
4853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE);
4863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (RelaxAll)
4873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    S->getAssembler().setRelaxAll(true);
4883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  return S;
4893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
490