MCELFStreamer.cpp revision 234353
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 "MCELF.h" 15234353Sdim#include "llvm/ADT/SmallPtrSet.h" 16234353Sdim#include "llvm/MC/MCAssembler.h" 17234353Sdim#include "llvm/MC/MCCodeEmitter.h" 18234353Sdim#include "llvm/MC/MCContext.h" 19234353Sdim#include "llvm/MC/MCSectionELF.h" 20212793Sdim#include "llvm/MC/MCStreamer.h" 21212793Sdim#include "llvm/MC/MCELFSymbolFlags.h" 22212793Sdim#include "llvm/MC/MCExpr.h" 23212793Sdim#include "llvm/MC/MCInst.h" 24234353Sdim#include "llvm/MC/MCObjectStreamer.h" 25212793Sdim#include "llvm/MC/MCSection.h" 26212793Sdim#include "llvm/MC/MCSymbol.h" 27218893Sdim#include "llvm/MC/MCValue.h" 28226633Sdim#include "llvm/MC/MCAsmBackend.h" 29212793Sdim#include "llvm/Support/Debug.h" 30212793Sdim#include "llvm/Support/ELF.h" 31212793Sdim#include "llvm/Support/ErrorHandling.h" 32212793Sdim#include "llvm/Support/raw_ostream.h" 33212793Sdim 34212793Sdimusing namespace llvm; 35212793Sdim 36234353Sdimnamespace { 37234353Sdimclass MCELFStreamer : public MCObjectStreamer { 38234353Sdimpublic: 39234353Sdim MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, 40234353Sdim raw_ostream &OS, MCCodeEmitter *Emitter) 41234353Sdim : MCObjectStreamer(Context, TAB, OS, Emitter) {} 42234353Sdim 43234353Sdim MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, 44234353Sdim raw_ostream &OS, MCCodeEmitter *Emitter, 45234353Sdim MCAssembler *Assembler) 46234353Sdim : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {} 47234353Sdim 48234353Sdim 49234353Sdim ~MCELFStreamer() {} 50234353Sdim 51234353Sdim /// @name MCStreamer Interface 52234353Sdim /// @{ 53234353Sdim 54234353Sdim virtual void InitSections(); 55234353Sdim virtual void ChangeSection(const MCSection *Section); 56234353Sdim virtual void EmitLabel(MCSymbol *Symbol); 57234353Sdim virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 58234353Sdim virtual void EmitThumbFunc(MCSymbol *Func); 59234353Sdim virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); 60234353Sdim virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); 61234353Sdim virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 62234353Sdim virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 63234353Sdim llvm_unreachable("ELF doesn't support this directive"); 64234353Sdim } 65234353Sdim virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 66234353Sdim unsigned ByteAlignment); 67234353Sdim virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) { 68234353Sdim llvm_unreachable("ELF doesn't support this directive"); 69234353Sdim } 70234353Sdim 71234353Sdim virtual void EmitCOFFSymbolStorageClass(int StorageClass) { 72234353Sdim llvm_unreachable("ELF doesn't support this directive"); 73234353Sdim } 74234353Sdim 75234353Sdim virtual void EmitCOFFSymbolType(int Type) { 76234353Sdim llvm_unreachable("ELF doesn't support this directive"); 77234353Sdim } 78234353Sdim 79234353Sdim virtual void EndCOFFSymbolDef() { 80234353Sdim llvm_unreachable("ELF doesn't support this directive"); 81234353Sdim } 82234353Sdim 83234353Sdim virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 84234353Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 85234353Sdim SD.setSize(Value); 86234353Sdim } 87234353Sdim 88234353Sdim virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 89234353Sdim unsigned ByteAlignment); 90234353Sdim 91234353Sdim virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 92234353Sdim unsigned Size = 0, unsigned ByteAlignment = 0) { 93234353Sdim llvm_unreachable("ELF doesn't support this directive"); 94234353Sdim } 95234353Sdim virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 96234353Sdim uint64_t Size, unsigned ByteAlignment = 0) { 97234353Sdim llvm_unreachable("ELF doesn't support this directive"); 98234353Sdim } 99234353Sdim virtual void EmitBytes(StringRef Data, unsigned AddrSpace); 100234353Sdim virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 101234353Sdim unsigned ValueSize = 1, 102234353Sdim unsigned MaxBytesToEmit = 0); 103234353Sdim virtual void EmitCodeAlignment(unsigned ByteAlignment, 104234353Sdim unsigned MaxBytesToEmit = 0); 105234353Sdim virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, 106234353Sdim unsigned AddrSpace); 107234353Sdim 108234353Sdim virtual void EmitFileDirective(StringRef Filename); 109234353Sdim 110234353Sdim virtual void FinishImpl(); 111234353Sdim 112234353Sdimprivate: 113234353Sdim virtual void EmitInstToFragment(const MCInst &Inst); 114234353Sdim virtual void EmitInstToData(const MCInst &Inst); 115234353Sdim 116234353Sdim void fixSymbolsInTLSFixups(const MCExpr *expr); 117234353Sdim 118234353Sdim struct LocalCommon { 119234353Sdim MCSymbolData *SD; 120234353Sdim uint64_t Size; 121234353Sdim unsigned ByteAlignment; 122234353Sdim }; 123234353Sdim std::vector<LocalCommon> LocalCommons; 124234353Sdim 125234353Sdim SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; 126234353Sdim /// @} 127234353Sdim void SetSection(StringRef Section, unsigned Type, unsigned Flags, 128234353Sdim SectionKind Kind) { 129234353Sdim SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind)); 130234353Sdim } 131234353Sdim 132234353Sdim void SetSectionData() { 133234353Sdim SetSection(".data", ELF::SHT_PROGBITS, 134234353Sdim ELF::SHF_WRITE |ELF::SHF_ALLOC, 135234353Sdim SectionKind::getDataRel()); 136234353Sdim EmitCodeAlignment(4, 0); 137234353Sdim } 138234353Sdim void SetSectionText() { 139234353Sdim SetSection(".text", ELF::SHT_PROGBITS, 140234353Sdim ELF::SHF_EXECINSTR | 141234353Sdim ELF::SHF_ALLOC, SectionKind::getText()); 142234353Sdim EmitCodeAlignment(4, 0); 143234353Sdim } 144234353Sdim void SetSectionBss() { 145234353Sdim SetSection(".bss", ELF::SHT_NOBITS, 146234353Sdim ELF::SHF_WRITE | 147234353Sdim ELF::SHF_ALLOC, SectionKind::getBSS()); 148234353Sdim EmitCodeAlignment(4, 0); 149234353Sdim } 150234353Sdim}; 151234353Sdim} 152234353Sdim 153218893Sdimvoid MCELFStreamer::InitSections() { 154218893Sdim // This emulates the same behavior of GNU as. This makes it easier 155218893Sdim // to compare the output as the major sections are in the same order. 156218893Sdim SetSectionText(); 157218893Sdim SetSectionData(); 158218893Sdim SetSectionBss(); 159218893Sdim SetSectionText(); 160218893Sdim} 161218893Sdim 162212793Sdimvoid MCELFStreamer::EmitLabel(MCSymbol *Symbol) { 163212793Sdim assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 164212793Sdim 165218893Sdim MCObjectStreamer::EmitLabel(Symbol); 166212793Sdim 167218893Sdim const MCSectionELF &Section = 168218893Sdim static_cast<const MCSectionELF&>(Symbol->getSection()); 169218893Sdim MCSymbolData &SD = getAssembler().getSymbolData(*Symbol); 170218893Sdim if (Section.getFlags() & ELF::SHF_TLS) 171221345Sdim MCELF::SetType(SD, ELF::STT_TLS); 172212793Sdim} 173212793Sdim 174212793Sdimvoid MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 175212793Sdim switch (Flag) { 176218893Sdim case MCAF_SyntaxUnified: return; // no-op here. 177226633Sdim case MCAF_Code16: return; // Change parsing mode; no-op here. 178226633Sdim case MCAF_Code32: return; // Change parsing mode; no-op here. 179226633Sdim case MCAF_Code64: return; // Change parsing mode; no-op here. 180212793Sdim case MCAF_SubsectionsViaSymbols: 181212793Sdim getAssembler().setSubsectionsViaSymbols(true); 182212793Sdim return; 183212793Sdim } 184212793Sdim 185234353Sdim llvm_unreachable("invalid assembler flag!"); 186212793Sdim} 187212793Sdim 188218893Sdimvoid MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { 189218893Sdim // FIXME: Anything needed here to flag the function as thumb? 190223017Sdim 191223017Sdim getAssembler().setIsThumbFunc(Func); 192223017Sdim 193223017Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func); 194223017Sdim SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc); 195218893Sdim} 196218893Sdim 197212793Sdimvoid MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 198212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 199212793Sdim // MCObjectStreamer. 200212793Sdim // FIXME: Lift context changes into super class. 201212793Sdim getAssembler().getOrCreateSymbolData(*Symbol); 202212793Sdim Symbol->setVariableValue(AddValueSymbols(Value)); 203212793Sdim} 204212793Sdim 205218893Sdimvoid MCELFStreamer::ChangeSection(const MCSection *Section) { 206218893Sdim const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup(); 207218893Sdim if (Grp) 208218893Sdim getAssembler().getOrCreateSymbolData(*Grp); 209218893Sdim this->MCObjectStreamer::ChangeSection(Section); 210218893Sdim} 211218893Sdim 212218893Sdimvoid MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 213218893Sdim getAssembler().getOrCreateSymbolData(*Symbol); 214218893Sdim MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias); 215218893Sdim AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref); 216218893Sdim const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, getContext()); 217218893Sdim Alias->setVariableValue(Value); 218218893Sdim} 219218893Sdim 220212793Sdimvoid MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 221212793Sdim MCSymbolAttr Attribute) { 222212793Sdim // Indirect symbols are handled differently, to match how 'as' handles 223212793Sdim // them. This makes writing matching .o files easier. 224212793Sdim if (Attribute == MCSA_IndirectSymbol) { 225212793Sdim // Note that we intentionally cannot use the symbol data here; this is 226212793Sdim // important for matching the string table that 'as' generates. 227212793Sdim IndirectSymbolData ISD; 228212793Sdim ISD.Symbol = Symbol; 229212793Sdim ISD.SectionData = getCurrentSectionData(); 230212793Sdim getAssembler().getIndirectSymbols().push_back(ISD); 231212793Sdim return; 232212793Sdim } 233212793Sdim 234212793Sdim // Adding a symbol attribute always introduces the symbol, note that an 235212793Sdim // important side effect of calling getOrCreateSymbolData here is to register 236212793Sdim // the symbol with the assembler. 237212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 238212793Sdim 239212793Sdim // The implementation of symbol attributes is designed to match 'as', but it 240212793Sdim // leaves much to desired. It doesn't really make sense to arbitrarily add and 241212793Sdim // remove flags, but 'as' allows this (in particular, see .desc). 242212793Sdim // 243212793Sdim // In the future it might be worth trying to make these operations more well 244212793Sdim // defined. 245212793Sdim switch (Attribute) { 246212793Sdim case MCSA_LazyReference: 247212793Sdim case MCSA_Reference: 248212793Sdim case MCSA_NoDeadStrip: 249218893Sdim case MCSA_SymbolResolver: 250212793Sdim case MCSA_PrivateExtern: 251212793Sdim case MCSA_WeakDefinition: 252212793Sdim case MCSA_WeakDefAutoPrivate: 253212793Sdim case MCSA_Invalid: 254212793Sdim case MCSA_IndirectSymbol: 255234353Sdim llvm_unreachable("Invalid symbol attribute for ELF!"); 256212793Sdim 257218893Sdim case MCSA_ELF_TypeGnuUniqueObject: 258218893Sdim // Ignore for now. 259218893Sdim break; 260218893Sdim 261212793Sdim case MCSA_Global: 262221345Sdim MCELF::SetBinding(SD, ELF::STB_GLOBAL); 263212793Sdim SD.setExternal(true); 264218893Sdim BindingExplicitlySet.insert(Symbol); 265212793Sdim break; 266212793Sdim 267212793Sdim case MCSA_WeakReference: 268212793Sdim case MCSA_Weak: 269221345Sdim MCELF::SetBinding(SD, ELF::STB_WEAK); 270218893Sdim SD.setExternal(true); 271218893Sdim BindingExplicitlySet.insert(Symbol); 272212793Sdim break; 273212793Sdim 274212793Sdim case MCSA_Local: 275221345Sdim MCELF::SetBinding(SD, ELF::STB_LOCAL); 276218893Sdim SD.setExternal(false); 277218893Sdim BindingExplicitlySet.insert(Symbol); 278212793Sdim break; 279212793Sdim 280212793Sdim case MCSA_ELF_TypeFunction: 281221345Sdim MCELF::SetType(SD, ELF::STT_FUNC); 282212793Sdim break; 283212793Sdim 284234353Sdim case MCSA_ELF_TypeIndFunction: 285234353Sdim MCELF::SetType(SD, ELF::STT_GNU_IFUNC); 286234353Sdim break; 287234353Sdim 288212793Sdim case MCSA_ELF_TypeObject: 289221345Sdim MCELF::SetType(SD, ELF::STT_OBJECT); 290212793Sdim break; 291212793Sdim 292212793Sdim case MCSA_ELF_TypeTLS: 293221345Sdim MCELF::SetType(SD, ELF::STT_TLS); 294212793Sdim break; 295212793Sdim 296212793Sdim case MCSA_ELF_TypeCommon: 297221345Sdim MCELF::SetType(SD, ELF::STT_COMMON); 298212793Sdim break; 299212793Sdim 300212793Sdim case MCSA_ELF_TypeNoType: 301221345Sdim MCELF::SetType(SD, ELF::STT_NOTYPE); 302212793Sdim break; 303212793Sdim 304212793Sdim case MCSA_Protected: 305221345Sdim MCELF::SetVisibility(SD, ELF::STV_PROTECTED); 306212793Sdim break; 307212793Sdim 308212793Sdim case MCSA_Hidden: 309221345Sdim MCELF::SetVisibility(SD, ELF::STV_HIDDEN); 310212793Sdim break; 311212793Sdim 312212793Sdim case MCSA_Internal: 313221345Sdim MCELF::SetVisibility(SD, ELF::STV_INTERNAL); 314212793Sdim break; 315212793Sdim } 316212793Sdim} 317212793Sdim 318212793Sdimvoid MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 319212793Sdim unsigned ByteAlignment) { 320212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 321212793Sdim 322218893Sdim if (!BindingExplicitlySet.count(Symbol)) { 323221345Sdim MCELF::SetBinding(SD, ELF::STB_GLOBAL); 324218893Sdim SD.setExternal(true); 325218893Sdim } 326218893Sdim 327221345Sdim MCELF::SetType(SD, ELF::STT_OBJECT); 328218893Sdim 329221345Sdim if (MCELF::GetBinding(SD) == ELF_STB_Local) { 330212793Sdim const MCSection *Section = getAssembler().getContext().getELFSection(".bss", 331234353Sdim ELF::SHT_NOBITS, 332234353Sdim ELF::SHF_WRITE | 333234353Sdim ELF::SHF_ALLOC, 334234353Sdim SectionKind::getBSS()); 335218893Sdim Symbol->setSection(*Section); 336212793Sdim 337218893Sdim struct LocalCommon L = {&SD, Size, ByteAlignment}; 338218893Sdim LocalCommons.push_back(L); 339218893Sdim } else { 340218893Sdim SD.setCommon(Size, ByteAlignment); 341212793Sdim } 342212793Sdim 343218893Sdim SD.setSize(MCConstantExpr::Create(Size, getContext())); 344218893Sdim} 345212793Sdim 346226633Sdimvoid MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 347226633Sdim unsigned ByteAlignment) { 348218893Sdim // FIXME: Should this be caught and done earlier? 349218893Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 350221345Sdim MCELF::SetBinding(SD, ELF::STB_LOCAL); 351218893Sdim SD.setExternal(false); 352218893Sdim BindingExplicitlySet.insert(Symbol); 353226633Sdim EmitCommonSymbol(Symbol, Size, ByteAlignment); 354212793Sdim} 355212793Sdim 356212793Sdimvoid MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 357212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 358212793Sdim // MCObjectStreamer. 359212793Sdim getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 360212793Sdim} 361212793Sdim 362212793Sdimvoid MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, 363212793Sdim int64_t Value, unsigned ValueSize, 364212793Sdim unsigned MaxBytesToEmit) { 365212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 366212793Sdim // MCObjectStreamer. 367212793Sdim if (MaxBytesToEmit == 0) 368212793Sdim MaxBytesToEmit = ByteAlignment; 369212793Sdim new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 370212793Sdim getCurrentSectionData()); 371212793Sdim 372212793Sdim // Update the maximum alignment on the current section if necessary. 373212793Sdim if (ByteAlignment > getCurrentSectionData()->getAlignment()) 374212793Sdim getCurrentSectionData()->setAlignment(ByteAlignment); 375212793Sdim} 376212793Sdim 377212793Sdimvoid MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment, 378212793Sdim unsigned MaxBytesToEmit) { 379212793Sdim // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 380212793Sdim // MCObjectStreamer. 381212793Sdim if (MaxBytesToEmit == 0) 382212793Sdim MaxBytesToEmit = ByteAlignment; 383212793Sdim MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, 384212793Sdim getCurrentSectionData()); 385212793Sdim F->setEmitNops(true); 386212793Sdim 387212793Sdim // Update the maximum alignment on the current section if necessary. 388212793Sdim if (ByteAlignment > getCurrentSectionData()->getAlignment()) 389212793Sdim getCurrentSectionData()->setAlignment(ByteAlignment); 390212793Sdim} 391212793Sdim 392234353Sdimvoid MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 393234353Sdim unsigned AddrSpace) { 394234353Sdim fixSymbolsInTLSFixups(Value); 395234353Sdim MCObjectStreamer::EmitValueImpl(Value, Size, AddrSpace); 396234353Sdim} 397234353Sdim 398234353Sdim 399212793Sdim// Add a symbol for the file name of this module. This is the second 400212793Sdim// entry in the module's symbol table (the first being the null symbol). 401212793Sdimvoid MCELFStreamer::EmitFileDirective(StringRef Filename) { 402212793Sdim MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); 403218893Sdim Symbol->setSection(*getCurrentSection()); 404212793Sdim Symbol->setAbsolute(); 405212793Sdim 406212793Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 407212793Sdim 408212793Sdim SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); 409212793Sdim} 410212793Sdim 411218893Sdimvoid MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { 412218893Sdim switch (expr->getKind()) { 413218893Sdim case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!"); 414218893Sdim case MCExpr::Constant: 415218893Sdim break; 416212793Sdim 417218893Sdim case MCExpr::Binary: { 418218893Sdim const MCBinaryExpr *be = cast<MCBinaryExpr>(expr); 419218893Sdim fixSymbolsInTLSFixups(be->getLHS()); 420218893Sdim fixSymbolsInTLSFixups(be->getRHS()); 421218893Sdim break; 422218893Sdim } 423212793Sdim 424218893Sdim case MCExpr::SymbolRef: { 425218893Sdim const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr); 426218893Sdim switch (symRef.getKind()) { 427218893Sdim default: 428218893Sdim return; 429221345Sdim case MCSymbolRefExpr::VK_GOTTPOFF: 430221345Sdim case MCSymbolRefExpr::VK_INDNTPOFF: 431218893Sdim case MCSymbolRefExpr::VK_NTPOFF: 432218893Sdim case MCSymbolRefExpr::VK_GOTNTPOFF: 433218893Sdim case MCSymbolRefExpr::VK_TLSGD: 434221345Sdim case MCSymbolRefExpr::VK_TLSLD: 435218893Sdim case MCSymbolRefExpr::VK_TLSLDM: 436218893Sdim case MCSymbolRefExpr::VK_TPOFF: 437218893Sdim case MCSymbolRefExpr::VK_DTPOFF: 438218893Sdim case MCSymbolRefExpr::VK_ARM_TLSGD: 439221345Sdim case MCSymbolRefExpr::VK_ARM_TPOFF: 440221345Sdim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 441234353Sdim case MCSymbolRefExpr::VK_Mips_TLSGD: 442234353Sdim case MCSymbolRefExpr::VK_Mips_GOTTPREL: 443234353Sdim case MCSymbolRefExpr::VK_Mips_TPREL_HI: 444234353Sdim case MCSymbolRefExpr::VK_Mips_TPREL_LO: 445218893Sdim break; 446218893Sdim } 447218893Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol()); 448221345Sdim MCELF::SetType(SD, ELF::STT_TLS); 449218893Sdim break; 450218893Sdim } 451218893Sdim 452218893Sdim case MCExpr::Unary: 453218893Sdim fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr()); 454218893Sdim break; 455218893Sdim } 456212793Sdim} 457212793Sdim 458218893Sdimvoid MCELFStreamer::EmitInstToFragment(const MCInst &Inst) { 459218893Sdim this->MCObjectStreamer::EmitInstToFragment(Inst); 460218893Sdim MCInstFragment &F = *cast<MCInstFragment>(getCurrentFragment()); 461218893Sdim 462218893Sdim for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i) 463218893Sdim fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); 464218893Sdim} 465218893Sdim 466212793Sdimvoid MCELFStreamer::EmitInstToData(const MCInst &Inst) { 467212793Sdim MCDataFragment *DF = getOrCreateDataFragment(); 468212793Sdim 469212793Sdim SmallVector<MCFixup, 4> Fixups; 470212793Sdim SmallString<256> Code; 471212793Sdim raw_svector_ostream VecOS(Code); 472212793Sdim getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 473212793Sdim VecOS.flush(); 474212793Sdim 475218893Sdim for (unsigned i = 0, e = Fixups.size(); i != e; ++i) 476218893Sdim fixSymbolsInTLSFixups(Fixups[i].getValue()); 477218893Sdim 478212793Sdim // Add the fixups and data. 479212793Sdim for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 480212793Sdim Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 481212793Sdim DF->addFixup(Fixups[i]); 482212793Sdim } 483212793Sdim DF->getContents().append(Code.begin(), Code.end()); 484212793Sdim} 485212793Sdim 486234353Sdimvoid MCELFStreamer::FinishImpl() { 487223017Sdim EmitFrames(true); 488212793Sdim 489218893Sdim for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), 490218893Sdim e = LocalCommons.end(); 491218893Sdim i != e; ++i) { 492218893Sdim MCSymbolData *SD = i->SD; 493218893Sdim uint64_t Size = i->Size; 494218893Sdim unsigned ByteAlignment = i->ByteAlignment; 495218893Sdim const MCSymbol &Symbol = SD->getSymbol(); 496218893Sdim const MCSection &Section = Symbol.getSection(); 497212793Sdim 498218893Sdim MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section); 499218893Sdim new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData); 500212793Sdim 501218893Sdim MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); 502218893Sdim SD->setFragment(F); 503218893Sdim 504218893Sdim // Update the maximum alignment of the section if necessary. 505218893Sdim if (ByteAlignment > SectData.getAlignment()) 506218893Sdim SectData.setAlignment(ByteAlignment); 507212793Sdim } 508212793Sdim 509234353Sdim this->MCObjectStreamer::FinishImpl(); 510212793Sdim} 511212793Sdim 512226633SdimMCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, 513218893Sdim raw_ostream &OS, MCCodeEmitter *CE, 514218893Sdim bool RelaxAll, bool NoExecStack) { 515226633Sdim MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE); 516212793Sdim if (RelaxAll) 517212793Sdim S->getAssembler().setRelaxAll(true); 518218893Sdim if (NoExecStack) 519218893Sdim S->getAssembler().setNoExecStack(true); 520212793Sdim return S; 521212793Sdim} 522