1 //===- lib/MC/MachObjectWriter.cpp - Mach-O File Writer -------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCMachObjectWriter.h"
11 #include "llvm/ADT/StringMap.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCAsmBackend.h"
14 #include "llvm/MC/MCAsmLayout.h"
15 #include "llvm/MC/MCAssembler.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCFixupKindInfo.h"
18 #include "llvm/MC/MCMachOSymbolFlags.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSectionMachO.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/MachO.h"
29 #define DEBUG_TYPE "mc"
31 void MachObjectWriter::reset() {
33 IndirectSymBase
.clear();
35 LocalSymbolData
.clear();
36 ExternalSymbolData
.clear();
37 UndefinedSymbolData
.clear();
38 MCObjectWriter::reset();
41 bool MachObjectWriter::
42 doesSymbolRequireExternRelocation(const MCSymbolData
*SD
) {
43 // Undefined symbols are always extern.
44 if (SD
->getSymbol().isUndefined())
47 // References to weak definitions require external relocation entries; the
48 // definition may not always be the one in the same object file.
49 if (SD
->getFlags() & SF_WeakDefinition
)
52 // Otherwise, we can use an internal relocation.
56 bool MachObjectWriter::
57 MachSymbolData::operator<(const MachSymbolData
&RHS
) const {
58 return SymbolData
->getSymbol().getName() <
59 RHS
.SymbolData
->getSymbol().getName();
62 bool MachObjectWriter::isFixupKindPCRel(const MCAssembler
&Asm
, unsigned Kind
) {
63 const MCFixupKindInfo
&FKI
= Asm
.getBackend().getFixupKindInfo(
66 return FKI
.Flags
& MCFixupKindInfo::FKF_IsPCRel
;
69 uint64_t MachObjectWriter::getFragmentAddress(const MCFragment
*Fragment
,
70 const MCAsmLayout
&Layout
) const {
71 return getSectionAddress(Fragment
->getParent()) +
72 Layout
.getFragmentOffset(Fragment
);
75 uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData
* SD
,
76 const MCAsmLayout
&Layout
) const {
77 const MCSymbol
&S
= SD
->getSymbol();
79 // If this is a variable, then recursively evaluate now.
81 if (const MCConstantExpr
*C
=
82 dyn_cast
<const MCConstantExpr
>(S
.getVariableValue()))
87 if (!S
.getVariableValue()->EvaluateAsRelocatable(Target
, &Layout
, nullptr))
88 report_fatal_error("unable to evaluate offset for variable '" +
91 // Verify that any used symbols are defined.
92 if (Target
.getSymA() && Target
.getSymA()->getSymbol().isUndefined())
93 report_fatal_error("unable to evaluate offset to undefined symbol '" +
94 Target
.getSymA()->getSymbol().getName() + "'");
95 if (Target
.getSymB() && Target
.getSymB()->getSymbol().isUndefined())
96 report_fatal_error("unable to evaluate offset to undefined symbol '" +
97 Target
.getSymB()->getSymbol().getName() + "'");
99 uint64_t Address
= Target
.getConstant();
100 if (Target
.getSymA())
101 Address
+= getSymbolAddress(&Layout
.getAssembler().getSymbolData(
102 Target
.getSymA()->getSymbol()), Layout
);
103 if (Target
.getSymB())
104 Address
+= getSymbolAddress(&Layout
.getAssembler().getSymbolData(
105 Target
.getSymB()->getSymbol()), Layout
);
109 return getSectionAddress(SD
->getFragment()->getParent()) +
110 Layout
.getSymbolOffset(SD
);
113 uint64_t MachObjectWriter::getPaddingSize(const MCSectionData
*SD
,
114 const MCAsmLayout
&Layout
) const {
115 uint64_t EndAddr
= getSectionAddress(SD
) + Layout
.getSectionAddressSize(SD
);
116 unsigned Next
= SD
->getLayoutOrder() + 1;
117 if (Next
>= Layout
.getSectionOrder().size())
120 const MCSectionData
&NextSD
= *Layout
.getSectionOrder()[Next
];
121 if (NextSD
.getSection().isVirtualSection())
123 return OffsetToAlignment(EndAddr
, NextSD
.getAlignment());
126 void MachObjectWriter::WriteHeader(unsigned NumLoadCommands
,
127 unsigned LoadCommandsSize
,
128 bool SubsectionsViaSymbols
) {
131 if (SubsectionsViaSymbols
)
132 Flags
|= MachO::MH_SUBSECTIONS_VIA_SYMBOLS
;
134 // struct mach_header (28 bytes) or
135 // struct mach_header_64 (32 bytes)
137 uint64_t Start
= OS
.tell();
140 Write32(is64Bit() ? MachO::MH_MAGIC_64
: MachO::MH_MAGIC
);
142 Write32(TargetObjectWriter
->getCPUType());
143 Write32(TargetObjectWriter
->getCPUSubtype());
145 Write32(MachO::MH_OBJECT
);
146 Write32(NumLoadCommands
);
147 Write32(LoadCommandsSize
);
150 Write32(0); // reserved
152 assert(OS
.tell() - Start
==
153 (is64Bit()?sizeof(MachO::mach_header_64
): sizeof(MachO::mach_header
)));
156 /// WriteSegmentLoadCommand - Write a segment load command.
158 /// \param NumSections The number of sections in this segment.
159 /// \param SectionDataSize The total size of the sections.
160 void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections
,
162 uint64_t SectionDataStartOffset
,
163 uint64_t SectionDataSize
) {
164 // struct segment_command (56 bytes) or
165 // struct segment_command_64 (72 bytes)
167 uint64_t Start
= OS
.tell();
170 unsigned SegmentLoadCommandSize
=
171 is64Bit() ? sizeof(MachO::segment_command_64
):
172 sizeof(MachO::segment_command
);
173 Write32(is64Bit() ? MachO::LC_SEGMENT_64
: MachO::LC_SEGMENT
);
174 Write32(SegmentLoadCommandSize
+
175 NumSections
* (is64Bit() ? sizeof(MachO::section_64
) :
176 sizeof(MachO::section
)));
180 Write64(0); // vmaddr
181 Write64(VMSize
); // vmsize
182 Write64(SectionDataStartOffset
); // file offset
183 Write64(SectionDataSize
); // file size
185 Write32(0); // vmaddr
186 Write32(VMSize
); // vmsize
187 Write32(SectionDataStartOffset
); // file offset
188 Write32(SectionDataSize
); // file size
191 Write32(MachO::VM_PROT_READ
| MachO::VM_PROT_WRITE
| MachO::VM_PROT_EXECUTE
);
193 Write32(MachO::VM_PROT_READ
| MachO::VM_PROT_WRITE
| MachO::VM_PROT_EXECUTE
);
194 Write32(NumSections
);
197 assert(OS
.tell() - Start
== SegmentLoadCommandSize
);
200 void MachObjectWriter::WriteSection(const MCAssembler
&Asm
,
201 const MCAsmLayout
&Layout
,
202 const MCSectionData
&SD
,
204 uint64_t RelocationsStart
,
205 unsigned NumRelocations
) {
206 uint64_t SectionSize
= Layout
.getSectionAddressSize(&SD
);
208 // The offset is unused for virtual sections.
209 if (SD
.getSection().isVirtualSection()) {
210 assert(Layout
.getSectionFileSize(&SD
) == 0 && "Invalid file size!");
214 // struct section (68 bytes) or
215 // struct section_64 (80 bytes)
217 uint64_t Start
= OS
.tell();
220 const MCSectionMachO
&Section
= cast
<MCSectionMachO
>(SD
.getSection());
221 WriteBytes(Section
.getSectionName(), 16);
222 WriteBytes(Section
.getSegmentName(), 16);
224 Write64(getSectionAddress(&SD
)); // address
225 Write64(SectionSize
); // size
227 Write32(getSectionAddress(&SD
)); // address
228 Write32(SectionSize
); // size
232 unsigned Flags
= Section
.getTypeAndAttributes();
233 if (SD
.hasInstructions())
234 Flags
|= MachO::S_ATTR_SOME_INSTRUCTIONS
;
236 assert(isPowerOf2_32(SD
.getAlignment()) && "Invalid alignment!");
237 Write32(Log2_32(SD
.getAlignment()));
238 Write32(NumRelocations
? RelocationsStart
: 0);
239 Write32(NumRelocations
);
241 Write32(IndirectSymBase
.lookup(&SD
)); // reserved1
242 Write32(Section
.getStubSize()); // reserved2
244 Write32(0); // reserved3
246 assert(OS
.tell() - Start
== (is64Bit() ? sizeof(MachO::section_64
) :
247 sizeof(MachO::section
)));
250 void MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset
,
252 uint32_t StringTableOffset
,
253 uint32_t StringTableSize
) {
254 // struct symtab_command (24 bytes)
256 uint64_t Start
= OS
.tell();
259 Write32(MachO::LC_SYMTAB
);
260 Write32(sizeof(MachO::symtab_command
));
261 Write32(SymbolOffset
);
263 Write32(StringTableOffset
);
264 Write32(StringTableSize
);
266 assert(OS
.tell() - Start
== sizeof(MachO::symtab_command
));
269 void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol
,
270 uint32_t NumLocalSymbols
,
271 uint32_t FirstExternalSymbol
,
272 uint32_t NumExternalSymbols
,
273 uint32_t FirstUndefinedSymbol
,
274 uint32_t NumUndefinedSymbols
,
275 uint32_t IndirectSymbolOffset
,
276 uint32_t NumIndirectSymbols
) {
277 // struct dysymtab_command (80 bytes)
279 uint64_t Start
= OS
.tell();
282 Write32(MachO::LC_DYSYMTAB
);
283 Write32(sizeof(MachO::dysymtab_command
));
284 Write32(FirstLocalSymbol
);
285 Write32(NumLocalSymbols
);
286 Write32(FirstExternalSymbol
);
287 Write32(NumExternalSymbols
);
288 Write32(FirstUndefinedSymbol
);
289 Write32(NumUndefinedSymbols
);
290 Write32(0); // tocoff
292 Write32(0); // modtaboff
293 Write32(0); // nmodtab
294 Write32(0); // extrefsymoff
295 Write32(0); // nextrefsyms
296 Write32(IndirectSymbolOffset
);
297 Write32(NumIndirectSymbols
);
298 Write32(0); // extreloff
299 Write32(0); // nextrel
300 Write32(0); // locreloff
301 Write32(0); // nlocrel
303 assert(OS
.tell() - Start
== sizeof(MachO::dysymtab_command
));
306 MachObjectWriter::MachSymbolData
*
307 MachObjectWriter::findSymbolData(const MCSymbol
&Sym
) {
308 for (auto &Entry
: LocalSymbolData
)
309 if (&Entry
.SymbolData
->getSymbol() == &Sym
)
312 for (auto &Entry
: ExternalSymbolData
)
313 if (&Entry
.SymbolData
->getSymbol() == &Sym
)
316 for (auto &Entry
: UndefinedSymbolData
)
317 if (&Entry
.SymbolData
->getSymbol() == &Sym
)
323 void MachObjectWriter::WriteNlist(MachSymbolData
&MSD
,
324 const MCAsmLayout
&Layout
) {
325 MCSymbolData
&Data
= *MSD
.SymbolData
;
326 const MCSymbol
*Symbol
= &Data
.getSymbol();
327 const MCSymbol
*AliasedSymbol
= &Symbol
->AliasedSymbol();
328 uint8_t SectionIndex
= MSD
.SectionIndex
;
330 uint16_t Flags
= Data
.getFlags();
331 uint64_t Address
= 0;
332 bool IsAlias
= Symbol
!= AliasedSymbol
;
334 MachSymbolData
*AliaseeInfo
;
336 AliaseeInfo
= findSymbolData(*AliasedSymbol
);
338 SectionIndex
= AliaseeInfo
->SectionIndex
;
339 Symbol
= AliasedSymbol
;
342 // Set the N_TYPE bits. See <mach-o/nlist.h>.
344 // FIXME: Are the prebound or indirect fields possible here?
345 if (IsAlias
&& Symbol
->isUndefined())
346 Type
= MachO::N_INDR
;
347 else if (Symbol
->isUndefined())
348 Type
= MachO::N_UNDF
;
349 else if (Symbol
->isAbsolute())
352 Type
= MachO::N_SECT
;
354 // FIXME: Set STAB bits.
356 if (Data
.isPrivateExtern())
357 Type
|= MachO::N_PEXT
;
360 if (Data
.isExternal() || (!IsAlias
&& Symbol
->isUndefined()))
361 Type
|= MachO::N_EXT
;
363 // Compute the symbol address.
364 if (IsAlias
&& Symbol
->isUndefined())
365 Address
= AliaseeInfo
->StringIndex
;
366 else if (Symbol
->isDefined())
367 Address
= getSymbolAddress(&Data
, Layout
);
368 else if (Data
.isCommon()) {
369 // Common symbols are encoded with the size in the address
370 // field, and their alignment in the flags.
371 Address
= Data
.getCommonSize();
373 // Common alignment is packed into the 'desc' bits.
374 if (unsigned Align
= Data
.getCommonAlignment()) {
375 unsigned Log2Size
= Log2_32(Align
);
376 assert((1U << Log2Size
) == Align
&& "Invalid 'common' alignment!");
378 report_fatal_error("invalid 'common' alignment '" +
379 Twine(Align
) + "' for '" + Symbol
->getName() + "'",
381 // FIXME: Keep this mask with the SymbolFlags enumeration.
382 Flags
= (Flags
& 0xF0FF) | (Log2Size
<< 8);
386 if (Layout
.getAssembler().isThumbFunc(Symbol
))
387 Flags
|= SF_ThumbFunc
;
389 // struct nlist (12 bytes)
391 Write32(MSD
.StringIndex
);
393 Write8(SectionIndex
);
395 // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
404 void MachObjectWriter::WriteLinkeditLoadCommand(uint32_t Type
,
407 uint64_t Start
= OS
.tell();
411 Write32(sizeof(MachO::linkedit_data_command
));
415 assert(OS
.tell() - Start
== sizeof(MachO::linkedit_data_command
));
418 static unsigned ComputeLinkerOptionsLoadCommandSize(
419 const std::vector
<std::string
> &Options
, bool is64Bit
)
421 unsigned Size
= sizeof(MachO::linker_option_command
);
422 for (unsigned i
= 0, e
= Options
.size(); i
!= e
; ++i
)
423 Size
+= Options
[i
].size() + 1;
424 return RoundUpToAlignment(Size
, is64Bit
? 8 : 4);
427 void MachObjectWriter::WriteLinkerOptionsLoadCommand(
428 const std::vector
<std::string
> &Options
)
430 unsigned Size
= ComputeLinkerOptionsLoadCommandSize(Options
, is64Bit());
431 uint64_t Start
= OS
.tell();
434 Write32(MachO::LC_LINKER_OPTION
);
436 Write32(Options
.size());
437 uint64_t BytesWritten
= sizeof(MachO::linker_option_command
);
438 for (unsigned i
= 0, e
= Options
.size(); i
!= e
; ++i
) {
439 // Write each string, including the null byte.
440 const std::string
&Option
= Options
[i
];
441 WriteBytes(Option
.c_str(), Option
.size() + 1);
442 BytesWritten
+= Option
.size() + 1;
445 // Pad to a multiple of the pointer size.
446 WriteBytes("", OffsetToAlignment(BytesWritten
, is64Bit() ? 8 : 4));
448 assert(OS
.tell() - Start
== Size
);
452 void MachObjectWriter::RecordRelocation(const MCAssembler
&Asm
,
453 const MCAsmLayout
&Layout
,
454 const MCFragment
*Fragment
,
455 const MCFixup
&Fixup
,
458 uint64_t &FixedValue
) {
459 TargetObjectWriter
->RecordRelocation(this, Asm
, Layout
, Fragment
, Fixup
,
463 void MachObjectWriter::BindIndirectSymbols(MCAssembler
&Asm
) {
464 // This is the point where 'as' creates actual symbols for indirect symbols
465 // (in the following two passes). It would be easier for us to do this sooner
466 // when we see the attribute, but that makes getting the order in the symbol
467 // table much more complicated than it is worth.
469 // FIXME: Revisit this when the dust settles.
471 // Report errors for use of .indirect_symbol not in a symbol pointer section
473 for (MCAssembler::indirect_symbol_iterator it
= Asm
.indirect_symbol_begin(),
474 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
) {
475 const MCSectionMachO
&Section
=
476 cast
<MCSectionMachO
>(it
->SectionData
->getSection());
478 if (Section
.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS
&&
479 Section
.getType() != MachO::S_LAZY_SYMBOL_POINTERS
&&
480 Section
.getType() != MachO::S_SYMBOL_STUBS
) {
481 MCSymbol
&Symbol
= *it
->Symbol
;
482 report_fatal_error("indirect symbol '" + Symbol
.getName() +
483 "' not in a symbol pointer or stub section");
487 // Bind non-lazy symbol pointers first.
488 unsigned IndirectIndex
= 0;
489 for (MCAssembler::indirect_symbol_iterator it
= Asm
.indirect_symbol_begin(),
490 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
, ++IndirectIndex
) {
491 const MCSectionMachO
&Section
=
492 cast
<MCSectionMachO
>(it
->SectionData
->getSection());
494 if (Section
.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS
)
497 // Initialize the section indirect symbol base, if necessary.
498 IndirectSymBase
.insert(std::make_pair(it
->SectionData
, IndirectIndex
));
500 Asm
.getOrCreateSymbolData(*it
->Symbol
);
503 // Then lazy symbol pointers and symbol stubs.
505 for (MCAssembler::indirect_symbol_iterator it
= Asm
.indirect_symbol_begin(),
506 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
, ++IndirectIndex
) {
507 const MCSectionMachO
&Section
=
508 cast
<MCSectionMachO
>(it
->SectionData
->getSection());
510 if (Section
.getType() != MachO::S_LAZY_SYMBOL_POINTERS
&&
511 Section
.getType() != MachO::S_SYMBOL_STUBS
)
514 // Initialize the section indirect symbol base, if necessary.
515 IndirectSymBase
.insert(std::make_pair(it
->SectionData
, IndirectIndex
));
517 // Set the symbol type to undefined lazy, but only on construction.
519 // FIXME: Do not hardcode.
521 MCSymbolData
&Entry
= Asm
.getOrCreateSymbolData(*it
->Symbol
, &Created
);
523 Entry
.setFlags(Entry
.getFlags() | 0x0001);
527 /// ComputeSymbolTable - Compute the symbol table data
528 void MachObjectWriter::ComputeSymbolTable(
529 MCAssembler
&Asm
, std::vector
<MachSymbolData
> &LocalSymbolData
,
530 std::vector
<MachSymbolData
> &ExternalSymbolData
,
531 std::vector
<MachSymbolData
> &UndefinedSymbolData
) {
532 // Build section lookup table.
533 DenseMap
<const MCSection
*, uint8_t> SectionIndexMap
;
535 for (MCAssembler::iterator it
= Asm
.begin(),
536 ie
= Asm
.end(); it
!= ie
; ++it
, ++Index
)
537 SectionIndexMap
[&it
->getSection()] = Index
;
538 assert(Index
<= 256 && "Too many sections!");
540 // Build the string table.
541 for (MCSymbolData
&SD
: Asm
.symbols()) {
542 const MCSymbol
&Symbol
= SD
.getSymbol();
543 if (!Asm
.isSymbolLinkerVisible(Symbol
))
546 StringTable
.add(Symbol
.getName());
548 StringTable
.finalize(StringTableBuilder::MachO
);
550 // Build the symbol arrays but only for non-local symbols.
552 // The particular order that we collect and then sort the symbols is chosen to
553 // match 'as'. Even though it doesn't matter for correctness, this is
554 // important for letting us diff .o files.
555 for (MCSymbolData
&SD
: Asm
.symbols()) {
556 const MCSymbol
&Symbol
= SD
.getSymbol();
558 // Ignore non-linker visible symbols.
559 if (!Asm
.isSymbolLinkerVisible(Symbol
))
562 if (!SD
.isExternal() && !Symbol
.isUndefined())
566 MSD
.SymbolData
= &SD
;
567 MSD
.StringIndex
= StringTable
.getOffset(Symbol
.getName());
569 if (Symbol
.isUndefined()) {
570 MSD
.SectionIndex
= 0;
571 UndefinedSymbolData
.push_back(MSD
);
572 } else if (Symbol
.isAbsolute()) {
573 MSD
.SectionIndex
= 0;
574 ExternalSymbolData
.push_back(MSD
);
576 MSD
.SectionIndex
= SectionIndexMap
.lookup(&Symbol
.getSection());
577 assert(MSD
.SectionIndex
&& "Invalid section index!");
578 ExternalSymbolData
.push_back(MSD
);
582 // Now add the data for local symbols.
583 for (MCSymbolData
&SD
: Asm
.symbols()) {
584 const MCSymbol
&Symbol
= SD
.getSymbol();
586 // Ignore non-linker visible symbols.
587 if (!Asm
.isSymbolLinkerVisible(Symbol
))
590 if (SD
.isExternal() || Symbol
.isUndefined())
594 MSD
.SymbolData
= &SD
;
595 MSD
.StringIndex
= StringTable
.getOffset(Symbol
.getName());
597 if (Symbol
.isAbsolute()) {
598 MSD
.SectionIndex
= 0;
599 LocalSymbolData
.push_back(MSD
);
601 MSD
.SectionIndex
= SectionIndexMap
.lookup(&Symbol
.getSection());
602 assert(MSD
.SectionIndex
&& "Invalid section index!");
603 LocalSymbolData
.push_back(MSD
);
607 // External and undefined symbols are required to be in lexicographic order.
608 std::sort(ExternalSymbolData
.begin(), ExternalSymbolData
.end());
609 std::sort(UndefinedSymbolData
.begin(), UndefinedSymbolData
.end());
611 // Set the symbol indices.
613 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
614 LocalSymbolData
[i
].SymbolData
->setIndex(Index
++);
615 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
616 ExternalSymbolData
[i
].SymbolData
->setIndex(Index
++);
617 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
618 UndefinedSymbolData
[i
].SymbolData
->setIndex(Index
++);
621 void MachObjectWriter::computeSectionAddresses(const MCAssembler
&Asm
,
622 const MCAsmLayout
&Layout
) {
623 uint64_t StartAddress
= 0;
624 const SmallVectorImpl
<MCSectionData
*> &Order
= Layout
.getSectionOrder();
625 for (int i
= 0, n
= Order
.size(); i
!= n
; ++i
) {
626 const MCSectionData
*SD
= Order
[i
];
627 StartAddress
= RoundUpToAlignment(StartAddress
, SD
->getAlignment());
628 SectionAddress
[SD
] = StartAddress
;
629 StartAddress
+= Layout
.getSectionAddressSize(SD
);
631 // Explicitly pad the section to match the alignment requirements of the
632 // following one. This is for 'gas' compatibility, it shouldn't
633 /// strictly be necessary.
634 StartAddress
+= getPaddingSize(SD
, Layout
);
638 void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler
&Asm
,
639 const MCAsmLayout
&Layout
) {
640 for (MCSymbolData
&SD
: Asm
.symbols()) {
641 if (!SD
.getSymbol().isVariable())
644 // Is the variable is a symbol difference (SA - SB + C) expression,
645 // and neither symbol is external, mark the variable as absolute.
646 const MCExpr
*Expr
= SD
.getSymbol().getVariableValue();
648 if (Expr
->EvaluateAsRelocatable(Value
, &Layout
, nullptr)) {
649 if (Value
.getSymA() && Value
.getSymB())
650 const_cast<MCSymbol
*>(&SD
.getSymbol())->setAbsolute();
655 void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler
&Asm
,
656 const MCAsmLayout
&Layout
) {
657 computeSectionAddresses(Asm
, Layout
);
659 // Create symbol data for any indirect symbols.
660 BindIndirectSymbols(Asm
);
662 // Mark symbol difference expressions in variables (from .set or = directives)
664 markAbsoluteVariableSymbols(Asm
, Layout
);
666 // Compute symbol table information and bind symbol indices.
667 ComputeSymbolTable(Asm
, LocalSymbolData
, ExternalSymbolData
,
668 UndefinedSymbolData
);
671 bool MachObjectWriter::
672 IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler
&Asm
,
673 const MCSymbolData
&DataA
,
674 const MCFragment
&FB
,
676 bool IsPCRel
) const {
680 // The effective address is
681 // addr(atom(A)) + offset(A)
682 // - addr(atom(B)) - offset(B)
683 // and the offsets are not relocatable, so the fixup is fully resolved when
684 // addr(atom(A)) - addr(atom(B)) == 0.
685 const MCSymbolData
*A_Base
= nullptr, *B_Base
= nullptr;
687 const MCSymbol
&SA
= DataA
.getSymbol().AliasedSymbol();
688 const MCSection
&SecA
= SA
.getSection();
689 const MCSection
&SecB
= FB
.getParent()->getSection();
692 // The simple (Darwin, except on x86_64) way of dealing with this was to
693 // assume that any reference to a temporary symbol *must* be a temporary
694 // symbol in the same atom, unless the sections differ. Therefore, any PCrel
695 // relocation to a temporary symbol (in the same section) is fully
696 // resolved. This also works in conjunction with absolutized .set, which
697 // requires the compiler to use .set to absolutize the differences between
698 // symbols which the compiler knows to be assembly time constants, so we
699 // don't need to worry about considering symbol differences fully resolved.
701 // If the file isn't using sub-sections-via-symbols, we can make the
702 // same assumptions about any symbol that we normally make about
705 bool hasReliableSymbolDifference
= isX86_64();
706 if (!hasReliableSymbolDifference
) {
707 if (!SA
.isInSection() || &SecA
!= &SecB
||
708 (!SA
.isTemporary() &&
709 FB
.getAtom() != Asm
.getSymbolData(SA
).getFragment()->getAtom() &&
710 Asm
.getSubsectionsViaSymbols()))
714 // For Darwin x86_64, there is one special case when the reference IsPCRel.
715 // If the fragment with the reference does not have a base symbol but meets
716 // the simple way of dealing with this, in that it is a temporary symbol in
717 // the same atom then it is assumed to be fully resolved. This is needed so
718 // a relocation entry is not created and so the static linker does not
719 // mess up the reference later.
720 else if(!FB
.getAtom() &&
721 SA
.isTemporary() && SA
.isInSection() && &SecA
== &SecB
){
725 if (!TargetObjectWriter
->useAggressiveSymbolFolding())
729 // If they are not in the same section, we can't compute the diff.
733 const MCFragment
*FA
= Asm
.getSymbolData(SA
).getFragment();
735 // Bail if the symbol has no fragment.
739 A_Base
= FA
->getAtom();
740 B_Base
= FB
.getAtom();
742 // If the atoms are the same, they are guaranteed to have the same address.
743 if (A_Base
== B_Base
)
746 // Otherwise, we can't prove this is fully resolved.
750 void MachObjectWriter::WriteObject(MCAssembler
&Asm
,
751 const MCAsmLayout
&Layout
) {
752 unsigned NumSections
= Asm
.size();
753 const MCAssembler::VersionMinInfoType
&VersionInfo
=
754 Layout
.getAssembler().getVersionMinInfo();
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
= is64Bit() ?
760 sizeof(MachO::segment_command_64
) + NumSections
* sizeof(MachO::section_64
):
761 sizeof(MachO::segment_command
) + NumSections
* sizeof(MachO::section
);
763 // Add the deployment target version info load command size, if used.
764 if (VersionInfo
.Major
!= 0) {
766 LoadCommandsSize
+= sizeof(MachO::version_min_command
);
769 // Add the data-in-code load command size, if used.
770 unsigned NumDataRegions
= Asm
.getDataRegions().size();
771 if (NumDataRegions
) {
773 LoadCommandsSize
+= sizeof(MachO::linkedit_data_command
);
776 // Add the loh load command size, if used.
777 uint64_t LOHRawSize
= Asm
.getLOHContainer().getEmitSize(*this, Layout
);
778 uint64_t LOHSize
= RoundUpToAlignment(LOHRawSize
, is64Bit() ? 8 : 4);
781 LoadCommandsSize
+= sizeof(MachO::linkedit_data_command
);
784 // Add the symbol table load command sizes, if used.
785 unsigned NumSymbols
= LocalSymbolData
.size() + ExternalSymbolData
.size() +
786 UndefinedSymbolData
.size();
788 NumLoadCommands
+= 2;
789 LoadCommandsSize
+= (sizeof(MachO::symtab_command
) +
790 sizeof(MachO::dysymtab_command
));
793 // Add the linker option load commands sizes.
794 const std::vector
<std::vector
<std::string
> > &LinkerOptions
=
795 Asm
.getLinkerOptions();
796 for (unsigned i
= 0, e
= LinkerOptions
.size(); i
!= e
; ++i
) {
798 LoadCommandsSize
+= ComputeLinkerOptionsLoadCommandSize(LinkerOptions
[i
],
802 // Compute the total size of the section data, as well as its file size and vm
804 uint64_t SectionDataStart
= (is64Bit() ? sizeof(MachO::mach_header_64
) :
805 sizeof(MachO::mach_header
)) + LoadCommandsSize
;
806 uint64_t SectionDataSize
= 0;
807 uint64_t SectionDataFileSize
= 0;
809 for (MCAssembler::const_iterator it
= Asm
.begin(),
810 ie
= Asm
.end(); it
!= ie
; ++it
) {
811 const MCSectionData
&SD
= *it
;
812 uint64_t Address
= getSectionAddress(&SD
);
813 uint64_t Size
= Layout
.getSectionAddressSize(&SD
);
814 uint64_t FileSize
= Layout
.getSectionFileSize(&SD
);
815 FileSize
+= getPaddingSize(&SD
, Layout
);
817 VMSize
= std::max(VMSize
, Address
+ Size
);
819 if (SD
.getSection().isVirtualSection())
822 SectionDataSize
= std::max(SectionDataSize
, Address
+ Size
);
823 SectionDataFileSize
= std::max(SectionDataFileSize
, Address
+ FileSize
);
826 // The section data is padded to 4 bytes.
828 // FIXME: Is this machine dependent?
829 unsigned SectionDataPadding
= OffsetToAlignment(SectionDataFileSize
, 4);
830 SectionDataFileSize
+= SectionDataPadding
;
832 // Write the prolog, starting with the header and load command...
833 WriteHeader(NumLoadCommands
, LoadCommandsSize
,
834 Asm
.getSubsectionsViaSymbols());
835 WriteSegmentLoadCommand(NumSections
, VMSize
,
836 SectionDataStart
, SectionDataSize
);
838 // ... and then the section headers.
839 uint64_t RelocTableEnd
= SectionDataStart
+ SectionDataFileSize
;
840 for (MCAssembler::const_iterator it
= Asm
.begin(),
841 ie
= Asm
.end(); it
!= ie
; ++it
) {
842 std::vector
<MachO::any_relocation_info
> &Relocs
= Relocations
[it
];
843 unsigned NumRelocs
= Relocs
.size();
844 uint64_t SectionStart
= SectionDataStart
+ getSectionAddress(it
);
845 WriteSection(Asm
, Layout
, *it
, SectionStart
, RelocTableEnd
, NumRelocs
);
846 RelocTableEnd
+= NumRelocs
* sizeof(MachO::any_relocation_info
);
849 // Write out the deployment target information, if it's available.
850 if (VersionInfo
.Major
!= 0) {
851 assert(VersionInfo
.Update
< 256 && "unencodable update target version");
852 assert(VersionInfo
.Minor
< 256 && "unencodable minor target version");
853 assert(VersionInfo
.Major
< 65536 && "unencodable major target version");
854 uint32_t EncodedVersion
= VersionInfo
.Update
| (VersionInfo
.Minor
<< 8) |
855 (VersionInfo
.Major
<< 16);
856 Write32(VersionInfo
.Kind
== MCVM_OSXVersionMin
? MachO::LC_VERSION_MIN_MACOSX
:
857 MachO::LC_VERSION_MIN_IPHONEOS
);
858 Write32(sizeof(MachO::version_min_command
));
859 Write32(EncodedVersion
);
860 Write32(0); // reserved.
863 // Write the data-in-code load command, if used.
864 uint64_t DataInCodeTableEnd
= RelocTableEnd
+ NumDataRegions
* 8;
865 if (NumDataRegions
) {
866 uint64_t DataRegionsOffset
= RelocTableEnd
;
867 uint64_t DataRegionsSize
= NumDataRegions
* 8;
868 WriteLinkeditLoadCommand(MachO::LC_DATA_IN_CODE
, DataRegionsOffset
,
872 // Write the loh load command, if used.
873 uint64_t LOHTableEnd
= DataInCodeTableEnd
+ LOHSize
;
875 WriteLinkeditLoadCommand(MachO::LC_LINKER_OPTIMIZATION_HINT
,
876 DataInCodeTableEnd
, LOHSize
);
878 // Write the symbol table load command, if used.
880 unsigned FirstLocalSymbol
= 0;
881 unsigned NumLocalSymbols
= LocalSymbolData
.size();
882 unsigned FirstExternalSymbol
= FirstLocalSymbol
+ NumLocalSymbols
;
883 unsigned NumExternalSymbols
= ExternalSymbolData
.size();
884 unsigned FirstUndefinedSymbol
= FirstExternalSymbol
+ NumExternalSymbols
;
885 unsigned NumUndefinedSymbols
= UndefinedSymbolData
.size();
886 unsigned NumIndirectSymbols
= Asm
.indirect_symbol_size();
887 unsigned NumSymTabSymbols
=
888 NumLocalSymbols
+ NumExternalSymbols
+ NumUndefinedSymbols
;
889 uint64_t IndirectSymbolSize
= NumIndirectSymbols
* 4;
890 uint64_t IndirectSymbolOffset
= 0;
892 // If used, the indirect symbols are written after the section data.
893 if (NumIndirectSymbols
)
894 IndirectSymbolOffset
= LOHTableEnd
;
896 // The symbol table is written after the indirect symbol data.
897 uint64_t SymbolTableOffset
= LOHTableEnd
+ IndirectSymbolSize
;
899 // The string table is written after symbol table.
900 uint64_t StringTableOffset
=
901 SymbolTableOffset
+ NumSymTabSymbols
* (is64Bit() ?
902 sizeof(MachO::nlist_64
) :
903 sizeof(MachO::nlist
));
904 WriteSymtabLoadCommand(SymbolTableOffset
, NumSymTabSymbols
,
905 StringTableOffset
, StringTable
.data().size());
907 WriteDysymtabLoadCommand(FirstLocalSymbol
, NumLocalSymbols
,
908 FirstExternalSymbol
, NumExternalSymbols
,
909 FirstUndefinedSymbol
, NumUndefinedSymbols
,
910 IndirectSymbolOffset
, NumIndirectSymbols
);
913 // Write the linker options load commands.
914 for (unsigned i
= 0, e
= LinkerOptions
.size(); i
!= e
; ++i
) {
915 WriteLinkerOptionsLoadCommand(LinkerOptions
[i
]);
918 // Write the actual section data.
919 for (MCAssembler::const_iterator it
= Asm
.begin(),
920 ie
= Asm
.end(); it
!= ie
; ++it
) {
921 Asm
.writeSectionData(it
, Layout
);
923 uint64_t Pad
= getPaddingSize(it
, Layout
);
924 for (unsigned int i
= 0; i
< Pad
; ++i
)
928 // Write the extra padding.
929 WriteZeros(SectionDataPadding
);
931 // Write the relocation entries.
932 for (MCAssembler::const_iterator it
= Asm
.begin(),
933 ie
= Asm
.end(); it
!= ie
; ++it
) {
934 // Write the section relocation entries, in reverse order to match 'as'
935 // (approximately, the exact algorithm is more complicated than this).
936 std::vector
<MachO::any_relocation_info
> &Relocs
= Relocations
[it
];
937 for (unsigned i
= 0, e
= Relocs
.size(); i
!= e
; ++i
) {
938 Write32(Relocs
[e
- i
- 1].r_word0
);
939 Write32(Relocs
[e
- i
- 1].r_word1
);
943 // Write out the data-in-code region payload, if there is one.
944 for (MCAssembler::const_data_region_iterator
945 it
= Asm
.data_region_begin(), ie
= Asm
.data_region_end();
947 const DataRegionData
*Data
= &(*it
);
949 getSymbolAddress(&Layout
.getAssembler().getSymbolData(*Data
->Start
),
952 getSymbolAddress(&Layout
.getAssembler().getSymbolData(*Data
->End
),
954 DEBUG(dbgs() << "data in code region-- kind: " << Data
->Kind
955 << " start: " << Start
<< "(" << Data
->Start
->getName() << ")"
956 << " end: " << End
<< "(" << Data
->End
->getName() << ")"
957 << " size: " << End
- Start
960 Write16(End
- Start
);
964 // Write out the loh commands, if there is one.
967 unsigned Start
= OS
.tell();
969 Asm
.getLOHContainer().Emit(*this, Layout
);
970 // Pad to a multiple of the pointer size.
971 WriteBytes("", OffsetToAlignment(LOHRawSize
, is64Bit() ? 8 : 4));
972 assert(OS
.tell() - Start
== LOHSize
);
975 // Write the symbol table data, if used.
977 // Write the indirect symbol entries.
978 for (MCAssembler::const_indirect_symbol_iterator
979 it
= Asm
.indirect_symbol_begin(),
980 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
) {
981 // Indirect symbols in the non-lazy symbol pointer section have some
983 const MCSectionMachO
&Section
=
984 static_cast<const MCSectionMachO
&>(it
->SectionData
->getSection());
985 if (Section
.getType() == MachO::S_NON_LAZY_SYMBOL_POINTERS
) {
986 // If this symbol is defined and internal, mark it as such.
987 if (it
->Symbol
->isDefined() &&
988 !Asm
.getSymbolData(*it
->Symbol
).isExternal()) {
989 uint32_t Flags
= MachO::INDIRECT_SYMBOL_LOCAL
;
990 if (it
->Symbol
->isAbsolute())
991 Flags
|= MachO::INDIRECT_SYMBOL_ABS
;
997 Write32(Asm
.getSymbolData(*it
->Symbol
).getIndex());
1000 // FIXME: Check that offsets match computed ones.
1002 // Write the symbol table entries.
1003 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
1004 WriteNlist(LocalSymbolData
[i
], Layout
);
1005 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
1006 WriteNlist(ExternalSymbolData
[i
], Layout
);
1007 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
1008 WriteNlist(UndefinedSymbolData
[i
], Layout
);
1010 // Write the string table.
1011 OS
<< StringTable
.data();
1015 MCObjectWriter
*llvm::createMachObjectWriter(MCMachObjectTargetWriter
*MOTW
,
1017 bool IsLittleEndian
) {
1018 return new MachObjectWriter(MOTW
, OS
, IsLittleEndian
);