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