MCAssembler.cpp revision 0bcf074867d4d366f7988a219c7a53265fcb4f23
1//===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===// 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#define DEBUG_TYPE "assembler" 11#include "llvm/MC/MCAssembler.h" 12#include "llvm/MC/MCExpr.h" 13#include "llvm/MC/MCSectionMachO.h" 14#include "llvm/MC/MCSymbol.h" 15#include "llvm/MC/MCValue.h" 16#include "llvm/ADT/DenseMap.h" 17#include "llvm/ADT/SmallString.h" 18#include "llvm/ADT/Statistic.h" 19#include "llvm/ADT/StringExtras.h" 20#include "llvm/ADT/StringMap.h" 21#include "llvm/ADT/Twine.h" 22#include "llvm/Support/ErrorHandling.h" 23#include "llvm/Support/MachO.h" 24#include "llvm/Support/raw_ostream.h" 25#include "llvm/Support/Debug.h" 26#include <vector> 27using namespace llvm; 28 29class MachObjectWriter; 30 31STATISTIC(EmittedFragments, "Number of emitted assembler fragments"); 32 33// FIXME FIXME FIXME: There are number of places in this file where we convert 34// what is a 64-bit assembler value used for computation into a value in the 35// object file, which may truncate it. We should detect that truncation where 36// invalid and report errors back. 37 38static void WriteFileData(raw_ostream &OS, const MCSectionData &SD, 39 MachObjectWriter &MOW); 40 41/// isVirtualSection - Check if this is a section which does not actually exist 42/// in the object file. 43static bool isVirtualSection(const MCSection &Section) { 44 // FIXME: Lame. 45 const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 46 unsigned Type = SMO.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE; 47 return (Type == MCSectionMachO::S_ZEROFILL); 48} 49 50class MachObjectWriter { 51 // See <mach-o/loader.h>. 52 enum { 53 Header_Magic32 = 0xFEEDFACE, 54 Header_Magic64 = 0xFEEDFACF 55 }; 56 57 static const unsigned Header32Size = 28; 58 static const unsigned Header64Size = 32; 59 static const unsigned SegmentLoadCommand32Size = 56; 60 static const unsigned Section32Size = 68; 61 static const unsigned SymtabLoadCommandSize = 24; 62 static const unsigned DysymtabLoadCommandSize = 80; 63 static const unsigned Nlist32Size = 12; 64 static const unsigned RelocationInfoSize = 8; 65 66 enum HeaderFileType { 67 HFT_Object = 0x1 68 }; 69 70 enum HeaderFlags { 71 HF_SubsectionsViaSymbols = 0x2000 72 }; 73 74 enum LoadCommandType { 75 LCT_Segment = 0x1, 76 LCT_Symtab = 0x2, 77 LCT_Dysymtab = 0xb 78 }; 79 80 // See <mach-o/nlist.h>. 81 enum SymbolTypeType { 82 STT_Undefined = 0x00, 83 STT_Absolute = 0x02, 84 STT_Section = 0x0e 85 }; 86 87 enum SymbolTypeFlags { 88 // If any of these bits are set, then the entry is a stab entry number (see 89 // <mach-o/stab.h>. Otherwise the other masks apply. 90 STF_StabsEntryMask = 0xe0, 91 92 STF_TypeMask = 0x0e, 93 STF_External = 0x01, 94 STF_PrivateExtern = 0x10 95 }; 96 97 /// IndirectSymbolFlags - Flags for encoding special values in the indirect 98 /// symbol entry. 99 enum IndirectSymbolFlags { 100 ISF_Local = 0x80000000, 101 ISF_Absolute = 0x40000000 102 }; 103 104 /// RelocationFlags - Special flags for addresses. 105 enum RelocationFlags { 106 RF_Scattered = 0x80000000 107 }; 108 109 enum RelocationInfoType { 110 RIT_Vanilla = 0, 111 RIT_Pair = 1, 112 RIT_Difference = 2, 113 RIT_PreboundLazyPointer = 3, 114 RIT_LocalDifference = 4 115 }; 116 117 /// MachSymbolData - Helper struct for containing some precomputed information 118 /// on symbols. 119 struct MachSymbolData { 120 MCSymbolData *SymbolData; 121 uint64_t StringIndex; 122 uint8_t SectionIndex; 123 124 // Support lexicographic sorting. 125 bool operator<(const MachSymbolData &RHS) const { 126 const std::string &Name = SymbolData->getSymbol().getName(); 127 return Name < RHS.SymbolData->getSymbol().getName(); 128 } 129 }; 130 131 raw_ostream &OS; 132 bool IsLSB; 133 134public: 135 MachObjectWriter(raw_ostream &_OS, bool _IsLSB = true) 136 : OS(_OS), IsLSB(_IsLSB) { 137 } 138 139 /// @name Helper Methods 140 /// @{ 141 142 void Write8(uint8_t Value) { 143 OS << char(Value); 144 } 145 146 void Write16(uint16_t Value) { 147 if (IsLSB) { 148 Write8(uint8_t(Value >> 0)); 149 Write8(uint8_t(Value >> 8)); 150 } else { 151 Write8(uint8_t(Value >> 8)); 152 Write8(uint8_t(Value >> 0)); 153 } 154 } 155 156 void Write32(uint32_t Value) { 157 if (IsLSB) { 158 Write16(uint16_t(Value >> 0)); 159 Write16(uint16_t(Value >> 16)); 160 } else { 161 Write16(uint16_t(Value >> 16)); 162 Write16(uint16_t(Value >> 0)); 163 } 164 } 165 166 void Write64(uint64_t Value) { 167 if (IsLSB) { 168 Write32(uint32_t(Value >> 0)); 169 Write32(uint32_t(Value >> 32)); 170 } else { 171 Write32(uint32_t(Value >> 32)); 172 Write32(uint32_t(Value >> 0)); 173 } 174 } 175 176 void WriteZeros(unsigned N) { 177 const char Zeros[16] = { 0 }; 178 179 for (unsigned i = 0, e = N / 16; i != e; ++i) 180 OS << StringRef(Zeros, 16); 181 182 OS << StringRef(Zeros, N % 16); 183 } 184 185 void WriteString(StringRef Str, unsigned ZeroFillSize = 0) { 186 OS << Str; 187 if (ZeroFillSize) 188 WriteZeros(ZeroFillSize - Str.size()); 189 } 190 191 /// @} 192 193 void WriteHeader32(unsigned NumLoadCommands, unsigned LoadCommandsSize, 194 bool SubsectionsViaSymbols) { 195 uint32_t Flags = 0; 196 197 if (SubsectionsViaSymbols) 198 Flags |= HF_SubsectionsViaSymbols; 199 200 // struct mach_header (28 bytes) 201 202 uint64_t Start = OS.tell(); 203 (void) Start; 204 205 Write32(Header_Magic32); 206 207 // FIXME: Support cputype. 208 Write32(MachO::CPUTypeI386); 209 // FIXME: Support cpusubtype. 210 Write32(MachO::CPUSubType_I386_ALL); 211 Write32(HFT_Object); 212 Write32(NumLoadCommands); // Object files have a single load command, the 213 // segment. 214 Write32(LoadCommandsSize); 215 Write32(Flags); 216 217 assert(OS.tell() - Start == Header32Size); 218 } 219 220 /// WriteSegmentLoadCommand32 - Write a 32-bit segment load command. 221 /// 222 /// \arg NumSections - The number of sections in this segment. 223 /// \arg SectionDataSize - The total size of the sections. 224 void WriteSegmentLoadCommand32(unsigned NumSections, 225 uint64_t VMSize, 226 uint64_t SectionDataStartOffset, 227 uint64_t SectionDataSize) { 228 // struct segment_command (56 bytes) 229 230 uint64_t Start = OS.tell(); 231 (void) Start; 232 233 Write32(LCT_Segment); 234 Write32(SegmentLoadCommand32Size + NumSections * Section32Size); 235 236 WriteString("", 16); 237 Write32(0); // vmaddr 238 Write32(VMSize); // vmsize 239 Write32(SectionDataStartOffset); // file offset 240 Write32(SectionDataSize); // file size 241 Write32(0x7); // maxprot 242 Write32(0x7); // initprot 243 Write32(NumSections); 244 Write32(0); // flags 245 246 assert(OS.tell() - Start == SegmentLoadCommand32Size); 247 } 248 249 void WriteSection32(const MCSectionData &SD, uint64_t FileOffset, 250 uint64_t RelocationsStart, unsigned NumRelocations) { 251 // The offset is unused for virtual sections. 252 if (isVirtualSection(SD.getSection())) { 253 assert(SD.getFileSize() == 0 && "Invalid file size!"); 254 FileOffset = 0; 255 } 256 257 // struct section (68 bytes) 258 259 uint64_t Start = OS.tell(); 260 (void) Start; 261 262 // FIXME: cast<> support! 263 const MCSectionMachO &Section = 264 static_cast<const MCSectionMachO&>(SD.getSection()); 265 WriteString(Section.getSectionName(), 16); 266 WriteString(Section.getSegmentName(), 16); 267 Write32(SD.getAddress()); // address 268 Write32(SD.getSize()); // size 269 Write32(FileOffset); 270 271 unsigned Flags = Section.getTypeAndAttributes(); 272 if (SD.hasInstructions()) 273 Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS; 274 275 assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); 276 Write32(Log2_32(SD.getAlignment())); 277 Write32(NumRelocations ? RelocationsStart : 0); 278 Write32(NumRelocations); 279 Write32(Flags); 280 Write32(0); // reserved1 281 Write32(Section.getStubSize()); // reserved2 282 283 assert(OS.tell() - Start == Section32Size); 284 } 285 286 void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, 287 uint32_t StringTableOffset, 288 uint32_t StringTableSize) { 289 // struct symtab_command (24 bytes) 290 291 uint64_t Start = OS.tell(); 292 (void) Start; 293 294 Write32(LCT_Symtab); 295 Write32(SymtabLoadCommandSize); 296 Write32(SymbolOffset); 297 Write32(NumSymbols); 298 Write32(StringTableOffset); 299 Write32(StringTableSize); 300 301 assert(OS.tell() - Start == SymtabLoadCommandSize); 302 } 303 304 void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, 305 uint32_t NumLocalSymbols, 306 uint32_t FirstExternalSymbol, 307 uint32_t NumExternalSymbols, 308 uint32_t FirstUndefinedSymbol, 309 uint32_t NumUndefinedSymbols, 310 uint32_t IndirectSymbolOffset, 311 uint32_t NumIndirectSymbols) { 312 // struct dysymtab_command (80 bytes) 313 314 uint64_t Start = OS.tell(); 315 (void) Start; 316 317 Write32(LCT_Dysymtab); 318 Write32(DysymtabLoadCommandSize); 319 Write32(FirstLocalSymbol); 320 Write32(NumLocalSymbols); 321 Write32(FirstExternalSymbol); 322 Write32(NumExternalSymbols); 323 Write32(FirstUndefinedSymbol); 324 Write32(NumUndefinedSymbols); 325 Write32(0); // tocoff 326 Write32(0); // ntoc 327 Write32(0); // modtaboff 328 Write32(0); // nmodtab 329 Write32(0); // extrefsymoff 330 Write32(0); // nextrefsyms 331 Write32(IndirectSymbolOffset); 332 Write32(NumIndirectSymbols); 333 Write32(0); // extreloff 334 Write32(0); // nextrel 335 Write32(0); // locreloff 336 Write32(0); // nlocrel 337 338 assert(OS.tell() - Start == DysymtabLoadCommandSize); 339 } 340 341 void WriteNlist32(MachSymbolData &MSD) { 342 MCSymbolData &Data = *MSD.SymbolData; 343 const MCSymbol &Symbol = Data.getSymbol(); 344 uint8_t Type = 0; 345 uint16_t Flags = Data.getFlags(); 346 uint32_t Address = 0; 347 348 // Set the N_TYPE bits. See <mach-o/nlist.h>. 349 // 350 // FIXME: Are the prebound or indirect fields possible here? 351 if (Symbol.isUndefined()) 352 Type = STT_Undefined; 353 else if (Symbol.isAbsolute()) 354 Type = STT_Absolute; 355 else 356 Type = STT_Section; 357 358 // FIXME: Set STAB bits. 359 360 if (Data.isPrivateExtern()) 361 Type |= STF_PrivateExtern; 362 363 // Set external bit. 364 if (Data.isExternal() || Symbol.isUndefined()) 365 Type |= STF_External; 366 367 // Compute the symbol address. 368 if (Symbol.isDefined()) { 369 if (Symbol.isAbsolute()) { 370 llvm_unreachable("FIXME: Not yet implemented!"); 371 } else { 372 Address = Data.getFragment()->getAddress() + Data.getOffset(); 373 } 374 } else if (Data.isCommon()) { 375 // Common symbols are encoded with the size in the address 376 // field, and their alignment in the flags. 377 Address = Data.getCommonSize(); 378 379 // Common alignment is packed into the 'desc' bits. 380 if (unsigned Align = Data.getCommonAlignment()) { 381 unsigned Log2Size = Log2_32(Align); 382 assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); 383 if (Log2Size > 15) 384 llvm_report_error("invalid 'common' alignment '" + 385 Twine(Align) + "'"); 386 // FIXME: Keep this mask with the SymbolFlags enumeration. 387 Flags = (Flags & 0xF0FF) | (Log2Size << 8); 388 } 389 } 390 391 // struct nlist (12 bytes) 392 393 Write32(MSD.StringIndex); 394 Write8(Type); 395 Write8(MSD.SectionIndex); 396 397 // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' 398 // value. 399 Write16(Flags); 400 Write32(Address); 401 } 402 403 struct MachRelocationEntry { 404 uint32_t Word0; 405 uint32_t Word1; 406 }; 407 void ComputeScatteredRelocationInfo(MCAssembler &Asm, MCFragment &Fragment, 408 MCAsmFixup &Fixup, 409 const MCValue &Target, 410 DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap, 411 std::vector<MachRelocationEntry> &Relocs) { 412 uint32_t Address = Fragment.getOffset() + Fixup.Offset; 413 unsigned IsPCRel = 0; 414 unsigned Type = RIT_Vanilla; 415 416 // See <reloc.h>. 417 const MCSymbol *A = Target.getSymA(); 418 MCSymbolData *SD = SymbolMap.lookup(A); 419 uint32_t Value = SD->getFragment()->getAddress() + SD->getOffset(); 420 uint32_t Value2 = 0; 421 422 if (const MCSymbol *B = Target.getSymB()) { 423 Type = RIT_LocalDifference; 424 425 MCSymbolData *SD = SymbolMap.lookup(B); 426 Value2 = SD->getFragment()->getAddress() + SD->getOffset(); 427 } 428 429 unsigned Log2Size = Log2_32(Fixup.Size); 430 assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!"); 431 432 // The value which goes in the fixup is current value of the expression. 433 Fixup.FixedValue = Value - Value2 + Target.getConstant(); 434 435 MachRelocationEntry MRE; 436 MRE.Word0 = ((Address << 0) | 437 (Type << 24) | 438 (Log2Size << 28) | 439 (IsPCRel << 30) | 440 RF_Scattered); 441 MRE.Word1 = Value; 442 Relocs.push_back(MRE); 443 444 if (Type == RIT_LocalDifference) { 445 Type = RIT_Pair; 446 447 MachRelocationEntry MRE; 448 MRE.Word0 = ((0 << 0) | 449 (Type << 24) | 450 (Log2Size << 28) | 451 (0 << 30) | 452 RF_Scattered); 453 MRE.Word1 = Value2; 454 Relocs.push_back(MRE); 455 } 456 } 457 458 void ComputeRelocationInfo(MCAssembler &Asm, MCDataFragment &Fragment, 459 MCAsmFixup &Fixup, 460 DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap, 461 std::vector<MachRelocationEntry> &Relocs) { 462 MCValue Target; 463 if (!Fixup.Value->EvaluateAsRelocatable(Target)) 464 llvm_report_error("expected relocatable expression"); 465 466 // If this is a difference or a local symbol plus an offset, then we need a 467 // scattered relocation entry. 468 if (Target.getSymB() || 469 (Target.getSymA() && !Target.getSymA()->isUndefined() && 470 Target.getConstant())) 471 return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target, 472 SymbolMap, Relocs); 473 474 // See <reloc.h>. 475 uint32_t Address = Fragment.getOffset() + Fixup.Offset; 476 uint32_t Value = 0; 477 unsigned Index = 0; 478 unsigned IsPCRel = 0; 479 unsigned IsExtern = 0; 480 unsigned Type = 0; 481 482 if (Target.isAbsolute()) { // constant 483 // SymbolNum of 0 indicates the absolute section. 484 // 485 // FIXME: When is this generated? 486 Type = RIT_Vanilla; 487 Value = 0; 488 llvm_unreachable("FIXME: Not yet implemented!"); 489 } else { 490 const MCSymbol *Symbol = Target.getSymA(); 491 MCSymbolData *SD = SymbolMap.lookup(Symbol); 492 493 if (Symbol->isUndefined()) { 494 IsExtern = 1; 495 Index = SD->getIndex(); 496 Value = 0; 497 } else { 498 // The index is the section ordinal. 499 // 500 // FIXME: O(N) 501 Index = 1; 502 for (MCAssembler::iterator it = Asm.begin(), 503 ie = Asm.end(); it != ie; ++it, ++Index) 504 if (&*it == SD->getFragment()->getParent()) 505 break; 506 Value = SD->getFragment()->getAddress() + SD->getOffset(); 507 } 508 509 Type = RIT_Vanilla; 510 } 511 512 // The value which goes in the fixup is current value of the expression. 513 Fixup.FixedValue = Value + Target.getConstant(); 514 515 unsigned Log2Size = Log2_32(Fixup.Size); 516 assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!"); 517 518 // struct relocation_info (8 bytes) 519 MachRelocationEntry MRE; 520 MRE.Word0 = Address; 521 MRE.Word1 = ((Index << 0) | 522 (IsPCRel << 24) | 523 (Log2Size << 25) | 524 (IsExtern << 27) | 525 (Type << 28)); 526 Relocs.push_back(MRE); 527 } 528 529 void BindIndirectSymbols(MCAssembler &Asm, 530 DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap) { 531 // This is the point where 'as' creates actual symbols for indirect symbols 532 // (in the following two passes). It would be easier for us to do this 533 // sooner when we see the attribute, but that makes getting the order in the 534 // symbol table much more complicated than it is worth. 535 // 536 // FIXME: Revisit this when the dust settles. 537 538 // Bind non lazy symbol pointers first. 539 for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 540 ie = Asm.indirect_symbol_end(); it != ie; ++it) { 541 // FIXME: cast<> support! 542 const MCSectionMachO &Section = 543 static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 544 545 unsigned Type = 546 Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE; 547 if (Type != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) 548 continue; 549 550 MCSymbolData *&Entry = SymbolMap[it->Symbol]; 551 if (!Entry) 552 Entry = new MCSymbolData(*it->Symbol, 0, 0, &Asm); 553 } 554 555 // Then lazy symbol pointers and symbol stubs. 556 for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 557 ie = Asm.indirect_symbol_end(); it != ie; ++it) { 558 // FIXME: cast<> support! 559 const MCSectionMachO &Section = 560 static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 561 562 unsigned Type = 563 Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE; 564 if (Type != MCSectionMachO::S_LAZY_SYMBOL_POINTERS && 565 Type != MCSectionMachO::S_SYMBOL_STUBS) 566 continue; 567 568 MCSymbolData *&Entry = SymbolMap[it->Symbol]; 569 if (!Entry) { 570 Entry = new MCSymbolData(*it->Symbol, 0, 0, &Asm); 571 572 // Set the symbol type to undefined lazy, but only on construction. 573 // 574 // FIXME: Do not hardcode. 575 Entry->setFlags(Entry->getFlags() | 0x0001); 576 } 577 } 578 } 579 580 /// ComputeSymbolTable - Compute the symbol table data 581 /// 582 /// \param StringTable [out] - The string table data. 583 /// \param StringIndexMap [out] - Map from symbol names to offsets in the 584 /// string table. 585 void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, 586 std::vector<MachSymbolData> &LocalSymbolData, 587 std::vector<MachSymbolData> &ExternalSymbolData, 588 std::vector<MachSymbolData> &UndefinedSymbolData) { 589 // Build section lookup table. 590 DenseMap<const MCSection*, uint8_t> SectionIndexMap; 591 unsigned Index = 1; 592 for (MCAssembler::iterator it = Asm.begin(), 593 ie = Asm.end(); it != ie; ++it, ++Index) 594 SectionIndexMap[&it->getSection()] = Index; 595 assert(Index <= 256 && "Too many sections!"); 596 597 // Index 0 is always the empty string. 598 StringMap<uint64_t> StringIndexMap; 599 StringTable += '\x00'; 600 601 // Build the symbol arrays and the string table, but only for non-local 602 // symbols. 603 // 604 // The particular order that we collect the symbols and create the string 605 // table, then sort the symbols is chosen to match 'as'. Even though it 606 // doesn't matter for correctness, this is important for letting us diff .o 607 // files. 608 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 609 ie = Asm.symbol_end(); it != ie; ++it) { 610 const MCSymbol &Symbol = it->getSymbol(); 611 612 // Ignore assembler temporaries. 613 if (it->getSymbol().isTemporary()) 614 continue; 615 616 if (!it->isExternal() && !Symbol.isUndefined()) 617 continue; 618 619 uint64_t &Entry = StringIndexMap[Symbol.getName()]; 620 if (!Entry) { 621 Entry = StringTable.size(); 622 StringTable += Symbol.getName(); 623 StringTable += '\x00'; 624 } 625 626 MachSymbolData MSD; 627 MSD.SymbolData = it; 628 MSD.StringIndex = Entry; 629 630 if (Symbol.isUndefined()) { 631 MSD.SectionIndex = 0; 632 UndefinedSymbolData.push_back(MSD); 633 } else if (Symbol.isAbsolute()) { 634 MSD.SectionIndex = 0; 635 ExternalSymbolData.push_back(MSD); 636 } else { 637 MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 638 assert(MSD.SectionIndex && "Invalid section index!"); 639 ExternalSymbolData.push_back(MSD); 640 } 641 } 642 643 // Now add the data for local symbols. 644 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 645 ie = Asm.symbol_end(); it != ie; ++it) { 646 const MCSymbol &Symbol = it->getSymbol(); 647 648 // Ignore assembler temporaries. 649 if (it->getSymbol().isTemporary()) 650 continue; 651 652 if (it->isExternal() || Symbol.isUndefined()) 653 continue; 654 655 uint64_t &Entry = StringIndexMap[Symbol.getName()]; 656 if (!Entry) { 657 Entry = StringTable.size(); 658 StringTable += Symbol.getName(); 659 StringTable += '\x00'; 660 } 661 662 MachSymbolData MSD; 663 MSD.SymbolData = it; 664 MSD.StringIndex = Entry; 665 666 if (Symbol.isAbsolute()) { 667 MSD.SectionIndex = 0; 668 LocalSymbolData.push_back(MSD); 669 } else { 670 MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 671 assert(MSD.SectionIndex && "Invalid section index!"); 672 LocalSymbolData.push_back(MSD); 673 } 674 } 675 676 // External and undefined symbols are required to be in lexicographic order. 677 std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 678 std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 679 680 // Set the symbol indices. 681 Index = 0; 682 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 683 LocalSymbolData[i].SymbolData->setIndex(Index++); 684 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 685 ExternalSymbolData[i].SymbolData->setIndex(Index++); 686 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 687 UndefinedSymbolData[i].SymbolData->setIndex(Index++); 688 689 // The string table is padded to a multiple of 4. 690 while (StringTable.size() % 4) 691 StringTable += '\x00'; 692 } 693 694 void WriteObject(MCAssembler &Asm) { 695 unsigned NumSections = Asm.size(); 696 697 // Compute the symbol -> symbol data map. 698 // 699 // FIXME: This should not be here. 700 DenseMap<const MCSymbol*, MCSymbolData *> SymbolMap; 701 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 702 ie = Asm.symbol_end(); it != ie; ++it) 703 SymbolMap[&it->getSymbol()] = it; 704 705 // Create symbol data for any indirect symbols. 706 BindIndirectSymbols(Asm, SymbolMap); 707 708 // Compute symbol table information. 709 SmallString<256> StringTable; 710 std::vector<MachSymbolData> LocalSymbolData; 711 std::vector<MachSymbolData> ExternalSymbolData; 712 std::vector<MachSymbolData> UndefinedSymbolData; 713 unsigned NumSymbols = Asm.symbol_size(); 714 715 // No symbol table command is written if there are no symbols. 716 if (NumSymbols) 717 ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData, 718 UndefinedSymbolData); 719 720 // The section data starts after the header, the segment load command (and 721 // section headers) and the symbol table. 722 unsigned NumLoadCommands = 1; 723 uint64_t LoadCommandsSize = 724 SegmentLoadCommand32Size + NumSections * Section32Size; 725 726 // Add the symbol table load command sizes, if used. 727 if (NumSymbols) { 728 NumLoadCommands += 2; 729 LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize; 730 } 731 732 // Compute the total size of the section data, as well as its file size and 733 // vm size. 734 uint64_t SectionDataStart = Header32Size + LoadCommandsSize; 735 uint64_t SectionDataSize = 0; 736 uint64_t SectionDataFileSize = 0; 737 uint64_t VMSize = 0; 738 for (MCAssembler::iterator it = Asm.begin(), 739 ie = Asm.end(); it != ie; ++it) { 740 MCSectionData &SD = *it; 741 742 VMSize = std::max(VMSize, SD.getAddress() + SD.getSize()); 743 744 if (isVirtualSection(SD.getSection())) 745 continue; 746 747 SectionDataSize = std::max(SectionDataSize, 748 SD.getAddress() + SD.getSize()); 749 SectionDataFileSize = std::max(SectionDataFileSize, 750 SD.getAddress() + SD.getFileSize()); 751 } 752 753 // The section data is padded to 4 bytes. 754 // 755 // FIXME: Is this machine dependent? 756 unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4); 757 SectionDataFileSize += SectionDataPadding; 758 759 // Write the prolog, starting with the header and load command... 760 WriteHeader32(NumLoadCommands, LoadCommandsSize, 761 Asm.getSubsectionsViaSymbols()); 762 WriteSegmentLoadCommand32(NumSections, VMSize, 763 SectionDataStart, SectionDataSize); 764 765 // ... and then the section headers. 766 // 767 // We also compute the section relocations while we do this. Note that 768 // computing relocation info will also update the fixup to have the correct 769 // value; this will overwrite the appropriate data in the fragment when it 770 // is written. 771 std::vector<MachRelocationEntry> RelocInfos; 772 uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; 773 for (MCAssembler::iterator it = Asm.begin(), 774 ie = Asm.end(); it != ie; ++it) { 775 MCSectionData &SD = *it; 776 777 // The assembler writes relocations in the reverse order they were seen. 778 // 779 // FIXME: It is probably more complicated than this. 780 unsigned NumRelocsStart = RelocInfos.size(); 781 for (MCSectionData::reverse_iterator it2 = SD.rbegin(), 782 ie2 = SD.rend(); it2 != ie2; ++it2) 783 if (MCDataFragment *DF = dyn_cast<MCDataFragment>(&*it2)) 784 for (unsigned i = 0, e = DF->fixup_size(); i != e; ++i) 785 ComputeRelocationInfo(Asm, *DF, DF->getFixups()[e - i - 1], 786 SymbolMap, RelocInfos); 787 788 unsigned NumRelocs = RelocInfos.size() - NumRelocsStart; 789 uint64_t SectionStart = SectionDataStart + SD.getAddress(); 790 WriteSection32(SD, SectionStart, RelocTableEnd, NumRelocs); 791 RelocTableEnd += NumRelocs * RelocationInfoSize; 792 } 793 794 // Write the symbol table load command, if used. 795 if (NumSymbols) { 796 unsigned FirstLocalSymbol = 0; 797 unsigned NumLocalSymbols = LocalSymbolData.size(); 798 unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols; 799 unsigned NumExternalSymbols = ExternalSymbolData.size(); 800 unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols; 801 unsigned NumUndefinedSymbols = UndefinedSymbolData.size(); 802 unsigned NumIndirectSymbols = Asm.indirect_symbol_size(); 803 unsigned NumSymTabSymbols = 804 NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols; 805 uint64_t IndirectSymbolSize = NumIndirectSymbols * 4; 806 uint64_t IndirectSymbolOffset = 0; 807 808 // If used, the indirect symbols are written after the section data. 809 if (NumIndirectSymbols) 810 IndirectSymbolOffset = RelocTableEnd; 811 812 // The symbol table is written after the indirect symbol data. 813 uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize; 814 815 // The string table is written after symbol table. 816 uint64_t StringTableOffset = 817 SymbolTableOffset + NumSymTabSymbols * Nlist32Size; 818 WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols, 819 StringTableOffset, StringTable.size()); 820 821 WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols, 822 FirstExternalSymbol, NumExternalSymbols, 823 FirstUndefinedSymbol, NumUndefinedSymbols, 824 IndirectSymbolOffset, NumIndirectSymbols); 825 } 826 827 // Write the actual section data. 828 for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) 829 WriteFileData(OS, *it, *this); 830 831 // Write the extra padding. 832 WriteZeros(SectionDataPadding); 833 834 // Write the relocation entries. 835 for (unsigned i = 0, e = RelocInfos.size(); i != e; ++i) { 836 Write32(RelocInfos[i].Word0); 837 Write32(RelocInfos[i].Word1); 838 } 839 840 // Write the symbol table data, if used. 841 if (NumSymbols) { 842 // Write the indirect symbol entries. 843 for (MCAssembler::indirect_symbol_iterator 844 it = Asm.indirect_symbol_begin(), 845 ie = Asm.indirect_symbol_end(); it != ie; ++it) { 846 // Indirect symbols in the non lazy symbol pointer section have some 847 // special handling. 848 const MCSectionMachO &Section = 849 static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 850 unsigned Type = 851 Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE; 852 if (Type == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) { 853 // If this symbol is defined and internal, mark it as such. 854 if (it->Symbol->isDefined() && 855 !SymbolMap.lookup(it->Symbol)->isExternal()) { 856 uint32_t Flags = ISF_Local; 857 if (it->Symbol->isAbsolute()) 858 Flags |= ISF_Absolute; 859 Write32(Flags); 860 continue; 861 } 862 } 863 864 Write32(SymbolMap[it->Symbol]->getIndex()); 865 } 866 867 // FIXME: Check that offsets match computed ones. 868 869 // Write the symbol table entries. 870 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 871 WriteNlist32(LocalSymbolData[i]); 872 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 873 WriteNlist32(ExternalSymbolData[i]); 874 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 875 WriteNlist32(UndefinedSymbolData[i]); 876 877 // Write the string table. 878 OS << StringTable.str(); 879 } 880 } 881 882 void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF) { 883 // FIXME: Endianness assumption. 884 for (unsigned i = 0; i != Fixup.Size; ++i) 885 DF.getContents()[Fixup.Offset + i] = uint8_t(Fixup.FixedValue >> (i * 8)); 886 } 887}; 888 889/* *** */ 890 891MCFragment::MCFragment() : Kind(FragmentType(~0)) { 892} 893 894MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) 895 : Kind(_Kind), 896 Parent(_Parent), 897 FileSize(~UINT64_C(0)) 898{ 899 if (Parent) 900 Parent->getFragmentList().push_back(this); 901} 902 903MCFragment::~MCFragment() { 904} 905 906uint64_t MCFragment::getAddress() const { 907 assert(getParent() && "Missing Section!"); 908 return getParent()->getAddress() + Offset; 909} 910 911/* *** */ 912 913MCSectionData::MCSectionData() : Section(0) {} 914 915MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) 916 : Section(&_Section), 917 Alignment(1), 918 Address(~UINT64_C(0)), 919 Size(~UINT64_C(0)), 920 FileSize(~UINT64_C(0)), 921 HasInstructions(false) 922{ 923 if (A) 924 A->getSectionList().push_back(this); 925} 926 927/* *** */ 928 929MCSymbolData::MCSymbolData() : Symbol(0) {} 930 931MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, 932 uint64_t _Offset, MCAssembler *A) 933 : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset), 934 IsExternal(false), IsPrivateExtern(false), 935 CommonSize(0), CommonAlign(0), Flags(0), Index(0) 936{ 937 if (A) 938 A->getSymbolList().push_back(this); 939} 940 941/* *** */ 942 943MCAssembler::MCAssembler(MCContext &_Context, raw_ostream &_OS) 944 : Context(_Context), OS(_OS), SubsectionsViaSymbols(false) 945{ 946} 947 948MCAssembler::~MCAssembler() { 949} 950 951void MCAssembler::LayoutSection(MCSectionData &SD) { 952 uint64_t Address = SD.getAddress(); 953 954 for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) { 955 MCFragment &F = *it; 956 957 F.setOffset(Address - SD.getAddress()); 958 959 // Evaluate fragment size. 960 switch (F.getKind()) { 961 case MCFragment::FT_Align: { 962 MCAlignFragment &AF = cast<MCAlignFragment>(F); 963 964 uint64_t Size = OffsetToAlignment(Address, AF.getAlignment()); 965 if (Size > AF.getMaxBytesToEmit()) 966 AF.setFileSize(0); 967 else 968 AF.setFileSize(Size); 969 break; 970 } 971 972 case MCFragment::FT_Data: 973 case MCFragment::FT_Fill: 974 F.setFileSize(F.getMaxFileSize()); 975 break; 976 977 case MCFragment::FT_Org: { 978 MCOrgFragment &OF = cast<MCOrgFragment>(F); 979 980 MCValue Target; 981 if (!OF.getOffset().EvaluateAsRelocatable(Target)) 982 llvm_report_error("expected relocatable expression"); 983 984 if (!Target.isAbsolute()) 985 llvm_unreachable("FIXME: Not yet implemented!"); 986 uint64_t OrgOffset = Target.getConstant(); 987 uint64_t Offset = Address - SD.getAddress(); 988 989 // FIXME: We need a way to communicate this error. 990 if (OrgOffset < Offset) 991 llvm_report_error("invalid .org offset '" + Twine(OrgOffset) + 992 "' (at offset '" + Twine(Offset) + "'"); 993 994 F.setFileSize(OrgOffset - Offset); 995 break; 996 } 997 998 case MCFragment::FT_ZeroFill: { 999 MCZeroFillFragment &ZFF = cast<MCZeroFillFragment>(F); 1000 1001 // Align the fragment offset; it is safe to adjust the offset freely since 1002 // this is only in virtual sections. 1003 uint64_t Aligned = RoundUpToAlignment(Address, ZFF.getAlignment()); 1004 F.setOffset(Aligned - SD.getAddress()); 1005 1006 // FIXME: This is misnamed. 1007 F.setFileSize(ZFF.getSize()); 1008 break; 1009 } 1010 } 1011 1012 Address += F.getFileSize(); 1013 } 1014 1015 // Set the section sizes. 1016 SD.setSize(Address - SD.getAddress()); 1017 if (isVirtualSection(SD.getSection())) 1018 SD.setFileSize(0); 1019 else 1020 SD.setFileSize(Address - SD.getAddress()); 1021} 1022 1023/// WriteFileData - Write the \arg F data to the output file. 1024static void WriteFileData(raw_ostream &OS, const MCFragment &F, 1025 MachObjectWriter &MOW) { 1026 uint64_t Start = OS.tell(); 1027 (void) Start; 1028 1029 ++EmittedFragments; 1030 1031 // FIXME: Embed in fragments instead? 1032 switch (F.getKind()) { 1033 case MCFragment::FT_Align: { 1034 MCAlignFragment &AF = cast<MCAlignFragment>(F); 1035 uint64_t Count = AF.getFileSize() / AF.getValueSize(); 1036 1037 // FIXME: This error shouldn't actually occur (the front end should emit 1038 // multiple .align directives to enforce the semantics it wants), but is 1039 // severe enough that we want to report it. How to handle this? 1040 if (Count * AF.getValueSize() != AF.getFileSize()) 1041 llvm_report_error("undefined .align directive, value size '" + 1042 Twine(AF.getValueSize()) + 1043 "' is not a divisor of padding size '" + 1044 Twine(AF.getFileSize()) + "'"); 1045 1046 for (uint64_t i = 0; i != Count; ++i) { 1047 switch (AF.getValueSize()) { 1048 default: 1049 assert(0 && "Invalid size!"); 1050 case 1: MOW.Write8 (uint8_t (AF.getValue())); break; 1051 case 2: MOW.Write16(uint16_t(AF.getValue())); break; 1052 case 4: MOW.Write32(uint32_t(AF.getValue())); break; 1053 case 8: MOW.Write64(uint64_t(AF.getValue())); break; 1054 } 1055 } 1056 break; 1057 } 1058 1059 case MCFragment::FT_Data: { 1060 MCDataFragment &DF = cast<MCDataFragment>(F); 1061 1062 // Apply the fixups. 1063 // 1064 // FIXME: Move elsewhere. 1065 for (MCDataFragment::const_fixup_iterator it = DF.fixup_begin(), 1066 ie = DF.fixup_end(); it != ie; ++it) 1067 MOW.ApplyFixup(*it, DF); 1068 1069 OS << cast<MCDataFragment>(F).getContents().str(); 1070 break; 1071 } 1072 1073 case MCFragment::FT_Fill: { 1074 MCFillFragment &FF = cast<MCFillFragment>(F); 1075 for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) { 1076 switch (FF.getValueSize()) { 1077 default: 1078 assert(0 && "Invalid size!"); 1079 case 1: MOW.Write8 (uint8_t (FF.getValue())); break; 1080 case 2: MOW.Write16(uint16_t(FF.getValue())); break; 1081 case 4: MOW.Write32(uint32_t(FF.getValue())); break; 1082 case 8: MOW.Write64(uint64_t(FF.getValue())); break; 1083 } 1084 } 1085 break; 1086 } 1087 1088 case MCFragment::FT_Org: { 1089 MCOrgFragment &OF = cast<MCOrgFragment>(F); 1090 1091 for (uint64_t i = 0, e = OF.getFileSize(); i != e; ++i) 1092 MOW.Write8(uint8_t(OF.getValue())); 1093 1094 break; 1095 } 1096 1097 case MCFragment::FT_ZeroFill: { 1098 assert(0 && "Invalid zero fill fragment in concrete section!"); 1099 break; 1100 } 1101 } 1102 1103 assert(OS.tell() - Start == F.getFileSize()); 1104} 1105 1106/// WriteFileData - Write the \arg SD data to the output file. 1107static void WriteFileData(raw_ostream &OS, const MCSectionData &SD, 1108 MachObjectWriter &MOW) { 1109 // Ignore virtual sections. 1110 if (isVirtualSection(SD.getSection())) { 1111 assert(SD.getFileSize() == 0); 1112 return; 1113 } 1114 1115 uint64_t Start = OS.tell(); 1116 (void) Start; 1117 1118 for (MCSectionData::const_iterator it = SD.begin(), 1119 ie = SD.end(); it != ie; ++it) 1120 WriteFileData(OS, *it, MOW); 1121 1122 // Add section padding. 1123 assert(SD.getFileSize() >= SD.getSize() && "Invalid section sizes!"); 1124 MOW.WriteZeros(SD.getFileSize() - SD.getSize()); 1125 1126 assert(OS.tell() - Start == SD.getFileSize()); 1127} 1128 1129void MCAssembler::Finish() { 1130 DEBUG_WITH_TYPE("mc-dump", { 1131 llvm::errs() << "assembler backend - pre-layout\n--\n"; 1132 dump(); }); 1133 1134 // Layout the concrete sections and fragments. 1135 uint64_t Address = 0; 1136 MCSectionData *Prev = 0; 1137 for (iterator it = begin(), ie = end(); it != ie; ++it) { 1138 MCSectionData &SD = *it; 1139 1140 // Skip virtual sections. 1141 if (isVirtualSection(SD.getSection())) 1142 continue; 1143 1144 // Align this section if necessary by adding padding bytes to the previous 1145 // section. 1146 if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment())) { 1147 assert(Prev && "Missing prev section!"); 1148 Prev->setFileSize(Prev->getFileSize() + Pad); 1149 Address += Pad; 1150 } 1151 1152 // Layout the section fragments and its size. 1153 SD.setAddress(Address); 1154 LayoutSection(SD); 1155 Address += SD.getFileSize(); 1156 1157 Prev = &SD; 1158 } 1159 1160 // Layout the virtual sections. 1161 for (iterator it = begin(), ie = end(); it != ie; ++it) { 1162 MCSectionData &SD = *it; 1163 1164 if (!isVirtualSection(SD.getSection())) 1165 continue; 1166 1167 SD.setAddress(Address); 1168 LayoutSection(SD); 1169 Address += SD.getSize(); 1170 } 1171 1172 DEBUG_WITH_TYPE("mc-dump", { 1173 llvm::errs() << "assembler backend - post-layout\n--\n"; 1174 dump(); }); 1175 1176 // Write the object file. 1177 MachObjectWriter MOW(OS); 1178 MOW.WriteObject(*this); 1179 1180 OS.flush(); 1181} 1182 1183 1184// Debugging methods 1185 1186namespace llvm { 1187 1188raw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) { 1189 OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << AF.Value 1190 << " Size:" << AF.Size << ">"; 1191 return OS; 1192} 1193 1194} 1195 1196void MCFragment::dump() { 1197 raw_ostream &OS = llvm::errs(); 1198 1199 OS << "<MCFragment " << (void*) this << " Offset:" << Offset 1200 << " FileSize:" << FileSize; 1201 1202 OS << ">"; 1203} 1204 1205void MCAlignFragment::dump() { 1206 raw_ostream &OS = llvm::errs(); 1207 1208 OS << "<MCAlignFragment "; 1209 this->MCFragment::dump(); 1210 OS << "\n "; 1211 OS << " Alignment:" << getAlignment() 1212 << " Value:" << getValue() << " ValueSize:" << getValueSize() 1213 << " MaxBytesToEmit:" << getMaxBytesToEmit() << ">"; 1214} 1215 1216void MCDataFragment::dump() { 1217 raw_ostream &OS = llvm::errs(); 1218 1219 OS << "<MCDataFragment "; 1220 this->MCFragment::dump(); 1221 OS << "\n "; 1222 OS << " Contents:["; 1223 for (unsigned i = 0, e = getContents().size(); i != e; ++i) { 1224 if (i) OS << ","; 1225 OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); 1226 } 1227 OS << "]"; 1228 1229 if (!getFixups().empty()) { 1230 OS << ",\n "; 1231 OS << " Fixups:["; 1232 for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) { 1233 if (it != fixup_begin()) OS << ",\n "; 1234 OS << *it; 1235 } 1236 OS << "]"; 1237 } 1238 1239 OS << ">"; 1240} 1241 1242void MCFillFragment::dump() { 1243 raw_ostream &OS = llvm::errs(); 1244 1245 OS << "<MCFillFragment "; 1246 this->MCFragment::dump(); 1247 OS << "\n "; 1248 OS << " Value:" << getValue() << " ValueSize:" << getValueSize() 1249 << " Count:" << getCount() << ">"; 1250} 1251 1252void MCOrgFragment::dump() { 1253 raw_ostream &OS = llvm::errs(); 1254 1255 OS << "<MCOrgFragment "; 1256 this->MCFragment::dump(); 1257 OS << "\n "; 1258 OS << " Offset:" << getOffset() << " Value:" << getValue() << ">"; 1259} 1260 1261void MCZeroFillFragment::dump() { 1262 raw_ostream &OS = llvm::errs(); 1263 1264 OS << "<MCZeroFillFragment "; 1265 this->MCFragment::dump(); 1266 OS << "\n "; 1267 OS << " Size:" << getSize() << " Alignment:" << getAlignment() << ">"; 1268} 1269 1270void MCSectionData::dump() { 1271 raw_ostream &OS = llvm::errs(); 1272 1273 OS << "<MCSectionData"; 1274 OS << " Alignment:" << getAlignment() << " Address:" << Address 1275 << " Size:" << Size << " FileSize:" << FileSize 1276 << " Fragments:["; 1277 for (iterator it = begin(), ie = end(); it != ie; ++it) { 1278 if (it != begin()) OS << ",\n "; 1279 it->dump(); 1280 } 1281 OS << "]>"; 1282} 1283 1284void MCSymbolData::dump() { 1285 raw_ostream &OS = llvm::errs(); 1286 1287 OS << "<MCSymbolData Symbol:" << getSymbol() 1288 << " Fragment:" << getFragment() << " Offset:" << getOffset() 1289 << " Flags:" << getFlags() << " Index:" << getIndex(); 1290 if (isCommon()) 1291 OS << " (common, size:" << getCommonSize() 1292 << " align: " << getCommonAlignment() << ")"; 1293 if (isExternal()) 1294 OS << " (external)"; 1295 if (isPrivateExtern()) 1296 OS << " (private extern)"; 1297 OS << ">"; 1298} 1299 1300void MCAssembler::dump() { 1301 raw_ostream &OS = llvm::errs(); 1302 1303 OS << "<MCAssembler\n"; 1304 OS << " Sections:["; 1305 for (iterator it = begin(), ie = end(); it != ie; ++it) { 1306 if (it != begin()) OS << ",\n "; 1307 it->dump(); 1308 } 1309 OS << "],\n"; 1310 OS << " Symbols:["; 1311 1312 for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { 1313 if (it != symbol_begin()) OS << ",\n "; 1314 it->dump(); 1315 } 1316 OS << "]>\n"; 1317} 1318