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