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