MachObjectWriter.cpp revision 212904
1//===- lib/MC/MachObjectWriter.cpp - Mach-O File Writer -------------------===// 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#include "llvm/MC/MachObjectWriter.h" 11#include "llvm/ADT/StringMap.h" 12#include "llvm/ADT/Twine.h" 13#include "llvm/MC/MCAssembler.h" 14#include "llvm/MC/MCAsmLayout.h" 15#include "llvm/MC/MCExpr.h" 16#include "llvm/MC/MCObjectWriter.h" 17#include "llvm/MC/MCSectionMachO.h" 18#include "llvm/MC/MCSymbol.h" 19#include "llvm/MC/MCMachOSymbolFlags.h" 20#include "llvm/MC/MCValue.h" 21#include "llvm/Support/ErrorHandling.h" 22#include "llvm/Support/MachO.h" 23#include "llvm/Target/TargetAsmBackend.h" 24 25// FIXME: Gross. 26#include "../Target/X86/X86FixupKinds.h" 27 28#include <vector> 29using namespace llvm; 30 31static unsigned getFixupKindLog2Size(unsigned Kind) { 32 switch (Kind) { 33 default: llvm_unreachable("invalid fixup kind!"); 34 case X86::reloc_pcrel_1byte: 35 case FK_Data_1: return 0; 36 case X86::reloc_pcrel_2byte: 37 case FK_Data_2: return 1; 38 case X86::reloc_pcrel_4byte: 39 case X86::reloc_riprel_4byte: 40 case X86::reloc_riprel_4byte_movq_load: 41 case FK_Data_4: return 2; 42 case FK_Data_8: return 3; 43 } 44} 45 46static bool isFixupKindPCRel(unsigned Kind) { 47 switch (Kind) { 48 default: 49 return false; 50 case X86::reloc_pcrel_1byte: 51 case X86::reloc_pcrel_2byte: 52 case X86::reloc_pcrel_4byte: 53 case X86::reloc_riprel_4byte: 54 case X86::reloc_riprel_4byte_movq_load: 55 return true; 56 } 57} 58 59static bool isFixupKindRIPRel(unsigned Kind) { 60 return Kind == X86::reloc_riprel_4byte || 61 Kind == X86::reloc_riprel_4byte_movq_load; 62} 63 64static bool doesSymbolRequireExternRelocation(MCSymbolData *SD) { 65 // Undefined symbols are always extern. 66 if (SD->Symbol->isUndefined()) 67 return true; 68 69 // References to weak definitions require external relocation entries; the 70 // definition may not always be the one in the same object file. 71 if (SD->getFlags() & SF_WeakDefinition) 72 return true; 73 74 // Otherwise, we can use an internal relocation. 75 return false; 76} 77 78namespace { 79 80class MachObjectWriterImpl { 81 // See <mach-o/loader.h>. 82 enum { 83 Header_Magic32 = 0xFEEDFACE, 84 Header_Magic64 = 0xFEEDFACF 85 }; 86 87 enum { 88 Header32Size = 28, 89 Header64Size = 32, 90 SegmentLoadCommand32Size = 56, 91 SegmentLoadCommand64Size = 72, 92 Section32Size = 68, 93 Section64Size = 80, 94 SymtabLoadCommandSize = 24, 95 DysymtabLoadCommandSize = 80, 96 Nlist32Size = 12, 97 Nlist64Size = 16, 98 RelocationInfoSize = 8 99 }; 100 101 enum HeaderFileType { 102 HFT_Object = 0x1 103 }; 104 105 enum HeaderFlags { 106 HF_SubsectionsViaSymbols = 0x2000 107 }; 108 109 enum LoadCommandType { 110 LCT_Segment = 0x1, 111 LCT_Symtab = 0x2, 112 LCT_Dysymtab = 0xb, 113 LCT_Segment64 = 0x19 114 }; 115 116 // See <mach-o/nlist.h>. 117 enum SymbolTypeType { 118 STT_Undefined = 0x00, 119 STT_Absolute = 0x02, 120 STT_Section = 0x0e 121 }; 122 123 enum SymbolTypeFlags { 124 // If any of these bits are set, then the entry is a stab entry number (see 125 // <mach-o/stab.h>. Otherwise the other masks apply. 126 STF_StabsEntryMask = 0xe0, 127 128 STF_TypeMask = 0x0e, 129 STF_External = 0x01, 130 STF_PrivateExtern = 0x10 131 }; 132 133 /// IndirectSymbolFlags - Flags for encoding special values in the indirect 134 /// symbol entry. 135 enum IndirectSymbolFlags { 136 ISF_Local = 0x80000000, 137 ISF_Absolute = 0x40000000 138 }; 139 140 /// RelocationFlags - Special flags for addresses. 141 enum RelocationFlags { 142 RF_Scattered = 0x80000000 143 }; 144 145 enum RelocationInfoType { 146 RIT_Vanilla = 0, 147 RIT_Pair = 1, 148 RIT_Difference = 2, 149 RIT_PreboundLazyPointer = 3, 150 RIT_LocalDifference = 4, 151 RIT_TLV = 5 152 }; 153 154 /// X86_64 uses its own relocation types. 155 enum RelocationInfoTypeX86_64 { 156 RIT_X86_64_Unsigned = 0, 157 RIT_X86_64_Signed = 1, 158 RIT_X86_64_Branch = 2, 159 RIT_X86_64_GOTLoad = 3, 160 RIT_X86_64_GOT = 4, 161 RIT_X86_64_Subtractor = 5, 162 RIT_X86_64_Signed1 = 6, 163 RIT_X86_64_Signed2 = 7, 164 RIT_X86_64_Signed4 = 8, 165 RIT_X86_64_TLV = 9 166 }; 167 168 /// MachSymbolData - Helper struct for containing some precomputed information 169 /// on symbols. 170 struct MachSymbolData { 171 MCSymbolData *SymbolData; 172 uint64_t StringIndex; 173 uint8_t SectionIndex; 174 175 // Support lexicographic sorting. 176 bool operator<(const MachSymbolData &RHS) const { 177 return SymbolData->getSymbol().getName() < 178 RHS.SymbolData->getSymbol().getName(); 179 } 180 }; 181 182 /// @name Relocation Data 183 /// @{ 184 185 struct MachRelocationEntry { 186 uint32_t Word0; 187 uint32_t Word1; 188 }; 189 190 llvm::DenseMap<const MCSectionData*, 191 std::vector<MachRelocationEntry> > Relocations; 192 llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase; 193 194 /// @} 195 /// @name Symbol Table Data 196 /// @{ 197 198 SmallString<256> StringTable; 199 std::vector<MachSymbolData> LocalSymbolData; 200 std::vector<MachSymbolData> ExternalSymbolData; 201 std::vector<MachSymbolData> UndefinedSymbolData; 202 203 /// @} 204 205 MachObjectWriter *Writer; 206 207 raw_ostream &OS; 208 209 unsigned Is64Bit : 1; 210 211public: 212 MachObjectWriterImpl(MachObjectWriter *_Writer, bool _Is64Bit) 213 : Writer(_Writer), OS(Writer->getStream()), Is64Bit(_Is64Bit) { 214 } 215 216 void Write8(uint8_t Value) { Writer->Write8(Value); } 217 void Write16(uint16_t Value) { Writer->Write16(Value); } 218 void Write32(uint32_t Value) { Writer->Write32(Value); } 219 void Write64(uint64_t Value) { Writer->Write64(Value); } 220 void WriteZeros(unsigned N) { Writer->WriteZeros(N); } 221 void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { 222 Writer->WriteBytes(Str, ZeroFillSize); 223 } 224 225 void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, 226 bool SubsectionsViaSymbols) { 227 uint32_t Flags = 0; 228 229 if (SubsectionsViaSymbols) 230 Flags |= HF_SubsectionsViaSymbols; 231 232 // struct mach_header (28 bytes) or 233 // struct mach_header_64 (32 bytes) 234 235 uint64_t Start = OS.tell(); 236 (void) Start; 237 238 Write32(Is64Bit ? Header_Magic64 : Header_Magic32); 239 240 // FIXME: Support cputype. 241 Write32(Is64Bit ? MachO::CPUTypeX86_64 : MachO::CPUTypeI386); 242 // FIXME: Support cpusubtype. 243 Write32(MachO::CPUSubType_I386_ALL); 244 Write32(HFT_Object); 245 Write32(NumLoadCommands); // Object files have a single load command, the 246 // segment. 247 Write32(LoadCommandsSize); 248 Write32(Flags); 249 if (Is64Bit) 250 Write32(0); // reserved 251 252 assert(OS.tell() - Start == Is64Bit ? Header64Size : Header32Size); 253 } 254 255 /// WriteSegmentLoadCommand - Write a segment load command. 256 /// 257 /// \arg NumSections - The number of sections in this segment. 258 /// \arg SectionDataSize - The total size of the sections. 259 void WriteSegmentLoadCommand(unsigned NumSections, 260 uint64_t VMSize, 261 uint64_t SectionDataStartOffset, 262 uint64_t SectionDataSize) { 263 // struct segment_command (56 bytes) or 264 // struct segment_command_64 (72 bytes) 265 266 uint64_t Start = OS.tell(); 267 (void) Start; 268 269 unsigned SegmentLoadCommandSize = Is64Bit ? SegmentLoadCommand64Size : 270 SegmentLoadCommand32Size; 271 Write32(Is64Bit ? LCT_Segment64 : LCT_Segment); 272 Write32(SegmentLoadCommandSize + 273 NumSections * (Is64Bit ? Section64Size : Section32Size)); 274 275 WriteBytes("", 16); 276 if (Is64Bit) { 277 Write64(0); // vmaddr 278 Write64(VMSize); // vmsize 279 Write64(SectionDataStartOffset); // file offset 280 Write64(SectionDataSize); // file size 281 } else { 282 Write32(0); // vmaddr 283 Write32(VMSize); // vmsize 284 Write32(SectionDataStartOffset); // file offset 285 Write32(SectionDataSize); // file size 286 } 287 Write32(0x7); // maxprot 288 Write32(0x7); // initprot 289 Write32(NumSections); 290 Write32(0); // flags 291 292 assert(OS.tell() - Start == SegmentLoadCommandSize); 293 } 294 295 void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, 296 const MCSectionData &SD, uint64_t FileOffset, 297 uint64_t RelocationsStart, unsigned NumRelocations) { 298 uint64_t SectionSize = Layout.getSectionSize(&SD); 299 300 // The offset is unused for virtual sections. 301 if (Asm.getBackend().isVirtualSection(SD.getSection())) { 302 assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!"); 303 FileOffset = 0; 304 } 305 306 // struct section (68 bytes) or 307 // struct section_64 (80 bytes) 308 309 uint64_t Start = OS.tell(); 310 (void) Start; 311 312 const MCSectionMachO &Section = cast<MCSectionMachO>(SD.getSection()); 313 WriteBytes(Section.getSectionName(), 16); 314 WriteBytes(Section.getSegmentName(), 16); 315 if (Is64Bit) { 316 Write64(Layout.getSectionAddress(&SD)); // address 317 Write64(SectionSize); // size 318 } else { 319 Write32(Layout.getSectionAddress(&SD)); // address 320 Write32(SectionSize); // size 321 } 322 Write32(FileOffset); 323 324 unsigned Flags = Section.getTypeAndAttributes(); 325 if (SD.hasInstructions()) 326 Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS; 327 328 assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); 329 Write32(Log2_32(SD.getAlignment())); 330 Write32(NumRelocations ? RelocationsStart : 0); 331 Write32(NumRelocations); 332 Write32(Flags); 333 Write32(IndirectSymBase.lookup(&SD)); // reserved1 334 Write32(Section.getStubSize()); // reserved2 335 if (Is64Bit) 336 Write32(0); // reserved3 337 338 assert(OS.tell() - Start == Is64Bit ? Section64Size : Section32Size); 339 } 340 341 void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, 342 uint32_t StringTableOffset, 343 uint32_t StringTableSize) { 344 // struct symtab_command (24 bytes) 345 346 uint64_t Start = OS.tell(); 347 (void) Start; 348 349 Write32(LCT_Symtab); 350 Write32(SymtabLoadCommandSize); 351 Write32(SymbolOffset); 352 Write32(NumSymbols); 353 Write32(StringTableOffset); 354 Write32(StringTableSize); 355 356 assert(OS.tell() - Start == SymtabLoadCommandSize); 357 } 358 359 void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, 360 uint32_t NumLocalSymbols, 361 uint32_t FirstExternalSymbol, 362 uint32_t NumExternalSymbols, 363 uint32_t FirstUndefinedSymbol, 364 uint32_t NumUndefinedSymbols, 365 uint32_t IndirectSymbolOffset, 366 uint32_t NumIndirectSymbols) { 367 // struct dysymtab_command (80 bytes) 368 369 uint64_t Start = OS.tell(); 370 (void) Start; 371 372 Write32(LCT_Dysymtab); 373 Write32(DysymtabLoadCommandSize); 374 Write32(FirstLocalSymbol); 375 Write32(NumLocalSymbols); 376 Write32(FirstExternalSymbol); 377 Write32(NumExternalSymbols); 378 Write32(FirstUndefinedSymbol); 379 Write32(NumUndefinedSymbols); 380 Write32(0); // tocoff 381 Write32(0); // ntoc 382 Write32(0); // modtaboff 383 Write32(0); // nmodtab 384 Write32(0); // extrefsymoff 385 Write32(0); // nextrefsyms 386 Write32(IndirectSymbolOffset); 387 Write32(NumIndirectSymbols); 388 Write32(0); // extreloff 389 Write32(0); // nextrel 390 Write32(0); // locreloff 391 Write32(0); // nlocrel 392 393 assert(OS.tell() - Start == DysymtabLoadCommandSize); 394 } 395 396 void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout) { 397 MCSymbolData &Data = *MSD.SymbolData; 398 const MCSymbol &Symbol = Data.getSymbol(); 399 uint8_t Type = 0; 400 uint16_t Flags = Data.getFlags(); 401 uint32_t Address = 0; 402 403 // Set the N_TYPE bits. See <mach-o/nlist.h>. 404 // 405 // FIXME: Are the prebound or indirect fields possible here? 406 if (Symbol.isUndefined()) 407 Type = STT_Undefined; 408 else if (Symbol.isAbsolute()) 409 Type = STT_Absolute; 410 else 411 Type = STT_Section; 412 413 // FIXME: Set STAB bits. 414 415 if (Data.isPrivateExtern()) 416 Type |= STF_PrivateExtern; 417 418 // Set external bit. 419 if (Data.isExternal() || Symbol.isUndefined()) 420 Type |= STF_External; 421 422 // Compute the symbol address. 423 if (Symbol.isDefined()) { 424 if (Symbol.isAbsolute()) { 425 Address = cast<MCConstantExpr>(Symbol.getVariableValue())->getValue(); 426 } else { 427 Address = Layout.getSymbolAddress(&Data); 428 } 429 } else if (Data.isCommon()) { 430 // Common symbols are encoded with the size in the address 431 // field, and their alignment in the flags. 432 Address = Data.getCommonSize(); 433 434 // Common alignment is packed into the 'desc' bits. 435 if (unsigned Align = Data.getCommonAlignment()) { 436 unsigned Log2Size = Log2_32(Align); 437 assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); 438 if (Log2Size > 15) 439 report_fatal_error("invalid 'common' alignment '" + 440 Twine(Align) + "'"); 441 // FIXME: Keep this mask with the SymbolFlags enumeration. 442 Flags = (Flags & 0xF0FF) | (Log2Size << 8); 443 } 444 } 445 446 // struct nlist (12 bytes) 447 448 Write32(MSD.StringIndex); 449 Write8(Type); 450 Write8(MSD.SectionIndex); 451 452 // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' 453 // value. 454 Write16(Flags); 455 if (Is64Bit) 456 Write64(Address); 457 else 458 Write32(Address); 459 } 460 461 // FIXME: We really need to improve the relocation validation. Basically, we 462 // want to implement a separate computation which evaluates the relocation 463 // entry as the linker would, and verifies that the resultant fixup value is 464 // exactly what the encoder wanted. This will catch several classes of 465 // problems: 466 // 467 // - Relocation entry bugs, the two algorithms are unlikely to have the same 468 // exact bug. 469 // 470 // - Relaxation issues, where we forget to relax something. 471 // 472 // - Input errors, where something cannot be correctly encoded. 'as' allows 473 // these through in many cases. 474 475 void RecordX86_64Relocation(const MCAssembler &Asm, const MCAsmLayout &Layout, 476 const MCFragment *Fragment, 477 const MCFixup &Fixup, MCValue Target, 478 uint64_t &FixedValue) { 479 unsigned IsPCRel = isFixupKindPCRel(Fixup.getKind()); 480 unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind()); 481 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); 482 483 // See <reloc.h>. 484 uint32_t FixupOffset = 485 Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 486 uint32_t FixupAddress = 487 Layout.getFragmentAddress(Fragment) + Fixup.getOffset(); 488 int64_t Value = 0; 489 unsigned Index = 0; 490 unsigned IsExtern = 0; 491 unsigned Type = 0; 492 493 Value = Target.getConstant(); 494 495 if (IsPCRel) { 496 // Compensate for the relocation offset, Darwin x86_64 relocations only 497 // have the addend and appear to have attempted to define it to be the 498 // actual expression addend without the PCrel bias. However, instructions 499 // with data following the relocation are not accomodated for (see comment 500 // below regarding SIGNED{1,2,4}), so it isn't exactly that either. 501 Value += 1LL << Log2Size; 502 } 503 504 if (Target.isAbsolute()) { // constant 505 // SymbolNum of 0 indicates the absolute section. 506 Type = RIT_X86_64_Unsigned; 507 Index = 0; 508 509 // FIXME: I believe this is broken, I don't think the linker can 510 // understand it. I think it would require a local relocation, but I'm not 511 // sure if that would work either. The official way to get an absolute 512 // PCrel relocation is to use an absolute symbol (which we don't support 513 // yet). 514 if (IsPCRel) { 515 IsExtern = 1; 516 Type = RIT_X86_64_Branch; 517 } 518 } else if (Target.getSymB()) { // A - B + constant 519 const MCSymbol *A = &Target.getSymA()->getSymbol(); 520 MCSymbolData &A_SD = Asm.getSymbolData(*A); 521 const MCSymbolData *A_Base = Asm.getAtom(Layout, &A_SD); 522 523 const MCSymbol *B = &Target.getSymB()->getSymbol(); 524 MCSymbolData &B_SD = Asm.getSymbolData(*B); 525 const MCSymbolData *B_Base = Asm.getAtom(Layout, &B_SD); 526 527 // Neither symbol can be modified. 528 if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None || 529 Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) 530 report_fatal_error("unsupported relocation of modified symbol"); 531 532 // We don't support PCrel relocations of differences. Darwin 'as' doesn't 533 // implement most of these correctly. 534 if (IsPCRel) 535 report_fatal_error("unsupported pc-relative relocation of difference"); 536 537 // We don't currently support any situation where one or both of the 538 // symbols would require a local relocation. This is almost certainly 539 // unused and may not be possible to encode correctly. 540 if (!A_Base || !B_Base) 541 report_fatal_error("unsupported local relocations in difference"); 542 543 // Darwin 'as' doesn't emit correct relocations for this (it ends up with 544 // a single SIGNED relocation); reject it for now. 545 if (A_Base == B_Base) 546 report_fatal_error("unsupported relocation with identical base"); 547 548 Value += Layout.getSymbolAddress(&A_SD) - Layout.getSymbolAddress(A_Base); 549 Value -= Layout.getSymbolAddress(&B_SD) - Layout.getSymbolAddress(B_Base); 550 551 Index = A_Base->getIndex(); 552 IsExtern = 1; 553 Type = RIT_X86_64_Unsigned; 554 555 MachRelocationEntry MRE; 556 MRE.Word0 = FixupOffset; 557 MRE.Word1 = ((Index << 0) | 558 (IsPCRel << 24) | 559 (Log2Size << 25) | 560 (IsExtern << 27) | 561 (Type << 28)); 562 Relocations[Fragment->getParent()].push_back(MRE); 563 564 Index = B_Base->getIndex(); 565 IsExtern = 1; 566 Type = RIT_X86_64_Subtractor; 567 } else { 568 const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); 569 MCSymbolData &SD = Asm.getSymbolData(*Symbol); 570 const MCSymbolData *Base = Asm.getAtom(Layout, &SD); 571 572 // Relocations inside debug sections always use local relocations when 573 // possible. This seems to be done because the debugger doesn't fully 574 // understand x86_64 relocation entries, and expects to find values that 575 // have already been fixed up. 576 if (Symbol->isInSection()) { 577 const MCSectionMachO &Section = static_cast<const MCSectionMachO&>( 578 Fragment->getParent()->getSection()); 579 if (Section.hasAttribute(MCSectionMachO::S_ATTR_DEBUG)) 580 Base = 0; 581 } 582 583 // x86_64 almost always uses external relocations, except when there is no 584 // symbol to use as a base address (a local symbol with no preceeding 585 // non-local symbol). 586 if (Base) { 587 Index = Base->getIndex(); 588 IsExtern = 1; 589 590 // Add the local offset, if needed. 591 if (Base != &SD) 592 Value += Layout.getSymbolAddress(&SD) - Layout.getSymbolAddress(Base); 593 } else if (Symbol->isInSection()) { 594 // The index is the section ordinal (1-based). 595 Index = SD.getFragment()->getParent()->getOrdinal() + 1; 596 IsExtern = 0; 597 Value += Layout.getSymbolAddress(&SD); 598 599 if (IsPCRel) 600 Value -= FixupAddress + (1 << Log2Size); 601 } else { 602 report_fatal_error("unsupported relocation of undefined symbol '" + 603 Symbol->getName() + "'"); 604 } 605 606 MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); 607 if (IsPCRel) { 608 if (IsRIPRel) { 609 if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) { 610 // x86_64 distinguishes movq foo@GOTPCREL so that the linker can 611 // rewrite the movq to an leaq at link time if the symbol ends up in 612 // the same linkage unit. 613 if (unsigned(Fixup.getKind()) == X86::reloc_riprel_4byte_movq_load) 614 Type = RIT_X86_64_GOTLoad; 615 else 616 Type = RIT_X86_64_GOT; 617 } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { 618 Type = RIT_X86_64_TLV; 619 } else if (Modifier != MCSymbolRefExpr::VK_None) { 620 report_fatal_error("unsupported symbol modifier in relocation"); 621 } else { 622 Type = RIT_X86_64_Signed; 623 624 // The Darwin x86_64 relocation format has a problem where it cannot 625 // encode an address (L<foo> + <constant>) which is outside the atom 626 // containing L<foo>. Generally, this shouldn't occur but it does 627 // happen when we have a RIPrel instruction with data following the 628 // relocation entry (e.g., movb $012, L0(%rip)). Even with the PCrel 629 // adjustment Darwin x86_64 uses, the offset is still negative and 630 // the linker has no way to recognize this. 631 // 632 // To work around this, Darwin uses several special relocation types 633 // to indicate the offsets. However, the specification or 634 // implementation of these seems to also be incomplete; they should 635 // adjust the addend as well based on the actual encoded instruction 636 // (the additional bias), but instead appear to just look at the 637 // final offset. 638 switch (-(Target.getConstant() + (1LL << Log2Size))) { 639 case 1: Type = RIT_X86_64_Signed1; break; 640 case 2: Type = RIT_X86_64_Signed2; break; 641 case 4: Type = RIT_X86_64_Signed4; break; 642 } 643 } 644 } else { 645 if (Modifier != MCSymbolRefExpr::VK_None) 646 report_fatal_error("unsupported symbol modifier in branch " 647 "relocation"); 648 649 Type = RIT_X86_64_Branch; 650 } 651 } else { 652 if (Modifier == MCSymbolRefExpr::VK_GOT) { 653 Type = RIT_X86_64_GOT; 654 } else if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) { 655 // GOTPCREL is allowed as a modifier on non-PCrel instructions, in 656 // which case all we do is set the PCrel bit in the relocation entry; 657 // this is used with exception handling, for example. The source is 658 // required to include any necessary offset directly. 659 Type = RIT_X86_64_GOT; 660 IsPCRel = 1; 661 } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { 662 report_fatal_error("TLVP symbol modifier should have been rip-rel"); 663 } else if (Modifier != MCSymbolRefExpr::VK_None) 664 report_fatal_error("unsupported symbol modifier in relocation"); 665 else 666 Type = RIT_X86_64_Unsigned; 667 } 668 } 669 670 // x86_64 always writes custom values into the fixups. 671 FixedValue = Value; 672 673 // struct relocation_info (8 bytes) 674 MachRelocationEntry MRE; 675 MRE.Word0 = FixupOffset; 676 MRE.Word1 = ((Index << 0) | 677 (IsPCRel << 24) | 678 (Log2Size << 25) | 679 (IsExtern << 27) | 680 (Type << 28)); 681 Relocations[Fragment->getParent()].push_back(MRE); 682 } 683 684 void RecordScatteredRelocation(const MCAssembler &Asm, 685 const MCAsmLayout &Layout, 686 const MCFragment *Fragment, 687 const MCFixup &Fixup, MCValue Target, 688 uint64_t &FixedValue) { 689 uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); 690 unsigned IsPCRel = isFixupKindPCRel(Fixup.getKind()); 691 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); 692 unsigned Type = RIT_Vanilla; 693 694 // See <reloc.h>. 695 const MCSymbol *A = &Target.getSymA()->getSymbol(); 696 MCSymbolData *A_SD = &Asm.getSymbolData(*A); 697 698 if (!A_SD->getFragment()) 699 report_fatal_error("symbol '" + A->getName() + 700 "' can not be undefined in a subtraction expression"); 701 702 uint32_t Value = Layout.getSymbolAddress(A_SD); 703 uint32_t Value2 = 0; 704 705 if (const MCSymbolRefExpr *B = Target.getSymB()) { 706 MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); 707 708 if (!B_SD->getFragment()) 709 report_fatal_error("symbol '" + B->getSymbol().getName() + 710 "' can not be undefined in a subtraction expression"); 711 712 // Select the appropriate difference relocation type. 713 // 714 // Note that there is no longer any semantic difference between these two 715 // relocation types from the linkers point of view, this is done solely 716 // for pedantic compatibility with 'as'. 717 Type = A_SD->isExternal() ? RIT_Difference : RIT_LocalDifference; 718 Value2 = Layout.getSymbolAddress(B_SD); 719 } 720 721 // Relocations are written out in reverse order, so the PAIR comes first. 722 if (Type == RIT_Difference || Type == RIT_LocalDifference) { 723 MachRelocationEntry MRE; 724 MRE.Word0 = ((0 << 0) | 725 (RIT_Pair << 24) | 726 (Log2Size << 28) | 727 (IsPCRel << 30) | 728 RF_Scattered); 729 MRE.Word1 = Value2; 730 Relocations[Fragment->getParent()].push_back(MRE); 731 } 732 733 MachRelocationEntry MRE; 734 MRE.Word0 = ((FixupOffset << 0) | 735 (Type << 24) | 736 (Log2Size << 28) | 737 (IsPCRel << 30) | 738 RF_Scattered); 739 MRE.Word1 = Value; 740 Relocations[Fragment->getParent()].push_back(MRE); 741 } 742 743 void RecordTLVPRelocation(const MCAssembler &Asm, 744 const MCAsmLayout &Layout, 745 const MCFragment *Fragment, 746 const MCFixup &Fixup, MCValue Target, 747 uint64_t &FixedValue) { 748 assert(Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP && 749 !Is64Bit && 750 "Should only be called with a 32-bit TLVP relocation!"); 751 752 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); 753 uint32_t Value = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); 754 unsigned IsPCRel = 0; 755 756 // Get the symbol data. 757 MCSymbolData *SD_A = &Asm.getSymbolData(Target.getSymA()->getSymbol()); 758 unsigned Index = SD_A->getIndex(); 759 760 // We're only going to have a second symbol in pic mode and it'll be a 761 // subtraction from the picbase. For 32-bit pic the addend is the difference 762 // between the picbase and the next address. For 32-bit static the addend 763 // is zero. 764 if (Target.getSymB()) { 765 // If this is a subtraction then we're pcrel. 766 uint32_t FixupAddress = 767 Layout.getFragmentAddress(Fragment) + Fixup.getOffset(); 768 MCSymbolData *SD_B = &Asm.getSymbolData(Target.getSymB()->getSymbol()); 769 IsPCRel = 1; 770 FixedValue = (FixupAddress - Layout.getSymbolAddress(SD_B) + 771 Target.getConstant()); 772 FixedValue += 1ULL << Log2Size; 773 } else { 774 FixedValue = 0; 775 } 776 777 // struct relocation_info (8 bytes) 778 MachRelocationEntry MRE; 779 MRE.Word0 = Value; 780 MRE.Word1 = ((Index << 0) | 781 (IsPCRel << 24) | 782 (Log2Size << 25) | 783 (1 << 27) | // Extern 784 (RIT_TLV << 28)); // Type 785 Relocations[Fragment->getParent()].push_back(MRE); 786 } 787 788 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, 789 const MCFragment *Fragment, const MCFixup &Fixup, 790 MCValue Target, uint64_t &FixedValue) { 791 if (Is64Bit) { 792 RecordX86_64Relocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); 793 return; 794 } 795 796 unsigned IsPCRel = isFixupKindPCRel(Fixup.getKind()); 797 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); 798 799 // If this is a 32-bit TLVP reloc it's handled a bit differently. 800 if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP) { 801 RecordTLVPRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); 802 return; 803 } 804 805 // If this is a difference or a defined symbol plus an offset, then we need 806 // a scattered relocation entry. 807 // Differences always require scattered relocations. 808 if (Target.getSymB()) 809 return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, 810 Target, FixedValue); 811 812 // Get the symbol data, if any. 813 MCSymbolData *SD = 0; 814 if (Target.getSymA()) 815 SD = &Asm.getSymbolData(Target.getSymA()->getSymbol()); 816 817 // If this is an internal relocation with an offset, it also needs a 818 // scattered relocation entry. 819 uint32_t Offset = Target.getConstant(); 820 if (IsPCRel) 821 Offset += 1 << Log2Size; 822 if (Offset && SD && !doesSymbolRequireExternRelocation(SD)) 823 return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, 824 Target, FixedValue); 825 826 // See <reloc.h>. 827 uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); 828 unsigned Index = 0; 829 unsigned IsExtern = 0; 830 unsigned Type = 0; 831 832 if (Target.isAbsolute()) { // constant 833 // SymbolNum of 0 indicates the absolute section. 834 // 835 // FIXME: Currently, these are never generated (see code below). I cannot 836 // find a case where they are actually emitted. 837 Type = RIT_Vanilla; 838 } else { 839 // Check whether we need an external or internal relocation. 840 if (doesSymbolRequireExternRelocation(SD)) { 841 IsExtern = 1; 842 Index = SD->getIndex(); 843 // For external relocations, make sure to offset the fixup value to 844 // compensate for the addend of the symbol address, if it was 845 // undefined. This occurs with weak definitions, for example. 846 if (!SD->Symbol->isUndefined()) 847 FixedValue -= Layout.getSymbolAddress(SD); 848 } else { 849 // The index is the section ordinal (1-based). 850 Index = SD->getFragment()->getParent()->getOrdinal() + 1; 851 } 852 853 Type = RIT_Vanilla; 854 } 855 856 // struct relocation_info (8 bytes) 857 MachRelocationEntry MRE; 858 MRE.Word0 = FixupOffset; 859 MRE.Word1 = ((Index << 0) | 860 (IsPCRel << 24) | 861 (Log2Size << 25) | 862 (IsExtern << 27) | 863 (Type << 28)); 864 Relocations[Fragment->getParent()].push_back(MRE); 865 } 866 867 void BindIndirectSymbols(MCAssembler &Asm) { 868 // This is the point where 'as' creates actual symbols for indirect symbols 869 // (in the following two passes). It would be easier for us to do this 870 // sooner when we see the attribute, but that makes getting the order in the 871 // symbol table much more complicated than it is worth. 872 // 873 // FIXME: Revisit this when the dust settles. 874 875 // Bind non lazy symbol pointers first. 876 unsigned IndirectIndex = 0; 877 for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 878 ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { 879 const MCSectionMachO &Section = 880 cast<MCSectionMachO>(it->SectionData->getSection()); 881 882 if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) 883 continue; 884 885 // Initialize the section indirect symbol base, if necessary. 886 if (!IndirectSymBase.count(it->SectionData)) 887 IndirectSymBase[it->SectionData] = IndirectIndex; 888 889 Asm.getOrCreateSymbolData(*it->Symbol); 890 } 891 892 // Then lazy symbol pointers and symbol stubs. 893 IndirectIndex = 0; 894 for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 895 ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { 896 const MCSectionMachO &Section = 897 cast<MCSectionMachO>(it->SectionData->getSection()); 898 899 if (Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS && 900 Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) 901 continue; 902 903 // Initialize the section indirect symbol base, if necessary. 904 if (!IndirectSymBase.count(it->SectionData)) 905 IndirectSymBase[it->SectionData] = IndirectIndex; 906 907 // Set the symbol type to undefined lazy, but only on construction. 908 // 909 // FIXME: Do not hardcode. 910 bool Created; 911 MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created); 912 if (Created) 913 Entry.setFlags(Entry.getFlags() | 0x0001); 914 } 915 } 916 917 /// ComputeSymbolTable - Compute the symbol table data 918 /// 919 /// \param StringTable [out] - The string table data. 920 /// \param StringIndexMap [out] - Map from symbol names to offsets in the 921 /// string table. 922 void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, 923 std::vector<MachSymbolData> &LocalSymbolData, 924 std::vector<MachSymbolData> &ExternalSymbolData, 925 std::vector<MachSymbolData> &UndefinedSymbolData) { 926 // Build section lookup table. 927 DenseMap<const MCSection*, uint8_t> SectionIndexMap; 928 unsigned Index = 1; 929 for (MCAssembler::iterator it = Asm.begin(), 930 ie = Asm.end(); it != ie; ++it, ++Index) 931 SectionIndexMap[&it->getSection()] = Index; 932 assert(Index <= 256 && "Too many sections!"); 933 934 // Index 0 is always the empty string. 935 StringMap<uint64_t> StringIndexMap; 936 StringTable += '\x00'; 937 938 // Build the symbol arrays and the string table, but only for non-local 939 // symbols. 940 // 941 // The particular order that we collect the symbols and create the string 942 // table, then sort the symbols is chosen to match 'as'. Even though it 943 // doesn't matter for correctness, this is important for letting us diff .o 944 // files. 945 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 946 ie = Asm.symbol_end(); it != ie; ++it) { 947 const MCSymbol &Symbol = it->getSymbol(); 948 949 // Ignore non-linker visible symbols. 950 if (!Asm.isSymbolLinkerVisible(it->getSymbol())) 951 continue; 952 953 if (!it->isExternal() && !Symbol.isUndefined()) 954 continue; 955 956 uint64_t &Entry = StringIndexMap[Symbol.getName()]; 957 if (!Entry) { 958 Entry = StringTable.size(); 959 StringTable += Symbol.getName(); 960 StringTable += '\x00'; 961 } 962 963 MachSymbolData MSD; 964 MSD.SymbolData = it; 965 MSD.StringIndex = Entry; 966 967 if (Symbol.isUndefined()) { 968 MSD.SectionIndex = 0; 969 UndefinedSymbolData.push_back(MSD); 970 } else if (Symbol.isAbsolute()) { 971 MSD.SectionIndex = 0; 972 ExternalSymbolData.push_back(MSD); 973 } else { 974 MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 975 assert(MSD.SectionIndex && "Invalid section index!"); 976 ExternalSymbolData.push_back(MSD); 977 } 978 } 979 980 // Now add the data for local symbols. 981 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 982 ie = Asm.symbol_end(); it != ie; ++it) { 983 const MCSymbol &Symbol = it->getSymbol(); 984 985 // Ignore non-linker visible symbols. 986 if (!Asm.isSymbolLinkerVisible(it->getSymbol())) 987 continue; 988 989 if (it->isExternal() || Symbol.isUndefined()) 990 continue; 991 992 uint64_t &Entry = StringIndexMap[Symbol.getName()]; 993 if (!Entry) { 994 Entry = StringTable.size(); 995 StringTable += Symbol.getName(); 996 StringTable += '\x00'; 997 } 998 999 MachSymbolData MSD; 1000 MSD.SymbolData = it; 1001 MSD.StringIndex = Entry; 1002 1003 if (Symbol.isAbsolute()) { 1004 MSD.SectionIndex = 0; 1005 LocalSymbolData.push_back(MSD); 1006 } else { 1007 MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 1008 assert(MSD.SectionIndex && "Invalid section index!"); 1009 LocalSymbolData.push_back(MSD); 1010 } 1011 } 1012 1013 // External and undefined symbols are required to be in lexicographic order. 1014 std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 1015 std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 1016 1017 // Set the symbol indices. 1018 Index = 0; 1019 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 1020 LocalSymbolData[i].SymbolData->setIndex(Index++); 1021 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 1022 ExternalSymbolData[i].SymbolData->setIndex(Index++); 1023 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 1024 UndefinedSymbolData[i].SymbolData->setIndex(Index++); 1025 1026 // The string table is padded to a multiple of 4. 1027 while (StringTable.size() % 4) 1028 StringTable += '\x00'; 1029 } 1030 1031 void ExecutePostLayoutBinding(MCAssembler &Asm) { 1032 // Create symbol data for any indirect symbols. 1033 BindIndirectSymbols(Asm); 1034 1035 // Compute symbol table information and bind symbol indices. 1036 ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData, 1037 UndefinedSymbolData); 1038 } 1039 1040 void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout) { 1041 unsigned NumSections = Asm.size(); 1042 1043 // The section data starts after the header, the segment load command (and 1044 // section headers) and the symbol table. 1045 unsigned NumLoadCommands = 1; 1046 uint64_t LoadCommandsSize = Is64Bit ? 1047 SegmentLoadCommand64Size + NumSections * Section64Size : 1048 SegmentLoadCommand32Size + NumSections * Section32Size; 1049 1050 // Add the symbol table load command sizes, if used. 1051 unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() + 1052 UndefinedSymbolData.size(); 1053 if (NumSymbols) { 1054 NumLoadCommands += 2; 1055 LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize; 1056 } 1057 1058 // Compute the total size of the section data, as well as its file size and 1059 // vm size. 1060 uint64_t SectionDataStart = (Is64Bit ? Header64Size : Header32Size) 1061 + LoadCommandsSize; 1062 uint64_t SectionDataSize = 0; 1063 uint64_t SectionDataFileSize = 0; 1064 uint64_t VMSize = 0; 1065 for (MCAssembler::const_iterator it = Asm.begin(), 1066 ie = Asm.end(); it != ie; ++it) { 1067 const MCSectionData &SD = *it; 1068 uint64_t Address = Layout.getSectionAddress(&SD); 1069 uint64_t Size = Layout.getSectionSize(&SD); 1070 uint64_t FileSize = Layout.getSectionFileSize(&SD); 1071 1072 VMSize = std::max(VMSize, Address + Size); 1073 1074 if (Asm.getBackend().isVirtualSection(SD.getSection())) 1075 continue; 1076 1077 SectionDataSize = std::max(SectionDataSize, Address + Size); 1078 SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize); 1079 } 1080 1081 // The section data is padded to 4 bytes. 1082 // 1083 // FIXME: Is this machine dependent? 1084 unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4); 1085 SectionDataFileSize += SectionDataPadding; 1086 1087 // Write the prolog, starting with the header and load command... 1088 WriteHeader(NumLoadCommands, LoadCommandsSize, 1089 Asm.getSubsectionsViaSymbols()); 1090 WriteSegmentLoadCommand(NumSections, VMSize, 1091 SectionDataStart, SectionDataSize); 1092 1093 // ... and then the section headers. 1094 uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; 1095 for (MCAssembler::const_iterator it = Asm.begin(), 1096 ie = Asm.end(); it != ie; ++it) { 1097 std::vector<MachRelocationEntry> &Relocs = Relocations[it]; 1098 unsigned NumRelocs = Relocs.size(); 1099 uint64_t SectionStart = SectionDataStart + Layout.getSectionAddress(it); 1100 WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs); 1101 RelocTableEnd += NumRelocs * RelocationInfoSize; 1102 } 1103 1104 // Write the symbol table load command, if used. 1105 if (NumSymbols) { 1106 unsigned FirstLocalSymbol = 0; 1107 unsigned NumLocalSymbols = LocalSymbolData.size(); 1108 unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols; 1109 unsigned NumExternalSymbols = ExternalSymbolData.size(); 1110 unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols; 1111 unsigned NumUndefinedSymbols = UndefinedSymbolData.size(); 1112 unsigned NumIndirectSymbols = Asm.indirect_symbol_size(); 1113 unsigned NumSymTabSymbols = 1114 NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols; 1115 uint64_t IndirectSymbolSize = NumIndirectSymbols * 4; 1116 uint64_t IndirectSymbolOffset = 0; 1117 1118 // If used, the indirect symbols are written after the section data. 1119 if (NumIndirectSymbols) 1120 IndirectSymbolOffset = RelocTableEnd; 1121 1122 // The symbol table is written after the indirect symbol data. 1123 uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize; 1124 1125 // The string table is written after symbol table. 1126 uint64_t StringTableOffset = 1127 SymbolTableOffset + NumSymTabSymbols * (Is64Bit ? Nlist64Size : 1128 Nlist32Size); 1129 WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols, 1130 StringTableOffset, StringTable.size()); 1131 1132 WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols, 1133 FirstExternalSymbol, NumExternalSymbols, 1134 FirstUndefinedSymbol, NumUndefinedSymbols, 1135 IndirectSymbolOffset, NumIndirectSymbols); 1136 } 1137 1138 // Write the actual section data. 1139 for (MCAssembler::const_iterator it = Asm.begin(), 1140 ie = Asm.end(); it != ie; ++it) 1141 Asm.WriteSectionData(it, Layout, Writer); 1142 1143 // Write the extra padding. 1144 WriteZeros(SectionDataPadding); 1145 1146 // Write the relocation entries. 1147 for (MCAssembler::const_iterator it = Asm.begin(), 1148 ie = Asm.end(); it != ie; ++it) { 1149 // Write the section relocation entries, in reverse order to match 'as' 1150 // (approximately, the exact algorithm is more complicated than this). 1151 std::vector<MachRelocationEntry> &Relocs = Relocations[it]; 1152 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 1153 Write32(Relocs[e - i - 1].Word0); 1154 Write32(Relocs[e - i - 1].Word1); 1155 } 1156 } 1157 1158 // Write the symbol table data, if used. 1159 if (NumSymbols) { 1160 // Write the indirect symbol entries. 1161 for (MCAssembler::const_indirect_symbol_iterator 1162 it = Asm.indirect_symbol_begin(), 1163 ie = Asm.indirect_symbol_end(); it != ie; ++it) { 1164 // Indirect symbols in the non lazy symbol pointer section have some 1165 // special handling. 1166 const MCSectionMachO &Section = 1167 static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 1168 if (Section.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) { 1169 // If this symbol is defined and internal, mark it as such. 1170 if (it->Symbol->isDefined() && 1171 !Asm.getSymbolData(*it->Symbol).isExternal()) { 1172 uint32_t Flags = ISF_Local; 1173 if (it->Symbol->isAbsolute()) 1174 Flags |= ISF_Absolute; 1175 Write32(Flags); 1176 continue; 1177 } 1178 } 1179 1180 Write32(Asm.getSymbolData(*it->Symbol).getIndex()); 1181 } 1182 1183 // FIXME: Check that offsets match computed ones. 1184 1185 // Write the symbol table entries. 1186 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 1187 WriteNlist(LocalSymbolData[i], Layout); 1188 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 1189 WriteNlist(ExternalSymbolData[i], Layout); 1190 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 1191 WriteNlist(UndefinedSymbolData[i], Layout); 1192 1193 // Write the string table. 1194 OS << StringTable.str(); 1195 } 1196 } 1197}; 1198 1199} 1200 1201MachObjectWriter::MachObjectWriter(raw_ostream &OS, 1202 bool Is64Bit, 1203 bool IsLittleEndian) 1204 : MCObjectWriter(OS, IsLittleEndian) 1205{ 1206 Impl = new MachObjectWriterImpl(this, Is64Bit); 1207} 1208 1209MachObjectWriter::~MachObjectWriter() { 1210 delete (MachObjectWriterImpl*) Impl; 1211} 1212 1213void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { 1214 ((MachObjectWriterImpl*) Impl)->ExecutePostLayoutBinding(Asm); 1215} 1216 1217void MachObjectWriter::RecordRelocation(const MCAssembler &Asm, 1218 const MCAsmLayout &Layout, 1219 const MCFragment *Fragment, 1220 const MCFixup &Fixup, MCValue Target, 1221 uint64_t &FixedValue) { 1222 ((MachObjectWriterImpl*) Impl)->RecordRelocation(Asm, Layout, Fragment, Fixup, 1223 Target, FixedValue); 1224} 1225 1226void MachObjectWriter::WriteObject(const MCAssembler &Asm, 1227 const MCAsmLayout &Layout) { 1228 ((MachObjectWriterImpl*) Impl)->WriteObject(Asm, Layout); 1229} 1230