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