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/OwningPtr.h"
12 #include "llvm/ADT/StringMap.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCAsmLayout.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCObjectWriter.h"
18 #include "llvm/MC/MCSectionMachO.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/MC/MCMachOSymbolFlags.h"
21 #include "llvm/MC/MCValue.h"
22 #include "llvm/Object/MachOFormat.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Target/TargetAsmBackend.h"
27 #include "../Target/ARM/ARMFixupKinds.h"
28 #include "../Target/X86/X86FixupKinds.h"
32 using namespace llvm::object
;
34 // FIXME: this has been copied from (or to) X86AsmBackend.cpp
35 static unsigned getFixupKindLog2Size(unsigned Kind
) {
38 llvm_unreachable("invalid fixup kind!");
40 case FK_Data_1
: return 0;
42 case FK_Data_2
: return 1;
44 // FIXME: Remove these!!!
45 case X86::reloc_riprel_4byte
:
46 case X86::reloc_riprel_4byte_movq_load
:
47 case X86::reloc_signed_4byte
:
48 case FK_Data_4
: return 2;
49 case FK_Data_8
: return 3;
53 static bool doesSymbolRequireExternRelocation(MCSymbolData
*SD
) {
54 // Undefined symbols are always extern.
55 if (SD
->Symbol
->isUndefined())
58 // References to weak definitions require external relocation entries; the
59 // definition may not always be the one in the same object file.
60 if (SD
->getFlags() & SF_WeakDefinition
)
63 // Otherwise, we can use an internal relocation.
69 class MachObjectWriter
: public MCObjectWriter
{
70 /// MachSymbolData - Helper struct for containing some precomputed information
72 struct MachSymbolData
{
73 MCSymbolData
*SymbolData
;
77 // Support lexicographic sorting.
78 bool operator<(const MachSymbolData
&RHS
) const {
79 return SymbolData
->getSymbol().getName() <
80 RHS
.SymbolData
->getSymbol().getName();
84 /// The target specific Mach-O writer instance.
85 llvm::OwningPtr
<MCMachObjectTargetWriter
> TargetObjectWriter
;
87 /// @name Relocation Data
90 llvm::DenseMap
<const MCSectionData
*,
91 std::vector
<macho::RelocationEntry
> > Relocations
;
92 llvm::DenseMap
<const MCSectionData
*, unsigned> IndirectSymBase
;
95 /// @name Symbol Table Data
98 SmallString
<256> StringTable
;
99 std::vector
<MachSymbolData
> LocalSymbolData
;
100 std::vector
<MachSymbolData
> ExternalSymbolData
;
101 std::vector
<MachSymbolData
> UndefinedSymbolData
;
106 /// @name Utility Methods
109 bool isFixupKindPCRel(const MCAssembler
&Asm
, unsigned Kind
) {
110 const MCFixupKindInfo
&FKI
= Asm
.getBackend().getFixupKindInfo(
113 return FKI
.Flags
& MCFixupKindInfo::FKF_IsPCRel
;
118 SectionAddrMap SectionAddress
;
119 uint64_t getSectionAddress(const MCSectionData
* SD
) const {
120 return SectionAddress
.lookup(SD
);
122 uint64_t getSymbolAddress(const MCSymbolData
* SD
,
123 const MCAsmLayout
&Layout
) const {
124 const MCSymbol
&S
= SD
->getSymbol();
126 // If this is a variable, then recursively evaluate now.
127 if (S
.isVariable()) {
129 if (!S
.getVariableValue()->EvaluateAsRelocatable(Target
, Layout
))
130 report_fatal_error("unable to evaluate offset for variable '" +
133 // Verify that any used symbols are defined.
134 if (Target
.getSymA() && Target
.getSymA()->getSymbol().isUndefined())
135 report_fatal_error("unable to evaluate offset to undefined symbol '" +
136 Target
.getSymA()->getSymbol().getName() + "'");
137 if (Target
.getSymB() && Target
.getSymB()->getSymbol().isUndefined())
138 report_fatal_error("unable to evaluate offset to undefined symbol '" +
139 Target
.getSymB()->getSymbol().getName() + "'");
141 uint64_t Address
= Target
.getConstant();
142 if (Target
.getSymA())
143 Address
+= getSymbolAddress(&Layout
.getAssembler().getSymbolData(
144 Target
.getSymA()->getSymbol()), Layout
);
145 if (Target
.getSymB())
146 Address
+= getSymbolAddress(&Layout
.getAssembler().getSymbolData(
147 Target
.getSymB()->getSymbol()), Layout
);
151 return getSectionAddress(SD
->getFragment()->getParent()) +
152 Layout
.getSymbolOffset(SD
);
154 uint64_t getFragmentAddress(const MCFragment
*Fragment
,
155 const MCAsmLayout
&Layout
) const {
156 return getSectionAddress(Fragment
->getParent()) +
157 Layout
.getFragmentOffset(Fragment
);
160 uint64_t getPaddingSize(const MCSectionData
*SD
,
161 const MCAsmLayout
&Layout
) const {
162 uint64_t EndAddr
= getSectionAddress(SD
) + Layout
.getSectionAddressSize(SD
);
163 unsigned Next
= SD
->getLayoutOrder() + 1;
164 if (Next
>= Layout
.getSectionOrder().size())
167 const MCSectionData
&NextSD
= *Layout
.getSectionOrder()[Next
];
168 if (NextSD
.getSection().isVirtualSection())
170 return OffsetToAlignment(EndAddr
, NextSD
.getAlignment());
174 MachObjectWriter(MCMachObjectTargetWriter
*MOTW
, raw_ostream
&_OS
,
175 bool _IsLittleEndian
)
176 : MCObjectWriter(_OS
, _IsLittleEndian
), TargetObjectWriter(MOTW
) {
179 /// @name Target Writer Proxy Accessors
182 bool is64Bit() const { return TargetObjectWriter
->is64Bit(); }
184 uint32_t CPUType
= TargetObjectWriter
->getCPUType() & ~mach::CTFM_ArchMask
;
185 return CPUType
== mach::CTM_ARM
;
190 void WriteHeader(unsigned NumLoadCommands
, unsigned LoadCommandsSize
,
191 bool SubsectionsViaSymbols
) {
194 if (SubsectionsViaSymbols
)
195 Flags
|= macho::HF_SubsectionsViaSymbols
;
197 // struct mach_header (28 bytes) or
198 // struct mach_header_64 (32 bytes)
200 uint64_t Start
= OS
.tell();
203 Write32(is64Bit() ? macho::HM_Object64
: macho::HM_Object32
);
205 Write32(TargetObjectWriter
->getCPUType());
206 Write32(TargetObjectWriter
->getCPUSubtype());
208 Write32(macho::HFT_Object
);
209 Write32(NumLoadCommands
);
210 Write32(LoadCommandsSize
);
213 Write32(0); // reserved
215 assert(OS
.tell() - Start
==
216 (is64Bit() ? macho::Header64Size
: macho::Header32Size
));
219 /// WriteSegmentLoadCommand - Write a segment load command.
221 /// \arg NumSections - The number of sections in this segment.
222 /// \arg SectionDataSize - The total size of the sections.
223 void WriteSegmentLoadCommand(unsigned NumSections
,
225 uint64_t SectionDataStartOffset
,
226 uint64_t SectionDataSize
) {
227 // struct segment_command (56 bytes) or
228 // struct segment_command_64 (72 bytes)
230 uint64_t Start
= OS
.tell();
233 unsigned SegmentLoadCommandSize
=
234 is64Bit() ? macho::SegmentLoadCommand64Size
:
235 macho::SegmentLoadCommand32Size
;
236 Write32(is64Bit() ? macho::LCT_Segment64
: macho::LCT_Segment
);
237 Write32(SegmentLoadCommandSize
+
238 NumSections
* (is64Bit() ? macho::Section64Size
:
239 macho::Section32Size
));
243 Write64(0); // vmaddr
244 Write64(VMSize
); // vmsize
245 Write64(SectionDataStartOffset
); // file offset
246 Write64(SectionDataSize
); // file size
248 Write32(0); // vmaddr
249 Write32(VMSize
); // vmsize
250 Write32(SectionDataStartOffset
); // file offset
251 Write32(SectionDataSize
); // file size
253 Write32(0x7); // maxprot
254 Write32(0x7); // initprot
255 Write32(NumSections
);
258 assert(OS
.tell() - Start
== SegmentLoadCommandSize
);
261 void WriteSection(const MCAssembler
&Asm
, const MCAsmLayout
&Layout
,
262 const MCSectionData
&SD
, uint64_t FileOffset
,
263 uint64_t RelocationsStart
, unsigned NumRelocations
) {
264 uint64_t SectionSize
= Layout
.getSectionAddressSize(&SD
);
266 // The offset is unused for virtual sections.
267 if (SD
.getSection().isVirtualSection()) {
268 assert(Layout
.getSectionFileSize(&SD
) == 0 && "Invalid file size!");
272 // struct section (68 bytes) or
273 // struct section_64 (80 bytes)
275 uint64_t Start
= OS
.tell();
278 const MCSectionMachO
&Section
= cast
<MCSectionMachO
>(SD
.getSection());
279 WriteBytes(Section
.getSectionName(), 16);
280 WriteBytes(Section
.getSegmentName(), 16);
282 Write64(getSectionAddress(&SD
)); // address
283 Write64(SectionSize
); // size
285 Write32(getSectionAddress(&SD
)); // address
286 Write32(SectionSize
); // size
290 unsigned Flags
= Section
.getTypeAndAttributes();
291 if (SD
.hasInstructions())
292 Flags
|= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS
;
294 assert(isPowerOf2_32(SD
.getAlignment()) && "Invalid alignment!");
295 Write32(Log2_32(SD
.getAlignment()));
296 Write32(NumRelocations
? RelocationsStart
: 0);
297 Write32(NumRelocations
);
299 Write32(IndirectSymBase
.lookup(&SD
)); // reserved1
300 Write32(Section
.getStubSize()); // reserved2
302 Write32(0); // reserved3
304 assert(OS
.tell() - Start
== (is64Bit() ? macho::Section64Size
:
305 macho::Section32Size
));
308 void WriteSymtabLoadCommand(uint32_t SymbolOffset
, uint32_t NumSymbols
,
309 uint32_t StringTableOffset
,
310 uint32_t StringTableSize
) {
311 // struct symtab_command (24 bytes)
313 uint64_t Start
= OS
.tell();
316 Write32(macho::LCT_Symtab
);
317 Write32(macho::SymtabLoadCommandSize
);
318 Write32(SymbolOffset
);
320 Write32(StringTableOffset
);
321 Write32(StringTableSize
);
323 assert(OS
.tell() - Start
== macho::SymtabLoadCommandSize
);
326 void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol
,
327 uint32_t NumLocalSymbols
,
328 uint32_t FirstExternalSymbol
,
329 uint32_t NumExternalSymbols
,
330 uint32_t FirstUndefinedSymbol
,
331 uint32_t NumUndefinedSymbols
,
332 uint32_t IndirectSymbolOffset
,
333 uint32_t NumIndirectSymbols
) {
334 // struct dysymtab_command (80 bytes)
336 uint64_t Start
= OS
.tell();
339 Write32(macho::LCT_Dysymtab
);
340 Write32(macho::DysymtabLoadCommandSize
);
341 Write32(FirstLocalSymbol
);
342 Write32(NumLocalSymbols
);
343 Write32(FirstExternalSymbol
);
344 Write32(NumExternalSymbols
);
345 Write32(FirstUndefinedSymbol
);
346 Write32(NumUndefinedSymbols
);
347 Write32(0); // tocoff
349 Write32(0); // modtaboff
350 Write32(0); // nmodtab
351 Write32(0); // extrefsymoff
352 Write32(0); // nextrefsyms
353 Write32(IndirectSymbolOffset
);
354 Write32(NumIndirectSymbols
);
355 Write32(0); // extreloff
356 Write32(0); // nextrel
357 Write32(0); // locreloff
358 Write32(0); // nlocrel
360 assert(OS
.tell() - Start
== macho::DysymtabLoadCommandSize
);
363 void WriteNlist(MachSymbolData
&MSD
, const MCAsmLayout
&Layout
) {
364 MCSymbolData
&Data
= *MSD
.SymbolData
;
365 const MCSymbol
&Symbol
= Data
.getSymbol();
367 uint16_t Flags
= Data
.getFlags();
368 uint32_t Address
= 0;
370 // Set the N_TYPE bits. See <mach-o/nlist.h>.
372 // FIXME: Are the prebound or indirect fields possible here?
373 if (Symbol
.isUndefined())
374 Type
= macho::STT_Undefined
;
375 else if (Symbol
.isAbsolute())
376 Type
= macho::STT_Absolute
;
378 Type
= macho::STT_Section
;
380 // FIXME: Set STAB bits.
382 if (Data
.isPrivateExtern())
383 Type
|= macho::STF_PrivateExtern
;
386 if (Data
.isExternal() || Symbol
.isUndefined())
387 Type
|= macho::STF_External
;
389 // Compute the symbol address.
390 if (Symbol
.isDefined()) {
391 if (Symbol
.isAbsolute()) {
392 Address
= cast
<MCConstantExpr
>(Symbol
.getVariableValue())->getValue();
394 Address
= getSymbolAddress(&Data
, Layout
);
396 } else if (Data
.isCommon()) {
397 // Common symbols are encoded with the size in the address
398 // field, and their alignment in the flags.
399 Address
= Data
.getCommonSize();
401 // Common alignment is packed into the 'desc' bits.
402 if (unsigned Align
= Data
.getCommonAlignment()) {
403 unsigned Log2Size
= Log2_32(Align
);
404 assert((1U << Log2Size
) == Align
&& "Invalid 'common' alignment!");
406 report_fatal_error("invalid 'common' alignment '" +
408 // FIXME: Keep this mask with the SymbolFlags enumeration.
409 Flags
= (Flags
& 0xF0FF) | (Log2Size
<< 8);
413 // struct nlist (12 bytes)
415 Write32(MSD
.StringIndex
);
417 Write8(MSD
.SectionIndex
);
419 // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
428 // FIXME: We really need to improve the relocation validation. Basically, we
429 // want to implement a separate computation which evaluates the relocation
430 // entry as the linker would, and verifies that the resultant fixup value is
431 // exactly what the encoder wanted. This will catch several classes of
434 // - Relocation entry bugs, the two algorithms are unlikely to have the same
437 // - Relaxation issues, where we forget to relax something.
439 // - Input errors, where something cannot be correctly encoded. 'as' allows
440 // these through in many cases.
442 static bool isFixupKindRIPRel(unsigned Kind
) {
443 return Kind
== X86::reloc_riprel_4byte
||
444 Kind
== X86::reloc_riprel_4byte_movq_load
;
446 void RecordX86_64Relocation(const MCAssembler
&Asm
, const MCAsmLayout
&Layout
,
447 const MCFragment
*Fragment
,
448 const MCFixup
&Fixup
, MCValue Target
,
449 uint64_t &FixedValue
) {
450 unsigned IsPCRel
= isFixupKindPCRel(Asm
, Fixup
.getKind());
451 unsigned IsRIPRel
= isFixupKindRIPRel(Fixup
.getKind());
452 unsigned Log2Size
= getFixupKindLog2Size(Fixup
.getKind());
455 uint32_t FixupOffset
=
456 Layout
.getFragmentOffset(Fragment
) + Fixup
.getOffset();
457 uint32_t FixupAddress
=
458 getFragmentAddress(Fragment
, Layout
) + Fixup
.getOffset();
461 unsigned IsExtern
= 0;
464 Value
= Target
.getConstant();
467 // Compensate for the relocation offset, Darwin x86_64 relocations only
468 // have the addend and appear to have attempted to define it to be the
469 // actual expression addend without the PCrel bias. However, instructions
470 // with data following the relocation are not accommodated for (see comment
471 // below regarding SIGNED{1,2,4}), so it isn't exactly that either.
472 Value
+= 1LL << Log2Size
;
475 if (Target
.isAbsolute()) { // constant
476 // SymbolNum of 0 indicates the absolute section.
477 Type
= macho::RIT_X86_64_Unsigned
;
480 // FIXME: I believe this is broken, I don't think the linker can
481 // understand it. I think it would require a local relocation, but I'm not
482 // sure if that would work either. The official way to get an absolute
483 // PCrel relocation is to use an absolute symbol (which we don't support
487 Type
= macho::RIT_X86_64_Branch
;
489 } else if (Target
.getSymB()) { // A - B + constant
490 const MCSymbol
*A
= &Target
.getSymA()->getSymbol();
491 MCSymbolData
&A_SD
= Asm
.getSymbolData(*A
);
492 const MCSymbolData
*A_Base
= Asm
.getAtom(&A_SD
);
494 const MCSymbol
*B
= &Target
.getSymB()->getSymbol();
495 MCSymbolData
&B_SD
= Asm
.getSymbolData(*B
);
496 const MCSymbolData
*B_Base
= Asm
.getAtom(&B_SD
);
498 // Neither symbol can be modified.
499 if (Target
.getSymA()->getKind() != MCSymbolRefExpr::VK_None
||
500 Target
.getSymB()->getKind() != MCSymbolRefExpr::VK_None
)
501 report_fatal_error("unsupported relocation of modified symbol");
503 // We don't support PCrel relocations of differences. Darwin 'as' doesn't
504 // implement most of these correctly.
506 report_fatal_error("unsupported pc-relative relocation of difference");
508 // The support for the situation where one or both of the symbols would
509 // require a local relocation is handled just like if the symbols were
510 // external. This is certainly used in the case of debug sections where
511 // the section has only temporary symbols and thus the symbols don't have
512 // base symbols. This is encoded using the section ordinal and
513 // non-extern relocation entries.
515 // Darwin 'as' doesn't emit correct relocations for this (it ends up with
516 // a single SIGNED relocation); reject it for now. Except the case where
517 // both symbols don't have a base, equal but both NULL.
518 if (A_Base
== B_Base
&& A_Base
)
519 report_fatal_error("unsupported relocation with identical base");
521 Value
+= getSymbolAddress(&A_SD
, Layout
) -
522 (A_Base
== NULL
? 0 : getSymbolAddress(A_Base
, Layout
));
523 Value
-= getSymbolAddress(&B_SD
, Layout
) -
524 (B_Base
== NULL
? 0 : getSymbolAddress(B_Base
, Layout
));
527 Index
= A_Base
->getIndex();
531 Index
= A_SD
.getFragment()->getParent()->getOrdinal() + 1;
534 Type
= macho::RIT_X86_64_Unsigned
;
536 macho::RelocationEntry MRE
;
537 MRE
.Word0
= FixupOffset
;
538 MRE
.Word1
= ((Index
<< 0) |
543 Relocations
[Fragment
->getParent()].push_back(MRE
);
546 Index
= B_Base
->getIndex();
550 Index
= B_SD
.getFragment()->getParent()->getOrdinal() + 1;
553 Type
= macho::RIT_X86_64_Subtractor
;
555 const MCSymbol
*Symbol
= &Target
.getSymA()->getSymbol();
556 MCSymbolData
&SD
= Asm
.getSymbolData(*Symbol
);
557 const MCSymbolData
*Base
= Asm
.getAtom(&SD
);
559 // Relocations inside debug sections always use local relocations when
560 // possible. This seems to be done because the debugger doesn't fully
561 // understand x86_64 relocation entries, and expects to find values that
562 // have already been fixed up.
563 if (Symbol
->isInSection()) {
564 const MCSectionMachO
&Section
= static_cast<const MCSectionMachO
&>(
565 Fragment
->getParent()->getSection());
566 if (Section
.hasAttribute(MCSectionMachO::S_ATTR_DEBUG
))
570 // x86_64 almost always uses external relocations, except when there is no
571 // symbol to use as a base address (a local symbol with no preceding
572 // non-local symbol).
574 Index
= Base
->getIndex();
577 // Add the local offset, if needed.
579 Value
+= Layout
.getSymbolOffset(&SD
) - Layout
.getSymbolOffset(Base
);
580 } else if (Symbol
->isInSection() && !Symbol
->isVariable()) {
581 // The index is the section ordinal (1-based).
582 Index
= SD
.getFragment()->getParent()->getOrdinal() + 1;
584 Value
+= getSymbolAddress(&SD
, Layout
);
587 Value
-= FixupAddress
+ (1 << Log2Size
);
588 } else if (Symbol
->isVariable()) {
589 const MCExpr
*Value
= Symbol
->getVariableValue();
591 bool isAbs
= Value
->EvaluateAsAbsolute(Res
, Layout
, SectionAddress
);
596 report_fatal_error("unsupported relocation of variable '" +
597 Symbol
->getName() + "'");
600 report_fatal_error("unsupported relocation of undefined symbol '" +
601 Symbol
->getName() + "'");
604 MCSymbolRefExpr::VariantKind Modifier
= Target
.getSymA()->getKind();
607 if (Modifier
== MCSymbolRefExpr::VK_GOTPCREL
) {
608 // x86_64 distinguishes movq foo@GOTPCREL so that the linker can
609 // rewrite the movq to an leaq at link time if the symbol ends up in
610 // the same linkage unit.
611 if (unsigned(Fixup
.getKind()) == X86::reloc_riprel_4byte_movq_load
)
612 Type
= macho::RIT_X86_64_GOTLoad
;
614 Type
= macho::RIT_X86_64_GOT
;
615 } else if (Modifier
== MCSymbolRefExpr::VK_TLVP
) {
616 Type
= macho::RIT_X86_64_TLV
;
617 } else if (Modifier
!= MCSymbolRefExpr::VK_None
) {
618 report_fatal_error("unsupported symbol modifier in relocation");
620 Type
= macho::RIT_X86_64_Signed
;
622 // The Darwin x86_64 relocation format has a problem where it cannot
623 // encode an address (L<foo> + <constant>) which is outside the atom
624 // containing L<foo>. Generally, this shouldn't occur but it does
625 // happen when we have a RIPrel instruction with data following the
626 // relocation entry (e.g., movb $012, L0(%rip)). Even with the PCrel
627 // adjustment Darwin x86_64 uses, the offset is still negative and
628 // the linker has no way to recognize this.
630 // To work around this, Darwin uses several special relocation types
631 // to indicate the offsets. However, the specification or
632 // implementation of these seems to also be incomplete; they should
633 // adjust the addend as well based on the actual encoded instruction
634 // (the additional bias), but instead appear to just look at the
636 switch (-(Target
.getConstant() + (1LL << Log2Size
))) {
637 case 1: Type
= macho::RIT_X86_64_Signed1
; break;
638 case 2: Type
= macho::RIT_X86_64_Signed2
; break;
639 case 4: Type
= macho::RIT_X86_64_Signed4
; break;
643 if (Modifier
!= MCSymbolRefExpr::VK_None
)
644 report_fatal_error("unsupported symbol modifier in branch "
647 Type
= macho::RIT_X86_64_Branch
;
650 if (Modifier
== MCSymbolRefExpr::VK_GOT
) {
651 Type
= macho::RIT_X86_64_GOT
;
652 } else if (Modifier
== MCSymbolRefExpr::VK_GOTPCREL
) {
653 // GOTPCREL is allowed as a modifier on non-PCrel instructions, in
654 // which case all we do is set the PCrel bit in the relocation entry;
655 // this is used with exception handling, for example. The source is
656 // required to include any necessary offset directly.
657 Type
= macho::RIT_X86_64_GOT
;
659 } else if (Modifier
== MCSymbolRefExpr::VK_TLVP
) {
660 report_fatal_error("TLVP symbol modifier should have been rip-rel");
661 } else if (Modifier
!= MCSymbolRefExpr::VK_None
)
662 report_fatal_error("unsupported symbol modifier in relocation");
664 Type
= macho::RIT_X86_64_Unsigned
;
668 // x86_64 always writes custom values into the fixups.
671 // struct relocation_info (8 bytes)
672 macho::RelocationEntry MRE
;
673 MRE
.Word0
= FixupOffset
;
674 MRE
.Word1
= ((Index
<< 0) |
679 Relocations
[Fragment
->getParent()].push_back(MRE
);
682 void RecordScatteredRelocation(const MCAssembler
&Asm
,
683 const MCAsmLayout
&Layout
,
684 const MCFragment
*Fragment
,
685 const MCFixup
&Fixup
, MCValue Target
,
687 uint64_t &FixedValue
) {
688 uint32_t FixupOffset
= Layout
.getFragmentOffset(Fragment
)+Fixup
.getOffset();
689 unsigned IsPCRel
= isFixupKindPCRel(Asm
, Fixup
.getKind());
690 unsigned Type
= macho::RIT_Vanilla
;
693 const MCSymbol
*A
= &Target
.getSymA()->getSymbol();
694 MCSymbolData
*A_SD
= &Asm
.getSymbolData(*A
);
696 if (!A_SD
->getFragment())
697 report_fatal_error("symbol '" + A
->getName() +
698 "' can not be undefined in a subtraction expression");
700 uint32_t Value
= getSymbolAddress(A_SD
, Layout
);
701 uint64_t SecAddr
= getSectionAddress(A_SD
->getFragment()->getParent());
702 FixedValue
+= SecAddr
;
705 if (const MCSymbolRefExpr
*B
= Target
.getSymB()) {
706 MCSymbolData
*B_SD
= &Asm
.getSymbolData(B
->getSymbol());
708 if (!B_SD
->getFragment())
709 report_fatal_error("symbol '" + B
->getSymbol().getName() +
710 "' can not be undefined in a subtraction expression");
712 // Select the appropriate difference relocation type.
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() ? (unsigned)macho::RIT_Difference
:
718 (unsigned)macho::RIT_Generic_LocalDifference
;
719 Value2
= getSymbolAddress(B_SD
, Layout
);
720 FixedValue
-= getSectionAddress(B_SD
->getFragment()->getParent());
723 // Relocations are written out in reverse order, so the PAIR comes first.
724 if (Type
== macho::RIT_Difference
||
725 Type
== macho::RIT_Generic_LocalDifference
) {
726 macho::RelocationEntry MRE
;
727 MRE
.Word0
= ((0 << 0) |
728 (macho::RIT_Pair
<< 24) |
731 macho::RF_Scattered
);
733 Relocations
[Fragment
->getParent()].push_back(MRE
);
736 macho::RelocationEntry MRE
;
737 MRE
.Word0
= ((FixupOffset
<< 0) |
741 macho::RF_Scattered
);
743 Relocations
[Fragment
->getParent()].push_back(MRE
);
746 void RecordARMScatteredRelocation(const MCAssembler
&Asm
,
747 const MCAsmLayout
&Layout
,
748 const MCFragment
*Fragment
,
749 const MCFixup
&Fixup
, MCValue Target
,
751 uint64_t &FixedValue
) {
752 uint32_t FixupOffset
= Layout
.getFragmentOffset(Fragment
)+Fixup
.getOffset();
753 unsigned IsPCRel
= isFixupKindPCRel(Asm
, Fixup
.getKind());
754 unsigned Type
= macho::RIT_Vanilla
;
757 const MCSymbol
*A
= &Target
.getSymA()->getSymbol();
758 MCSymbolData
*A_SD
= &Asm
.getSymbolData(*A
);
760 if (!A_SD
->getFragment())
761 report_fatal_error("symbol '" + A
->getName() +
762 "' can not be undefined in a subtraction expression");
764 uint32_t Value
= getSymbolAddress(A_SD
, Layout
);
765 uint64_t SecAddr
= getSectionAddress(A_SD
->getFragment()->getParent());
766 FixedValue
+= SecAddr
;
769 if (const MCSymbolRefExpr
*B
= Target
.getSymB()) {
770 MCSymbolData
*B_SD
= &Asm
.getSymbolData(B
->getSymbol());
772 if (!B_SD
->getFragment())
773 report_fatal_error("symbol '" + B
->getSymbol().getName() +
774 "' can not be undefined in a subtraction expression");
776 // Select the appropriate difference relocation type.
777 Type
= macho::RIT_Difference
;
778 Value2
= getSymbolAddress(B_SD
, Layout
);
779 FixedValue
-= getSectionAddress(B_SD
->getFragment()->getParent());
782 // Relocations are written out in reverse order, so the PAIR comes first.
783 if (Type
== macho::RIT_Difference
||
784 Type
== macho::RIT_Generic_LocalDifference
) {
785 macho::RelocationEntry MRE
;
786 MRE
.Word0
= ((0 << 0) |
787 (macho::RIT_Pair
<< 24) |
790 macho::RF_Scattered
);
792 Relocations
[Fragment
->getParent()].push_back(MRE
);
795 macho::RelocationEntry MRE
;
796 MRE
.Word0
= ((FixupOffset
<< 0) |
800 macho::RF_Scattered
);
802 Relocations
[Fragment
->getParent()].push_back(MRE
);
805 void RecordARMMovwMovtRelocation(const MCAssembler
&Asm
,
806 const MCAsmLayout
&Layout
,
807 const MCFragment
*Fragment
,
808 const MCFixup
&Fixup
, MCValue Target
,
809 uint64_t &FixedValue
) {
810 uint32_t FixupOffset
= Layout
.getFragmentOffset(Fragment
)+Fixup
.getOffset();
811 unsigned IsPCRel
= isFixupKindPCRel(Asm
, Fixup
.getKind());
812 unsigned Type
= macho::RIT_ARM_Half
;
815 const MCSymbol
*A
= &Target
.getSymA()->getSymbol();
816 MCSymbolData
*A_SD
= &Asm
.getSymbolData(*A
);
818 if (!A_SD
->getFragment())
819 report_fatal_error("symbol '" + A
->getName() +
820 "' can not be undefined in a subtraction expression");
822 uint32_t Value
= getSymbolAddress(A_SD
, Layout
);
824 uint64_t SecAddr
= getSectionAddress(A_SD
->getFragment()->getParent());
825 FixedValue
+= SecAddr
;
827 if (const MCSymbolRefExpr
*B
= Target
.getSymB()) {
828 MCSymbolData
*B_SD
= &Asm
.getSymbolData(B
->getSymbol());
830 if (!B_SD
->getFragment())
831 report_fatal_error("symbol '" + B
->getSymbol().getName() +
832 "' can not be undefined in a subtraction expression");
834 // Select the appropriate difference relocation type.
835 Type
= macho::RIT_ARM_HalfDifference
;
836 Value2
= getSymbolAddress(B_SD
, Layout
);
837 FixedValue
-= getSectionAddress(B_SD
->getFragment()->getParent());
840 // Relocations are written out in reverse order, so the PAIR comes first.
841 // ARM_RELOC_HALF and ARM_RELOC_HALF_SECTDIFF abuse the r_length field:
843 // For these two r_type relocations they always have a pair following them
844 // and the r_length bits are used differently. The encoding of the
845 // r_length is as follows:
846 // low bit of r_length:
847 // 0 - :lower16: for movw instructions
848 // 1 - :upper16: for movt instructions
849 // high bit of r_length:
850 // 0 - arm instructions
851 // 1 - thumb instructions
852 // the other half of the relocated expression is in the following pair
853 // relocation entry in the the low 16 bits of r_address field.
854 unsigned ThumbBit
= 0;
855 unsigned MovtBit
= 0;
856 switch ((unsigned)Fixup
.getKind()) {
858 case ARM::fixup_arm_movt_hi16
:
859 case ARM::fixup_arm_movt_hi16_pcrel
:
862 case ARM::fixup_t2_movt_hi16
:
863 case ARM::fixup_t2_movt_hi16_pcrel
:
866 case ARM::fixup_t2_movw_lo16
:
867 case ARM::fixup_t2_movw_lo16_pcrel
:
873 if (Type
== macho::RIT_ARM_HalfDifference
) {
874 uint32_t OtherHalf
= MovtBit
875 ? (FixedValue
& 0xffff) : ((FixedValue
& 0xffff0000) >> 16);
877 macho::RelocationEntry MRE
;
878 MRE
.Word0
= ((OtherHalf
<< 0) |
879 (macho::RIT_Pair
<< 24) |
883 macho::RF_Scattered
);
885 Relocations
[Fragment
->getParent()].push_back(MRE
);
888 macho::RelocationEntry MRE
;
889 MRE
.Word0
= ((FixupOffset
<< 0) |
894 macho::RF_Scattered
);
896 Relocations
[Fragment
->getParent()].push_back(MRE
);
899 void RecordTLVPRelocation(const MCAssembler
&Asm
,
900 const MCAsmLayout
&Layout
,
901 const MCFragment
*Fragment
,
902 const MCFixup
&Fixup
, MCValue Target
,
903 uint64_t &FixedValue
) {
904 assert(Target
.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP
&&
906 "Should only be called with a 32-bit TLVP relocation!");
908 unsigned Log2Size
= getFixupKindLog2Size(Fixup
.getKind());
909 uint32_t Value
= Layout
.getFragmentOffset(Fragment
)+Fixup
.getOffset();
910 unsigned IsPCRel
= 0;
912 // Get the symbol data.
913 MCSymbolData
*SD_A
= &Asm
.getSymbolData(Target
.getSymA()->getSymbol());
914 unsigned Index
= SD_A
->getIndex();
916 // We're only going to have a second symbol in pic mode and it'll be a
917 // subtraction from the picbase. For 32-bit pic the addend is the difference
918 // between the picbase and the next address. For 32-bit static the addend
920 if (Target
.getSymB()) {
921 // If this is a subtraction then we're pcrel.
922 uint32_t FixupAddress
=
923 getFragmentAddress(Fragment
, Layout
) + Fixup
.getOffset();
924 MCSymbolData
*SD_B
= &Asm
.getSymbolData(Target
.getSymB()->getSymbol());
926 FixedValue
= (FixupAddress
- getSymbolAddress(SD_B
, Layout
) +
927 Target
.getConstant());
928 FixedValue
+= 1ULL << Log2Size
;
933 // struct relocation_info (8 bytes)
934 macho::RelocationEntry MRE
;
936 MRE
.Word1
= ((Index
<< 0) |
939 (1 << 27) | // Extern
940 (macho::RIT_Generic_TLV
<< 28)); // Type
941 Relocations
[Fragment
->getParent()].push_back(MRE
);
944 static bool getARMFixupKindMachOInfo(unsigned Kind
, unsigned &RelocType
,
945 unsigned &Log2Size
) {
946 RelocType
= unsigned(macho::RIT_Vanilla
);
954 Log2Size
= llvm::Log2_32(1);
957 Log2Size
= llvm::Log2_32(2);
960 Log2Size
= llvm::Log2_32(4);
963 Log2Size
= llvm::Log2_32(8);
966 // Handle 24-bit branch kinds.
967 case ARM::fixup_arm_ldst_pcrel_12
:
968 case ARM::fixup_arm_pcrel_10
:
969 case ARM::fixup_arm_adr_pcrel_12
:
970 case ARM::fixup_arm_condbranch
:
971 case ARM::fixup_arm_uncondbranch
:
972 RelocType
= unsigned(macho::RIT_ARM_Branch24Bit
);
973 // Report as 'long', even though that is not quite accurate.
974 Log2Size
= llvm::Log2_32(4);
977 // Handle Thumb branches.
978 case ARM::fixup_arm_thumb_br
:
979 RelocType
= unsigned(macho::RIT_ARM_ThumbBranch22Bit
);
980 Log2Size
= llvm::Log2_32(2);
983 case ARM::fixup_arm_thumb_bl
:
984 case ARM::fixup_arm_thumb_blx
:
985 RelocType
= unsigned(macho::RIT_ARM_ThumbBranch22Bit
);
986 Log2Size
= llvm::Log2_32(4);
989 case ARM::fixup_arm_movt_hi16
:
990 case ARM::fixup_arm_movt_hi16_pcrel
:
991 case ARM::fixup_t2_movt_hi16
:
992 case ARM::fixup_t2_movt_hi16_pcrel
:
993 RelocType
= unsigned(macho::RIT_ARM_HalfDifference
);
994 // Report as 'long', even though that is not quite accurate.
995 Log2Size
= llvm::Log2_32(4);
998 case ARM::fixup_arm_movw_lo16
:
999 case ARM::fixup_arm_movw_lo16_pcrel
:
1000 case ARM::fixup_t2_movw_lo16
:
1001 case ARM::fixup_t2_movw_lo16_pcrel
:
1002 RelocType
= unsigned(macho::RIT_ARM_Half
);
1003 // Report as 'long', even though that is not quite accurate.
1004 Log2Size
= llvm::Log2_32(4);
1008 void RecordARMRelocation(const MCAssembler
&Asm
, const MCAsmLayout
&Layout
,
1009 const MCFragment
*Fragment
, const MCFixup
&Fixup
,
1010 MCValue Target
, uint64_t &FixedValue
) {
1011 unsigned IsPCRel
= isFixupKindPCRel(Asm
, Fixup
.getKind());
1013 unsigned RelocType
= macho::RIT_Vanilla
;
1014 if (!getARMFixupKindMachOInfo(Fixup
.getKind(), RelocType
, Log2Size
)) {
1015 report_fatal_error("unknown ARM fixup kind!");
1019 // If this is a difference or a defined symbol plus an offset, then we need
1020 // a scattered relocation entry. Differences always require scattered
1022 if (Target
.getSymB()) {
1023 if (RelocType
== macho::RIT_ARM_Half
||
1024 RelocType
== macho::RIT_ARM_HalfDifference
)
1025 return RecordARMMovwMovtRelocation(Asm
, Layout
, Fragment
, Fixup
,
1026 Target
, FixedValue
);
1027 return RecordARMScatteredRelocation(Asm
, Layout
, Fragment
, Fixup
,
1028 Target
, Log2Size
, FixedValue
);
1031 // Get the symbol data, if any.
1032 MCSymbolData
*SD
= 0;
1033 if (Target
.getSymA())
1034 SD
= &Asm
.getSymbolData(Target
.getSymA()->getSymbol());
1036 // FIXME: For other platforms, we need to use scattered relocations for
1037 // internal relocations with offsets. If this is an internal relocation
1038 // with an offset, it also needs a scattered relocation entry.
1040 // Is this right for ARM?
1041 uint32_t Offset
= Target
.getConstant();
1042 if (IsPCRel
&& RelocType
== macho::RIT_Vanilla
)
1043 Offset
+= 1 << Log2Size
;
1044 if (Offset
&& SD
&& !doesSymbolRequireExternRelocation(SD
))
1045 return RecordARMScatteredRelocation(Asm
, Layout
, Fragment
, Fixup
, Target
,
1046 Log2Size
, FixedValue
);
1049 uint32_t FixupOffset
= Layout
.getFragmentOffset(Fragment
)+Fixup
.getOffset();
1051 unsigned IsExtern
= 0;
1054 if (Target
.isAbsolute()) { // constant
1056 report_fatal_error("FIXME: relocations to absolute targets "
1057 "not yet implemented");
1059 // Resolve constant variables.
1060 if (SD
->getSymbol().isVariable()) {
1062 if (SD
->getSymbol().getVariableValue()->EvaluateAsAbsolute(
1063 Res
, Layout
, SectionAddress
)) {
1069 // Check whether we need an external or internal relocation.
1070 if (doesSymbolRequireExternRelocation(SD
)) {
1072 Index
= SD
->getIndex();
1073 // For external relocations, make sure to offset the fixup value to
1074 // compensate for the addend of the symbol address, if it was
1075 // undefined. This occurs with weak definitions, for example.
1076 if (!SD
->Symbol
->isUndefined())
1077 FixedValue
-= Layout
.getSymbolOffset(SD
);
1079 // The index is the section ordinal (1-based).
1080 const MCSectionData
&SymSD
= Asm
.getSectionData(
1081 SD
->getSymbol().getSection());
1082 Index
= SymSD
.getOrdinal() + 1;
1083 FixedValue
+= getSectionAddress(&SymSD
);
1086 FixedValue
-= getSectionAddress(Fragment
->getParent());
1088 // The type is determined by the fixup kind.
1092 // struct relocation_info (8 bytes)
1093 macho::RelocationEntry MRE
;
1094 MRE
.Word0
= FixupOffset
;
1095 MRE
.Word1
= ((Index
<< 0) |
1100 Relocations
[Fragment
->getParent()].push_back(MRE
);
1103 void RecordRelocation(const MCAssembler
&Asm
, const MCAsmLayout
&Layout
,
1104 const MCFragment
*Fragment
, const MCFixup
&Fixup
,
1105 MCValue Target
, uint64_t &FixedValue
) {
1106 // FIXME: These needs to be factored into the target Mach-O writer.
1108 RecordARMRelocation(Asm
, Layout
, Fragment
, Fixup
, Target
, FixedValue
);
1112 RecordX86_64Relocation(Asm
, Layout
, Fragment
, Fixup
, Target
, FixedValue
);
1116 unsigned IsPCRel
= isFixupKindPCRel(Asm
, Fixup
.getKind());
1117 unsigned Log2Size
= getFixupKindLog2Size(Fixup
.getKind());
1119 // If this is a 32-bit TLVP reloc it's handled a bit differently.
1120 if (Target
.getSymA() &&
1121 Target
.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP
) {
1122 RecordTLVPRelocation(Asm
, Layout
, Fragment
, Fixup
, Target
, FixedValue
);
1126 // If this is a difference or a defined symbol plus an offset, then we need
1127 // a scattered relocation entry.
1128 // Differences always require scattered relocations.
1129 if (Target
.getSymB())
1130 return RecordScatteredRelocation(Asm
, Layout
, Fragment
, Fixup
,
1131 Target
, Log2Size
, FixedValue
);
1133 // Get the symbol data, if any.
1134 MCSymbolData
*SD
= 0;
1135 if (Target
.getSymA())
1136 SD
= &Asm
.getSymbolData(Target
.getSymA()->getSymbol());
1138 // If this is an internal relocation with an offset, it also needs a
1139 // scattered relocation entry.
1140 uint32_t Offset
= Target
.getConstant();
1142 Offset
+= 1 << Log2Size
;
1143 if (Offset
&& SD
&& !doesSymbolRequireExternRelocation(SD
))
1144 return RecordScatteredRelocation(Asm
, Layout
, Fragment
, Fixup
,
1145 Target
, Log2Size
, FixedValue
);
1148 uint32_t FixupOffset
= Layout
.getFragmentOffset(Fragment
)+Fixup
.getOffset();
1150 unsigned IsExtern
= 0;
1153 if (Target
.isAbsolute()) { // constant
1154 // SymbolNum of 0 indicates the absolute section.
1156 // FIXME: Currently, these are never generated (see code below). I cannot
1157 // find a case where they are actually emitted.
1158 Type
= macho::RIT_Vanilla
;
1160 // Resolve constant variables.
1161 if (SD
->getSymbol().isVariable()) {
1163 if (SD
->getSymbol().getVariableValue()->EvaluateAsAbsolute(
1164 Res
, Layout
, SectionAddress
)) {
1170 // Check whether we need an external or internal relocation.
1171 if (doesSymbolRequireExternRelocation(SD
)) {
1173 Index
= SD
->getIndex();
1174 // For external relocations, make sure to offset the fixup value to
1175 // compensate for the addend of the symbol address, if it was
1176 // undefined. This occurs with weak definitions, for example.
1177 if (!SD
->Symbol
->isUndefined())
1178 FixedValue
-= Layout
.getSymbolOffset(SD
);
1180 // The index is the section ordinal (1-based).
1181 const MCSectionData
&SymSD
= Asm
.getSectionData(
1182 SD
->getSymbol().getSection());
1183 Index
= SymSD
.getOrdinal() + 1;
1184 FixedValue
+= getSectionAddress(&SymSD
);
1187 FixedValue
-= getSectionAddress(Fragment
->getParent());
1189 Type
= macho::RIT_Vanilla
;
1192 // struct relocation_info (8 bytes)
1193 macho::RelocationEntry MRE
;
1194 MRE
.Word0
= FixupOffset
;
1195 MRE
.Word1
= ((Index
<< 0) |
1200 Relocations
[Fragment
->getParent()].push_back(MRE
);
1203 void BindIndirectSymbols(MCAssembler
&Asm
) {
1204 // This is the point where 'as' creates actual symbols for indirect symbols
1205 // (in the following two passes). It would be easier for us to do this
1206 // sooner when we see the attribute, but that makes getting the order in the
1207 // symbol table much more complicated than it is worth.
1209 // FIXME: Revisit this when the dust settles.
1211 // Bind non lazy symbol pointers first.
1212 unsigned IndirectIndex
= 0;
1213 for (MCAssembler::indirect_symbol_iterator it
= Asm
.indirect_symbol_begin(),
1214 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
, ++IndirectIndex
) {
1215 const MCSectionMachO
&Section
=
1216 cast
<MCSectionMachO
>(it
->SectionData
->getSection());
1218 if (Section
.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS
)
1221 // Initialize the section indirect symbol base, if necessary.
1222 if (!IndirectSymBase
.count(it
->SectionData
))
1223 IndirectSymBase
[it
->SectionData
] = IndirectIndex
;
1225 Asm
.getOrCreateSymbolData(*it
->Symbol
);
1228 // Then lazy symbol pointers and symbol stubs.
1230 for (MCAssembler::indirect_symbol_iterator it
= Asm
.indirect_symbol_begin(),
1231 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
, ++IndirectIndex
) {
1232 const MCSectionMachO
&Section
=
1233 cast
<MCSectionMachO
>(it
->SectionData
->getSection());
1235 if (Section
.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS
&&
1236 Section
.getType() != MCSectionMachO::S_SYMBOL_STUBS
)
1239 // Initialize the section indirect symbol base, if necessary.
1240 if (!IndirectSymBase
.count(it
->SectionData
))
1241 IndirectSymBase
[it
->SectionData
] = IndirectIndex
;
1243 // Set the symbol type to undefined lazy, but only on construction.
1245 // FIXME: Do not hardcode.
1247 MCSymbolData
&Entry
= Asm
.getOrCreateSymbolData(*it
->Symbol
, &Created
);
1249 Entry
.setFlags(Entry
.getFlags() | 0x0001);
1253 /// ComputeSymbolTable - Compute the symbol table data
1255 /// \param StringTable [out] - The string table data.
1256 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
1258 void ComputeSymbolTable(MCAssembler
&Asm
, SmallString
<256> &StringTable
,
1259 std::vector
<MachSymbolData
> &LocalSymbolData
,
1260 std::vector
<MachSymbolData
> &ExternalSymbolData
,
1261 std::vector
<MachSymbolData
> &UndefinedSymbolData
) {
1262 // Build section lookup table.
1263 DenseMap
<const MCSection
*, uint8_t> SectionIndexMap
;
1265 for (MCAssembler::iterator it
= Asm
.begin(),
1266 ie
= Asm
.end(); it
!= ie
; ++it
, ++Index
)
1267 SectionIndexMap
[&it
->getSection()] = Index
;
1268 assert(Index
<= 256 && "Too many sections!");
1270 // Index 0 is always the empty string.
1271 StringMap
<uint64_t> StringIndexMap
;
1272 StringTable
+= '\x00';
1274 // Build the symbol arrays and the string table, but only for non-local
1277 // The particular order that we collect the symbols and create the string
1278 // table, then sort the symbols is chosen to match 'as'. Even though it
1279 // doesn't matter for correctness, this is important for letting us diff .o
1281 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
1282 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
1283 const MCSymbol
&Symbol
= it
->getSymbol();
1285 // Ignore non-linker visible symbols.
1286 if (!Asm
.isSymbolLinkerVisible(it
->getSymbol()))
1289 if (!it
->isExternal() && !Symbol
.isUndefined())
1292 uint64_t &Entry
= StringIndexMap
[Symbol
.getName()];
1294 Entry
= StringTable
.size();
1295 StringTable
+= Symbol
.getName();
1296 StringTable
+= '\x00';
1300 MSD
.SymbolData
= it
;
1301 MSD
.StringIndex
= Entry
;
1303 if (Symbol
.isUndefined()) {
1304 MSD
.SectionIndex
= 0;
1305 UndefinedSymbolData
.push_back(MSD
);
1306 } else if (Symbol
.isAbsolute()) {
1307 MSD
.SectionIndex
= 0;
1308 ExternalSymbolData
.push_back(MSD
);
1310 MSD
.SectionIndex
= SectionIndexMap
.lookup(&Symbol
.getSection());
1311 assert(MSD
.SectionIndex
&& "Invalid section index!");
1312 ExternalSymbolData
.push_back(MSD
);
1316 // Now add the data for local symbols.
1317 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
1318 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
1319 const MCSymbol
&Symbol
= it
->getSymbol();
1321 // Ignore non-linker visible symbols.
1322 if (!Asm
.isSymbolLinkerVisible(it
->getSymbol()))
1325 if (it
->isExternal() || Symbol
.isUndefined())
1328 uint64_t &Entry
= StringIndexMap
[Symbol
.getName()];
1330 Entry
= StringTable
.size();
1331 StringTable
+= Symbol
.getName();
1332 StringTable
+= '\x00';
1336 MSD
.SymbolData
= it
;
1337 MSD
.StringIndex
= Entry
;
1339 if (Symbol
.isAbsolute()) {
1340 MSD
.SectionIndex
= 0;
1341 LocalSymbolData
.push_back(MSD
);
1343 MSD
.SectionIndex
= SectionIndexMap
.lookup(&Symbol
.getSection());
1344 assert(MSD
.SectionIndex
&& "Invalid section index!");
1345 LocalSymbolData
.push_back(MSD
);
1349 // External and undefined symbols are required to be in lexicographic order.
1350 std::sort(ExternalSymbolData
.begin(), ExternalSymbolData
.end());
1351 std::sort(UndefinedSymbolData
.begin(), UndefinedSymbolData
.end());
1353 // Set the symbol indices.
1355 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
1356 LocalSymbolData
[i
].SymbolData
->setIndex(Index
++);
1357 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
1358 ExternalSymbolData
[i
].SymbolData
->setIndex(Index
++);
1359 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
1360 UndefinedSymbolData
[i
].SymbolData
->setIndex(Index
++);
1362 // The string table is padded to a multiple of 4.
1363 while (StringTable
.size() % 4)
1364 StringTable
+= '\x00';
1367 void computeSectionAddresses(const MCAssembler
&Asm
,
1368 const MCAsmLayout
&Layout
) {
1369 uint64_t StartAddress
= 0;
1370 const SmallVectorImpl
<MCSectionData
*> &Order
= Layout
.getSectionOrder();
1371 for (int i
= 0, n
= Order
.size(); i
!= n
; ++i
) {
1372 const MCSectionData
*SD
= Order
[i
];
1373 StartAddress
= RoundUpToAlignment(StartAddress
, SD
->getAlignment());
1374 SectionAddress
[SD
] = StartAddress
;
1375 StartAddress
+= Layout
.getSectionAddressSize(SD
);
1376 // Explicitly pad the section to match the alignment requirements of the
1377 // following one. This is for 'gas' compatibility, it shouldn't
1378 /// strictly be necessary.
1379 StartAddress
+= getPaddingSize(SD
, Layout
);
1383 void ExecutePostLayoutBinding(MCAssembler
&Asm
, const MCAsmLayout
&Layout
) {
1384 computeSectionAddresses(Asm
, Layout
);
1386 // Create symbol data for any indirect symbols.
1387 BindIndirectSymbols(Asm
);
1389 // Compute symbol table information and bind symbol indices.
1390 ComputeSymbolTable(Asm
, StringTable
, LocalSymbolData
, ExternalSymbolData
,
1391 UndefinedSymbolData
);
1394 virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler
&Asm
,
1395 const MCSymbolData
&DataA
,
1396 const MCFragment
&FB
,
1398 bool IsPCRel
) const {
1402 // The effective address is
1403 // addr(atom(A)) + offset(A)
1404 // - addr(atom(B)) - offset(B)
1405 // and the offsets are not relocatable, so the fixup is fully resolved when
1406 // addr(atom(A)) - addr(atom(B)) == 0.
1407 const MCSymbolData
*A_Base
= 0, *B_Base
= 0;
1409 const MCSymbol
&SA
= DataA
.getSymbol().AliasedSymbol();
1410 const MCSection
&SecA
= SA
.getSection();
1411 const MCSection
&SecB
= FB
.getParent()->getSection();
1414 // The simple (Darwin, except on x86_64) way of dealing with this was to
1415 // assume that any reference to a temporary symbol *must* be a temporary
1416 // symbol in the same atom, unless the sections differ. Therefore, any
1417 // PCrel relocation to a temporary symbol (in the same section) is fully
1418 // resolved. This also works in conjunction with absolutized .set, which
1419 // requires the compiler to use .set to absolutize the differences between
1420 // symbols which the compiler knows to be assembly time constants, so we
1421 // don't need to worry about considering symbol differences fully
1424 if (!Asm
.getBackend().hasReliableSymbolDifference()) {
1425 if (!SA
.isTemporary() || !SA
.isInSection() || &SecA
!= &SecB
)
1430 if (!TargetObjectWriter
->useAggressiveSymbolFolding())
1434 const MCFragment
&FA
= *Asm
.getSymbolData(SA
).getFragment();
1436 A_Base
= FA
.getAtom();
1440 B_Base
= FB
.getAtom();
1444 // If the atoms are the same, they are guaranteed to have the same address.
1445 if (A_Base
== B_Base
)
1448 // Otherwise, we can't prove this is fully resolved.
1452 void WriteObject(MCAssembler
&Asm
, const MCAsmLayout
&Layout
) {
1453 unsigned NumSections
= Asm
.size();
1455 // The section data starts after the header, the segment load command (and
1456 // section headers) and the symbol table.
1457 unsigned NumLoadCommands
= 1;
1458 uint64_t LoadCommandsSize
= is64Bit() ?
1459 macho::SegmentLoadCommand64Size
+ NumSections
* macho::Section64Size
:
1460 macho::SegmentLoadCommand32Size
+ NumSections
* macho::Section32Size
;
1462 // Add the symbol table load command sizes, if used.
1463 unsigned NumSymbols
= LocalSymbolData
.size() + ExternalSymbolData
.size() +
1464 UndefinedSymbolData
.size();
1466 NumLoadCommands
+= 2;
1467 LoadCommandsSize
+= (macho::SymtabLoadCommandSize
+
1468 macho::DysymtabLoadCommandSize
);
1471 // Compute the total size of the section data, as well as its file size and
1473 uint64_t SectionDataStart
= (is64Bit() ? macho::Header64Size
:
1474 macho::Header32Size
) + LoadCommandsSize
;
1475 uint64_t SectionDataSize
= 0;
1476 uint64_t SectionDataFileSize
= 0;
1477 uint64_t VMSize
= 0;
1478 for (MCAssembler::const_iterator it
= Asm
.begin(),
1479 ie
= Asm
.end(); it
!= ie
; ++it
) {
1480 const MCSectionData
&SD
= *it
;
1481 uint64_t Address
= getSectionAddress(&SD
);
1482 uint64_t Size
= Layout
.getSectionAddressSize(&SD
);
1483 uint64_t FileSize
= Layout
.getSectionFileSize(&SD
);
1484 FileSize
+= getPaddingSize(&SD
, Layout
);
1486 VMSize
= std::max(VMSize
, Address
+ Size
);
1488 if (SD
.getSection().isVirtualSection())
1491 SectionDataSize
= std::max(SectionDataSize
, Address
+ Size
);
1492 SectionDataFileSize
= std::max(SectionDataFileSize
, Address
+ FileSize
);
1495 // The section data is padded to 4 bytes.
1497 // FIXME: Is this machine dependent?
1498 unsigned SectionDataPadding
= OffsetToAlignment(SectionDataFileSize
, 4);
1499 SectionDataFileSize
+= SectionDataPadding
;
1501 // Write the prolog, starting with the header and load command...
1502 WriteHeader(NumLoadCommands
, LoadCommandsSize
,
1503 Asm
.getSubsectionsViaSymbols());
1504 WriteSegmentLoadCommand(NumSections
, VMSize
,
1505 SectionDataStart
, SectionDataSize
);
1507 // ... and then the section headers.
1508 uint64_t RelocTableEnd
= SectionDataStart
+ SectionDataFileSize
;
1509 for (MCAssembler::const_iterator it
= Asm
.begin(),
1510 ie
= Asm
.end(); it
!= ie
; ++it
) {
1511 std::vector
<macho::RelocationEntry
> &Relocs
= Relocations
[it
];
1512 unsigned NumRelocs
= Relocs
.size();
1513 uint64_t SectionStart
= SectionDataStart
+ getSectionAddress(it
);
1514 WriteSection(Asm
, Layout
, *it
, SectionStart
, RelocTableEnd
, NumRelocs
);
1515 RelocTableEnd
+= NumRelocs
* macho::RelocationInfoSize
;
1518 // Write the symbol table load command, if used.
1520 unsigned FirstLocalSymbol
= 0;
1521 unsigned NumLocalSymbols
= LocalSymbolData
.size();
1522 unsigned FirstExternalSymbol
= FirstLocalSymbol
+ NumLocalSymbols
;
1523 unsigned NumExternalSymbols
= ExternalSymbolData
.size();
1524 unsigned FirstUndefinedSymbol
= FirstExternalSymbol
+ NumExternalSymbols
;
1525 unsigned NumUndefinedSymbols
= UndefinedSymbolData
.size();
1526 unsigned NumIndirectSymbols
= Asm
.indirect_symbol_size();
1527 unsigned NumSymTabSymbols
=
1528 NumLocalSymbols
+ NumExternalSymbols
+ NumUndefinedSymbols
;
1529 uint64_t IndirectSymbolSize
= NumIndirectSymbols
* 4;
1530 uint64_t IndirectSymbolOffset
= 0;
1532 // If used, the indirect symbols are written after the section data.
1533 if (NumIndirectSymbols
)
1534 IndirectSymbolOffset
= RelocTableEnd
;
1536 // The symbol table is written after the indirect symbol data.
1537 uint64_t SymbolTableOffset
= RelocTableEnd
+ IndirectSymbolSize
;
1539 // The string table is written after symbol table.
1540 uint64_t StringTableOffset
=
1541 SymbolTableOffset
+ NumSymTabSymbols
* (is64Bit() ? macho::Nlist64Size
:
1542 macho::Nlist32Size
);
1543 WriteSymtabLoadCommand(SymbolTableOffset
, NumSymTabSymbols
,
1544 StringTableOffset
, StringTable
.size());
1546 WriteDysymtabLoadCommand(FirstLocalSymbol
, NumLocalSymbols
,
1547 FirstExternalSymbol
, NumExternalSymbols
,
1548 FirstUndefinedSymbol
, NumUndefinedSymbols
,
1549 IndirectSymbolOffset
, NumIndirectSymbols
);
1552 // Write the actual section data.
1553 for (MCAssembler::const_iterator it
= Asm
.begin(),
1554 ie
= Asm
.end(); it
!= ie
; ++it
) {
1555 Asm
.WriteSectionData(it
, Layout
);
1557 uint64_t Pad
= getPaddingSize(it
, Layout
);
1558 for (unsigned int i
= 0; i
< Pad
; ++i
)
1562 // Write the extra padding.
1563 WriteZeros(SectionDataPadding
);
1565 // Write the relocation entries.
1566 for (MCAssembler::const_iterator it
= Asm
.begin(),
1567 ie
= Asm
.end(); it
!= ie
; ++it
) {
1568 // Write the section relocation entries, in reverse order to match 'as'
1569 // (approximately, the exact algorithm is more complicated than this).
1570 std::vector
<macho::RelocationEntry
> &Relocs
= Relocations
[it
];
1571 for (unsigned i
= 0, e
= Relocs
.size(); i
!= e
; ++i
) {
1572 Write32(Relocs
[e
- i
- 1].Word0
);
1573 Write32(Relocs
[e
- i
- 1].Word1
);
1577 // Write the symbol table data, if used.
1579 // Write the indirect symbol entries.
1580 for (MCAssembler::const_indirect_symbol_iterator
1581 it
= Asm
.indirect_symbol_begin(),
1582 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
) {
1583 // Indirect symbols in the non lazy symbol pointer section have some
1584 // special handling.
1585 const MCSectionMachO
&Section
=
1586 static_cast<const MCSectionMachO
&>(it
->SectionData
->getSection());
1587 if (Section
.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS
) {
1588 // If this symbol is defined and internal, mark it as such.
1589 if (it
->Symbol
->isDefined() &&
1590 !Asm
.getSymbolData(*it
->Symbol
).isExternal()) {
1591 uint32_t Flags
= macho::ISF_Local
;
1592 if (it
->Symbol
->isAbsolute())
1593 Flags
|= macho::ISF_Absolute
;
1599 Write32(Asm
.getSymbolData(*it
->Symbol
).getIndex());
1602 // FIXME: Check that offsets match computed ones.
1604 // Write the symbol table entries.
1605 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
1606 WriteNlist(LocalSymbolData
[i
], Layout
);
1607 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
1608 WriteNlist(ExternalSymbolData
[i
], Layout
);
1609 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
1610 WriteNlist(UndefinedSymbolData
[i
], Layout
);
1612 // Write the string table.
1613 OS
<< StringTable
.str();
1620 MCObjectWriter
*llvm::createMachObjectWriter(MCMachObjectTargetWriter
*MOTW
,
1622 bool IsLittleEndian
) {
1623 return new MachObjectWriter(MOTW
, OS
, IsLittleEndian
);