1 //===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===//
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 #define DEBUG_TYPE "assembler"
11 #include "llvm/MC/MCAssembler.h"
12 #include "llvm/MC/MCSectionMachO.h"
13 #include "llvm/Target/TargetMachOWriterInfo.h"
14 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/ADT/StringMap.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
24 class MachObjectWriter
;
26 STATISTIC(EmittedFragments
, "Number of emitted assembler fragments");
28 // FIXME FIXME FIXME: There are number of places in this file where we convert
29 // what is a 64-bit assembler value used for computation into a value in the
30 // object file, which may truncate it. We should detect that truncation where
31 // invalid and report errors back.
33 static void WriteFileData(raw_ostream
&OS
, const MCSectionData
&SD
,
34 MachObjectWriter
&MOW
);
36 /// isVirtualSection - Check if this is a section which does not actually exist
37 /// in the object file.
38 static bool isVirtualSection(const MCSection
&Section
) {
40 const MCSectionMachO
&SMO
= static_cast<const MCSectionMachO
&>(Section
);
41 unsigned Type
= SMO
.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE
;
42 return (Type
== MCSectionMachO::S_ZEROFILL
);
45 class MachObjectWriter
{
46 // See <mach-o/loader.h>.
48 Header_Magic32
= 0xFEEDFACE,
49 Header_Magic64
= 0xFEEDFACF
52 static const unsigned Header32Size
= 28;
53 static const unsigned Header64Size
= 32;
54 static const unsigned SegmentLoadCommand32Size
= 56;
55 static const unsigned Section32Size
= 68;
56 static const unsigned SymtabLoadCommandSize
= 24;
57 static const unsigned DysymtabLoadCommandSize
= 80;
58 static const unsigned Nlist32Size
= 12;
59 static const unsigned RelocationInfoSize
= 8;
66 HF_SubsectionsViaSymbols
= 0x2000
69 enum LoadCommandType
{
75 // See <mach-o/nlist.h>.
82 enum SymbolTypeFlags
{
83 // If any of these bits are set, then the entry is a stab entry number (see
84 // <mach-o/stab.h>. Otherwise the other masks apply.
85 STF_StabsEntryMask
= 0xe0,
89 STF_PrivateExtern
= 0x10
92 /// IndirectSymbolFlags - Flags for encoding special values in the indirect
94 enum IndirectSymbolFlags
{
95 ISF_Local
= 0x80000000,
96 ISF_Absolute
= 0x40000000
99 /// RelocationFlags - Special flags for addresses.
100 enum RelocationFlags
{
101 RF_Scattered
= 0x80000000
104 enum RelocationInfoType
{
108 RIT_PreboundLazyPointer
= 3,
109 RIT_LocalDifference
= 4
112 /// MachSymbolData - Helper struct for containing some precomputed information
114 struct MachSymbolData
{
115 MCSymbolData
*SymbolData
;
116 uint64_t StringIndex
;
117 uint8_t SectionIndex
;
119 // Support lexicographic sorting.
120 bool operator<(const MachSymbolData
&RHS
) const {
121 const std::string
&Name
= SymbolData
->getSymbol().getName();
122 return Name
< RHS
.SymbolData
->getSymbol().getName();
130 MachObjectWriter(raw_ostream
&_OS
, bool _IsLSB
= true)
131 : OS(_OS
), IsLSB(_IsLSB
) {
134 /// @name Helper Methods
137 void Write8(uint8_t Value
) {
141 void Write16(uint16_t Value
) {
143 Write8(uint8_t(Value
>> 0));
144 Write8(uint8_t(Value
>> 8));
146 Write8(uint8_t(Value
>> 8));
147 Write8(uint8_t(Value
>> 0));
151 void Write32(uint32_t Value
) {
153 Write16(uint16_t(Value
>> 0));
154 Write16(uint16_t(Value
>> 16));
156 Write16(uint16_t(Value
>> 16));
157 Write16(uint16_t(Value
>> 0));
161 void Write64(uint64_t Value
) {
163 Write32(uint32_t(Value
>> 0));
164 Write32(uint32_t(Value
>> 32));
166 Write32(uint32_t(Value
>> 32));
167 Write32(uint32_t(Value
>> 0));
171 void WriteZeros(unsigned N
) {
172 const char Zeros
[16] = { 0 };
174 for (unsigned i
= 0, e
= N
/ 16; i
!= e
; ++i
)
175 OS
<< StringRef(Zeros
, 16);
177 OS
<< StringRef(Zeros
, N
% 16);
180 void WriteString(const StringRef
&Str
, unsigned ZeroFillSize
= 0) {
183 WriteZeros(ZeroFillSize
- Str
.size());
188 void WriteHeader32(unsigned NumLoadCommands
, unsigned LoadCommandsSize
,
189 bool SubsectionsViaSymbols
) {
192 if (SubsectionsViaSymbols
)
193 Flags
|= HF_SubsectionsViaSymbols
;
195 // struct mach_header (28 bytes)
197 uint64_t Start
= OS
.tell();
200 Write32(Header_Magic32
);
202 // FIXME: Support cputype.
203 Write32(TargetMachOWriterInfo::HDR_CPU_TYPE_I386
);
204 // FIXME: Support cpusubtype.
205 Write32(TargetMachOWriterInfo::HDR_CPU_SUBTYPE_I386_ALL
);
207 Write32(NumLoadCommands
); // Object files have a single load command, the
209 Write32(LoadCommandsSize
);
212 assert(OS
.tell() - Start
== Header32Size
);
215 /// WriteSegmentLoadCommand32 - Write a 32-bit segment load command.
217 /// \arg NumSections - The number of sections in this segment.
218 /// \arg SectionDataSize - The total size of the sections.
219 void WriteSegmentLoadCommand32(unsigned NumSections
,
221 uint64_t SectionDataStartOffset
,
222 uint64_t SectionDataSize
) {
223 // struct segment_command (56 bytes)
225 uint64_t Start
= OS
.tell();
228 Write32(LCT_Segment
);
229 Write32(SegmentLoadCommand32Size
+ NumSections
* Section32Size
);
232 Write32(0); // vmaddr
233 Write32(VMSize
); // vmsize
234 Write32(SectionDataStartOffset
); // file offset
235 Write32(SectionDataSize
); // file size
236 Write32(0x7); // maxprot
237 Write32(0x7); // initprot
238 Write32(NumSections
);
241 assert(OS
.tell() - Start
== SegmentLoadCommand32Size
);
244 void WriteSection32(const MCSectionData
&SD
, uint64_t FileOffset
,
245 uint64_t RelocationsStart
, unsigned NumRelocations
) {
246 // The offset is unused for virtual sections.
247 if (isVirtualSection(SD
.getSection())) {
248 assert(SD
.getFileSize() == 0 && "Invalid file size!");
252 // struct section (68 bytes)
254 uint64_t Start
= OS
.tell();
257 // FIXME: cast<> support!
258 const MCSectionMachO
&Section
=
259 static_cast<const MCSectionMachO
&>(SD
.getSection());
260 WriteString(Section
.getSectionName(), 16);
261 WriteString(Section
.getSegmentName(), 16);
262 Write32(SD
.getAddress()); // address
263 Write32(SD
.getSize()); // size
266 assert(isPowerOf2_32(SD
.getAlignment()) && "Invalid alignment!");
267 Write32(Log2_32(SD
.getAlignment()));
268 Write32(NumRelocations
? RelocationsStart
: 0);
269 Write32(NumRelocations
);
270 Write32(Section
.getTypeAndAttributes());
271 Write32(0); // reserved1
272 Write32(Section
.getStubSize()); // reserved2
274 assert(OS
.tell() - Start
== Section32Size
);
277 void WriteSymtabLoadCommand(uint32_t SymbolOffset
, uint32_t NumSymbols
,
278 uint32_t StringTableOffset
,
279 uint32_t StringTableSize
) {
280 // struct symtab_command (24 bytes)
282 uint64_t Start
= OS
.tell();
286 Write32(SymtabLoadCommandSize
);
287 Write32(SymbolOffset
);
289 Write32(StringTableOffset
);
290 Write32(StringTableSize
);
292 assert(OS
.tell() - Start
== SymtabLoadCommandSize
);
295 void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol
,
296 uint32_t NumLocalSymbols
,
297 uint32_t FirstExternalSymbol
,
298 uint32_t NumExternalSymbols
,
299 uint32_t FirstUndefinedSymbol
,
300 uint32_t NumUndefinedSymbols
,
301 uint32_t IndirectSymbolOffset
,
302 uint32_t NumIndirectSymbols
) {
303 // struct dysymtab_command (80 bytes)
305 uint64_t Start
= OS
.tell();
308 Write32(LCT_Dysymtab
);
309 Write32(DysymtabLoadCommandSize
);
310 Write32(FirstLocalSymbol
);
311 Write32(NumLocalSymbols
);
312 Write32(FirstExternalSymbol
);
313 Write32(NumExternalSymbols
);
314 Write32(FirstUndefinedSymbol
);
315 Write32(NumUndefinedSymbols
);
316 Write32(0); // tocoff
318 Write32(0); // modtaboff
319 Write32(0); // nmodtab
320 Write32(0); // extrefsymoff
321 Write32(0); // nextrefsyms
322 Write32(IndirectSymbolOffset
);
323 Write32(NumIndirectSymbols
);
324 Write32(0); // extreloff
325 Write32(0); // nextrel
326 Write32(0); // locreloff
327 Write32(0); // nlocrel
329 assert(OS
.tell() - Start
== DysymtabLoadCommandSize
);
332 void WriteNlist32(MachSymbolData
&MSD
) {
333 MCSymbolData
&Data
= *MSD
.SymbolData
;
334 const MCSymbol
&Symbol
= Data
.getSymbol();
336 uint16_t Flags
= Data
.getFlags();
337 uint32_t Address
= 0;
339 // Set the N_TYPE bits. See <mach-o/nlist.h>.
341 // FIXME: Are the prebound or indirect fields possible here?
342 if (Symbol
.isUndefined())
343 Type
= STT_Undefined
;
344 else if (Symbol
.isAbsolute())
349 // FIXME: Set STAB bits.
351 if (Data
.isPrivateExtern())
352 Type
|= STF_PrivateExtern
;
355 if (Data
.isExternal() || Symbol
.isUndefined())
356 Type
|= STF_External
;
358 // Compute the symbol address.
359 if (Symbol
.isDefined()) {
360 if (Symbol
.isAbsolute()) {
361 llvm_unreachable("FIXME: Not yet implemented!");
363 Address
= Data
.getFragment()->getAddress() + Data
.getOffset();
365 } else if (Data
.isCommon()) {
366 // Common symbols are encoded with the size in the address
367 // field, and their alignment in the flags.
368 Address
= Data
.getCommonSize();
370 // Common alignment is packed into the 'desc' bits.
371 if (unsigned Align
= Data
.getCommonAlignment()) {
372 unsigned Log2Size
= Log2_32(Align
);
373 assert((1U << Log2Size
) == Align
&& "Invalid 'common' alignment!");
375 llvm_report_error("invalid 'common' alignment '" +
377 // FIXME: Keep this mask with the SymbolFlags enumeration.
378 Flags
= (Flags
& 0xF0FF) | (Log2Size
<< 8);
382 // struct nlist (12 bytes)
384 Write32(MSD
.StringIndex
);
386 Write8(MSD
.SectionIndex
);
388 // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
394 struct MachRelocationEntry
{
398 void ComputeScatteredRelocationInfo(MCAssembler
&Asm
,
399 MCSectionData::Fixup
&Fixup
,
400 DenseMap
<const MCSymbol
*,MCSymbolData
*> &SymbolMap
,
401 std::vector
<MachRelocationEntry
> &Relocs
) {
402 uint32_t Address
= Fixup
.Fragment
->getOffset() + Fixup
.Offset
;
403 unsigned IsPCRel
= 0;
404 unsigned Type
= RIT_Vanilla
;
408 const MCSymbol
*A
= Fixup
.Value
.getSymA();
409 MCSymbolData
*SD
= SymbolMap
.lookup(A
);
410 uint32_t Value
= SD
->getFragment()->getAddress() + SD
->getOffset();
413 if (const MCSymbol
*B
= Fixup
.Value
.getSymB()) {
414 Type
= RIT_LocalDifference
;
416 MCSymbolData
*SD
= SymbolMap
.lookup(B
);
417 Value2
= SD
->getFragment()->getAddress() + SD
->getOffset();
420 unsigned Log2Size
= Log2_32(Fixup
.Size
);
421 assert((1U << Log2Size
) == Fixup
.Size
&& "Invalid fixup size!");
423 // The value which goes in the fixup is current value of the expression.
424 Fixup
.FixedValue
= Value
- Value2
+ Fixup
.Value
.getConstant();
426 MachRelocationEntry MRE
;
427 MRE
.Word0
= ((Address
<< 0) |
433 Relocs
.push_back(MRE
);
435 if (Type
== RIT_LocalDifference
) {
438 MachRelocationEntry MRE
;
439 MRE
.Word0
= ((0 << 0) |
445 Relocs
.push_back(MRE
);
449 void ComputeRelocationInfo(MCAssembler
&Asm
,
450 MCSectionData::Fixup
&Fixup
,
451 DenseMap
<const MCSymbol
*,MCSymbolData
*> &SymbolMap
,
452 std::vector
<MachRelocationEntry
> &Relocs
) {
453 // If this is a local symbol plus an offset or a difference, then we need a
454 // scattered relocation entry.
455 if (Fixup
.Value
.getSymB()) // a - b
456 return ComputeScatteredRelocationInfo(Asm
, Fixup
, SymbolMap
, Relocs
);
457 if (Fixup
.Value
.getSymA() && Fixup
.Value
.getConstant())
458 if (!Fixup
.Value
.getSymA()->isUndefined())
459 return ComputeScatteredRelocationInfo(Asm
, Fixup
, SymbolMap
, Relocs
);
462 uint32_t Address
= Fixup
.Fragment
->getOffset() + Fixup
.Offset
;
465 unsigned IsPCRel
= 0;
466 unsigned IsExtern
= 0;
469 if (Fixup
.Value
.isAbsolute()) { // constant
470 // SymbolNum of 0 indicates the absolute section.
473 llvm_unreachable("FIXME: Not yet implemented!");
475 const MCSymbol
*Symbol
= Fixup
.Value
.getSymA();
476 MCSymbolData
*SD
= SymbolMap
.lookup(Symbol
);
478 if (Symbol
->isUndefined()) {
480 Index
= SD
->getIndex();
483 // The index is the section ordinal.
487 for (MCAssembler::iterator it
= Asm
.begin(),
488 ie
= Asm
.end(); it
!= ie
; ++it
, ++Index
)
489 if (&*it
== SD
->getFragment()->getParent())
491 Value
= SD
->getFragment()->getAddress() + SD
->getOffset();
497 // The value which goes in the fixup is current value of the expression.
498 Fixup
.FixedValue
= Value
+ Fixup
.Value
.getConstant();
500 unsigned Log2Size
= Log2_32(Fixup
.Size
);
501 assert((1U << Log2Size
) == Fixup
.Size
&& "Invalid fixup size!");
503 // struct relocation_info (8 bytes)
504 MachRelocationEntry MRE
;
506 MRE
.Word1
= ((Index
<< 0) |
511 Relocs
.push_back(MRE
);
514 void BindIndirectSymbols(MCAssembler
&Asm
,
515 DenseMap
<const MCSymbol
*,MCSymbolData
*> &SymbolMap
) {
516 // This is the point where 'as' creates actual symbols for indirect symbols
517 // (in the following two passes). It would be easier for us to do this
518 // sooner when we see the attribute, but that makes getting the order in the
519 // symbol table much more complicated than it is worth.
521 // FIXME: Revisit this when the dust settles.
523 // Bind non lazy symbol pointers first.
524 for (MCAssembler::indirect_symbol_iterator it
= Asm
.indirect_symbol_begin(),
525 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
) {
526 // FIXME: cast<> support!
527 const MCSectionMachO
&Section
=
528 static_cast<const MCSectionMachO
&>(it
->SectionData
->getSection());
531 Section
.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE
;
532 if (Type
!= MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS
)
535 MCSymbolData
*&Entry
= SymbolMap
[it
->Symbol
];
537 Entry
= new MCSymbolData(*it
->Symbol
, 0, 0, &Asm
);
540 // Then lazy symbol pointers and symbol stubs.
541 for (MCAssembler::indirect_symbol_iterator it
= Asm
.indirect_symbol_begin(),
542 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
) {
543 // FIXME: cast<> support!
544 const MCSectionMachO
&Section
=
545 static_cast<const MCSectionMachO
&>(it
->SectionData
->getSection());
548 Section
.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE
;
549 if (Type
!= MCSectionMachO::S_LAZY_SYMBOL_POINTERS
&&
550 Type
!= MCSectionMachO::S_SYMBOL_STUBS
)
553 MCSymbolData
*&Entry
= SymbolMap
[it
->Symbol
];
555 Entry
= new MCSymbolData(*it
->Symbol
, 0, 0, &Asm
);
557 // Set the symbol type to undefined lazy, but only on construction.
559 // FIXME: Do not hardcode.
560 Entry
->setFlags(Entry
->getFlags() | 0x0001);
565 /// ComputeSymbolTable - Compute the symbol table data
567 /// \param StringTable [out] - The string table data.
568 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
570 void ComputeSymbolTable(MCAssembler
&Asm
, SmallString
<256> &StringTable
,
571 std::vector
<MachSymbolData
> &LocalSymbolData
,
572 std::vector
<MachSymbolData
> &ExternalSymbolData
,
573 std::vector
<MachSymbolData
> &UndefinedSymbolData
) {
574 // Build section lookup table.
575 DenseMap
<const MCSection
*, uint8_t> SectionIndexMap
;
577 for (MCAssembler::iterator it
= Asm
.begin(),
578 ie
= Asm
.end(); it
!= ie
; ++it
, ++Index
)
579 SectionIndexMap
[&it
->getSection()] = Index
;
580 assert(Index
<= 256 && "Too many sections!");
582 // Index 0 is always the empty string.
583 StringMap
<uint64_t> StringIndexMap
;
584 StringTable
+= '\x00';
586 // Build the symbol arrays and the string table, but only for non-local
589 // The particular order that we collect the symbols and create the string
590 // table, then sort the symbols is chosen to match 'as'. Even though it
591 // doesn't matter for correctness, this is important for letting us diff .o
593 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
594 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
595 const MCSymbol
&Symbol
= it
->getSymbol();
597 // Ignore assembler temporaries.
598 if (it
->getSymbol().isTemporary())
601 if (!it
->isExternal() && !Symbol
.isUndefined())
604 uint64_t &Entry
= StringIndexMap
[Symbol
.getName()];
606 Entry
= StringTable
.size();
607 StringTable
+= Symbol
.getName();
608 StringTable
+= '\x00';
613 MSD
.StringIndex
= Entry
;
615 if (Symbol
.isUndefined()) {
616 MSD
.SectionIndex
= 0;
617 UndefinedSymbolData
.push_back(MSD
);
618 } else if (Symbol
.isAbsolute()) {
619 MSD
.SectionIndex
= 0;
620 ExternalSymbolData
.push_back(MSD
);
622 MSD
.SectionIndex
= SectionIndexMap
.lookup(&Symbol
.getSection());
623 assert(MSD
.SectionIndex
&& "Invalid section index!");
624 ExternalSymbolData
.push_back(MSD
);
628 // Now add the data for local symbols.
629 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
630 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
631 const MCSymbol
&Symbol
= it
->getSymbol();
633 // Ignore assembler temporaries.
634 if (it
->getSymbol().isTemporary())
637 if (it
->isExternal() || Symbol
.isUndefined())
640 uint64_t &Entry
= StringIndexMap
[Symbol
.getName()];
642 Entry
= StringTable
.size();
643 StringTable
+= Symbol
.getName();
644 StringTable
+= '\x00';
649 MSD
.StringIndex
= Entry
;
651 if (Symbol
.isAbsolute()) {
652 MSD
.SectionIndex
= 0;
653 LocalSymbolData
.push_back(MSD
);
655 MSD
.SectionIndex
= SectionIndexMap
.lookup(&Symbol
.getSection());
656 assert(MSD
.SectionIndex
&& "Invalid section index!");
657 LocalSymbolData
.push_back(MSD
);
661 // External and undefined symbols are required to be in lexicographic order.
662 std::sort(ExternalSymbolData
.begin(), ExternalSymbolData
.end());
663 std::sort(UndefinedSymbolData
.begin(), UndefinedSymbolData
.end());
665 // Set the symbol indices.
667 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
668 LocalSymbolData
[i
].SymbolData
->setIndex(Index
++);
669 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
670 ExternalSymbolData
[i
].SymbolData
->setIndex(Index
++);
671 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
672 UndefinedSymbolData
[i
].SymbolData
->setIndex(Index
++);
674 // The string table is padded to a multiple of 4.
676 // FIXME: Check to see if this varies per arch.
677 while (StringTable
.size() % 4)
678 StringTable
+= '\x00';
681 void WriteObject(MCAssembler
&Asm
) {
682 unsigned NumSections
= Asm
.size();
684 // Compute the symbol -> symbol data map.
686 // FIXME: This should not be here.
687 DenseMap
<const MCSymbol
*, MCSymbolData
*> SymbolMap
;
688 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
689 ie
= Asm
.symbol_end(); it
!= ie
; ++it
)
690 SymbolMap
[&it
->getSymbol()] = it
;
692 // Create symbol data for any indirect symbols.
693 BindIndirectSymbols(Asm
, SymbolMap
);
695 // Compute symbol table information.
696 SmallString
<256> StringTable
;
697 std::vector
<MachSymbolData
> LocalSymbolData
;
698 std::vector
<MachSymbolData
> ExternalSymbolData
;
699 std::vector
<MachSymbolData
> UndefinedSymbolData
;
700 unsigned NumSymbols
= Asm
.symbol_size();
702 // No symbol table command is written if there are no symbols.
704 ComputeSymbolTable(Asm
, StringTable
, LocalSymbolData
, ExternalSymbolData
,
705 UndefinedSymbolData
);
707 // The section data starts after the header, the segment load command (and
708 // section headers) and the symbol table.
709 unsigned NumLoadCommands
= 1;
710 uint64_t LoadCommandsSize
=
711 SegmentLoadCommand32Size
+ NumSections
* Section32Size
;
713 // Add the symbol table load command sizes, if used.
715 NumLoadCommands
+= 2;
716 LoadCommandsSize
+= SymtabLoadCommandSize
+ DysymtabLoadCommandSize
;
719 // Compute the total size of the section data, as well as its file size and
721 uint64_t SectionDataStart
= Header32Size
+ LoadCommandsSize
;
722 uint64_t SectionDataSize
= 0;
723 uint64_t SectionDataFileSize
= 0;
725 for (MCAssembler::iterator it
= Asm
.begin(),
726 ie
= Asm
.end(); it
!= ie
; ++it
) {
727 MCSectionData
&SD
= *it
;
729 VMSize
= std::max(VMSize
, SD
.getAddress() + SD
.getSize());
731 if (isVirtualSection(SD
.getSection()))
734 SectionDataSize
= std::max(SectionDataSize
,
735 SD
.getAddress() + SD
.getSize());
736 SectionDataFileSize
= std::max(SectionDataFileSize
,
737 SD
.getAddress() + SD
.getFileSize());
740 // The section data is passed to 4 bytes.
742 // FIXME: Is this machine dependent?
743 unsigned SectionDataPadding
= OffsetToAlignment(SectionDataFileSize
, 4);
744 SectionDataFileSize
+= SectionDataPadding
;
746 // Write the prolog, starting with the header and load command...
747 WriteHeader32(NumLoadCommands
, LoadCommandsSize
,
748 Asm
.getSubsectionsViaSymbols());
749 WriteSegmentLoadCommand32(NumSections
, VMSize
,
750 SectionDataStart
, SectionDataSize
);
752 // ... and then the section headers.
754 // We also compute the section relocations while we do this. Note that
755 // compute relocation info will also update the fixup to have the correct
756 // value; this will be overwrite the appropriate data in the fragment when
758 std::vector
<MachRelocationEntry
> RelocInfos
;
759 uint64_t RelocTableEnd
= SectionDataStart
+ SectionDataFileSize
;
760 for (MCAssembler::iterator it
= Asm
.begin(), ie
= Asm
.end(); it
!= ie
;
762 MCSectionData
&SD
= *it
;
764 // The assembler writes relocations in the reverse order they were seen.
766 // FIXME: It is probably more complicated than this.
767 unsigned NumRelocsStart
= RelocInfos
.size();
768 for (unsigned i
= 0, e
= SD
.fixup_size(); i
!= e
; ++i
)
769 ComputeRelocationInfo(Asm
, SD
.getFixups()[e
- i
- 1], SymbolMap
,
772 unsigned NumRelocs
= RelocInfos
.size() - NumRelocsStart
;
773 uint64_t SectionStart
= SectionDataStart
+ SD
.getAddress();
774 WriteSection32(SD
, SectionStart
, RelocTableEnd
, NumRelocs
);
775 RelocTableEnd
+= NumRelocs
* RelocationInfoSize
;
778 // Write the symbol table load command, if used.
780 unsigned FirstLocalSymbol
= 0;
781 unsigned NumLocalSymbols
= LocalSymbolData
.size();
782 unsigned FirstExternalSymbol
= FirstLocalSymbol
+ NumLocalSymbols
;
783 unsigned NumExternalSymbols
= ExternalSymbolData
.size();
784 unsigned FirstUndefinedSymbol
= FirstExternalSymbol
+ NumExternalSymbols
;
785 unsigned NumUndefinedSymbols
= UndefinedSymbolData
.size();
786 unsigned NumIndirectSymbols
= Asm
.indirect_symbol_size();
787 unsigned NumSymTabSymbols
=
788 NumLocalSymbols
+ NumExternalSymbols
+ NumUndefinedSymbols
;
789 uint64_t IndirectSymbolSize
= NumIndirectSymbols
* 4;
790 uint64_t IndirectSymbolOffset
= 0;
792 // If used, the indirect symbols are written after the section data.
793 if (NumIndirectSymbols
)
794 IndirectSymbolOffset
= RelocTableEnd
;
796 // The symbol table is written after the indirect symbol data.
797 uint64_t SymbolTableOffset
= RelocTableEnd
+ IndirectSymbolSize
;
799 // The string table is written after symbol table.
800 uint64_t StringTableOffset
=
801 SymbolTableOffset
+ NumSymTabSymbols
* Nlist32Size
;
802 WriteSymtabLoadCommand(SymbolTableOffset
, NumSymTabSymbols
,
803 StringTableOffset
, StringTable
.size());
805 WriteDysymtabLoadCommand(FirstLocalSymbol
, NumLocalSymbols
,
806 FirstExternalSymbol
, NumExternalSymbols
,
807 FirstUndefinedSymbol
, NumUndefinedSymbols
,
808 IndirectSymbolOffset
, NumIndirectSymbols
);
811 // Write the actual section data.
812 for (MCAssembler::iterator it
= Asm
.begin(), ie
= Asm
.end(); it
!= ie
; ++it
)
813 WriteFileData(OS
, *it
, *this);
815 // Write the extra padding.
816 WriteZeros(SectionDataPadding
);
818 // Write the relocation entries.
819 for (unsigned i
= 0, e
= RelocInfos
.size(); i
!= e
; ++i
) {
820 Write32(RelocInfos
[i
].Word0
);
821 Write32(RelocInfos
[i
].Word1
);
824 // Write the symbol table data, if used.
826 // Write the indirect symbol entries.
827 for (MCAssembler::indirect_symbol_iterator
828 it
= Asm
.indirect_symbol_begin(),
829 ie
= Asm
.indirect_symbol_end(); it
!= ie
; ++it
) {
830 // Indirect symbols in the non lazy symbol pointer section have some
832 const MCSectionMachO
&Section
=
833 static_cast<const MCSectionMachO
&>(it
->SectionData
->getSection());
835 Section
.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE
;
836 if (Type
== MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS
) {
837 // If this symbol is defined and internal, mark it as such.
838 if (it
->Symbol
->isDefined() &&
839 !SymbolMap
.lookup(it
->Symbol
)->isExternal()) {
840 uint32_t Flags
= ISF_Local
;
841 if (it
->Symbol
->isAbsolute())
842 Flags
|= ISF_Absolute
;
848 Write32(SymbolMap
[it
->Symbol
]->getIndex());
851 // FIXME: Check that offsets match computed ones.
853 // Write the symbol table entries.
854 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
855 WriteNlist32(LocalSymbolData
[i
]);
856 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
857 WriteNlist32(ExternalSymbolData
[i
]);
858 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
859 WriteNlist32(UndefinedSymbolData
[i
]);
861 // Write the string table.
862 OS
<< StringTable
.str();
869 MCFragment::MCFragment() : Kind(FragmentType(~0)) {
872 MCFragment::MCFragment(FragmentType _Kind
, MCSectionData
*_Parent
)
875 FileSize(~UINT64_C(0))
878 Parent
->getFragmentList().push_back(this);
881 MCFragment::~MCFragment() {
884 uint64_t MCFragment::getAddress() const {
885 assert(getParent() && "Missing Section!");
886 return getParent()->getAddress() + Offset
;
891 MCSectionData::MCSectionData() : Section(0) {}
893 MCSectionData::MCSectionData(const MCSection
&_Section
, MCAssembler
*A
)
894 : Section(&_Section
),
896 Address(~UINT64_C(0)),
898 FileSize(~UINT64_C(0)),
902 A
->getSectionList().push_back(this);
905 const MCSectionData::Fixup
*
906 MCSectionData::LookupFixup(const MCFragment
*Fragment
, uint64_t Offset
) const {
907 // Use a one level cache to turn the common case of accessing the fixups in
908 // order into O(1) instead of O(N).
909 unsigned i
= LastFixupLookup
, Count
= Fixups
.size(), End
= Fixups
.size();
913 const Fixup
&F
= Fixups
[i
];
914 if (F
.Fragment
== Fragment
&& F
.Offset
== Offset
) {
929 MCSymbolData::MCSymbolData() : Symbol(0) {}
931 MCSymbolData::MCSymbolData(const MCSymbol
&_Symbol
, MCFragment
*_Fragment
,
932 uint64_t _Offset
, MCAssembler
*A
)
933 : Symbol(&_Symbol
), Fragment(_Fragment
), Offset(_Offset
),
934 IsExternal(false), IsPrivateExtern(false),
935 CommonSize(0), CommonAlign(0), Flags(0), Index(0)
938 A
->getSymbolList().push_back(this);
943 MCAssembler::MCAssembler(MCContext
&_Context
, raw_ostream
&_OS
)
944 : Context(_Context
), OS(_OS
), SubsectionsViaSymbols(false)
948 MCAssembler::~MCAssembler() {
951 void MCAssembler::LayoutSection(MCSectionData
&SD
) {
952 uint64_t Address
= SD
.getAddress();
954 for (MCSectionData::iterator it
= SD
.begin(), ie
= SD
.end(); it
!= ie
; ++it
) {
957 F
.setOffset(Address
- SD
.getAddress());
959 // Evaluate fragment size.
960 switch (F
.getKind()) {
961 case MCFragment::FT_Align
: {
962 MCAlignFragment
&AF
= cast
<MCAlignFragment
>(F
);
964 uint64_t Size
= OffsetToAlignment(Address
, AF
.getAlignment());
965 if (Size
> AF
.getMaxBytesToEmit())
968 AF
.setFileSize(Size
);
972 case MCFragment::FT_Data
:
973 F
.setFileSize(F
.getMaxFileSize());
976 case MCFragment::FT_Fill
: {
977 MCFillFragment
&FF
= cast
<MCFillFragment
>(F
);
979 F
.setFileSize(F
.getMaxFileSize());
981 // If the fill value is constant, thats it.
982 if (FF
.getValue().isAbsolute())
985 // Otherwise, add fixups for the values.
986 for (uint64_t i
= 0, e
= FF
.getCount(); i
!= e
; ++i
) {
987 MCSectionData::Fixup
Fix(F
, i
* FF
.getValueSize(),
988 FF
.getValue(),FF
.getValueSize());
989 SD
.getFixups().push_back(Fix
);
994 case MCFragment::FT_Org
: {
995 MCOrgFragment
&OF
= cast
<MCOrgFragment
>(F
);
997 if (!OF
.getOffset().isAbsolute())
998 llvm_unreachable("FIXME: Not yet implemented!");
999 uint64_t OrgOffset
= OF
.getOffset().getConstant();
1000 uint64_t Offset
= Address
- SD
.getAddress();
1002 // FIXME: We need a way to communicate this error.
1003 if (OrgOffset
< Offset
)
1004 llvm_report_error("invalid .org offset '" + Twine(OrgOffset
) +
1005 "' (at offset '" + Twine(Offset
) + "'");
1007 F
.setFileSize(OrgOffset
- Offset
);
1011 case MCFragment::FT_ZeroFill
: {
1012 MCZeroFillFragment
&ZFF
= cast
<MCZeroFillFragment
>(F
);
1014 // Align the fragment offset; it is safe to adjust the offset freely since
1015 // this is only in virtual sections.
1016 uint64_t Aligned
= RoundUpToAlignment(Address
, ZFF
.getAlignment());
1017 F
.setOffset(Aligned
- SD
.getAddress());
1019 // FIXME: This is misnamed.
1020 F
.setFileSize(ZFF
.getSize());
1025 Address
+= F
.getFileSize();
1028 // Set the section sizes.
1029 SD
.setSize(Address
- SD
.getAddress());
1030 if (isVirtualSection(SD
.getSection()))
1033 SD
.setFileSize(Address
- SD
.getAddress());
1036 /// WriteFileData - Write the \arg F data to the output file.
1037 static void WriteFileData(raw_ostream
&OS
, const MCFragment
&F
,
1038 MachObjectWriter
&MOW
) {
1039 uint64_t Start
= OS
.tell();
1044 // FIXME: Embed in fragments instead?
1045 switch (F
.getKind()) {
1046 case MCFragment::FT_Align
: {
1047 MCAlignFragment
&AF
= cast
<MCAlignFragment
>(F
);
1048 uint64_t Count
= AF
.getFileSize() / AF
.getValueSize();
1050 // FIXME: This error shouldn't actually occur (the front end should emit
1051 // multiple .align directives to enforce the semantics it wants), but is
1052 // severe enough that we want to report it. How to handle this?
1053 if (Count
* AF
.getValueSize() != AF
.getFileSize())
1054 llvm_report_error("undefined .align directive, value size '" +
1055 Twine(AF
.getValueSize()) +
1056 "' is not a divisor of padding size '" +
1057 Twine(AF
.getFileSize()) + "'");
1059 for (uint64_t i
= 0; i
!= Count
; ++i
) {
1060 switch (AF
.getValueSize()) {
1062 assert(0 && "Invalid size!");
1063 case 1: MOW
.Write8 (uint8_t (AF
.getValue())); break;
1064 case 2: MOW
.Write16(uint16_t(AF
.getValue())); break;
1065 case 4: MOW
.Write32(uint32_t(AF
.getValue())); break;
1066 case 8: MOW
.Write64(uint64_t(AF
.getValue())); break;
1072 case MCFragment::FT_Data
:
1073 OS
<< cast
<MCDataFragment
>(F
).getContents().str();
1076 case MCFragment::FT_Fill
: {
1077 MCFillFragment
&FF
= cast
<MCFillFragment
>(F
);
1080 if (FF
.getValue().isAbsolute())
1081 Value
= FF
.getValue().getConstant();
1082 for (uint64_t i
= 0, e
= FF
.getCount(); i
!= e
; ++i
) {
1083 if (!FF
.getValue().isAbsolute()) {
1086 // FIXME: Find a better way to write in the fixes.
1087 const MCSectionData::Fixup
*Fixup
=
1088 F
.getParent()->LookupFixup(&F
, i
* FF
.getValueSize());
1089 assert(Fixup
&& "Missing fixup for fill value!");
1090 Value
= Fixup
->FixedValue
;
1093 switch (FF
.getValueSize()) {
1095 assert(0 && "Invalid size!");
1096 case 1: MOW
.Write8 (uint8_t (Value
)); break;
1097 case 2: MOW
.Write16(uint16_t(Value
)); break;
1098 case 4: MOW
.Write32(uint32_t(Value
)); break;
1099 case 8: MOW
.Write64(uint64_t(Value
)); break;
1105 case MCFragment::FT_Org
: {
1106 MCOrgFragment
&OF
= cast
<MCOrgFragment
>(F
);
1108 for (uint64_t i
= 0, e
= OF
.getFileSize(); i
!= e
; ++i
)
1109 MOW
.Write8(uint8_t(OF
.getValue()));
1114 case MCFragment::FT_ZeroFill
: {
1115 assert(0 && "Invalid zero fill fragment in concrete section!");
1120 assert(OS
.tell() - Start
== F
.getFileSize());
1123 /// WriteFileData - Write the \arg SD data to the output file.
1124 static void WriteFileData(raw_ostream
&OS
, const MCSectionData
&SD
,
1125 MachObjectWriter
&MOW
) {
1126 // Ignore virtual sections.
1127 if (isVirtualSection(SD
.getSection())) {
1128 assert(SD
.getFileSize() == 0);
1132 uint64_t Start
= OS
.tell();
1135 for (MCSectionData::const_iterator it
= SD
.begin(),
1136 ie
= SD
.end(); it
!= ie
; ++it
)
1137 WriteFileData(OS
, *it
, MOW
);
1139 // Add section padding.
1140 assert(SD
.getFileSize() >= SD
.getSize() && "Invalid section sizes!");
1141 MOW
.WriteZeros(SD
.getFileSize() - SD
.getSize());
1143 assert(OS
.tell() - Start
== SD
.getFileSize());
1146 void MCAssembler::Finish() {
1147 // Layout the concrete sections and fragments.
1148 uint64_t Address
= 0;
1149 MCSectionData
*Prev
= 0;
1150 for (iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
1151 MCSectionData
&SD
= *it
;
1153 // Skip virtual sections.
1154 if (isVirtualSection(SD
.getSection()))
1157 // Align this section if necessary by adding padding bytes to the previous
1159 if (uint64_t Pad
= OffsetToAlignment(Address
, it
->getAlignment())) {
1160 assert(Prev
&& "Missing prev section!");
1161 Prev
->setFileSize(Prev
->getFileSize() + Pad
);
1165 // Layout the section fragments and its size.
1166 SD
.setAddress(Address
);
1168 Address
+= SD
.getFileSize();
1173 // Layout the virtual sections.
1174 for (iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
1175 MCSectionData
&SD
= *it
;
1177 if (!isVirtualSection(SD
.getSection()))
1180 SD
.setAddress(Address
);
1182 Address
+= SD
.getSize();
1185 // Write the object file.
1186 MachObjectWriter
MOW(OS
);
1187 MOW
.WriteObject(*this);