MCELFStreamer.cpp revision f79856986d47553240fb3f5fe796faa2a57be1bb
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"
27484291c27319668ad99cb87def000254357736fbRafael Espindola#include "llvm/MC/MCValue.h"
283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h"
293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h"
303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h"
313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/raw_ostream.h"
323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Target/TargetAsmBackend.h"
333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
343565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm;
353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
363565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingnamespace {
373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
383565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingclass MCELFStreamer : public MCObjectStreamer {
393565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingpublic:
403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                  raw_ostream &OS, MCCodeEmitter *Emitter)
4259ff3c913449402ad5447bbe3ae6338402fb84b0Rafael Espindola    : MCObjectStreamer(Context, TAB, OS, Emitter, false) {}
433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  ~MCELFStreamer() {}
453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  /// @name MCStreamer Interface
473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  /// @{
483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
49d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  virtual void InitSections();
503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitLabel(MCSymbol *Symbol);
513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
53484291c27319668ad99cb87def000254357736fbRafael Espindola  virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
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 Finish();
1113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
112f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindolaprivate:
113f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  virtual void EmitInstToFragment(const MCInst &Inst);
114f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  virtual void EmitInstToData(const MCInst &Inst);
115f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
1169e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  struct LocalCommon {
1179e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    MCSymbolData *SD;
1189e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    uint64_t Size;
1199e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    unsigned ByteAlignment;
1209e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  };
1219e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  std::vector<LocalCommon> LocalCommons;
1229e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
123f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
1243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  /// @}
125d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSection(StringRef Section, unsigned Type, unsigned Flags,
126d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola                  SectionKind Kind) {
127d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind));
128d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
129d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola
130d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSectionData() {
131d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SetSection(".data", MCSectionELF::SHT_PROGBITS,
132d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
133d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               SectionKind::getDataRel());
134d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    EmitCodeAlignment(4, 0);
135d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
136d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSectionText() {
137d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SetSection(".text", MCSectionELF::SHT_PROGBITS,
138d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_EXECINSTR |
139d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_ALLOC, SectionKind::getText());
140d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    EmitCodeAlignment(4, 0);
141d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
142d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSectionBss() {
143d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SetSection(".bss", MCSectionELF::SHT_NOBITS,
144d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_WRITE |
145d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_ALLOC, SectionKind::getBSS());
146d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    EmitCodeAlignment(4, 0);
147d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
1483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming};
1493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} // end anonymous namespace.
1513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
152d80781b98b771d370730ab7c630018f23e202b57Rafael Espindolavoid MCELFStreamer::InitSections() {
153d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  // This emulates the same behavior of GNU as. This makes it easier
154d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  // to compare the output as the major sections are in the same order.
155d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionText();
156d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionData();
157d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionBss();
158d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionText();
159d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola}
160d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola
1613565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
1623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
1633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
16473ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola  Symbol->setSection(*CurSection);
16573ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
16673ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
16773ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
1683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: This is wasteful, we don't necessarily need to create a data
1693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // fragment. Instead, we should mark the symbol as pointing into the data
1703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // fragment if it exists, otherwise we should just queue the label and set its
1713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // fragment pointer when we emit the next fragment.
1723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *F = getOrCreateDataFragment();
17373ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
1743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
1753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SD.setFragment(F);
1763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SD.setOffset(F->getContents().size());
1773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1793565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
1803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  switch (Flag) {
181afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim  case MCAF_SyntaxUnified:  return; // no-op here?
1823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCAF_SubsectionsViaSymbols:
1833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getAssembler().setSubsectionsViaSymbols(true);
1843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    return;
1853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(0 && "invalid assembler flag!");
1883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1903565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
1913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
1923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
1933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Lift context changes into super class.
1943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getAssembler().getOrCreateSymbolData(*Symbol);
1953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setVariableValue(AddValueSymbols(Value));
1963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
198484291c27319668ad99cb87def000254357736fbRafael Espindola// This is a hack. To be able to implement weakrefs the writer has to be able
199484291c27319668ad99cb87def000254357736fbRafael Espindola// to distinguish
200484291c27319668ad99cb87def000254357736fbRafael Espindola//    .weakref foo, bar
201484291c27319668ad99cb87def000254357736fbRafael Espindola//    .long foo
202484291c27319668ad99cb87def000254357736fbRafael Espindola// from
203484291c27319668ad99cb87def000254357736fbRafael Espindola//   .weakref foo, bar
204484291c27319668ad99cb87def000254357736fbRafael Espindola//   .long bar
205484291c27319668ad99cb87def000254357736fbRafael Espindola// since the first case should produce a weak undefined reference and the second
206484291c27319668ad99cb87def000254357736fbRafael Espindola// one a strong one.
207484291c27319668ad99cb87def000254357736fbRafael Espindola// If we created foo as a regular alias pointing to bar (foo = bar), then
208484291c27319668ad99cb87def000254357736fbRafael Espindola// MCExpr::EvaluateAsRelocatable would recurse on foo and the writer would
209484291c27319668ad99cb87def000254357736fbRafael Espindola// never see it used in a relocation.
210484291c27319668ad99cb87def000254357736fbRafael Espindola// What we do is create a MCTargetExpr that when evaluated produces a symbol
211484291c27319668ad99cb87def000254357736fbRafael Espindola// ref to a temporary symbol. This temporary symbol in turn is a variable
212484291c27319668ad99cb87def000254357736fbRafael Espindola// that equals the original symbol (tmp = bar). With this hack the writer
213484291c27319668ad99cb87def000254357736fbRafael Espindola// gets a relocation with tmp and can correctly implement weak references.
214484291c27319668ad99cb87def000254357736fbRafael Espindola
215f79856986d47553240fb3f5fe796faa2a57be1bbBenjamin Kramernamespace {
216484291c27319668ad99cb87def000254357736fbRafael Espindolaclass WeakRefExpr : public MCTargetExpr {
217484291c27319668ad99cb87def000254357736fbRafael Espindolaprivate:
218484291c27319668ad99cb87def000254357736fbRafael Espindola  const MCSymbolRefExpr *Alias;
219484291c27319668ad99cb87def000254357736fbRafael Espindola
220484291c27319668ad99cb87def000254357736fbRafael Espindola  explicit WeakRefExpr(const MCSymbolRefExpr *Alias_)
221484291c27319668ad99cb87def000254357736fbRafael Espindola    : MCTargetExpr(), Alias(Alias_) {}
222484291c27319668ad99cb87def000254357736fbRafael Espindola
223484291c27319668ad99cb87def000254357736fbRafael Espindolapublic:
224484291c27319668ad99cb87def000254357736fbRafael Espindola  virtual void PrintImpl(raw_ostream &OS) const {
225484291c27319668ad99cb87def000254357736fbRafael Espindola    llvm_unreachable("Unimplemented");
226484291c27319668ad99cb87def000254357736fbRafael Espindola  }
227484291c27319668ad99cb87def000254357736fbRafael Espindola
228484291c27319668ad99cb87def000254357736fbRafael Espindola  virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
229484291c27319668ad99cb87def000254357736fbRafael Espindola                                         const MCAsmLayout *Layout) const {
230484291c27319668ad99cb87def000254357736fbRafael Espindola    Res = MCValue::get(Alias, 0, 0);
231484291c27319668ad99cb87def000254357736fbRafael Espindola    return true;
232484291c27319668ad99cb87def000254357736fbRafael Espindola  }
233484291c27319668ad99cb87def000254357736fbRafael Espindola
234484291c27319668ad99cb87def000254357736fbRafael Espindola  static const WeakRefExpr *Create(const MCSymbol *Alias, MCContext &Ctx) {
235484291c27319668ad99cb87def000254357736fbRafael Espindola    const MCSymbolRefExpr *A = MCSymbolRefExpr::Create(Alias, Ctx);
236484291c27319668ad99cb87def000254357736fbRafael Espindola    return new (Ctx) WeakRefExpr(A);
237484291c27319668ad99cb87def000254357736fbRafael Espindola  }
238484291c27319668ad99cb87def000254357736fbRafael Espindola};
239f79856986d47553240fb3f5fe796faa2a57be1bbBenjamin Kramer} // end anonymous namespace
240484291c27319668ad99cb87def000254357736fbRafael Espindola
241484291c27319668ad99cb87def000254357736fbRafael Espindolavoid MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
242484291c27319668ad99cb87def000254357736fbRafael Espindola  getAssembler().getOrCreateSymbolData(*Symbol);
243484291c27319668ad99cb87def000254357736fbRafael Espindola  MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias);
244484291c27319668ad99cb87def000254357736fbRafael Espindola  AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref);
245484291c27319668ad99cb87def000254357736fbRafael Espindola
246484291c27319668ad99cb87def000254357736fbRafael Espindola  // Create the alias that actually points to Symbol
247484291c27319668ad99cb87def000254357736fbRafael Espindola  const MCSymbolRefExpr *SymRef = MCSymbolRefExpr::Create(Symbol, getContext());
248484291c27319668ad99cb87def000254357736fbRafael Espindola  MCSymbol *RealAlias = getContext().CreateTempSymbol();
249484291c27319668ad99cb87def000254357736fbRafael Espindola  RealAlias->setVariableValue(SymRef);
250484291c27319668ad99cb87def000254357736fbRafael Espindola
251484291c27319668ad99cb87def000254357736fbRafael Espindola  MCSymbolData &RealAliasSD = getAssembler().getOrCreateSymbolData(*RealAlias);
252484291c27319668ad99cb87def000254357736fbRafael Espindola  RealAliasSD.setFlags(RealAliasSD.getFlags() | ELF_Other_Weakref);
253484291c27319668ad99cb87def000254357736fbRafael Espindola
254484291c27319668ad99cb87def000254357736fbRafael Espindola  const MCExpr *Value = WeakRefExpr::Create(RealAlias, getContext());
255484291c27319668ad99cb87def000254357736fbRafael Espindola  Alias->setVariableValue(Value);
256484291c27319668ad99cb87def000254357736fbRafael Espindola}
257484291c27319668ad99cb87def000254357736fbRafael Espindola
258f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindolastatic void SetBinding(MCSymbolData &SD, unsigned Binding) {
259f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
260f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Binding == ELF::STB_WEAK);
261f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift);
262f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift));
263f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola}
264f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
265f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindolastatic unsigned GetBinding(const MCSymbolData &SD) {
266f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift;
267f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
268f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola         Binding == ELF::STB_WEAK);
269f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  return Binding;
270f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola}
271f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
272f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindolastatic void SetType(MCSymbolData &SD, unsigned Type) {
273f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT ||
274f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Type == ELF::STT_FUNC || Type == ELF::STT_SECTION ||
275f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Type == ELF::STT_FILE || Type == ELF::STT_COMMON ||
276f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Type == ELF::STT_TLS);
277f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
278f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift);
279f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  SD.setFlags(OtherFlags | (Type << ELF_STT_Shift));
280f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola}
281f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
282f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindolastatic void SetVisibility(MCSymbolData &SD, unsigned Visibility) {
283f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
284f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola         Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
285f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
286f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STV_Shift);
287f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola  SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
288f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola}
289f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola
2903565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
2913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                          MCSymbolAttr Attribute) {
2923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Indirect symbols are handled differently, to match how 'as' handles
2933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // them. This makes writing matching .o files easier.
2943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (Attribute == MCSA_IndirectSymbol) {
2953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Note that we intentionally cannot use the symbol data here; this is
2963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // important for matching the string table that 'as' generates.
2973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    IndirectSymbolData ISD;
2983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ISD.Symbol = Symbol;
2993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ISD.SectionData = getCurrentSectionData();
3003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getAssembler().getIndirectSymbols().push_back(ISD);
3013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    return;
3023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Adding a symbol attribute always introduces the symbol, note that an
3053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // important side effect of calling getOrCreateSymbolData here is to register
3063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // the symbol with the assembler.
3073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
3083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The implementation of symbol attributes is designed to match 'as', but it
3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // leaves much to desired. It doesn't really make sense to arbitrarily add and
3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // remove flags, but 'as' allows this (in particular, see .desc).
3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // In the future it might be worth trying to make these operations more well
3143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // defined.
3153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  switch (Attribute) {
3163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_LazyReference:
3173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Reference:
3183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_NoDeadStrip:
3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_PrivateExtern:
3203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_WeakDefinition:
321f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman  case MCSA_WeakDefAutoPrivate:
3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Invalid:
3233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeIndFunction:
3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_IndirectSymbol:
3253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "Invalid symbol attribute for ELF!");
3263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Global:
329f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetBinding(SD, ELF::STB_GLOBAL);
3303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    SD.setExternal(true);
331f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    BindingExplicitlySet.insert(Symbol);
3323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
334230c27472458d5f1f52f96347b655d1b5c531f33Benjamin Kramer  case MCSA_WeakReference:
3353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Weak:
336f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetBinding(SD, ELF::STB_WEAK);
3373223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola    SD.setExternal(true);
338f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    BindingExplicitlySet.insert(Symbol);
3393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Local:
342f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetBinding(SD, ELF::STB_LOCAL);
343f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SD.setExternal(false);
344f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    BindingExplicitlySet.insert(Symbol);
3453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeFunction:
348f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_FUNC);
3493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeObject:
352f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_OBJECT);
3533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeTLS:
356f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_TLS);
3573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeCommon:
360f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_COMMON);
3613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeNoType:
364f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_NOTYPE);
3653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Protected:
368f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetVisibility(SD, ELF::STV_PROTECTED);
3693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Hidden:
372f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetVisibility(SD, ELF::STV_HIDDEN);
3733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Internal:
376f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetVisibility(SD, ELF::STV_INTERNAL);
3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3813565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
3823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                       unsigned ByteAlignment) {
3833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
3843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
385f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  if (!BindingExplicitlySet.count(Symbol)) {
386f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SetBinding(SD, ELF::STB_GLOBAL);
387f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SD.setExternal(true);
388f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  }
389f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
390f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  if (GetBinding(SD) == ELF_STB_Local) {
3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSection *Section = getAssembler().getContext().getELFSection(".bss",
3923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    MCSectionELF::SHT_NOBITS,
3933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    MCSectionELF::SHF_WRITE |
3943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    MCSectionELF::SHF_ALLOC,
3953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    SectionKind::getBSS());
3963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    Symbol->setSection(*Section);
3971963572f9de87cd1ac5f16e504e27c3c26267e6fRafael Espindola
3989e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    struct LocalCommon L = {&SD, Size, ByteAlignment};
3999e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    LocalCommons.push_back(L);
400f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  } else {
401f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SD.setCommon(Size, ByteAlignment);
4023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
4033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
404f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  SD.setSize(MCConstantExpr::Create(Size, getContext()));
4053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4073565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
4083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
4093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
4113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4133565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitValue(const MCExpr *Value, unsigned Size,
4143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                unsigned AddrSpace) {
4153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
4163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *DF = getOrCreateDataFragment();
4183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Avoid fixups when possible.
4203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  int64_t AbsValue;
4213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
4223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // FIXME: Endianness assumption.
4233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    for (unsigned i = 0; i != Size; ++i)
4243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
4253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  } else {
4263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DF->addFixup(MCFixup::Create(DF->getContents().size(), AddValueSymbols(Value),
4273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                 MCFixup::getKindForSize(Size)));
4283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DF->getContents().resize(DF->getContents().size() + Size, 0);
4293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
4303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4323565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
4333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                           int64_t Value, unsigned ValueSize,
4343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                           unsigned MaxBytesToEmit) {
4353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
4363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (MaxBytesToEmit == 0)
4383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MaxBytesToEmit = ByteAlignment;
4393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
4403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                      getCurrentSectionData());
4413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Update the maximum alignment on the current section if necessary.
4433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (ByteAlignment > getCurrentSectionData()->getAlignment())
4443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getCurrentSectionData()->setAlignment(ByteAlignment);
4453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4473565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
4483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                        unsigned MaxBytesToEmit) {
4493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
4503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (MaxBytesToEmit == 0)
4523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MaxBytesToEmit = ByteAlignment;
4533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
4543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                           getCurrentSectionData());
4553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->setEmitNops(true);
4563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Update the maximum alignment on the current section if necessary.
4583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (ByteAlignment > getCurrentSectionData()->getAlignment())
4593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getCurrentSectionData()->setAlignment(ByteAlignment);
4603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4623565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitValueToOffset(const MCExpr *Offset,
4633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                        unsigned char Value) {
4643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as MCMachOStreamer. Consider merging into
4653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  new MCOrgFragment(*Offset, Value, getCurrentSectionData());
4673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Add a symbol for the file name of this module. This is the second
4703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// entry in the module's symbol table (the first being the null symbol).
4713565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitFileDirective(StringRef Filename) {
4723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename);
4733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setSection(*CurSection);
4743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setAbsolute();
4753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
4773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default);
4793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
48193ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramervoid MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
48293ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
4833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
48493ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // Add the fixups and data.
48593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  //
48693ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // FIXME: Revisit this design decision when relaxation is done, we may be
48793ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // able to get away with not storing any extra data in the MCInst.
48893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  SmallVector<MCFixup, 4> Fixups;
48993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  SmallString<256> Code;
49093ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  raw_svector_ostream VecOS(Code);
49193ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
49293ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  VecOS.flush();
4933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
49493ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  IF->getCode() = Code;
49593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  IF->getFixups() = Fixups;
49693ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer}
49793ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer
49893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramervoid MCELFStreamer::EmitInstToData(const MCInst &Inst) {
49993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  MCDataFragment *DF = getOrCreateDataFragment();
5003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SmallVector<MCFixup, 4> Fixups;
5023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SmallString<256> Code;
5033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  raw_svector_ostream VecOS(Code);
5043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
5053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  VecOS.flush();
5063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
50793ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // Add the fixups and data.
5083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
50993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
51093ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    DF->addFixup(Fixups[i]);
5113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
51293ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  DF->getContents().append(Code.begin(), Code.end());
51393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer}
5143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5153565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::Finish() {
516c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola  // FIXME: duplicated code with the MachO streamer.
517c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola  // Dump out the dwarf file & directory tables and line tables.
518c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola  if (getContext().hasDwarfFiles()) {
519c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola    const MCSection *DwarfLineSection =
520c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola      getContext().getELFSection(".debug_line", 0, 0,
521c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola                                 SectionKind::getDataRelLocal());
522c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola    MCDwarfFileTable::Emit(this, DwarfLineSection);
523c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola  }
524c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola
5259e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),
5269e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola                                                e = LocalCommons.end();
5279e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola       i != e; ++i) {
5289e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    MCSymbolData *SD = i->SD;
5299e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    uint64_t Size = i->Size;
5309e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    unsigned ByteAlignment = i->ByteAlignment;
5319e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    const MCSymbol &Symbol = SD->getSymbol();
5329e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    const MCSection &Section = Symbol.getSection();
5339e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
5349e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section);
5359e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData);
5369e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
5379e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
5389e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    SD->setFragment(F);
5399e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
5409e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    // Update the maximum alignment of the section if necessary.
5419e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    if (ByteAlignment > SectData.getAlignment())
5429e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola      SectData.setAlignment(ByteAlignment);
5439e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  }
5449e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
54573ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola  this->MCObjectStreamer::Finish();
5463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
5473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5483565a06ebf44a193a8b333cbeff2ee154298d450Matt FlemingMCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
5493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                      raw_ostream &OS, MCCodeEmitter *CE,
5503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                      bool RelaxAll) {
5513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE);
5523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (RelaxAll)
5533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    S->getAssembler().setRelaxAll(true);
5543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  return S;
5553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
556