MCELFStreamer.cpp revision f90a2de72c25e24f26577b0dd8145ac21fe10f5e
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, false) {} 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 EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); 128 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 129 unsigned ValueSize = 1, 130 unsigned MaxBytesToEmit = 0); 131 virtual void EmitCodeAlignment(unsigned ByteAlignment, 132 unsigned MaxBytesToEmit = 0); 133 virtual void EmitValueToOffset(const MCExpr *Offset, 134 unsigned char Value = 0); 135 136 virtual void EmitFileDirective(StringRef Filename); 137 138 virtual void Finish(); 139 140private: 141 virtual void EmitInstToFragment(const MCInst &Inst); 142 virtual void EmitInstToData(const MCInst &Inst); 143 144 void fixSymbolsInTLSFixups(const MCExpr *expr); 145 146 struct LocalCommon { 147 MCSymbolData *SD; 148 uint64_t Size; 149 unsigned ByteAlignment; 150 }; 151 std::vector<LocalCommon> LocalCommons; 152 153 SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; 154 /// @} 155 void SetSection(StringRef Section, unsigned Type, unsigned Flags, 156 SectionKind Kind) { 157 SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind)); 158 } 159 160 void SetSectionData() { 161 SetSection(".data", MCSectionELF::SHT_PROGBITS, 162 MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC, 163 SectionKind::getDataRel()); 164 EmitCodeAlignment(4, 0); 165 } 166 void SetSectionText() { 167 SetSection(".text", MCSectionELF::SHT_PROGBITS, 168 MCSectionELF::SHF_EXECINSTR | 169 MCSectionELF::SHF_ALLOC, SectionKind::getText()); 170 EmitCodeAlignment(4, 0); 171 } 172 void SetSectionBss() { 173 SetSection(".bss", MCSectionELF::SHT_NOBITS, 174 MCSectionELF::SHF_WRITE | 175 MCSectionELF::SHF_ALLOC, SectionKind::getBSS()); 176 EmitCodeAlignment(4, 0); 177 } 178}; 179 180} // end anonymous namespace. 181 182void MCELFStreamer::InitSections() { 183 // This emulates the same behavior of GNU as. This makes it easier 184 // to compare the output as the major sections are in the same order. 185 SetSectionText(); 186 SetSectionData(); 187 SetSectionBss(); 188 SetSectionText(); 189} 190 191void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { 192 MCObjectStreamer::EmitLabel(Symbol); 193 194 const MCSectionELF &Section = 195 static_cast<const MCSectionELF&>(Symbol->getSection()); 196 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 197 if (Section.getFlags() & MCSectionELF::SHF_TLS) 198 SetType(SD, ELF::STT_TLS); 199} 200 201void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 202 switch (Flag) { 203 case MCAF_SyntaxUnified: return; // no-op here. 204 case MCAF_Code16: return; // no-op here. 205 case MCAF_Code32: return; // no-op here. 206 case MCAF_SubsectionsViaSymbols: 207 getAssembler().setSubsectionsViaSymbols(true); 208 return; 209 } 210 211 assert(0 && "invalid assembler flag!"); 212} 213 214void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { 215 // FIXME: Anything needed here to flag the function as thumb? 216} 217 218void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 219 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 220 // MCObjectStreamer. 221 // FIXME: Lift context changes into super class. 222 getAssembler().getOrCreateSymbolData(*Symbol); 223 Symbol->setVariableValue(AddValueSymbols(Value)); 224} 225 226void MCELFStreamer::SwitchSection(const MCSection *Section) { 227 const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup(); 228 if (Grp) 229 getAssembler().getOrCreateSymbolData(*Grp); 230 this->MCObjectStreamer::SwitchSection(Section); 231} 232 233void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 234 getAssembler().getOrCreateSymbolData(*Symbol); 235 MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias); 236 AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref); 237 const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, getContext()); 238 Alias->setVariableValue(Value); 239} 240 241void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 242 MCSymbolAttr Attribute) { 243 // Indirect symbols are handled differently, to match how 'as' handles 244 // them. This makes writing matching .o files easier. 245 if (Attribute == MCSA_IndirectSymbol) { 246 // Note that we intentionally cannot use the symbol data here; this is 247 // important for matching the string table that 'as' generates. 248 IndirectSymbolData ISD; 249 ISD.Symbol = Symbol; 250 ISD.SectionData = getCurrentSectionData(); 251 getAssembler().getIndirectSymbols().push_back(ISD); 252 return; 253 } 254 255 // Adding a symbol attribute always introduces the symbol, note that an 256 // important side effect of calling getOrCreateSymbolData here is to register 257 // the symbol with the assembler. 258 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 259 260 // The implementation of symbol attributes is designed to match 'as', but it 261 // leaves much to desired. It doesn't really make sense to arbitrarily add and 262 // remove flags, but 'as' allows this (in particular, see .desc). 263 // 264 // In the future it might be worth trying to make these operations more well 265 // defined. 266 switch (Attribute) { 267 case MCSA_LazyReference: 268 case MCSA_Reference: 269 case MCSA_NoDeadStrip: 270 case MCSA_SymbolResolver: 271 case MCSA_PrivateExtern: 272 case MCSA_WeakDefinition: 273 case MCSA_WeakDefAutoPrivate: 274 case MCSA_Invalid: 275 case MCSA_ELF_TypeIndFunction: 276 case MCSA_IndirectSymbol: 277 assert(0 && "Invalid symbol attribute for ELF!"); 278 break; 279 280 case MCSA_ELF_TypeGnuUniqueObject: 281 // Ignore for now. 282 break; 283 284 case MCSA_Global: 285 SetBinding(SD, ELF::STB_GLOBAL); 286 SD.setExternal(true); 287 BindingExplicitlySet.insert(Symbol); 288 break; 289 290 case MCSA_WeakReference: 291 case MCSA_Weak: 292 SetBinding(SD, ELF::STB_WEAK); 293 SD.setExternal(true); 294 BindingExplicitlySet.insert(Symbol); 295 break; 296 297 case MCSA_Local: 298 SetBinding(SD, ELF::STB_LOCAL); 299 SD.setExternal(false); 300 BindingExplicitlySet.insert(Symbol); 301 break; 302 303 case MCSA_ELF_TypeFunction: 304 SetType(SD, ELF::STT_FUNC); 305 break; 306 307 case MCSA_ELF_TypeObject: 308 SetType(SD, ELF::STT_OBJECT); 309 break; 310 311 case MCSA_ELF_TypeTLS: 312 SetType(SD, ELF::STT_TLS); 313 break; 314 315 case MCSA_ELF_TypeCommon: 316 SetType(SD, ELF::STT_COMMON); 317 break; 318 319 case MCSA_ELF_TypeNoType: 320 SetType(SD, ELF::STT_NOTYPE); 321 break; 322 323 case MCSA_Protected: 324 SetVisibility(SD, ELF::STV_PROTECTED); 325 break; 326 327 case MCSA_Hidden: 328 SetVisibility(SD, ELF::STV_HIDDEN); 329 break; 330 331 case MCSA_Internal: 332 SetVisibility(SD, ELF::STV_INTERNAL); 333 break; 334 } 335} 336 337void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 338 unsigned ByteAlignment) { 339 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 340 341 if (!BindingExplicitlySet.count(Symbol)) { 342 SetBinding(SD, ELF::STB_GLOBAL); 343 SD.setExternal(true); 344 } 345 346 SetType(SD, ELF::STT_OBJECT); 347 348 if (GetBinding(SD) == ELF_STB_Local) { 349 const MCSection *Section = getAssembler().getContext().getELFSection(".bss", 350 MCSectionELF::SHT_NOBITS, 351 MCSectionELF::SHF_WRITE | 352 MCSectionELF::SHF_ALLOC, 353 SectionKind::getBSS()); 354 Symbol->setSection(*Section); 355 356 struct LocalCommon L = {&SD, Size, ByteAlignment}; 357 LocalCommons.push_back(L); 358 } else { 359 SD.setCommon(Size, ByteAlignment); 360 } 361 362 SD.setSize(MCConstantExpr::Create(Size, getContext())); 363} 364 365void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 366 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 367 // MCObjectStreamer. 368 getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 369} 370 371void MCELFStreamer::EmitValue(const MCExpr *Value, unsigned Size, 372 unsigned AddrSpace) { 373 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 374 // MCObjectStreamer. 375 MCDataFragment *DF = getOrCreateDataFragment(); 376 377 // Avoid fixups when possible. 378 int64_t AbsValue; 379 if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) { 380 // FIXME: Endianness assumption. 381 for (unsigned i = 0; i != Size; ++i) 382 DF->getContents().push_back(uint8_t(AbsValue >> (i * 8))); 383 } else { 384 DF->addFixup(MCFixup::Create(DF->getContents().size(), AddValueSymbols(Value), 385 MCFixup::getKindForSize(Size, false))); 386 DF->getContents().resize(DF->getContents().size() + Size, 0); 387 } 388} 389 390void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, 391 int64_t Value, unsigned ValueSize, 392 unsigned MaxBytesToEmit) { 393 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 394 // MCObjectStreamer. 395 if (MaxBytesToEmit == 0) 396 MaxBytesToEmit = ByteAlignment; 397 new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 398 getCurrentSectionData()); 399 400 // Update the maximum alignment on the current section if necessary. 401 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 402 getCurrentSectionData()->setAlignment(ByteAlignment); 403} 404 405void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment, 406 unsigned MaxBytesToEmit) { 407 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 408 // MCObjectStreamer. 409 if (MaxBytesToEmit == 0) 410 MaxBytesToEmit = ByteAlignment; 411 MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, 412 getCurrentSectionData()); 413 F->setEmitNops(true); 414 415 // Update the maximum alignment on the current section if necessary. 416 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 417 getCurrentSectionData()->setAlignment(ByteAlignment); 418} 419 420void MCELFStreamer::EmitValueToOffset(const MCExpr *Offset, 421 unsigned char Value) { 422 // TODO: This is exactly the same as MCMachOStreamer. Consider merging into 423 // MCObjectStreamer. 424 new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 425} 426 427// Add a symbol for the file name of this module. This is the second 428// entry in the module's symbol table (the first being the null symbol). 429void MCELFStreamer::EmitFileDirective(StringRef Filename) { 430 MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); 431 Symbol->setSection(*CurSection); 432 Symbol->setAbsolute(); 433 434 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 435 436 SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); 437} 438 439void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { 440 switch (expr->getKind()) { 441 case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!"); 442 case MCExpr::Constant: 443 break; 444 445 case MCExpr::Binary: { 446 const MCBinaryExpr *be = cast<MCBinaryExpr>(expr); 447 fixSymbolsInTLSFixups(be->getLHS()); 448 fixSymbolsInTLSFixups(be->getRHS()); 449 break; 450 } 451 452 case MCExpr::SymbolRef: { 453 const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr); 454 switch (symRef.getKind()) { 455 default: 456 return; 457 case MCSymbolRefExpr::VK_NTPOFF: 458 case MCSymbolRefExpr::VK_GOTNTPOFF: 459 case MCSymbolRefExpr::VK_TLSGD: 460 case MCSymbolRefExpr::VK_TLSLDM: 461 case MCSymbolRefExpr::VK_TPOFF: 462 case MCSymbolRefExpr::VK_DTPOFF: 463 case MCSymbolRefExpr::VK_GOTTPOFF: 464 case MCSymbolRefExpr::VK_TLSLD: 465 case MCSymbolRefExpr::VK_ARM_TLSGD: 466 break; 467 } 468 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol()); 469 SetType(SD, ELF::STT_TLS); 470 break; 471 } 472 473 case MCExpr::Unary: 474 fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr()); 475 break; 476 } 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 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) 493 fixSymbolsInTLSFixups(Fixups[i].getValue()); 494 495 IF->getCode() = Code; 496 IF->getFixups() = Fixups; 497} 498 499void MCELFStreamer::EmitInstToData(const MCInst &Inst) { 500 MCDataFragment *DF = getOrCreateDataFragment(); 501 502 SmallVector<MCFixup, 4> Fixups; 503 SmallString<256> Code; 504 raw_svector_ostream VecOS(Code); 505 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 506 VecOS.flush(); 507 508 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) 509 fixSymbolsInTLSFixups(Fixups[i].getValue()); 510 511 // Add the fixups and data. 512 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 513 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 514 DF->addFixup(Fixups[i]); 515 } 516 DF->getContents().append(Code.begin(), Code.end()); 517} 518 519void MCELFStreamer::Finish() { 520 // FIXME: duplicated code with the MachO streamer. 521 // Dump out the dwarf file & directory tables and line tables. 522 if (getContext().hasDwarfFiles()) { 523 const MCSection *DwarfLineSection = 524 getContext().getELFSection(".debug_line", 0, 0, 525 SectionKind::getDataRelLocal()); 526 MCSectionData &DLS = 527 getAssembler().getOrCreateSectionData(*DwarfLineSection); 528 int PointerSize = getAssembler().getBackend().getPointerSize(); 529 MCDwarfFileTable::Emit(this, DwarfLineSection, &DLS, PointerSize); 530 } 531 532 for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), 533 e = LocalCommons.end(); 534 i != e; ++i) { 535 MCSymbolData *SD = i->SD; 536 uint64_t Size = i->Size; 537 unsigned ByteAlignment = i->ByteAlignment; 538 const MCSymbol &Symbol = SD->getSymbol(); 539 const MCSection &Section = Symbol.getSection(); 540 541 MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section); 542 new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData); 543 544 MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); 545 SD->setFragment(F); 546 547 // Update the maximum alignment of the section if necessary. 548 if (ByteAlignment > SectData.getAlignment()) 549 SectData.setAlignment(ByteAlignment); 550 } 551 552 this->MCObjectStreamer::Finish(); 553} 554 555MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB, 556 raw_ostream &OS, MCCodeEmitter *CE, 557 bool RelaxAll) { 558 MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE); 559 if (RelaxAll) 560 S->getAssembler().setRelaxAll(true); 561 return S; 562} 563