MCELFStreamer.cpp revision 7e528a1724d8f38dd817396938aaf768887c8b30
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
38e1a2587ee273943390608df096378116ce52ffbaRafael Espindolastatic void SetBinding(MCSymbolData &SD, unsigned Binding) {
39e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
40e1a2587ee273943390608df096378116ce52ffbaRafael Espindola         Binding == ELF::STB_WEAK);
41e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift);
42e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift));
43e1a2587ee273943390608df096378116ce52ffbaRafael Espindola}
44e1a2587ee273943390608df096378116ce52ffbaRafael Espindola
45e1a2587ee273943390608df096378116ce52ffbaRafael Espindolastatic unsigned GetBinding(const MCSymbolData &SD) {
46e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift;
47e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
48e1a2587ee273943390608df096378116ce52ffbaRafael Espindola         Binding == ELF::STB_WEAK);
49e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  return Binding;
50e1a2587ee273943390608df096378116ce52ffbaRafael Espindola}
51e1a2587ee273943390608df096378116ce52ffbaRafael Espindola
52e1a2587ee273943390608df096378116ce52ffbaRafael Espindolastatic void SetType(MCSymbolData &SD, unsigned Type) {
53e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT ||
54e1a2587ee273943390608df096378116ce52ffbaRafael Espindola         Type == ELF::STT_FUNC || Type == ELF::STT_SECTION ||
55e1a2587ee273943390608df096378116ce52ffbaRafael Espindola         Type == ELF::STT_FILE || Type == ELF::STT_COMMON ||
56e1a2587ee273943390608df096378116ce52ffbaRafael Espindola         Type == ELF::STT_TLS);
57e1a2587ee273943390608df096378116ce52ffbaRafael Espindola
58e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift);
59e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  SD.setFlags(OtherFlags | (Type << ELF_STT_Shift));
60e1a2587ee273943390608df096378116ce52ffbaRafael Espindola}
61e1a2587ee273943390608df096378116ce52ffbaRafael Espindola
62e1a2587ee273943390608df096378116ce52ffbaRafael Espindolastatic void SetVisibility(MCSymbolData &SD, unsigned Visibility) {
63e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
64e1a2587ee273943390608df096378116ce52ffbaRafael Espindola         Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
65e1a2587ee273943390608df096378116ce52ffbaRafael Espindola
66e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STV_Shift);
67e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
68e1a2587ee273943390608df096378116ce52ffbaRafael Espindola}
69e1a2587ee273943390608df096378116ce52ffbaRafael Espindola
703565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingclass MCELFStreamer : public MCObjectStreamer {
713565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingpublic:
723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                  raw_ostream &OS, MCCodeEmitter *Emitter)
7459ff3c913449402ad5447bbe3ae6338402fb84b0Rafael Espindola    : MCObjectStreamer(Context, TAB, OS, Emitter, false) {}
753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  ~MCELFStreamer() {}
773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  /// @name MCStreamer Interface
793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  /// @{
803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
81d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  virtual void InitSections();
823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitLabel(MCSymbol *Symbol);
833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
84ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach  virtual void EmitThumbFunc(MCSymbol *Func);
853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
86484291c27319668ad99cb87def000254357736fbRafael Espindola  virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                unsigned ByteAlignment);
933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitCOFFSymbolType(int Type) {
1023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
1033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EndCOFFSymbolDef() {
1063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
1073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
1103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming     MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
1113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming     SD.setSize(Value);
1123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
1153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
1163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
1183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                            unsigned Size = 0, unsigned ByteAlignment = 0) {
1193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
1203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
1223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                              uint64_t Size, unsigned ByteAlignment = 0) {
1233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
1243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
1263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
1273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitGPRel32Value(const MCExpr *Value) {
1283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "ELF doesn't support this directive");
1293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
1313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                    unsigned ValueSize = 1,
1323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                    unsigned MaxBytesToEmit = 0);
1333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitCodeAlignment(unsigned ByteAlignment,
1343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                 unsigned MaxBytesToEmit = 0);
1353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitValueToOffset(const MCExpr *Offset,
1363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                 unsigned char Value = 0);
1373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitFileDirective(StringRef Filename);
1393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
1403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DEBUG(dbgs() << "FIXME: MCELFStreamer:EmitDwarfFileDirective not implemented\n");
1413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  virtual void Finish();
1443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
145f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindolaprivate:
146f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  virtual void EmitInstToFragment(const MCInst &Inst);
147f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  virtual void EmitInstToData(const MCInst &Inst);
148f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
1499e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  struct LocalCommon {
1509e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    MCSymbolData *SD;
1519e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    uint64_t Size;
1529e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    unsigned ByteAlignment;
1539e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  };
1549e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  std::vector<LocalCommon> LocalCommons;
1559e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
156f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
1573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  /// @}
158d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSection(StringRef Section, unsigned Type, unsigned Flags,
159d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola                  SectionKind Kind) {
160d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind));
161d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
162d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola
163d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSectionData() {
164d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SetSection(".data", MCSectionELF::SHT_PROGBITS,
165d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
166d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               SectionKind::getDataRel());
167d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    EmitCodeAlignment(4, 0);
168d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
169d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSectionText() {
170d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SetSection(".text", MCSectionELF::SHT_PROGBITS,
171d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_EXECINSTR |
172d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_ALLOC, SectionKind::getText());
173d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    EmitCodeAlignment(4, 0);
174d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
175d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  void SetSectionBss() {
176d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    SetSection(".bss", MCSectionELF::SHT_NOBITS,
177d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_WRITE |
178d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola               MCSectionELF::SHF_ALLOC, SectionKind::getBSS());
179d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    EmitCodeAlignment(4, 0);
180d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  }
1813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming};
1823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} // end anonymous namespace.
1843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
185d80781b98b771d370730ab7c630018f23e202b57Rafael Espindolavoid MCELFStreamer::InitSections() {
186d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  // This emulates the same behavior of GNU as. This makes it easier
187d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  // to compare the output as the major sections are in the same order.
188d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionText();
189d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionData();
190d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionBss();
191d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola  SetSectionText();
192d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola}
193d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola
1943565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
1953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
1963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
19773ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola  Symbol->setSection(*CurSection);
19873ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
19973ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
20073ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
201e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  const MCSectionELF &Section =
202e1a2587ee273943390608df096378116ce52ffbaRafael Espindola    static_cast<const MCSectionELF&>(Symbol->getSection());
203e1a2587ee273943390608df096378116ce52ffbaRafael Espindola  if (Section.getFlags() & MCSectionELF::SHF_TLS)
204e1a2587ee273943390608df096378116ce52ffbaRafael Espindola    SetType(SD, ELF::STT_TLS);
205e1a2587ee273943390608df096378116ce52ffbaRafael Espindola
2063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: This is wasteful, we don't necessarily need to create a data
2073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // fragment. Instead, we should mark the symbol as pointing into the data
2083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // fragment if it exists, otherwise we should just queue the label and set its
2093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // fragment pointer when we emit the next fragment.
2103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *F = getOrCreateDataFragment();
21173ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
2123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
2133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SD.setFragment(F);
2143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SD.setOffset(F->getContents().size());
2153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
2163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2173565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
2183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  switch (Flag) {
219ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach  case MCAF_SyntaxUnified: return; // no-op here.
220ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach  case MCAF_Code16: return; // no-op here.
221ba21957cbd7b25e3d25a3e9befe6151000242853Jim Grosbach  case MCAF_Code32: return; // no-op here.
2223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCAF_SubsectionsViaSymbols:
2233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getAssembler().setSubsectionsViaSymbols(true);
2243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    return;
2253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
2263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(0 && "invalid assembler flag!");
2283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
2293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
230ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbachvoid MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
231ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach  // FIXME: Anything needed here to flag the function as thumb?
232ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach}
233ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach
2343565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
2353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
2363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
2373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Lift context changes into super class.
2383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getAssembler().getOrCreateSymbolData(*Symbol);
2393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setVariableValue(AddValueSymbols(Value));
2403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
2413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
242484291c27319668ad99cb87def000254357736fbRafael Espindola// This is a hack. To be able to implement weakrefs the writer has to be able
243484291c27319668ad99cb87def000254357736fbRafael Espindola// to distinguish
244484291c27319668ad99cb87def000254357736fbRafael Espindola//    .weakref foo, bar
245484291c27319668ad99cb87def000254357736fbRafael Espindola//    .long foo
246484291c27319668ad99cb87def000254357736fbRafael Espindola// from
247484291c27319668ad99cb87def000254357736fbRafael Espindola//   .weakref foo, bar
248484291c27319668ad99cb87def000254357736fbRafael Espindola//   .long bar
249484291c27319668ad99cb87def000254357736fbRafael Espindola// since the first case should produce a weak undefined reference and the second
250484291c27319668ad99cb87def000254357736fbRafael Espindola// one a strong one.
251484291c27319668ad99cb87def000254357736fbRafael Espindola// If we created foo as a regular alias pointing to bar (foo = bar), then
252484291c27319668ad99cb87def000254357736fbRafael Espindola// MCExpr::EvaluateAsRelocatable would recurse on foo and the writer would
253484291c27319668ad99cb87def000254357736fbRafael Espindola// never see it used in a relocation.
254484291c27319668ad99cb87def000254357736fbRafael Espindola// What we do is create a MCTargetExpr that when evaluated produces a symbol
255484291c27319668ad99cb87def000254357736fbRafael Espindola// ref to a temporary symbol. This temporary symbol in turn is a variable
256484291c27319668ad99cb87def000254357736fbRafael Espindola// that equals the original symbol (tmp = bar). With this hack the writer
257484291c27319668ad99cb87def000254357736fbRafael Espindola// gets a relocation with tmp and can correctly implement weak references.
258484291c27319668ad99cb87def000254357736fbRafael Espindola
259f79856986d47553240fb3f5fe796faa2a57be1bbBenjamin Kramernamespace {
260484291c27319668ad99cb87def000254357736fbRafael Espindolaclass WeakRefExpr : public MCTargetExpr {
261484291c27319668ad99cb87def000254357736fbRafael Espindolaprivate:
262484291c27319668ad99cb87def000254357736fbRafael Espindola  const MCSymbolRefExpr *Alias;
263484291c27319668ad99cb87def000254357736fbRafael Espindola
264484291c27319668ad99cb87def000254357736fbRafael Espindola  explicit WeakRefExpr(const MCSymbolRefExpr *Alias_)
265484291c27319668ad99cb87def000254357736fbRafael Espindola    : MCTargetExpr(), Alias(Alias_) {}
266484291c27319668ad99cb87def000254357736fbRafael Espindola
267484291c27319668ad99cb87def000254357736fbRafael Espindolapublic:
268484291c27319668ad99cb87def000254357736fbRafael Espindola  virtual void PrintImpl(raw_ostream &OS) const {
269484291c27319668ad99cb87def000254357736fbRafael Espindola    llvm_unreachable("Unimplemented");
270484291c27319668ad99cb87def000254357736fbRafael Espindola  }
271484291c27319668ad99cb87def000254357736fbRafael Espindola
272484291c27319668ad99cb87def000254357736fbRafael Espindola  virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
273484291c27319668ad99cb87def000254357736fbRafael Espindola                                         const MCAsmLayout *Layout) const {
274484291c27319668ad99cb87def000254357736fbRafael Espindola    Res = MCValue::get(Alias, 0, 0);
275484291c27319668ad99cb87def000254357736fbRafael Espindola    return true;
276484291c27319668ad99cb87def000254357736fbRafael Espindola  }
277484291c27319668ad99cb87def000254357736fbRafael Espindola
278484291c27319668ad99cb87def000254357736fbRafael Espindola  static const WeakRefExpr *Create(const MCSymbol *Alias, MCContext &Ctx) {
279484291c27319668ad99cb87def000254357736fbRafael Espindola    const MCSymbolRefExpr *A = MCSymbolRefExpr::Create(Alias, Ctx);
280484291c27319668ad99cb87def000254357736fbRafael Espindola    return new (Ctx) WeakRefExpr(A);
281484291c27319668ad99cb87def000254357736fbRafael Espindola  }
282484291c27319668ad99cb87def000254357736fbRafael Espindola};
283f79856986d47553240fb3f5fe796faa2a57be1bbBenjamin Kramer} // end anonymous namespace
284484291c27319668ad99cb87def000254357736fbRafael Espindola
285484291c27319668ad99cb87def000254357736fbRafael Espindolavoid MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
286484291c27319668ad99cb87def000254357736fbRafael Espindola  getAssembler().getOrCreateSymbolData(*Symbol);
287484291c27319668ad99cb87def000254357736fbRafael Espindola  MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias);
288484291c27319668ad99cb87def000254357736fbRafael Espindola  AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref);
289484291c27319668ad99cb87def000254357736fbRafael Espindola
290484291c27319668ad99cb87def000254357736fbRafael Espindola  // Create the alias that actually points to Symbol
291484291c27319668ad99cb87def000254357736fbRafael Espindola  const MCSymbolRefExpr *SymRef = MCSymbolRefExpr::Create(Symbol, getContext());
292484291c27319668ad99cb87def000254357736fbRafael Espindola  MCSymbol *RealAlias = getContext().CreateTempSymbol();
293484291c27319668ad99cb87def000254357736fbRafael Espindola  RealAlias->setVariableValue(SymRef);
294484291c27319668ad99cb87def000254357736fbRafael Espindola
295484291c27319668ad99cb87def000254357736fbRafael Espindola  MCSymbolData &RealAliasSD = getAssembler().getOrCreateSymbolData(*RealAlias);
296484291c27319668ad99cb87def000254357736fbRafael Espindola  RealAliasSD.setFlags(RealAliasSD.getFlags() | ELF_Other_Weakref);
297484291c27319668ad99cb87def000254357736fbRafael Espindola
298484291c27319668ad99cb87def000254357736fbRafael Espindola  const MCExpr *Value = WeakRefExpr::Create(RealAlias, getContext());
299484291c27319668ad99cb87def000254357736fbRafael Espindola  Alias->setVariableValue(Value);
300484291c27319668ad99cb87def000254357736fbRafael Espindola}
301484291c27319668ad99cb87def000254357736fbRafael Espindola
3023565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
3033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                          MCSymbolAttr Attribute) {
3043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Indirect symbols are handled differently, to match how 'as' handles
3053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // them. This makes writing matching .o files easier.
3063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (Attribute == MCSA_IndirectSymbol) {
3073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Note that we intentionally cannot use the symbol data here; this is
3083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // important for matching the string table that 'as' generates.
3093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    IndirectSymbolData ISD;
3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ISD.Symbol = Symbol;
3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ISD.SectionData = getCurrentSectionData();
3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getAssembler().getIndirectSymbols().push_back(ISD);
3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    return;
3143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Adding a symbol attribute always introduces the symbol, note that an
3173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // important side effect of calling getOrCreateSymbolData here is to register
3183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // the symbol with the assembler.
3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
3203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The implementation of symbol attributes is designed to match 'as', but it
3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // leaves much to desired. It doesn't really make sense to arbitrarily add and
3233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // remove flags, but 'as' allows this (in particular, see .desc).
3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
3253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // In the future it might be worth trying to make these operations more well
3263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // defined.
3273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  switch (Attribute) {
3283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_LazyReference:
3293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Reference:
3303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_NoDeadStrip:
3313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_PrivateExtern:
3323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_WeakDefinition:
333f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman  case MCSA_WeakDefAutoPrivate:
3343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Invalid:
3353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeIndFunction:
3363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_IndirectSymbol:
3373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    assert(0 && "Invalid symbol attribute for ELF!");
3383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3407e528a1724d8f38dd817396938aaf768887c8b30Rafael Espindola  case MCSA_ELF_TypeGnuUniqueObject:
3417e528a1724d8f38dd817396938aaf768887c8b30Rafael Espindola    // Ignore for now.
3427e528a1724d8f38dd817396938aaf768887c8b30Rafael Espindola    break;
3437e528a1724d8f38dd817396938aaf768887c8b30Rafael Espindola
3443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Global:
345f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetBinding(SD, ELF::STB_GLOBAL);
3463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    SD.setExternal(true);
347f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    BindingExplicitlySet.insert(Symbol);
3483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
350230c27472458d5f1f52f96347b655d1b5c531f33Benjamin Kramer  case MCSA_WeakReference:
3513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Weak:
352f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetBinding(SD, ELF::STB_WEAK);
3533223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola    SD.setExternal(true);
354f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    BindingExplicitlySet.insert(Symbol);
3553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Local:
358f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetBinding(SD, ELF::STB_LOCAL);
359f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SD.setExternal(false);
360f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    BindingExplicitlySet.insert(Symbol);
3613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeFunction:
364f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_FUNC);
3653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeObject:
368f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_OBJECT);
3693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeTLS:
372f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_TLS);
3733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeCommon:
376f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_COMMON);
3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_ELF_TypeNoType:
380f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetType(SD, ELF::STT_NOTYPE);
3813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Protected:
384f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetVisibility(SD, ELF::STV_PROTECTED);
3853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Hidden:
388f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetVisibility(SD, ELF::STV_HIDDEN);
3893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  case MCSA_Internal:
392f713384be52aae0ec1d0f19618f71cc345acb1f9Rafael Espindola    SetVisibility(SD, ELF::STV_INTERNAL);
3933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    break;
3943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3973565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
3983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                       unsigned ByteAlignment) {
3993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
4003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
401f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  if (!BindingExplicitlySet.count(Symbol)) {
402f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SetBinding(SD, ELF::STB_GLOBAL);
403f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SD.setExternal(true);
404f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  }
405f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
406f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  if (GetBinding(SD) == ELF_STB_Local) {
4073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSection *Section = getAssembler().getContext().getELFSection(".bss",
4083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    MCSectionELF::SHT_NOBITS,
4093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    MCSectionELF::SHF_WRITE |
4103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    MCSectionELF::SHF_ALLOC,
4113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                                                    SectionKind::getBSS());
4123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    Symbol->setSection(*Section);
4131963572f9de87cd1ac5f16e504e27c3c26267e6fRafael Espindola
4149e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    struct LocalCommon L = {&SD, Size, ByteAlignment};
4159e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    LocalCommons.push_back(L);
416f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  } else {
417f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    SD.setCommon(Size, ByteAlignment);
4183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
4193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
420f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  SD.setSize(MCConstantExpr::Create(Size, getContext()));
4213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4233565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
4243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
4253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
4273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4293565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitValue(const MCExpr *Value, unsigned Size,
4303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                unsigned AddrSpace) {
4313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
4323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *DF = getOrCreateDataFragment();
4343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Avoid fixups when possible.
4363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  int64_t AbsValue;
4373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
4383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // FIXME: Endianness assumption.
4393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    for (unsigned i = 0; i != Size; ++i)
4403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
4413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  } else {
4423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DF->addFixup(MCFixup::Create(DF->getContents().size(), AddValueSymbols(Value),
4433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                 MCFixup::getKindForSize(Size)));
4443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DF->getContents().resize(DF->getContents().size() + Size, 0);
4453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
4463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4483565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
4493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                           int64_t Value, unsigned ValueSize,
4503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                           unsigned MaxBytesToEmit) {
4513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
4523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (MaxBytesToEmit == 0)
4543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MaxBytesToEmit = ByteAlignment;
4553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
4563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                      getCurrentSectionData());
4573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Update the maximum alignment on the current section if necessary.
4593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (ByteAlignment > getCurrentSectionData()->getAlignment())
4603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getCurrentSectionData()->setAlignment(ByteAlignment);
4613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4633565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
4643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                        unsigned MaxBytesToEmit) {
4653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
4663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (MaxBytesToEmit == 0)
4683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MaxBytesToEmit = ByteAlignment;
4693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
4703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                           getCurrentSectionData());
4713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->setEmitNops(true);
4723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Update the maximum alignment on the current section if necessary.
4743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (ByteAlignment > getCurrentSectionData()->getAlignment())
4753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    getCurrentSectionData()->setAlignment(ByteAlignment);
4763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4783565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitValueToOffset(const MCExpr *Offset,
4793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                        unsigned char Value) {
4803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // TODO: This is exactly the same as MCMachOStreamer. Consider merging into
4813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // MCObjectStreamer.
4823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  new MCOrgFragment(*Offset, Value, getCurrentSectionData());
4833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Add a symbol for the file name of this module. This is the second
4863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// entry in the module's symbol table (the first being the null symbol).
4873565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::EmitFileDirective(StringRef Filename) {
4883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename);
4893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setSection(*CurSection);
4903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Symbol->setAbsolute();
4913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
4933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default);
4953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
49793ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramervoid MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
49893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
4993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
50093ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // Add the fixups and data.
50193ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  //
50293ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // FIXME: Revisit this design decision when relaxation is done, we may be
50393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // able to get away with not storing any extra data in the MCInst.
50493ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  SmallVector<MCFixup, 4> Fixups;
50593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  SmallString<256> Code;
50693ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  raw_svector_ostream VecOS(Code);
50793ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
50893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  VecOS.flush();
5093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
51093ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  IF->getCode() = Code;
51193ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  IF->getFixups() = Fixups;
51293ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer}
51393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer
51493ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramervoid MCELFStreamer::EmitInstToData(const MCInst &Inst) {
51593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  MCDataFragment *DF = getOrCreateDataFragment();
5163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SmallVector<MCFixup, 4> Fixups;
5183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SmallString<256> Code;
5193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  raw_svector_ostream VecOS(Code);
5203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
5213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  VecOS.flush();
5223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
52393ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  // Add the fixups and data.
5243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
52593ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
52693ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer    DF->addFixup(Fixups[i]);
5273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
52893ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer  DF->getContents().append(Code.begin(), Code.end());
52993ded7371f5f821c342bdf83b40f4ef607467a3fBenjamin Kramer}
5303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5313565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingvoid MCELFStreamer::Finish() {
532c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola  // FIXME: duplicated code with the MachO streamer.
533c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola  // Dump out the dwarf file & directory tables and line tables.
534c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola  if (getContext().hasDwarfFiles()) {
535c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola    const MCSection *DwarfLineSection =
536c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola      getContext().getELFSection(".debug_line", 0, 0,
537c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola                                 SectionKind::getDataRelLocal());
538c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola    MCDwarfFileTable::Emit(this, DwarfLineSection);
539c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola  }
540c70a1d985aca40b33b3e4b046b179f0d5e5e238bRafael Espindola
5419e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),
5429e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola                                                e = LocalCommons.end();
5439e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola       i != e; ++i) {
5449e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    MCSymbolData *SD = i->SD;
5459e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    uint64_t Size = i->Size;
5469e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    unsigned ByteAlignment = i->ByteAlignment;
5479e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    const MCSymbol &Symbol = SD->getSymbol();
5489e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    const MCSection &Section = Symbol.getSection();
5499e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
5509e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section);
5519e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData);
5529e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
5539e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
5549e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    SD->setFragment(F);
5559e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
5569e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    // Update the maximum alignment of the section if necessary.
5579e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola    if (ByteAlignment > SectData.getAlignment())
5589e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola      SectData.setAlignment(ByteAlignment);
5599e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola  }
5609e3922e94975b7b3d98da42f0d20a524f3deed53Rafael Espindola
56173ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola  this->MCObjectStreamer::Finish();
5623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
5633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5643565a06ebf44a193a8b333cbeff2ee154298d450Matt FlemingMCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
5653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                      raw_ostream &OS, MCCodeEmitter *CE,
5663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                      bool RelaxAll) {
5673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE);
5683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (RelaxAll)
5693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    S->getAssembler().setRelaxAll(true);
5703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  return S;
5713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
572