MCELFStreamer.cpp revision 221345
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 14221345Sdim#include "MCELFStreamer.h" 15221345Sdim#include "MCELF.h" 16212793Sdim#include "llvm/MC/MCStreamer.h" 17212793Sdim#include "llvm/MC/MCCodeEmitter.h" 18212793Sdim#include "llvm/MC/MCELFSymbolFlags.h" 19212793Sdim#include "llvm/MC/MCExpr.h" 20212793Sdim#include "llvm/MC/MCInst.h" 21212793Sdim#include "llvm/MC/MCSection.h" 22212793Sdim#include "llvm/MC/MCSymbol.h" 23218893Sdim#include "llvm/MC/MCValue.h" 24212793Sdim#include "llvm/Support/Debug.h" 25212793Sdim#include "llvm/Support/ELF.h" 26212793Sdim#include "llvm/Support/ErrorHandling.h" 27212793Sdim#include "llvm/Support/raw_ostream.h" 28212793Sdim#include "llvm/Target/TargetAsmBackend.h" 29218893Sdim#include "llvm/Target/TargetAsmInfo.h" 30212793Sdim 31212793Sdimusing namespace llvm; 32212793Sdim 33218893Sdimvoid MCELFStreamer::InitSections() { 34218893Sdim // This emulates the same behavior of GNU as. This makes it easier 35218893Sdim // to compare the output as the major sections are in the same order. 36218893Sdim SetSectionText(); 37218893Sdim SetSectionData(); 38218893Sdim SetSectionBss(); 39218893Sdim SetSectionText(); 40218893Sdim} 41218893Sdim 42212793Sdimvoid MCELFStreamer::EmitLabel(MCSymbol *Symbol) { 43212793Sdim assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 44212793Sdim 45218893Sdim MCObjectStreamer::EmitLabel(Symbol); 46212793Sdim 47218893Sdim const MCSectionELF &Section = 48218893Sdim static_cast<const MCSectionELF&>(Symbol->getSection()); 49218893Sdim MCSymbolData &SD = getAssembler().getSymbolData(*Symbol); 50218893Sdim if (Section.getFlags() & ELF::SHF_TLS) 51221345Sdim MCELF::SetType(SD, ELF::STT_TLS); 52212793Sdim} 53212793Sdim 54212793Sdimvoid MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 55212793Sdim switch (Flag) { 56218893Sdim case MCAF_SyntaxUnified: return; // no-op here. 57218893Sdim case MCAF_Code16: return; // no-op here. 58218893Sdim case MCAF_Code32: return; // no-op here. 59212793Sdim case MCAF_SubsectionsViaSymbols: 60212793Sdim getAssembler().setSubsectionsViaSymbols(true); 61212793Sdim return; 62212793Sdim } 63212793Sdim 64212793Sdim assert(0 && "invalid assembler flag!"); 65212793Sdim} 66212793Sdim 67218893Sdimvoid MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { 68218893Sdim // FIXME: Anything needed here to flag the function as thumb? 69218893Sdim} 70218893Sdim 71212793Sdimvoid MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 72212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 73212793Sdim // MCObjectStreamer. 74212793Sdim // FIXME: Lift context changes into super class. 75212793Sdim getAssembler().getOrCreateSymbolData(*Symbol); 76212793Sdim Symbol->setVariableValue(AddValueSymbols(Value)); 77212793Sdim} 78212793Sdim 79218893Sdimvoid MCELFStreamer::ChangeSection(const MCSection *Section) { 80218893Sdim const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup(); 81218893Sdim if (Grp) 82218893Sdim getAssembler().getOrCreateSymbolData(*Grp); 83218893Sdim this->MCObjectStreamer::ChangeSection(Section); 84218893Sdim} 85218893Sdim 86218893Sdimvoid MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 87218893Sdim getAssembler().getOrCreateSymbolData(*Symbol); 88218893Sdim MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias); 89218893Sdim AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref); 90218893Sdim const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, getContext()); 91218893Sdim Alias->setVariableValue(Value); 92218893Sdim} 93218893Sdim 94212793Sdimvoid MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 95212793Sdim MCSymbolAttr Attribute) { 96212793Sdim // Indirect symbols are handled differently, to match how 'as' handles 97212793Sdim // them. This makes writing matching .o files easier. 98212793Sdim if (Attribute == MCSA_IndirectSymbol) { 99212793Sdim // Note that we intentionally cannot use the symbol data here; this is 100212793Sdim // important for matching the string table that 'as' generates. 101212793Sdim IndirectSymbolData ISD; 102212793Sdim ISD.Symbol = Symbol; 103212793Sdim ISD.SectionData = getCurrentSectionData(); 104212793Sdim getAssembler().getIndirectSymbols().push_back(ISD); 105212793Sdim return; 106212793Sdim } 107212793Sdim 108212793Sdim // Adding a symbol attribute always introduces the symbol, note that an 109212793Sdim // important side effect of calling getOrCreateSymbolData here is to register 110212793Sdim // the symbol with the assembler. 111212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 112212793Sdim 113212793Sdim // The implementation of symbol attributes is designed to match 'as', but it 114212793Sdim // leaves much to desired. It doesn't really make sense to arbitrarily add and 115212793Sdim // remove flags, but 'as' allows this (in particular, see .desc). 116212793Sdim // 117212793Sdim // In the future it might be worth trying to make these operations more well 118212793Sdim // defined. 119212793Sdim switch (Attribute) { 120212793Sdim case MCSA_LazyReference: 121212793Sdim case MCSA_Reference: 122212793Sdim case MCSA_NoDeadStrip: 123218893Sdim case MCSA_SymbolResolver: 124212793Sdim case MCSA_PrivateExtern: 125212793Sdim case MCSA_WeakDefinition: 126212793Sdim case MCSA_WeakDefAutoPrivate: 127212793Sdim case MCSA_Invalid: 128212793Sdim case MCSA_ELF_TypeIndFunction: 129212793Sdim case MCSA_IndirectSymbol: 130212793Sdim assert(0 && "Invalid symbol attribute for ELF!"); 131212793Sdim break; 132212793Sdim 133218893Sdim case MCSA_ELF_TypeGnuUniqueObject: 134218893Sdim // Ignore for now. 135218893Sdim break; 136218893Sdim 137212793Sdim case MCSA_Global: 138221345Sdim MCELF::SetBinding(SD, ELF::STB_GLOBAL); 139212793Sdim SD.setExternal(true); 140218893Sdim BindingExplicitlySet.insert(Symbol); 141212793Sdim break; 142212793Sdim 143212793Sdim case MCSA_WeakReference: 144212793Sdim case MCSA_Weak: 145221345Sdim MCELF::SetBinding(SD, ELF::STB_WEAK); 146218893Sdim SD.setExternal(true); 147218893Sdim BindingExplicitlySet.insert(Symbol); 148212793Sdim break; 149212793Sdim 150212793Sdim case MCSA_Local: 151221345Sdim MCELF::SetBinding(SD, ELF::STB_LOCAL); 152218893Sdim SD.setExternal(false); 153218893Sdim BindingExplicitlySet.insert(Symbol); 154212793Sdim break; 155212793Sdim 156212793Sdim case MCSA_ELF_TypeFunction: 157221345Sdim MCELF::SetType(SD, ELF::STT_FUNC); 158212793Sdim break; 159212793Sdim 160212793Sdim case MCSA_ELF_TypeObject: 161221345Sdim MCELF::SetType(SD, ELF::STT_OBJECT); 162212793Sdim break; 163212793Sdim 164212793Sdim case MCSA_ELF_TypeTLS: 165221345Sdim MCELF::SetType(SD, ELF::STT_TLS); 166212793Sdim break; 167212793Sdim 168212793Sdim case MCSA_ELF_TypeCommon: 169221345Sdim MCELF::SetType(SD, ELF::STT_COMMON); 170212793Sdim break; 171212793Sdim 172212793Sdim case MCSA_ELF_TypeNoType: 173221345Sdim MCELF::SetType(SD, ELF::STT_NOTYPE); 174212793Sdim break; 175212793Sdim 176212793Sdim case MCSA_Protected: 177221345Sdim MCELF::SetVisibility(SD, ELF::STV_PROTECTED); 178212793Sdim break; 179212793Sdim 180212793Sdim case MCSA_Hidden: 181221345Sdim MCELF::SetVisibility(SD, ELF::STV_HIDDEN); 182212793Sdim break; 183212793Sdim 184212793Sdim case MCSA_Internal: 185221345Sdim MCELF::SetVisibility(SD, ELF::STV_INTERNAL); 186212793Sdim break; 187212793Sdim } 188212793Sdim} 189212793Sdim 190212793Sdimvoid MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 191212793Sdim unsigned ByteAlignment) { 192212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 193212793Sdim 194218893Sdim if (!BindingExplicitlySet.count(Symbol)) { 195221345Sdim MCELF::SetBinding(SD, ELF::STB_GLOBAL); 196218893Sdim SD.setExternal(true); 197218893Sdim } 198218893Sdim 199221345Sdim MCELF::SetType(SD, ELF::STT_OBJECT); 200218893Sdim 201221345Sdim if (MCELF::GetBinding(SD) == ELF_STB_Local) { 202212793Sdim const MCSection *Section = getAssembler().getContext().getELFSection(".bss", 203218893Sdim ELF::SHT_NOBITS, 204218893Sdim ELF::SHF_WRITE | 205218893Sdim ELF::SHF_ALLOC, 206212793Sdim SectionKind::getBSS()); 207218893Sdim Symbol->setSection(*Section); 208212793Sdim 209218893Sdim struct LocalCommon L = {&SD, Size, ByteAlignment}; 210218893Sdim LocalCommons.push_back(L); 211218893Sdim } else { 212218893Sdim SD.setCommon(Size, ByteAlignment); 213212793Sdim } 214212793Sdim 215218893Sdim SD.setSize(MCConstantExpr::Create(Size, getContext())); 216218893Sdim} 217212793Sdim 218218893Sdimvoid MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { 219218893Sdim // FIXME: Should this be caught and done earlier? 220218893Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 221221345Sdim MCELF::SetBinding(SD, ELF::STB_LOCAL); 222218893Sdim SD.setExternal(false); 223218893Sdim BindingExplicitlySet.insert(Symbol); 224218893Sdim // FIXME: ByteAlignment is not needed here, but is required. 225218893Sdim EmitCommonSymbol(Symbol, Size, 1); 226212793Sdim} 227212793Sdim 228212793Sdimvoid MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 229212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 230212793Sdim // MCObjectStreamer. 231212793Sdim getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 232212793Sdim} 233212793Sdim 234212793Sdimvoid MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, 235212793Sdim int64_t Value, unsigned ValueSize, 236212793Sdim unsigned MaxBytesToEmit) { 237212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 238212793Sdim // MCObjectStreamer. 239212793Sdim if (MaxBytesToEmit == 0) 240212793Sdim MaxBytesToEmit = ByteAlignment; 241212793Sdim new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 242212793Sdim getCurrentSectionData()); 243212793Sdim 244212793Sdim // Update the maximum alignment on the current section if necessary. 245212793Sdim if (ByteAlignment > getCurrentSectionData()->getAlignment()) 246212793Sdim getCurrentSectionData()->setAlignment(ByteAlignment); 247212793Sdim} 248212793Sdim 249212793Sdimvoid MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment, 250212793Sdim unsigned MaxBytesToEmit) { 251212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 252212793Sdim // MCObjectStreamer. 253212793Sdim if (MaxBytesToEmit == 0) 254212793Sdim MaxBytesToEmit = ByteAlignment; 255212793Sdim MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, 256212793Sdim getCurrentSectionData()); 257212793Sdim F->setEmitNops(true); 258212793Sdim 259212793Sdim // Update the maximum alignment on the current section if necessary. 260212793Sdim if (ByteAlignment > getCurrentSectionData()->getAlignment()) 261212793Sdim getCurrentSectionData()->setAlignment(ByteAlignment); 262212793Sdim} 263212793Sdim 264212793Sdim// Add a symbol for the file name of this module. This is the second 265212793Sdim// entry in the module's symbol table (the first being the null symbol). 266212793Sdimvoid MCELFStreamer::EmitFileDirective(StringRef Filename) { 267212793Sdim MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); 268218893Sdim Symbol->setSection(*getCurrentSection()); 269212793Sdim Symbol->setAbsolute(); 270212793Sdim 271212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 272212793Sdim 273212793Sdim SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); 274212793Sdim} 275212793Sdim 276218893Sdimvoid MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { 277218893Sdim switch (expr->getKind()) { 278218893Sdim case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!"); 279218893Sdim case MCExpr::Constant: 280218893Sdim break; 281212793Sdim 282218893Sdim case MCExpr::Binary: { 283218893Sdim const MCBinaryExpr *be = cast<MCBinaryExpr>(expr); 284218893Sdim fixSymbolsInTLSFixups(be->getLHS()); 285218893Sdim fixSymbolsInTLSFixups(be->getRHS()); 286218893Sdim break; 287218893Sdim } 288212793Sdim 289218893Sdim case MCExpr::SymbolRef: { 290218893Sdim const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr); 291218893Sdim switch (symRef.getKind()) { 292218893Sdim default: 293218893Sdim return; 294221345Sdim case MCSymbolRefExpr::VK_GOTTPOFF: 295221345Sdim case MCSymbolRefExpr::VK_INDNTPOFF: 296218893Sdim case MCSymbolRefExpr::VK_NTPOFF: 297218893Sdim case MCSymbolRefExpr::VK_GOTNTPOFF: 298218893Sdim case MCSymbolRefExpr::VK_TLSGD: 299221345Sdim case MCSymbolRefExpr::VK_TLSLD: 300218893Sdim case MCSymbolRefExpr::VK_TLSLDM: 301218893Sdim case MCSymbolRefExpr::VK_TPOFF: 302218893Sdim case MCSymbolRefExpr::VK_DTPOFF: 303218893Sdim case MCSymbolRefExpr::VK_ARM_TLSGD: 304221345Sdim case MCSymbolRefExpr::VK_ARM_TPOFF: 305221345Sdim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 306218893Sdim break; 307218893Sdim } 308218893Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol()); 309221345Sdim MCELF::SetType(SD, ELF::STT_TLS); 310218893Sdim break; 311218893Sdim } 312218893Sdim 313218893Sdim case MCExpr::Unary: 314218893Sdim fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr()); 315218893Sdim break; 316218893Sdim } 317212793Sdim} 318212793Sdim 319218893Sdimvoid MCELFStreamer::EmitInstToFragment(const MCInst &Inst) { 320218893Sdim this->MCObjectStreamer::EmitInstToFragment(Inst); 321218893Sdim MCInstFragment &F = *cast<MCInstFragment>(getCurrentFragment()); 322218893Sdim 323218893Sdim for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i) 324218893Sdim fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); 325218893Sdim} 326218893Sdim 327212793Sdimvoid MCELFStreamer::EmitInstToData(const MCInst &Inst) { 328212793Sdim MCDataFragment *DF = getOrCreateDataFragment(); 329212793Sdim 330212793Sdim SmallVector<MCFixup, 4> Fixups; 331212793Sdim SmallString<256> Code; 332212793Sdim raw_svector_ostream VecOS(Code); 333212793Sdim getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 334212793Sdim VecOS.flush(); 335212793Sdim 336218893Sdim for (unsigned i = 0, e = Fixups.size(); i != e; ++i) 337218893Sdim fixSymbolsInTLSFixups(Fixups[i].getValue()); 338218893Sdim 339212793Sdim // Add the fixups and data. 340212793Sdim for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 341212793Sdim Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 342212793Sdim DF->addFixup(Fixups[i]); 343212793Sdim } 344212793Sdim DF->getContents().append(Code.begin(), Code.end()); 345212793Sdim} 346212793Sdim 347218893Sdimvoid MCELFStreamer::Finish() { 348218893Sdim if (getNumFrameInfos()) 349221345Sdim MCDwarfFrameEmitter::Emit(*this, true); 350212793Sdim 351218893Sdim for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), 352218893Sdim e = LocalCommons.end(); 353218893Sdim i != e; ++i) { 354218893Sdim MCSymbolData *SD = i->SD; 355218893Sdim uint64_t Size = i->Size; 356218893Sdim unsigned ByteAlignment = i->ByteAlignment; 357218893Sdim const MCSymbol &Symbol = SD->getSymbol(); 358218893Sdim const MCSection &Section = Symbol.getSection(); 359212793Sdim 360218893Sdim MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section); 361218893Sdim new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData); 362212793Sdim 363218893Sdim MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); 364218893Sdim SD->setFragment(F); 365218893Sdim 366218893Sdim // Update the maximum alignment of the section if necessary. 367218893Sdim if (ByteAlignment > SectData.getAlignment()) 368218893Sdim SectData.setAlignment(ByteAlignment); 369212793Sdim } 370212793Sdim 371218893Sdim this->MCObjectStreamer::Finish(); 372212793Sdim} 373212793Sdim 374212793SdimMCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB, 375218893Sdim raw_ostream &OS, MCCodeEmitter *CE, 376218893Sdim bool RelaxAll, bool NoExecStack) { 377212793Sdim MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE); 378212793Sdim if (RelaxAll) 379212793Sdim S->getAssembler().setRelaxAll(true); 380218893Sdim if (NoExecStack) 381218893Sdim S->getAssembler().setNoExecStack(true); 382212793Sdim return S; 383212793Sdim} 384