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