MCELFStreamer.cpp revision f7fd4aa2610f46467369de07f3ec669561d79be0
1//===- lib/MC/MCELFStreamer.cpp - ELF Object Output ------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file assembles .s files and emits ELF .o object files. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/MC/MCStreamer.h" 15 16#include "llvm/ADT/SmallPtrSet.h" 17#include "llvm/MC/MCAssembler.h" 18#include "llvm/MC/MCContext.h" 19#include "llvm/MC/MCCodeEmitter.h" 20#include "llvm/MC/MCELFSymbolFlags.h" 21#include "llvm/MC/MCExpr.h" 22#include "llvm/MC/MCInst.h" 23#include "llvm/MC/MCObjectStreamer.h" 24#include "llvm/MC/MCSection.h" 25#include "llvm/MC/MCSectionELF.h" 26#include "llvm/MC/MCSymbol.h" 27#include "llvm/MC/MCValue.h" 28#include "llvm/Support/Debug.h" 29#include "llvm/Support/ELF.h" 30#include "llvm/Support/ErrorHandling.h" 31#include "llvm/Support/raw_ostream.h" 32#include "llvm/Target/TargetAsmBackend.h" 33 34using namespace llvm; 35 36namespace { 37 38static void SetBinding(MCSymbolData &SD, unsigned Binding) { 39 assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || 40 Binding == ELF::STB_WEAK); 41 uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift); 42 SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift)); 43} 44 45static unsigned GetBinding(const MCSymbolData &SD) { 46 uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift; 47 assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || 48 Binding == ELF::STB_WEAK); 49 return Binding; 50} 51 52static void SetType(MCSymbolData &SD, unsigned Type) { 53 assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || 54 Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || 55 Type == ELF::STT_FILE || Type == ELF::STT_COMMON || 56 Type == ELF::STT_TLS); 57 58 uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift); 59 SD.setFlags(OtherFlags | (Type << ELF_STT_Shift)); 60} 61 62static void SetVisibility(MCSymbolData &SD, unsigned Visibility) { 63 assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || 64 Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); 65 66 uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STV_Shift); 67 SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift)); 68} 69 70class MCELFStreamer : public MCObjectStreamer { 71public: 72 MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB, 73 raw_ostream &OS, MCCodeEmitter *Emitter) 74 : MCObjectStreamer(Context, TAB, OS, Emitter) {} 75 76 ~MCELFStreamer() {} 77 78 /// @name MCStreamer Interface 79 /// @{ 80 81 virtual void InitSections(); 82 virtual void EmitLabel(MCSymbol *Symbol); 83 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 84 virtual void EmitThumbFunc(MCSymbol *Func); 85 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); 86 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); 87 virtual void SwitchSection(const MCSection *Section); 88 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 89 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 90 assert(0 && "ELF doesn't support this directive"); 91 } 92 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 93 unsigned ByteAlignment); 94 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) { 95 assert(0 && "ELF doesn't support this directive"); 96 } 97 98 virtual void EmitCOFFSymbolStorageClass(int StorageClass) { 99 assert(0 && "ELF doesn't support this directive"); 100 } 101 102 virtual void EmitCOFFSymbolType(int Type) { 103 assert(0 && "ELF doesn't support this directive"); 104 } 105 106 virtual void EndCOFFSymbolDef() { 107 assert(0 && "ELF doesn't support this directive"); 108 } 109 110 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 111 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 112 SD.setSize(Value); 113 } 114 115 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { 116 assert(0 && "ELF doesn't support this directive"); 117 } 118 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 119 unsigned Size = 0, unsigned ByteAlignment = 0) { 120 assert(0 && "ELF doesn't support this directive"); 121 } 122 virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 123 uint64_t Size, unsigned ByteAlignment = 0) { 124 assert(0 && "ELF doesn't support this directive"); 125 } 126 virtual void EmitBytes(StringRef Data, unsigned AddrSpace); 127 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 128 unsigned ValueSize = 1, 129 unsigned MaxBytesToEmit = 0); 130 virtual void EmitCodeAlignment(unsigned ByteAlignment, 131 unsigned MaxBytesToEmit = 0); 132 133 virtual void EmitFileDirective(StringRef Filename); 134 135 virtual void Finish(); 136 137private: 138 virtual void EmitInstToFragment(const MCInst &Inst); 139 virtual void EmitInstToData(const MCInst &Inst); 140 141 void fixSymbolsInTLSFixups(const MCExpr *expr); 142 143 struct LocalCommon { 144 MCSymbolData *SD; 145 uint64_t Size; 146 unsigned ByteAlignment; 147 }; 148 std::vector<LocalCommon> LocalCommons; 149 150 SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; 151 /// @} 152 void SetSection(StringRef Section, unsigned Type, unsigned Flags, 153 SectionKind Kind) { 154 SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind)); 155 } 156 157 void SetSectionData() { 158 SetSection(".data", MCSectionELF::SHT_PROGBITS, 159 MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC, 160 SectionKind::getDataRel()); 161 EmitCodeAlignment(4, 0); 162 } 163 void SetSectionText() { 164 SetSection(".text", MCSectionELF::SHT_PROGBITS, 165 MCSectionELF::SHF_EXECINSTR | 166 MCSectionELF::SHF_ALLOC, SectionKind::getText()); 167 EmitCodeAlignment(4, 0); 168 } 169 void SetSectionBss() { 170 SetSection(".bss", MCSectionELF::SHT_NOBITS, 171 MCSectionELF::SHF_WRITE | 172 MCSectionELF::SHF_ALLOC, SectionKind::getBSS()); 173 EmitCodeAlignment(4, 0); 174 } 175}; 176 177} // end anonymous namespace. 178 179void MCELFStreamer::InitSections() { 180 // This emulates the same behavior of GNU as. This makes it easier 181 // to compare the output as the major sections are in the same order. 182 SetSectionText(); 183 SetSectionData(); 184 SetSectionBss(); 185 SetSectionText(); 186} 187 188void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { 189 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 190 191 MCObjectStreamer::EmitLabel(Symbol); 192 193 const MCSectionELF &Section = 194 static_cast<const MCSectionELF&>(Symbol->getSection()); 195 MCSymbolData &SD = getAssembler().getSymbolData(*Symbol); 196 if (Section.getFlags() & MCSectionELF::SHF_TLS) 197 SetType(SD, ELF::STT_TLS); 198} 199 200void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 201 switch (Flag) { 202 case MCAF_SyntaxUnified: return; // no-op here. 203 case MCAF_Code16: return; // no-op here. 204 case MCAF_Code32: return; // no-op here. 205 case MCAF_SubsectionsViaSymbols: 206 getAssembler().setSubsectionsViaSymbols(true); 207 return; 208 } 209 210 assert(0 && "invalid assembler flag!"); 211} 212 213void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { 214 // FIXME: Anything needed here to flag the function as thumb? 215} 216 217void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 218 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 219 // MCObjectStreamer. 220 // FIXME: Lift context changes into super class. 221 getAssembler().getOrCreateSymbolData(*Symbol); 222 Symbol->setVariableValue(AddValueSymbols(Value)); 223} 224 225void MCELFStreamer::SwitchSection(const MCSection *Section) { 226 const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup(); 227 if (Grp) 228 getAssembler().getOrCreateSymbolData(*Grp); 229 this->MCObjectStreamer::SwitchSection(Section); 230} 231 232void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 233 getAssembler().getOrCreateSymbolData(*Symbol); 234 MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias); 235 AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref); 236 const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, getContext()); 237 Alias->setVariableValue(Value); 238} 239 240void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 241 MCSymbolAttr Attribute) { 242 // Indirect symbols are handled differently, to match how 'as' handles 243 // them. This makes writing matching .o files easier. 244 if (Attribute == MCSA_IndirectSymbol) { 245 // Note that we intentionally cannot use the symbol data here; this is 246 // important for matching the string table that 'as' generates. 247 IndirectSymbolData ISD; 248 ISD.Symbol = Symbol; 249 ISD.SectionData = getCurrentSectionData(); 250 getAssembler().getIndirectSymbols().push_back(ISD); 251 return; 252 } 253 254 // Adding a symbol attribute always introduces the symbol, note that an 255 // important side effect of calling getOrCreateSymbolData here is to register 256 // the symbol with the assembler. 257 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 258 259 // The implementation of symbol attributes is designed to match 'as', but it 260 // leaves much to desired. It doesn't really make sense to arbitrarily add and 261 // remove flags, but 'as' allows this (in particular, see .desc). 262 // 263 // In the future it might be worth trying to make these operations more well 264 // defined. 265 switch (Attribute) { 266 case MCSA_LazyReference: 267 case MCSA_Reference: 268 case MCSA_NoDeadStrip: 269 case MCSA_SymbolResolver: 270 case MCSA_PrivateExtern: 271 case MCSA_WeakDefinition: 272 case MCSA_WeakDefAutoPrivate: 273 case MCSA_Invalid: 274 case MCSA_ELF_TypeIndFunction: 275 case MCSA_IndirectSymbol: 276 assert(0 && "Invalid symbol attribute for ELF!"); 277 break; 278 279 case MCSA_ELF_TypeGnuUniqueObject: 280 // Ignore for now. 281 break; 282 283 case MCSA_Global: 284 SetBinding(SD, ELF::STB_GLOBAL); 285 SD.setExternal(true); 286 BindingExplicitlySet.insert(Symbol); 287 break; 288 289 case MCSA_WeakReference: 290 case MCSA_Weak: 291 SetBinding(SD, ELF::STB_WEAK); 292 SD.setExternal(true); 293 BindingExplicitlySet.insert(Symbol); 294 break; 295 296 case MCSA_Local: 297 SetBinding(SD, ELF::STB_LOCAL); 298 SD.setExternal(false); 299 BindingExplicitlySet.insert(Symbol); 300 break; 301 302 case MCSA_ELF_TypeFunction: 303 SetType(SD, ELF::STT_FUNC); 304 break; 305 306 case MCSA_ELF_TypeObject: 307 SetType(SD, ELF::STT_OBJECT); 308 break; 309 310 case MCSA_ELF_TypeTLS: 311 SetType(SD, ELF::STT_TLS); 312 break; 313 314 case MCSA_ELF_TypeCommon: 315 SetType(SD, ELF::STT_COMMON); 316 break; 317 318 case MCSA_ELF_TypeNoType: 319 SetType(SD, ELF::STT_NOTYPE); 320 break; 321 322 case MCSA_Protected: 323 SetVisibility(SD, ELF::STV_PROTECTED); 324 break; 325 326 case MCSA_Hidden: 327 SetVisibility(SD, ELF::STV_HIDDEN); 328 break; 329 330 case MCSA_Internal: 331 SetVisibility(SD, ELF::STV_INTERNAL); 332 break; 333 } 334} 335 336void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 337 unsigned ByteAlignment) { 338 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 339 340 if (!BindingExplicitlySet.count(Symbol)) { 341 SetBinding(SD, ELF::STB_GLOBAL); 342 SD.setExternal(true); 343 } 344 345 SetType(SD, ELF::STT_OBJECT); 346 347 if (GetBinding(SD) == ELF_STB_Local) { 348 const MCSection *Section = getAssembler().getContext().getELFSection(".bss", 349 MCSectionELF::SHT_NOBITS, 350 MCSectionELF::SHF_WRITE | 351 MCSectionELF::SHF_ALLOC, 352 SectionKind::getBSS()); 353 Symbol->setSection(*Section); 354 355 struct LocalCommon L = {&SD, Size, ByteAlignment}; 356 LocalCommons.push_back(L); 357 } else { 358 SD.setCommon(Size, ByteAlignment); 359 } 360 361 SD.setSize(MCConstantExpr::Create(Size, getContext())); 362} 363 364void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 365 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 366 // MCObjectStreamer. 367 getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 368} 369 370void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, 371 int64_t Value, unsigned ValueSize, 372 unsigned MaxBytesToEmit) { 373 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 374 // MCObjectStreamer. 375 if (MaxBytesToEmit == 0) 376 MaxBytesToEmit = ByteAlignment; 377 new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 378 getCurrentSectionData()); 379 380 // Update the maximum alignment on the current section if necessary. 381 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 382 getCurrentSectionData()->setAlignment(ByteAlignment); 383} 384 385void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment, 386 unsigned MaxBytesToEmit) { 387 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 388 // MCObjectStreamer. 389 if (MaxBytesToEmit == 0) 390 MaxBytesToEmit = ByteAlignment; 391 MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, 392 getCurrentSectionData()); 393 F->setEmitNops(true); 394 395 // Update the maximum alignment on the current section if necessary. 396 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 397 getCurrentSectionData()->setAlignment(ByteAlignment); 398} 399 400// Add a symbol for the file name of this module. This is the second 401// entry in the module's symbol table (the first being the null symbol). 402void MCELFStreamer::EmitFileDirective(StringRef Filename) { 403 MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); 404 Symbol->setSection(*CurSection); 405 Symbol->setAbsolute(); 406 407 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 408 409 SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); 410} 411 412void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { 413 switch (expr->getKind()) { 414 case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!"); 415 case MCExpr::Constant: 416 break; 417 418 case MCExpr::Binary: { 419 const MCBinaryExpr *be = cast<MCBinaryExpr>(expr); 420 fixSymbolsInTLSFixups(be->getLHS()); 421 fixSymbolsInTLSFixups(be->getRHS()); 422 break; 423 } 424 425 case MCExpr::SymbolRef: { 426 const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr); 427 switch (symRef.getKind()) { 428 default: 429 return; 430 case MCSymbolRefExpr::VK_NTPOFF: 431 case MCSymbolRefExpr::VK_GOTNTPOFF: 432 case MCSymbolRefExpr::VK_TLSGD: 433 case MCSymbolRefExpr::VK_TLSLDM: 434 case MCSymbolRefExpr::VK_TPOFF: 435 case MCSymbolRefExpr::VK_DTPOFF: 436 case MCSymbolRefExpr::VK_GOTTPOFF: 437 case MCSymbolRefExpr::VK_TLSLD: 438 case MCSymbolRefExpr::VK_ARM_TLSGD: 439 break; 440 } 441 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol()); 442 SetType(SD, ELF::STT_TLS); 443 break; 444 } 445 446 case MCExpr::Unary: 447 fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr()); 448 break; 449 } 450} 451 452void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) { 453 this->MCObjectStreamer::EmitInstToFragment(Inst); 454 MCInstFragment &F = *cast<MCInstFragment>(getCurrentFragment()); 455 456 for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i) 457 fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); 458} 459 460void MCELFStreamer::EmitInstToData(const MCInst &Inst) { 461 MCDataFragment *DF = getOrCreateDataFragment(); 462 463 SmallVector<MCFixup, 4> Fixups; 464 SmallString<256> Code; 465 raw_svector_ostream VecOS(Code); 466 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 467 VecOS.flush(); 468 469 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) 470 fixSymbolsInTLSFixups(Fixups[i].getValue()); 471 472 // Add the fixups and data. 473 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 474 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 475 DF->addFixup(Fixups[i]); 476 } 477 DF->getContents().append(Code.begin(), Code.end()); 478} 479 480void MCELFStreamer::Finish() { 481 // FIXME: duplicated code with the MachO streamer. 482 // Dump out the dwarf file & directory tables and line tables. 483 if (getContext().hasDwarfFiles()) { 484 const MCSection *DwarfLineSection = 485 getContext().getELFSection(".debug_line", 0, 0, 486 SectionKind::getDataRelLocal()); 487 MCDwarfFileTable::Emit(this, DwarfLineSection); 488 } 489 490 for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), 491 e = LocalCommons.end(); 492 i != e; ++i) { 493 MCSymbolData *SD = i->SD; 494 uint64_t Size = i->Size; 495 unsigned ByteAlignment = i->ByteAlignment; 496 const MCSymbol &Symbol = SD->getSymbol(); 497 const MCSection &Section = Symbol.getSection(); 498 499 MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section); 500 new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData); 501 502 MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); 503 SD->setFragment(F); 504 505 // Update the maximum alignment of the section if necessary. 506 if (ByteAlignment > SectData.getAlignment()) 507 SectData.setAlignment(ByteAlignment); 508 } 509 510 this->MCObjectStreamer::Finish(); 511} 512 513MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB, 514 raw_ostream &OS, MCCodeEmitter *CE, 515 bool RelaxAll) { 516 MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE); 517 if (RelaxAll) 518 S->getAssembler().setRelaxAll(true); 519 return S; 520} 521