MCELFStreamer.cpp revision c70a1d985aca40b33b3e4b046b179f0d5e5e238b
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 38class MCELFStreamer : public MCObjectStreamer { 39public: 40 MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB, 41 raw_ostream &OS, MCCodeEmitter *Emitter) 42 : MCObjectStreamer(Context, TAB, OS, Emitter, false) {} 43 44 ~MCELFStreamer() {} 45 46 /// @name MCStreamer Interface 47 /// @{ 48 49 virtual void InitSections(); 50 virtual void EmitLabel(MCSymbol *Symbol); 51 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 52 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); 53 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); 54 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 55 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 56 assert(0 && "ELF doesn't support this directive"); 57 } 58 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 59 unsigned ByteAlignment); 60 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) { 61 assert(0 && "ELF doesn't support this directive"); 62 } 63 64 virtual void EmitCOFFSymbolStorageClass(int StorageClass) { 65 assert(0 && "ELF doesn't support this directive"); 66 } 67 68 virtual void EmitCOFFSymbolType(int Type) { 69 assert(0 && "ELF doesn't support this directive"); 70 } 71 72 virtual void EndCOFFSymbolDef() { 73 assert(0 && "ELF doesn't support this directive"); 74 } 75 76 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 77 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 78 SD.setSize(Value); 79 } 80 81 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { 82 assert(0 && "ELF doesn't support this directive"); 83 } 84 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 85 unsigned Size = 0, unsigned ByteAlignment = 0) { 86 assert(0 && "ELF doesn't support this directive"); 87 } 88 virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 89 uint64_t Size, unsigned ByteAlignment = 0) { 90 assert(0 && "ELF doesn't support this directive"); 91 } 92 virtual void EmitBytes(StringRef Data, unsigned AddrSpace); 93 virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); 94 virtual void EmitGPRel32Value(const MCExpr *Value) { 95 assert(0 && "ELF doesn't support this directive"); 96 } 97 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 98 unsigned ValueSize = 1, 99 unsigned MaxBytesToEmit = 0); 100 virtual void EmitCodeAlignment(unsigned ByteAlignment, 101 unsigned MaxBytesToEmit = 0); 102 virtual void EmitValueToOffset(const MCExpr *Offset, 103 unsigned char Value = 0); 104 105 virtual void EmitFileDirective(StringRef Filename); 106 virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) { 107 DEBUG(dbgs() << "FIXME: MCELFStreamer:EmitDwarfFileDirective not implemented\n"); 108 } 109 110 virtual void Finish(); 111 112private: 113 virtual void EmitInstToFragment(const MCInst &Inst); 114 virtual void EmitInstToData(const MCInst &Inst); 115 116 struct LocalCommon { 117 MCSymbolData *SD; 118 uint64_t Size; 119 unsigned ByteAlignment; 120 }; 121 std::vector<LocalCommon> LocalCommons; 122 123 SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; 124 /// @} 125 void SetSection(StringRef Section, unsigned Type, unsigned Flags, 126 SectionKind Kind) { 127 SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind)); 128 } 129 130 void SetSectionData() { 131 SetSection(".data", MCSectionELF::SHT_PROGBITS, 132 MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC, 133 SectionKind::getDataRel()); 134 EmitCodeAlignment(4, 0); 135 } 136 void SetSectionText() { 137 SetSection(".text", MCSectionELF::SHT_PROGBITS, 138 MCSectionELF::SHF_EXECINSTR | 139 MCSectionELF::SHF_ALLOC, SectionKind::getText()); 140 EmitCodeAlignment(4, 0); 141 } 142 void SetSectionBss() { 143 SetSection(".bss", MCSectionELF::SHT_NOBITS, 144 MCSectionELF::SHF_WRITE | 145 MCSectionELF::SHF_ALLOC, SectionKind::getBSS()); 146 EmitCodeAlignment(4, 0); 147 } 148}; 149 150} // end anonymous namespace. 151 152void MCELFStreamer::InitSections() { 153 // This emulates the same behavior of GNU as. This makes it easier 154 // to compare the output as the major sections are in the same order. 155 SetSectionText(); 156 SetSectionData(); 157 SetSectionBss(); 158 SetSectionText(); 159} 160 161void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { 162 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 163 164 Symbol->setSection(*CurSection); 165 166 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 167 168 // FIXME: This is wasteful, we don't necessarily need to create a data 169 // fragment. Instead, we should mark the symbol as pointing into the data 170 // fragment if it exists, otherwise we should just queue the label and set its 171 // fragment pointer when we emit the next fragment. 172 MCDataFragment *F = getOrCreateDataFragment(); 173 174 assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 175 SD.setFragment(F); 176 SD.setOffset(F->getContents().size()); 177} 178 179void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 180 switch (Flag) { 181 case MCAF_SyntaxUnified: return; // no-op here? 182 case MCAF_SubsectionsViaSymbols: 183 getAssembler().setSubsectionsViaSymbols(true); 184 return; 185 } 186 187 assert(0 && "invalid assembler flag!"); 188} 189 190void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 191 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 192 // MCObjectStreamer. 193 // FIXME: Lift context changes into super class. 194 getAssembler().getOrCreateSymbolData(*Symbol); 195 Symbol->setVariableValue(AddValueSymbols(Value)); 196} 197 198// This is a hack. To be able to implement weakrefs the writer has to be able 199// to distinguish 200// .weakref foo, bar 201// .long foo 202// from 203// .weakref foo, bar 204// .long bar 205// since the first case should produce a weak undefined reference and the second 206// one a strong one. 207// If we created foo as a regular alias pointing to bar (foo = bar), then 208// MCExpr::EvaluateAsRelocatable would recurse on foo and the writer would 209// never see it used in a relocation. 210// What we do is create a MCTargetExpr that when evaluated produces a symbol 211// ref to a temporary symbol. This temporary symbol in turn is a variable 212// that equals the original symbol (tmp = bar). With this hack the writer 213// gets a relocation with tmp and can correctly implement weak references. 214 215class WeakRefExpr : public MCTargetExpr { 216private: 217 const MCSymbolRefExpr *Alias; 218 219 explicit WeakRefExpr(const MCSymbolRefExpr *Alias_) 220 : MCTargetExpr(), Alias(Alias_) {} 221 222public: 223 virtual void PrintImpl(raw_ostream &OS) const { 224 llvm_unreachable("Unimplemented"); 225 } 226 227 virtual bool EvaluateAsRelocatableImpl(MCValue &Res, 228 const MCAsmLayout *Layout) const { 229 Res = MCValue::get(Alias, 0, 0); 230 return true; 231 } 232 233 static const WeakRefExpr *Create(const MCSymbol *Alias, MCContext &Ctx) { 234 const MCSymbolRefExpr *A = MCSymbolRefExpr::Create(Alias, Ctx); 235 return new (Ctx) WeakRefExpr(A); 236 } 237}; 238 239void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 240 getAssembler().getOrCreateSymbolData(*Symbol); 241 MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias); 242 AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref); 243 244 // Create the alias that actually points to Symbol 245 const MCSymbolRefExpr *SymRef = MCSymbolRefExpr::Create(Symbol, getContext()); 246 MCSymbol *RealAlias = getContext().CreateTempSymbol(); 247 RealAlias->setVariableValue(SymRef); 248 249 MCSymbolData &RealAliasSD = getAssembler().getOrCreateSymbolData(*RealAlias); 250 RealAliasSD.setFlags(RealAliasSD.getFlags() | ELF_Other_Weakref); 251 252 const MCExpr *Value = WeakRefExpr::Create(RealAlias, getContext()); 253 Alias->setVariableValue(Value); 254} 255 256static void SetBinding(MCSymbolData &SD, unsigned Binding) { 257 assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || 258 Binding == ELF::STB_WEAK); 259 uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift); 260 SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift)); 261} 262 263static unsigned GetBinding(const MCSymbolData &SD) { 264 uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift; 265 assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || 266 Binding == ELF::STB_WEAK); 267 return Binding; 268} 269 270static void SetType(MCSymbolData &SD, unsigned Type) { 271 assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || 272 Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || 273 Type == ELF::STT_FILE || Type == ELF::STT_COMMON || 274 Type == ELF::STT_TLS); 275 276 uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift); 277 SD.setFlags(OtherFlags | (Type << ELF_STT_Shift)); 278} 279 280static void SetVisibility(MCSymbolData &SD, unsigned Visibility) { 281 assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || 282 Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); 283 284 uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STV_Shift); 285 SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift)); 286} 287 288void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 289 MCSymbolAttr Attribute) { 290 // Indirect symbols are handled differently, to match how 'as' handles 291 // them. This makes writing matching .o files easier. 292 if (Attribute == MCSA_IndirectSymbol) { 293 // Note that we intentionally cannot use the symbol data here; this is 294 // important for matching the string table that 'as' generates. 295 IndirectSymbolData ISD; 296 ISD.Symbol = Symbol; 297 ISD.SectionData = getCurrentSectionData(); 298 getAssembler().getIndirectSymbols().push_back(ISD); 299 return; 300 } 301 302 // Adding a symbol attribute always introduces the symbol, note that an 303 // important side effect of calling getOrCreateSymbolData here is to register 304 // the symbol with the assembler. 305 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 306 307 // The implementation of symbol attributes is designed to match 'as', but it 308 // leaves much to desired. It doesn't really make sense to arbitrarily add and 309 // remove flags, but 'as' allows this (in particular, see .desc). 310 // 311 // In the future it might be worth trying to make these operations more well 312 // defined. 313 switch (Attribute) { 314 case MCSA_LazyReference: 315 case MCSA_Reference: 316 case MCSA_NoDeadStrip: 317 case MCSA_PrivateExtern: 318 case MCSA_WeakDefinition: 319 case MCSA_WeakDefAutoPrivate: 320 case MCSA_Invalid: 321 case MCSA_ELF_TypeIndFunction: 322 case MCSA_IndirectSymbol: 323 assert(0 && "Invalid symbol attribute for ELF!"); 324 break; 325 326 case MCSA_Global: 327 SetBinding(SD, ELF::STB_GLOBAL); 328 SD.setExternal(true); 329 BindingExplicitlySet.insert(Symbol); 330 break; 331 332 case MCSA_WeakReference: 333 case MCSA_Weak: 334 SetBinding(SD, ELF::STB_WEAK); 335 SD.setExternal(true); 336 BindingExplicitlySet.insert(Symbol); 337 break; 338 339 case MCSA_Local: 340 SetBinding(SD, ELF::STB_LOCAL); 341 SD.setExternal(false); 342 BindingExplicitlySet.insert(Symbol); 343 break; 344 345 case MCSA_ELF_TypeFunction: 346 SetType(SD, ELF::STT_FUNC); 347 break; 348 349 case MCSA_ELF_TypeObject: 350 SetType(SD, ELF::STT_OBJECT); 351 break; 352 353 case MCSA_ELF_TypeTLS: 354 SetType(SD, ELF::STT_TLS); 355 break; 356 357 case MCSA_ELF_TypeCommon: 358 SetType(SD, ELF::STT_COMMON); 359 break; 360 361 case MCSA_ELF_TypeNoType: 362 SetType(SD, ELF::STT_NOTYPE); 363 break; 364 365 case MCSA_Protected: 366 SetVisibility(SD, ELF::STV_PROTECTED); 367 break; 368 369 case MCSA_Hidden: 370 SetVisibility(SD, ELF::STV_HIDDEN); 371 break; 372 373 case MCSA_Internal: 374 SetVisibility(SD, ELF::STV_INTERNAL); 375 break; 376 } 377} 378 379void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 380 unsigned ByteAlignment) { 381 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 382 383 if (!BindingExplicitlySet.count(Symbol)) { 384 SetBinding(SD, ELF::STB_GLOBAL); 385 SD.setExternal(true); 386 } 387 388 if (GetBinding(SD) == ELF_STB_Local) { 389 const MCSection *Section = getAssembler().getContext().getELFSection(".bss", 390 MCSectionELF::SHT_NOBITS, 391 MCSectionELF::SHF_WRITE | 392 MCSectionELF::SHF_ALLOC, 393 SectionKind::getBSS()); 394 Symbol->setSection(*Section); 395 396 struct LocalCommon L = {&SD, Size, ByteAlignment}; 397 LocalCommons.push_back(L); 398 } else { 399 SD.setCommon(Size, ByteAlignment); 400 } 401 402 SD.setSize(MCConstantExpr::Create(Size, getContext())); 403} 404 405void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 406 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 407 // MCObjectStreamer. 408 getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 409} 410 411void MCELFStreamer::EmitValue(const MCExpr *Value, unsigned Size, 412 unsigned AddrSpace) { 413 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 414 // MCObjectStreamer. 415 MCDataFragment *DF = getOrCreateDataFragment(); 416 417 // Avoid fixups when possible. 418 int64_t AbsValue; 419 if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) { 420 // FIXME: Endianness assumption. 421 for (unsigned i = 0; i != Size; ++i) 422 DF->getContents().push_back(uint8_t(AbsValue >> (i * 8))); 423 } else { 424 DF->addFixup(MCFixup::Create(DF->getContents().size(), AddValueSymbols(Value), 425 MCFixup::getKindForSize(Size))); 426 DF->getContents().resize(DF->getContents().size() + Size, 0); 427 } 428} 429 430void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, 431 int64_t Value, unsigned ValueSize, 432 unsigned MaxBytesToEmit) { 433 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 434 // MCObjectStreamer. 435 if (MaxBytesToEmit == 0) 436 MaxBytesToEmit = ByteAlignment; 437 new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 438 getCurrentSectionData()); 439 440 // Update the maximum alignment on the current section if necessary. 441 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 442 getCurrentSectionData()->setAlignment(ByteAlignment); 443} 444 445void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment, 446 unsigned MaxBytesToEmit) { 447 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 448 // MCObjectStreamer. 449 if (MaxBytesToEmit == 0) 450 MaxBytesToEmit = ByteAlignment; 451 MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, 452 getCurrentSectionData()); 453 F->setEmitNops(true); 454 455 // Update the maximum alignment on the current section if necessary. 456 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 457 getCurrentSectionData()->setAlignment(ByteAlignment); 458} 459 460void MCELFStreamer::EmitValueToOffset(const MCExpr *Offset, 461 unsigned char Value) { 462 // TODO: This is exactly the same as MCMachOStreamer. Consider merging into 463 // MCObjectStreamer. 464 new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 465} 466 467// Add a symbol for the file name of this module. This is the second 468// entry in the module's symbol table (the first being the null symbol). 469void MCELFStreamer::EmitFileDirective(StringRef Filename) { 470 MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); 471 Symbol->setSection(*CurSection); 472 Symbol->setAbsolute(); 473 474 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 475 476 SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); 477} 478 479void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) { 480 MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData()); 481 482 // Add the fixups and data. 483 // 484 // FIXME: Revisit this design decision when relaxation is done, we may be 485 // able to get away with not storing any extra data in the MCInst. 486 SmallVector<MCFixup, 4> Fixups; 487 SmallString<256> Code; 488 raw_svector_ostream VecOS(Code); 489 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 490 VecOS.flush(); 491 492 IF->getCode() = Code; 493 IF->getFixups() = Fixups; 494} 495 496void MCELFStreamer::EmitInstToData(const MCInst &Inst) { 497 MCDataFragment *DF = getOrCreateDataFragment(); 498 499 SmallVector<MCFixup, 4> Fixups; 500 SmallString<256> Code; 501 raw_svector_ostream VecOS(Code); 502 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 503 VecOS.flush(); 504 505 // Add the fixups and data. 506 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 507 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 508 DF->addFixup(Fixups[i]); 509 } 510 DF->getContents().append(Code.begin(), Code.end()); 511} 512 513void MCELFStreamer::Finish() { 514 // FIXME: duplicated code with the MachO streamer. 515 // Dump out the dwarf file & directory tables and line tables. 516 if (getContext().hasDwarfFiles()) { 517 const MCSection *DwarfLineSection = 518 getContext().getELFSection(".debug_line", 0, 0, 519 SectionKind::getDataRelLocal()); 520 MCDwarfFileTable::Emit(this, DwarfLineSection); 521 } 522 523 for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), 524 e = LocalCommons.end(); 525 i != e; ++i) { 526 MCSymbolData *SD = i->SD; 527 uint64_t Size = i->Size; 528 unsigned ByteAlignment = i->ByteAlignment; 529 const MCSymbol &Symbol = SD->getSymbol(); 530 const MCSection &Section = Symbol.getSection(); 531 532 MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section); 533 new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData); 534 535 MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); 536 SD->setFragment(F); 537 538 // Update the maximum alignment of the section if necessary. 539 if (ByteAlignment > SectData.getAlignment()) 540 SectData.setAlignment(ByteAlignment); 541 } 542 543 this->MCObjectStreamer::Finish(); 544} 545 546MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB, 547 raw_ostream &OS, MCCodeEmitter *CE, 548 bool RelaxAll) { 549 MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE); 550 if (RelaxAll) 551 S->getAssembler().setRelaxAll(true); 552 return S; 553} 554