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