MCELFStreamer.cpp revision 212793
1212793Sdim//===- lib/MC/MCELFStreamer.cpp - ELF Object Output ------------===// 2212793Sdim// 3212793Sdim// The LLVM Compiler Infrastructure 4212793Sdim// 5212793Sdim// This file is distributed under the University of Illinois Open Source 6212793Sdim// License. See LICENSE.TXT for details. 7212793Sdim// 8212793Sdim//===----------------------------------------------------------------------===// 9212793Sdim// 10212793Sdim// This file assembles .s files and emits ELF .o object files. 11212793Sdim// 12212793Sdim//===----------------------------------------------------------------------===// 13212793Sdim 14212793Sdim#include "llvm/MC/MCStreamer.h" 15212793Sdim 16212793Sdim#include "llvm/MC/MCAssembler.h" 17212793Sdim#include "llvm/MC/MCContext.h" 18212793Sdim#include "llvm/MC/MCCodeEmitter.h" 19212793Sdim#include "llvm/MC/MCELFSymbolFlags.h" 20212793Sdim#include "llvm/MC/MCExpr.h" 21212793Sdim#include "llvm/MC/MCInst.h" 22212793Sdim#include "llvm/MC/MCObjectStreamer.h" 23212793Sdim#include "llvm/MC/MCSection.h" 24212793Sdim#include "llvm/MC/MCSectionELF.h" 25212793Sdim#include "llvm/MC/MCSymbol.h" 26212793Sdim#include "llvm/Support/Debug.h" 27212793Sdim#include "llvm/Support/ELF.h" 28212793Sdim#include "llvm/Support/ErrorHandling.h" 29212793Sdim#include "llvm/Support/raw_ostream.h" 30212793Sdim#include "llvm/Target/TargetAsmBackend.h" 31212793Sdim 32212793Sdimusing namespace llvm; 33212793Sdim 34212793Sdimnamespace { 35212793Sdim 36212793Sdimclass MCELFStreamer : public MCObjectStreamer { 37212793Sdim void EmitInstToFragment(const MCInst &Inst); 38212793Sdim void EmitInstToData(const MCInst &Inst); 39212793Sdimpublic: 40212793Sdim MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB, 41212793Sdim raw_ostream &OS, MCCodeEmitter *Emitter) 42212793Sdim : MCObjectStreamer(Context, TAB, OS, Emitter) {} 43212793Sdim 44212793Sdim ~MCELFStreamer() {} 45212793Sdim 46212793Sdim /// @name MCStreamer Interface 47212793Sdim /// @{ 48212793Sdim 49212793Sdim virtual void EmitLabel(MCSymbol *Symbol); 50212793Sdim virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 51212793Sdim virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); 52212793Sdim virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 53212793Sdim virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 54212793Sdim assert(0 && "ELF doesn't support this directive"); 55212793Sdim } 56212793Sdim virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 57212793Sdim unsigned ByteAlignment); 58212793Sdim virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) { 59212793Sdim assert(0 && "ELF doesn't support this directive"); 60212793Sdim } 61212793Sdim 62212793Sdim virtual void EmitCOFFSymbolStorageClass(int StorageClass) { 63212793Sdim assert(0 && "ELF doesn't support this directive"); 64212793Sdim } 65212793Sdim 66212793Sdim virtual void EmitCOFFSymbolType(int Type) { 67212793Sdim assert(0 && "ELF doesn't support this directive"); 68212793Sdim } 69212793Sdim 70212793Sdim virtual void EndCOFFSymbolDef() { 71212793Sdim assert(0 && "ELF doesn't support this directive"); 72212793Sdim } 73212793Sdim 74212793Sdim virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 75212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 76212793Sdim SD.setSize(Value); 77212793Sdim } 78212793Sdim 79212793Sdim virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { 80212793Sdim assert(0 && "ELF doesn't support this directive"); 81212793Sdim } 82212793Sdim virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 83212793Sdim unsigned Size = 0, unsigned ByteAlignment = 0) { 84212793Sdim assert(0 && "ELF doesn't support this directive"); 85212793Sdim } 86212793Sdim virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 87212793Sdim uint64_t Size, unsigned ByteAlignment = 0) { 88212793Sdim assert(0 && "ELF doesn't support this directive"); 89212793Sdim } 90212793Sdim virtual void EmitBytes(StringRef Data, unsigned AddrSpace); 91212793Sdim virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); 92212793Sdim virtual void EmitGPRel32Value(const MCExpr *Value) { 93212793Sdim assert(0 && "ELF doesn't support this directive"); 94212793Sdim } 95212793Sdim virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 96212793Sdim unsigned ValueSize = 1, 97212793Sdim unsigned MaxBytesToEmit = 0); 98212793Sdim virtual void EmitCodeAlignment(unsigned ByteAlignment, 99212793Sdim unsigned MaxBytesToEmit = 0); 100212793Sdim virtual void EmitValueToOffset(const MCExpr *Offset, 101212793Sdim unsigned char Value = 0); 102212793Sdim 103212793Sdim virtual void EmitFileDirective(StringRef Filename); 104212793Sdim virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) { 105212793Sdim DEBUG(dbgs() << "FIXME: MCELFStreamer:EmitDwarfFileDirective not implemented\n"); 106212793Sdim } 107212793Sdim 108212793Sdim virtual void EmitInstruction(const MCInst &Inst); 109212793Sdim virtual void Finish(); 110212793Sdim 111212793Sdim /// @} 112212793Sdim}; 113212793Sdim 114212793Sdim} // end anonymous namespace. 115212793Sdim 116212793Sdimvoid MCELFStreamer::EmitLabel(MCSymbol *Symbol) { 117212793Sdim assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 118212793Sdim 119212793Sdim // FIXME: This is wasteful, we don't necessarily need to create a data 120212793Sdim // fragment. Instead, we should mark the symbol as pointing into the data 121212793Sdim // fragment if it exists, otherwise we should just queue the label and set its 122212793Sdim // fragment pointer when we emit the next fragment. 123212793Sdim MCDataFragment *F = getOrCreateDataFragment(); 124212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 125212793Sdim assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 126212793Sdim SD.setFragment(F); 127212793Sdim SD.setOffset(F->getContents().size()); 128212793Sdim 129212793Sdim Symbol->setSection(*CurSection); 130212793Sdim} 131212793Sdim 132212793Sdimvoid MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 133212793Sdim switch (Flag) { 134212793Sdim case MCAF_SubsectionsViaSymbols: 135212793Sdim getAssembler().setSubsectionsViaSymbols(true); 136212793Sdim return; 137212793Sdim } 138212793Sdim 139212793Sdim assert(0 && "invalid assembler flag!"); 140212793Sdim} 141212793Sdim 142212793Sdimvoid MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 143212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 144212793Sdim // MCObjectStreamer. 145212793Sdim // FIXME: Lift context changes into super class. 146212793Sdim getAssembler().getOrCreateSymbolData(*Symbol); 147212793Sdim Symbol->setVariableValue(AddValueSymbols(Value)); 148212793Sdim} 149212793Sdim 150212793Sdimvoid MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 151212793Sdim MCSymbolAttr Attribute) { 152212793Sdim // Indirect symbols are handled differently, to match how 'as' handles 153212793Sdim // them. This makes writing matching .o files easier. 154212793Sdim if (Attribute == MCSA_IndirectSymbol) { 155212793Sdim // Note that we intentionally cannot use the symbol data here; this is 156212793Sdim // important for matching the string table that 'as' generates. 157212793Sdim IndirectSymbolData ISD; 158212793Sdim ISD.Symbol = Symbol; 159212793Sdim ISD.SectionData = getCurrentSectionData(); 160212793Sdim getAssembler().getIndirectSymbols().push_back(ISD); 161212793Sdim return; 162212793Sdim } 163212793Sdim 164212793Sdim // Adding a symbol attribute always introduces the symbol, note that an 165212793Sdim // important side effect of calling getOrCreateSymbolData here is to register 166212793Sdim // the symbol with the assembler. 167212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 168212793Sdim 169212793Sdim // The implementation of symbol attributes is designed to match 'as', but it 170212793Sdim // leaves much to desired. It doesn't really make sense to arbitrarily add and 171212793Sdim // remove flags, but 'as' allows this (in particular, see .desc). 172212793Sdim // 173212793Sdim // In the future it might be worth trying to make these operations more well 174212793Sdim // defined. 175212793Sdim switch (Attribute) { 176212793Sdim case MCSA_LazyReference: 177212793Sdim case MCSA_Reference: 178212793Sdim case MCSA_NoDeadStrip: 179212793Sdim case MCSA_PrivateExtern: 180212793Sdim case MCSA_WeakDefinition: 181212793Sdim case MCSA_WeakDefAutoPrivate: 182212793Sdim case MCSA_Invalid: 183212793Sdim case MCSA_ELF_TypeIndFunction: 184212793Sdim case MCSA_IndirectSymbol: 185212793Sdim assert(0 && "Invalid symbol attribute for ELF!"); 186212793Sdim break; 187212793Sdim 188212793Sdim case MCSA_Global: 189212793Sdim SD.setFlags(SD.getFlags() | ELF_STB_Global); 190212793Sdim SD.setExternal(true); 191212793Sdim break; 192212793Sdim 193212793Sdim case MCSA_WeakReference: 194212793Sdim case MCSA_Weak: 195212793Sdim SD.setFlags(SD.getFlags() | ELF_STB_Weak); 196212793Sdim break; 197212793Sdim 198212793Sdim case MCSA_Local: 199212793Sdim SD.setFlags(SD.getFlags() | ELF_STB_Local); 200212793Sdim break; 201212793Sdim 202212793Sdim case MCSA_ELF_TypeFunction: 203212793Sdim SD.setFlags(SD.getFlags() | ELF_STT_Func); 204212793Sdim break; 205212793Sdim 206212793Sdim case MCSA_ELF_TypeObject: 207212793Sdim SD.setFlags(SD.getFlags() | ELF_STT_Object); 208212793Sdim break; 209212793Sdim 210212793Sdim case MCSA_ELF_TypeTLS: 211212793Sdim SD.setFlags(SD.getFlags() | ELF_STT_Tls); 212212793Sdim break; 213212793Sdim 214212793Sdim case MCSA_ELF_TypeCommon: 215212793Sdim SD.setFlags(SD.getFlags() | ELF_STT_Common); 216212793Sdim break; 217212793Sdim 218212793Sdim case MCSA_ELF_TypeNoType: 219212793Sdim SD.setFlags(SD.getFlags() | ELF_STT_Notype); 220212793Sdim break; 221212793Sdim 222212793Sdim case MCSA_Protected: 223212793Sdim SD.setFlags(SD.getFlags() | ELF_STV_Protected); 224212793Sdim break; 225212793Sdim 226212793Sdim case MCSA_Hidden: 227212793Sdim SD.setFlags(SD.getFlags() | ELF_STV_Hidden); 228212793Sdim break; 229212793Sdim 230212793Sdim case MCSA_Internal: 231212793Sdim SD.setFlags(SD.getFlags() | ELF_STV_Internal); 232212793Sdim break; 233212793Sdim } 234212793Sdim} 235212793Sdim 236212793Sdimvoid MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 237212793Sdim unsigned ByteAlignment) { 238212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 239212793Sdim 240212793Sdim if ((SD.getFlags() & (0xf << ELF_STB_Shift)) == ELF_STB_Local) { 241212793Sdim const MCSection *Section = getAssembler().getContext().getELFSection(".bss", 242212793Sdim MCSectionELF::SHT_NOBITS, 243212793Sdim MCSectionELF::SHF_WRITE | 244212793Sdim MCSectionELF::SHF_ALLOC, 245212793Sdim SectionKind::getBSS()); 246212793Sdim 247212793Sdim MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section); 248212793Sdim MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); 249212793Sdim SD.setFragment(F); 250212793Sdim Symbol->setSection(*Section); 251212793Sdim SD.setSize(MCConstantExpr::Create(Size, getContext())); 252212793Sdim } 253212793Sdim 254212793Sdim SD.setFlags(SD.getFlags() | ELF_STB_Global); 255212793Sdim SD.setExternal(true); 256212793Sdim 257212793Sdim SD.setCommon(Size, ByteAlignment); 258212793Sdim} 259212793Sdim 260212793Sdimvoid MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 261212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 262212793Sdim // MCObjectStreamer. 263212793Sdim getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 264212793Sdim} 265212793Sdim 266212793Sdimvoid MCELFStreamer::EmitValue(const MCExpr *Value, unsigned Size, 267212793Sdim unsigned AddrSpace) { 268212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 269212793Sdim // MCObjectStreamer. 270212793Sdim MCDataFragment *DF = getOrCreateDataFragment(); 271212793Sdim 272212793Sdim // Avoid fixups when possible. 273212793Sdim int64_t AbsValue; 274212793Sdim if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) { 275212793Sdim // FIXME: Endianness assumption. 276212793Sdim for (unsigned i = 0; i != Size; ++i) 277212793Sdim DF->getContents().push_back(uint8_t(AbsValue >> (i * 8))); 278212793Sdim } else { 279212793Sdim DF->addFixup(MCFixup::Create(DF->getContents().size(), AddValueSymbols(Value), 280212793Sdim MCFixup::getKindForSize(Size))); 281212793Sdim DF->getContents().resize(DF->getContents().size() + Size, 0); 282212793Sdim } 283212793Sdim} 284212793Sdim 285212793Sdimvoid MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, 286212793Sdim int64_t Value, unsigned ValueSize, 287212793Sdim unsigned MaxBytesToEmit) { 288212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 289212793Sdim // MCObjectStreamer. 290212793Sdim if (MaxBytesToEmit == 0) 291212793Sdim MaxBytesToEmit = ByteAlignment; 292212793Sdim new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 293212793Sdim getCurrentSectionData()); 294212793Sdim 295212793Sdim // Update the maximum alignment on the current section if necessary. 296212793Sdim if (ByteAlignment > getCurrentSectionData()->getAlignment()) 297212793Sdim getCurrentSectionData()->setAlignment(ByteAlignment); 298212793Sdim} 299212793Sdim 300212793Sdimvoid MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment, 301212793Sdim unsigned MaxBytesToEmit) { 302212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 303212793Sdim // MCObjectStreamer. 304212793Sdim if (MaxBytesToEmit == 0) 305212793Sdim MaxBytesToEmit = ByteAlignment; 306212793Sdim MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, 307212793Sdim getCurrentSectionData()); 308212793Sdim F->setEmitNops(true); 309212793Sdim 310212793Sdim // Update the maximum alignment on the current section if necessary. 311212793Sdim if (ByteAlignment > getCurrentSectionData()->getAlignment()) 312212793Sdim getCurrentSectionData()->setAlignment(ByteAlignment); 313212793Sdim} 314212793Sdim 315212793Sdimvoid MCELFStreamer::EmitValueToOffset(const MCExpr *Offset, 316212793Sdim unsigned char Value) { 317212793Sdim // TODO: This is exactly the same as MCMachOStreamer. Consider merging into 318212793Sdim // MCObjectStreamer. 319212793Sdim new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 320212793Sdim} 321212793Sdim 322212793Sdim// Add a symbol for the file name of this module. This is the second 323212793Sdim// entry in the module's symbol table (the first being the null symbol). 324212793Sdimvoid MCELFStreamer::EmitFileDirective(StringRef Filename) { 325212793Sdim MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); 326212793Sdim Symbol->setSection(*CurSection); 327212793Sdim Symbol->setAbsolute(); 328212793Sdim 329212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 330212793Sdim 331212793Sdim SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); 332212793Sdim} 333212793Sdim 334212793Sdimvoid MCELFStreamer::EmitInstToFragment(const MCInst &Inst) { 335212793Sdim MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData()); 336212793Sdim 337212793Sdim // Add the fixups and data. 338212793Sdim // 339212793Sdim // FIXME: Revisit this design decision when relaxation is done, we may be 340212793Sdim // able to get away with not storing any extra data in the MCInst. 341212793Sdim SmallVector<MCFixup, 4> Fixups; 342212793Sdim SmallString<256> Code; 343212793Sdim raw_svector_ostream VecOS(Code); 344212793Sdim getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 345212793Sdim VecOS.flush(); 346212793Sdim 347212793Sdim IF->getCode() = Code; 348212793Sdim IF->getFixups() = Fixups; 349212793Sdim} 350212793Sdim 351212793Sdimvoid MCELFStreamer::EmitInstToData(const MCInst &Inst) { 352212793Sdim MCDataFragment *DF = getOrCreateDataFragment(); 353212793Sdim 354212793Sdim SmallVector<MCFixup, 4> Fixups; 355212793Sdim SmallString<256> Code; 356212793Sdim raw_svector_ostream VecOS(Code); 357212793Sdim getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 358212793Sdim VecOS.flush(); 359212793Sdim 360212793Sdim // Add the fixups and data. 361212793Sdim for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 362212793Sdim Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 363212793Sdim DF->addFixup(Fixups[i]); 364212793Sdim } 365212793Sdim DF->getContents().append(Code.begin(), Code.end()); 366212793Sdim} 367212793Sdim 368212793Sdimvoid MCELFStreamer::EmitInstruction(const MCInst &Inst) { 369212793Sdim // Scan for values. 370212793Sdim for (unsigned i = 0; i != Inst.getNumOperands(); ++i) 371212793Sdim if (Inst.getOperand(i).isExpr()) 372212793Sdim AddValueSymbols(Inst.getOperand(i).getExpr()); 373212793Sdim 374212793Sdim getCurrentSectionData()->setHasInstructions(true); 375212793Sdim 376212793Sdim // If this instruction doesn't need relaxation, just emit it as data. 377212793Sdim if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) { 378212793Sdim EmitInstToData(Inst); 379212793Sdim return; 380212793Sdim } 381212793Sdim 382212793Sdim // Otherwise, if we are relaxing everything, relax the instruction as much as 383212793Sdim // possible and emit it as data. 384212793Sdim if (getAssembler().getRelaxAll()) { 385212793Sdim MCInst Relaxed; 386212793Sdim getAssembler().getBackend().RelaxInstruction(Inst, Relaxed); 387212793Sdim while (getAssembler().getBackend().MayNeedRelaxation(Relaxed)) 388212793Sdim getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed); 389212793Sdim EmitInstToData(Relaxed); 390212793Sdim return; 391212793Sdim } 392212793Sdim 393212793Sdim // Otherwise emit to a separate fragment. 394212793Sdim EmitInstToFragment(Inst); 395212793Sdim} 396212793Sdim 397212793Sdimvoid MCELFStreamer::Finish() { 398212793Sdim getAssembler().Finish(); 399212793Sdim} 400212793Sdim 401212793SdimMCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB, 402212793Sdim raw_ostream &OS, MCCodeEmitter *CE, 403212793Sdim bool RelaxAll) { 404212793Sdim MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE); 405212793Sdim if (RelaxAll) 406212793Sdim S->getAssembler().setRelaxAll(true); 407212793Sdim return S; 408212793Sdim} 409