• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- lib/MC/MachObjectWriter.cpp - Mach-O File Writer -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/MC/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/MCAsmBackend.h"
16 #include "llvm/MC/MCAsmLayout.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCObjectWriter.h"
19 #include "llvm/MC/MCSectionMachO.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/MC/MCMachOSymbolFlags.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/Object/MachOFormat.h"
24 #include "llvm/Support/ErrorHandling.h"
25 
26 #include <vector>
27 using namespace llvm;
28 using namespace llvm::object;
29 
30 bool MachObjectWriter::
doesSymbolRequireExternRelocation(const MCSymbolData * SD)31 doesSymbolRequireExternRelocation(const MCSymbolData *SD) {
32   // Undefined symbols are always extern.
33   if (SD->Symbol->isUndefined())
34     return true;
35 
36   // References to weak definitions require external relocation entries; the
37   // definition may not always be the one in the same object file.
38   if (SD->getFlags() & SF_WeakDefinition)
39     return true;
40 
41   // Otherwise, we can use an internal relocation.
42   return false;
43 }
44 
45 bool MachObjectWriter::
operator <(const MachSymbolData & RHS) const46 MachSymbolData::operator<(const MachSymbolData &RHS) const {
47   return SymbolData->getSymbol().getName() <
48     RHS.SymbolData->getSymbol().getName();
49 }
50 
isFixupKindPCRel(const MCAssembler & Asm,unsigned Kind)51 bool MachObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
52   const MCFixupKindInfo &FKI = Asm.getBackend().getFixupKindInfo(
53     (MCFixupKind) Kind);
54 
55   return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
56 }
57 
getFragmentAddress(const MCFragment * Fragment,const MCAsmLayout & Layout) const58 uint64_t MachObjectWriter::getFragmentAddress(const MCFragment *Fragment,
59                                               const MCAsmLayout &Layout) const {
60   return getSectionAddress(Fragment->getParent()) +
61     Layout.getFragmentOffset(Fragment);
62 }
63 
getSymbolAddress(const MCSymbolData * SD,const MCAsmLayout & Layout) const64 uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
65                                             const MCAsmLayout &Layout) const {
66   const MCSymbol &S = SD->getSymbol();
67 
68   // If this is a variable, then recursively evaluate now.
69   if (S.isVariable()) {
70     MCValue Target;
71     if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout))
72       report_fatal_error("unable to evaluate offset for variable '" +
73                          S.getName() + "'");
74 
75     // Verify that any used symbols are defined.
76     if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined())
77       report_fatal_error("unable to evaluate offset to undefined symbol '" +
78                          Target.getSymA()->getSymbol().getName() + "'");
79     if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined())
80       report_fatal_error("unable to evaluate offset to undefined symbol '" +
81                          Target.getSymB()->getSymbol().getName() + "'");
82 
83     uint64_t Address = Target.getConstant();
84     if (Target.getSymA())
85       Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
86                                     Target.getSymA()->getSymbol()), Layout);
87     if (Target.getSymB())
88       Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
89                                     Target.getSymB()->getSymbol()), Layout);
90     return Address;
91   }
92 
93   return getSectionAddress(SD->getFragment()->getParent()) +
94     Layout.getSymbolOffset(SD);
95 }
96 
getPaddingSize(const MCSectionData * SD,const MCAsmLayout & Layout) const97 uint64_t MachObjectWriter::getPaddingSize(const MCSectionData *SD,
98                                           const MCAsmLayout &Layout) const {
99   uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD);
100   unsigned Next = SD->getLayoutOrder() + 1;
101   if (Next >= Layout.getSectionOrder().size())
102     return 0;
103 
104   const MCSectionData &NextSD = *Layout.getSectionOrder()[Next];
105   if (NextSD.getSection().isVirtualSection())
106     return 0;
107   return OffsetToAlignment(EndAddr, NextSD.getAlignment());
108 }
109 
WriteHeader(unsigned NumLoadCommands,unsigned LoadCommandsSize,bool SubsectionsViaSymbols)110 void MachObjectWriter::WriteHeader(unsigned NumLoadCommands,
111                                    unsigned LoadCommandsSize,
112                                    bool SubsectionsViaSymbols) {
113   uint32_t Flags = 0;
114 
115   if (SubsectionsViaSymbols)
116     Flags |= macho::HF_SubsectionsViaSymbols;
117 
118   // struct mach_header (28 bytes) or
119   // struct mach_header_64 (32 bytes)
120 
121   uint64_t Start = OS.tell();
122   (void) Start;
123 
124   Write32(is64Bit() ? macho::HM_Object64 : macho::HM_Object32);
125 
126   Write32(TargetObjectWriter->getCPUType());
127   Write32(TargetObjectWriter->getCPUSubtype());
128 
129   Write32(macho::HFT_Object);
130   Write32(NumLoadCommands);
131   Write32(LoadCommandsSize);
132   Write32(Flags);
133   if (is64Bit())
134     Write32(0); // reserved
135 
136   assert(OS.tell() - Start ==
137          (is64Bit() ? macho::Header64Size : macho::Header32Size));
138 }
139 
140 /// WriteSegmentLoadCommand - Write a segment load command.
141 ///
142 /// \arg NumSections - The number of sections in this segment.
143 /// \arg SectionDataSize - The total size of the sections.
WriteSegmentLoadCommand(unsigned NumSections,uint64_t VMSize,uint64_t SectionDataStartOffset,uint64_t SectionDataSize)144 void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections,
145                                                uint64_t VMSize,
146                                                uint64_t SectionDataStartOffset,
147                                                uint64_t SectionDataSize) {
148   // struct segment_command (56 bytes) or
149   // struct segment_command_64 (72 bytes)
150 
151   uint64_t Start = OS.tell();
152   (void) Start;
153 
154   unsigned SegmentLoadCommandSize =
155     is64Bit() ? macho::SegmentLoadCommand64Size:
156     macho::SegmentLoadCommand32Size;
157   Write32(is64Bit() ? macho::LCT_Segment64 : macho::LCT_Segment);
158   Write32(SegmentLoadCommandSize +
159           NumSections * (is64Bit() ? macho::Section64Size :
160                          macho::Section32Size));
161 
162   WriteBytes("", 16);
163   if (is64Bit()) {
164     Write64(0); // vmaddr
165     Write64(VMSize); // vmsize
166     Write64(SectionDataStartOffset); // file offset
167     Write64(SectionDataSize); // file size
168   } else {
169     Write32(0); // vmaddr
170     Write32(VMSize); // vmsize
171     Write32(SectionDataStartOffset); // file offset
172     Write32(SectionDataSize); // file size
173   }
174   Write32(0x7); // maxprot
175   Write32(0x7); // initprot
176   Write32(NumSections);
177   Write32(0); // flags
178 
179   assert(OS.tell() - Start == SegmentLoadCommandSize);
180 }
181 
WriteSection(const MCAssembler & Asm,const MCAsmLayout & Layout,const MCSectionData & SD,uint64_t FileOffset,uint64_t RelocationsStart,unsigned NumRelocations)182 void MachObjectWriter::WriteSection(const MCAssembler &Asm,
183                                     const MCAsmLayout &Layout,
184                                     const MCSectionData &SD,
185                                     uint64_t FileOffset,
186                                     uint64_t RelocationsStart,
187                                     unsigned NumRelocations) {
188   uint64_t SectionSize = Layout.getSectionAddressSize(&SD);
189 
190   // The offset is unused for virtual sections.
191   if (SD.getSection().isVirtualSection()) {
192     assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!");
193     FileOffset = 0;
194   }
195 
196   // struct section (68 bytes) or
197   // struct section_64 (80 bytes)
198 
199   uint64_t Start = OS.tell();
200   (void) Start;
201 
202   const MCSectionMachO &Section = cast<MCSectionMachO>(SD.getSection());
203   WriteBytes(Section.getSectionName(), 16);
204   WriteBytes(Section.getSegmentName(), 16);
205   if (is64Bit()) {
206     Write64(getSectionAddress(&SD)); // address
207     Write64(SectionSize); // size
208   } else {
209     Write32(getSectionAddress(&SD)); // address
210     Write32(SectionSize); // size
211   }
212   Write32(FileOffset);
213 
214   unsigned Flags = Section.getTypeAndAttributes();
215   if (SD.hasInstructions())
216     Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS;
217 
218   assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
219   Write32(Log2_32(SD.getAlignment()));
220   Write32(NumRelocations ? RelocationsStart : 0);
221   Write32(NumRelocations);
222   Write32(Flags);
223   Write32(IndirectSymBase.lookup(&SD)); // reserved1
224   Write32(Section.getStubSize()); // reserved2
225   if (is64Bit())
226     Write32(0); // reserved3
227 
228   assert(OS.tell() - Start == (is64Bit() ? macho::Section64Size :
229                                macho::Section32Size));
230 }
231 
WriteSymtabLoadCommand(uint32_t SymbolOffset,uint32_t NumSymbols,uint32_t StringTableOffset,uint32_t StringTableSize)232 void MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset,
233                                               uint32_t NumSymbols,
234                                               uint32_t StringTableOffset,
235                                               uint32_t StringTableSize) {
236   // struct symtab_command (24 bytes)
237 
238   uint64_t Start = OS.tell();
239   (void) Start;
240 
241   Write32(macho::LCT_Symtab);
242   Write32(macho::SymtabLoadCommandSize);
243   Write32(SymbolOffset);
244   Write32(NumSymbols);
245   Write32(StringTableOffset);
246   Write32(StringTableSize);
247 
248   assert(OS.tell() - Start == macho::SymtabLoadCommandSize);
249 }
250 
WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,uint32_t NumLocalSymbols,uint32_t FirstExternalSymbol,uint32_t NumExternalSymbols,uint32_t FirstUndefinedSymbol,uint32_t NumUndefinedSymbols,uint32_t IndirectSymbolOffset,uint32_t NumIndirectSymbols)251 void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
252                                                 uint32_t NumLocalSymbols,
253                                                 uint32_t FirstExternalSymbol,
254                                                 uint32_t NumExternalSymbols,
255                                                 uint32_t FirstUndefinedSymbol,
256                                                 uint32_t NumUndefinedSymbols,
257                                                 uint32_t IndirectSymbolOffset,
258                                                 uint32_t NumIndirectSymbols) {
259   // struct dysymtab_command (80 bytes)
260 
261   uint64_t Start = OS.tell();
262   (void) Start;
263 
264   Write32(macho::LCT_Dysymtab);
265   Write32(macho::DysymtabLoadCommandSize);
266   Write32(FirstLocalSymbol);
267   Write32(NumLocalSymbols);
268   Write32(FirstExternalSymbol);
269   Write32(NumExternalSymbols);
270   Write32(FirstUndefinedSymbol);
271   Write32(NumUndefinedSymbols);
272   Write32(0); // tocoff
273   Write32(0); // ntoc
274   Write32(0); // modtaboff
275   Write32(0); // nmodtab
276   Write32(0); // extrefsymoff
277   Write32(0); // nextrefsyms
278   Write32(IndirectSymbolOffset);
279   Write32(NumIndirectSymbols);
280   Write32(0); // extreloff
281   Write32(0); // nextrel
282   Write32(0); // locreloff
283   Write32(0); // nlocrel
284 
285   assert(OS.tell() - Start == macho::DysymtabLoadCommandSize);
286 }
287 
WriteNlist(MachSymbolData & MSD,const MCAsmLayout & Layout)288 void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
289                                   const MCAsmLayout &Layout) {
290   MCSymbolData &Data = *MSD.SymbolData;
291   const MCSymbol &Symbol = Data.getSymbol();
292   uint8_t Type = 0;
293   uint16_t Flags = Data.getFlags();
294   uint64_t Address = 0;
295 
296   // Set the N_TYPE bits. See <mach-o/nlist.h>.
297   //
298   // FIXME: Are the prebound or indirect fields possible here?
299   if (Symbol.isUndefined())
300     Type = macho::STT_Undefined;
301   else if (Symbol.isAbsolute())
302     Type = macho::STT_Absolute;
303   else
304     Type = macho::STT_Section;
305 
306   // FIXME: Set STAB bits.
307 
308   if (Data.isPrivateExtern())
309     Type |= macho::STF_PrivateExtern;
310 
311   // Set external bit.
312   if (Data.isExternal() || Symbol.isUndefined())
313     Type |= macho::STF_External;
314 
315   // Compute the symbol address.
316   if (Symbol.isDefined()) {
317     if (Symbol.isAbsolute()) {
318       Address = cast<MCConstantExpr>(Symbol.getVariableValue())->getValue();
319     } else {
320       Address = getSymbolAddress(&Data, Layout);
321     }
322   } else if (Data.isCommon()) {
323     // Common symbols are encoded with the size in the address
324     // field, and their alignment in the flags.
325     Address = Data.getCommonSize();
326 
327     // Common alignment is packed into the 'desc' bits.
328     if (unsigned Align = Data.getCommonAlignment()) {
329       unsigned Log2Size = Log2_32(Align);
330       assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
331       if (Log2Size > 15)
332         report_fatal_error("invalid 'common' alignment '" +
333                            Twine(Align) + "'");
334       // FIXME: Keep this mask with the SymbolFlags enumeration.
335       Flags = (Flags & 0xF0FF) | (Log2Size << 8);
336     }
337   }
338 
339   // struct nlist (12 bytes)
340 
341   Write32(MSD.StringIndex);
342   Write8(Type);
343   Write8(MSD.SectionIndex);
344 
345   // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
346   // value.
347   Write16(Flags);
348   if (is64Bit())
349     Write64(Address);
350   else
351     Write32(Address);
352 }
353 
RecordRelocation(const MCAssembler & Asm,const MCAsmLayout & Layout,const MCFragment * Fragment,const MCFixup & Fixup,MCValue Target,uint64_t & FixedValue)354 void MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
355                                         const MCAsmLayout &Layout,
356                                         const MCFragment *Fragment,
357                                         const MCFixup &Fixup,
358                                         MCValue Target,
359                                         uint64_t &FixedValue) {
360   TargetObjectWriter->RecordRelocation(this, Asm, Layout, Fragment, Fixup,
361                                        Target, FixedValue);
362 }
363 
BindIndirectSymbols(MCAssembler & Asm)364 void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) {
365   // This is the point where 'as' creates actual symbols for indirect symbols
366   // (in the following two passes). It would be easier for us to do this sooner
367   // when we see the attribute, but that makes getting the order in the symbol
368   // table much more complicated than it is worth.
369   //
370   // FIXME: Revisit this when the dust settles.
371 
372   // Bind non lazy symbol pointers first.
373   unsigned IndirectIndex = 0;
374   for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
375          ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
376     const MCSectionMachO &Section =
377       cast<MCSectionMachO>(it->SectionData->getSection());
378 
379     if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS)
380       continue;
381 
382     // Initialize the section indirect symbol base, if necessary.
383     if (!IndirectSymBase.count(it->SectionData))
384       IndirectSymBase[it->SectionData] = IndirectIndex;
385 
386     Asm.getOrCreateSymbolData(*it->Symbol);
387   }
388 
389   // Then lazy symbol pointers and symbol stubs.
390   IndirectIndex = 0;
391   for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
392          ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
393     const MCSectionMachO &Section =
394       cast<MCSectionMachO>(it->SectionData->getSection());
395 
396     if (Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
397         Section.getType() != MCSectionMachO::S_SYMBOL_STUBS)
398       continue;
399 
400     // Initialize the section indirect symbol base, if necessary.
401     if (!IndirectSymBase.count(it->SectionData))
402       IndirectSymBase[it->SectionData] = IndirectIndex;
403 
404     // Set the symbol type to undefined lazy, but only on construction.
405     //
406     // FIXME: Do not hardcode.
407     bool Created;
408     MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created);
409     if (Created)
410       Entry.setFlags(Entry.getFlags() | 0x0001);
411   }
412 }
413 
414 /// ComputeSymbolTable - Compute the symbol table data
415 ///
416 /// \param StringTable [out] - The string table data.
417 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
418 /// string table.
419 void MachObjectWriter::
ComputeSymbolTable(MCAssembler & Asm,SmallString<256> & StringTable,std::vector<MachSymbolData> & LocalSymbolData,std::vector<MachSymbolData> & ExternalSymbolData,std::vector<MachSymbolData> & UndefinedSymbolData)420 ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
421                    std::vector<MachSymbolData> &LocalSymbolData,
422                    std::vector<MachSymbolData> &ExternalSymbolData,
423                    std::vector<MachSymbolData> &UndefinedSymbolData) {
424   // Build section lookup table.
425   DenseMap<const MCSection*, uint8_t> SectionIndexMap;
426   unsigned Index = 1;
427   for (MCAssembler::iterator it = Asm.begin(),
428          ie = Asm.end(); it != ie; ++it, ++Index)
429     SectionIndexMap[&it->getSection()] = Index;
430   assert(Index <= 256 && "Too many sections!");
431 
432   // Index 0 is always the empty string.
433   StringMap<uint64_t> StringIndexMap;
434   StringTable += '\x00';
435 
436   // Build the symbol arrays and the string table, but only for non-local
437   // symbols.
438   //
439   // The particular order that we collect the symbols and create the string
440   // table, then sort the symbols is chosen to match 'as'. Even though it
441   // doesn't matter for correctness, this is important for letting us diff .o
442   // files.
443   for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
444          ie = Asm.symbol_end(); it != ie; ++it) {
445     const MCSymbol &Symbol = it->getSymbol();
446 
447     // Ignore non-linker visible symbols.
448     if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
449       continue;
450 
451     if (!it->isExternal() && !Symbol.isUndefined())
452       continue;
453 
454     uint64_t &Entry = StringIndexMap[Symbol.getName()];
455     if (!Entry) {
456       Entry = StringTable.size();
457       StringTable += Symbol.getName();
458       StringTable += '\x00';
459     }
460 
461     MachSymbolData MSD;
462     MSD.SymbolData = it;
463     MSD.StringIndex = Entry;
464 
465     if (Symbol.isUndefined()) {
466       MSD.SectionIndex = 0;
467       UndefinedSymbolData.push_back(MSD);
468     } else if (Symbol.isAbsolute()) {
469       MSD.SectionIndex = 0;
470       ExternalSymbolData.push_back(MSD);
471     } else {
472       MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
473       assert(MSD.SectionIndex && "Invalid section index!");
474       ExternalSymbolData.push_back(MSD);
475     }
476   }
477 
478   // Now add the data for local symbols.
479   for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
480          ie = Asm.symbol_end(); it != ie; ++it) {
481     const MCSymbol &Symbol = it->getSymbol();
482 
483     // Ignore non-linker visible symbols.
484     if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
485       continue;
486 
487     if (it->isExternal() || Symbol.isUndefined())
488       continue;
489 
490     uint64_t &Entry = StringIndexMap[Symbol.getName()];
491     if (!Entry) {
492       Entry = StringTable.size();
493       StringTable += Symbol.getName();
494       StringTable += '\x00';
495     }
496 
497     MachSymbolData MSD;
498     MSD.SymbolData = it;
499     MSD.StringIndex = Entry;
500 
501     if (Symbol.isAbsolute()) {
502       MSD.SectionIndex = 0;
503       LocalSymbolData.push_back(MSD);
504     } else {
505       MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
506       assert(MSD.SectionIndex && "Invalid section index!");
507       LocalSymbolData.push_back(MSD);
508     }
509   }
510 
511   // External and undefined symbols are required to be in lexicographic order.
512   std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
513   std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
514 
515   // Set the symbol indices.
516   Index = 0;
517   for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
518     LocalSymbolData[i].SymbolData->setIndex(Index++);
519   for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
520     ExternalSymbolData[i].SymbolData->setIndex(Index++);
521   for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
522     UndefinedSymbolData[i].SymbolData->setIndex(Index++);
523 
524   // The string table is padded to a multiple of 4.
525   while (StringTable.size() % 4)
526     StringTable += '\x00';
527 }
528 
computeSectionAddresses(const MCAssembler & Asm,const MCAsmLayout & Layout)529 void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
530                                                const MCAsmLayout &Layout) {
531   uint64_t StartAddress = 0;
532   const SmallVectorImpl<MCSectionData*> &Order = Layout.getSectionOrder();
533   for (int i = 0, n = Order.size(); i != n ; ++i) {
534     const MCSectionData *SD = Order[i];
535     StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment());
536     SectionAddress[SD] = StartAddress;
537     StartAddress += Layout.getSectionAddressSize(SD);
538 
539     // Explicitly pad the section to match the alignment requirements of the
540     // following one. This is for 'gas' compatibility, it shouldn't
541     /// strictly be necessary.
542     StartAddress += getPaddingSize(SD, Layout);
543   }
544 }
545 
ExecutePostLayoutBinding(MCAssembler & Asm,const MCAsmLayout & Layout)546 void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
547                                                 const MCAsmLayout &Layout) {
548   computeSectionAddresses(Asm, Layout);
549 
550   // Create symbol data for any indirect symbols.
551   BindIndirectSymbols(Asm);
552 
553   // Compute symbol table information and bind symbol indices.
554   ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
555                      UndefinedSymbolData);
556 }
557 
558 bool MachObjectWriter::
IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler & Asm,const MCSymbolData & DataA,const MCFragment & FB,bool InSet,bool IsPCRel) const559 IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
560                                        const MCSymbolData &DataA,
561                                        const MCFragment &FB,
562                                        bool InSet,
563                                        bool IsPCRel) const {
564   if (InSet)
565     return true;
566 
567   // The effective address is
568   //     addr(atom(A)) + offset(A)
569   //   - addr(atom(B)) - offset(B)
570   // and the offsets are not relocatable, so the fixup is fully resolved when
571   //  addr(atom(A)) - addr(atom(B)) == 0.
572   const MCSymbolData *A_Base = 0, *B_Base = 0;
573 
574   const MCSymbol &SA = DataA.getSymbol().AliasedSymbol();
575   const MCSection &SecA = SA.getSection();
576   const MCSection &SecB = FB.getParent()->getSection();
577 
578   if (IsPCRel) {
579     // The simple (Darwin, except on x86_64) way of dealing with this was to
580     // assume that any reference to a temporary symbol *must* be a temporary
581     // symbol in the same atom, unless the sections differ. Therefore, any PCrel
582     // relocation to a temporary symbol (in the same section) is fully
583     // resolved. This also works in conjunction with absolutized .set, which
584     // requires the compiler to use .set to absolutize the differences between
585     // symbols which the compiler knows to be assembly time constants, so we
586     // don't need to worry about considering symbol differences fully resolved.
587 
588     if (!Asm.getBackend().hasReliableSymbolDifference()) {
589       if (!SA.isTemporary() || !SA.isInSection() || &SecA != &SecB)
590         return false;
591       return true;
592     }
593     // For Darwin x86_64, there is one special case when the reference IsPCRel.
594     // If the fragment with the reference does not have a base symbol but meets
595     // the simple way of dealing with this, in that it is a temporary symbol in
596     // the same atom then it is assumed to be fully resolved.  This is needed so
597     // a relocation entry is not created and so the static linker does not
598     // mess up the reference later.
599     else if(!FB.getAtom() &&
600             SA.isTemporary() && SA.isInSection() && &SecA == &SecB){
601       return true;
602     }
603   } else {
604     if (!TargetObjectWriter->useAggressiveSymbolFolding())
605       return false;
606   }
607 
608   const MCFragment *FA = Asm.getSymbolData(SA).getFragment();
609 
610   // Bail if the symbol has no fragment.
611   if (!FA)
612     return false;
613 
614   A_Base = FA->getAtom();
615   if (!A_Base)
616     return false;
617 
618   B_Base = FB.getAtom();
619   if (!B_Base)
620     return false;
621 
622   // If the atoms are the same, they are guaranteed to have the same address.
623   if (A_Base == B_Base)
624     return true;
625 
626   // Otherwise, we can't prove this is fully resolved.
627   return false;
628 }
629 
WriteObject(MCAssembler & Asm,const MCAsmLayout & Layout)630 void MachObjectWriter::WriteObject(MCAssembler &Asm,
631 				   const MCAsmLayout &Layout) {
632   unsigned NumSections = Asm.size();
633 
634   // The section data starts after the header, the segment load command (and
635   // section headers) and the symbol table.
636   unsigned NumLoadCommands = 1;
637   uint64_t LoadCommandsSize = is64Bit() ?
638     macho::SegmentLoadCommand64Size + NumSections * macho::Section64Size :
639     macho::SegmentLoadCommand32Size + NumSections * macho::Section32Size;
640 
641   // Add the symbol table load command sizes, if used.
642   unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
643     UndefinedSymbolData.size();
644   if (NumSymbols) {
645     NumLoadCommands += 2;
646     LoadCommandsSize += (macho::SymtabLoadCommandSize +
647                          macho::DysymtabLoadCommandSize);
648   }
649 
650   // Compute the total size of the section data, as well as its file size and vm
651   // size.
652   uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size :
653                                macho::Header32Size) + LoadCommandsSize;
654   uint64_t SectionDataSize = 0;
655   uint64_t SectionDataFileSize = 0;
656   uint64_t VMSize = 0;
657   for (MCAssembler::const_iterator it = Asm.begin(),
658          ie = Asm.end(); it != ie; ++it) {
659     const MCSectionData &SD = *it;
660     uint64_t Address = getSectionAddress(&SD);
661     uint64_t Size = Layout.getSectionAddressSize(&SD);
662     uint64_t FileSize = Layout.getSectionFileSize(&SD);
663     FileSize += getPaddingSize(&SD, Layout);
664 
665     VMSize = std::max(VMSize, Address + Size);
666 
667     if (SD.getSection().isVirtualSection())
668       continue;
669 
670     SectionDataSize = std::max(SectionDataSize, Address + Size);
671     SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
672   }
673 
674   // The section data is padded to 4 bytes.
675   //
676   // FIXME: Is this machine dependent?
677   unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
678   SectionDataFileSize += SectionDataPadding;
679 
680   // Write the prolog, starting with the header and load command...
681   WriteHeader(NumLoadCommands, LoadCommandsSize,
682               Asm.getSubsectionsViaSymbols());
683   WriteSegmentLoadCommand(NumSections, VMSize,
684                           SectionDataStart, SectionDataSize);
685 
686   // ... and then the section headers.
687   uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
688   for (MCAssembler::const_iterator it = Asm.begin(),
689          ie = Asm.end(); it != ie; ++it) {
690     std::vector<macho::RelocationEntry> &Relocs = Relocations[it];
691     unsigned NumRelocs = Relocs.size();
692     uint64_t SectionStart = SectionDataStart + getSectionAddress(it);
693     WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs);
694     RelocTableEnd += NumRelocs * macho::RelocationInfoSize;
695   }
696 
697   // Write the symbol table load command, if used.
698   if (NumSymbols) {
699     unsigned FirstLocalSymbol = 0;
700     unsigned NumLocalSymbols = LocalSymbolData.size();
701     unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
702     unsigned NumExternalSymbols = ExternalSymbolData.size();
703     unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
704     unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
705     unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
706     unsigned NumSymTabSymbols =
707       NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
708     uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
709     uint64_t IndirectSymbolOffset = 0;
710 
711     // If used, the indirect symbols are written after the section data.
712     if (NumIndirectSymbols)
713       IndirectSymbolOffset = RelocTableEnd;
714 
715     // The symbol table is written after the indirect symbol data.
716     uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize;
717 
718     // The string table is written after symbol table.
719     uint64_t StringTableOffset =
720       SymbolTableOffset + NumSymTabSymbols * (is64Bit() ? macho::Nlist64Size :
721                                               macho::Nlist32Size);
722     WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
723                            StringTableOffset, StringTable.size());
724 
725     WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
726                              FirstExternalSymbol, NumExternalSymbols,
727                              FirstUndefinedSymbol, NumUndefinedSymbols,
728                              IndirectSymbolOffset, NumIndirectSymbols);
729   }
730 
731   // Write the actual section data.
732   for (MCAssembler::const_iterator it = Asm.begin(),
733          ie = Asm.end(); it != ie; ++it) {
734     Asm.WriteSectionData(it, Layout);
735 
736     uint64_t Pad = getPaddingSize(it, Layout);
737     for (unsigned int i = 0; i < Pad; ++i)
738       Write8(0);
739   }
740 
741   // Write the extra padding.
742   WriteZeros(SectionDataPadding);
743 
744   // Write the relocation entries.
745   for (MCAssembler::const_iterator it = Asm.begin(),
746          ie = Asm.end(); it != ie; ++it) {
747     // Write the section relocation entries, in reverse order to match 'as'
748     // (approximately, the exact algorithm is more complicated than this).
749     std::vector<macho::RelocationEntry> &Relocs = Relocations[it];
750     for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
751       Write32(Relocs[e - i - 1].Word0);
752       Write32(Relocs[e - i - 1].Word1);
753     }
754   }
755 
756   // Write the symbol table data, if used.
757   if (NumSymbols) {
758     // Write the indirect symbol entries.
759     for (MCAssembler::const_indirect_symbol_iterator
760            it = Asm.indirect_symbol_begin(),
761            ie = Asm.indirect_symbol_end(); it != ie; ++it) {
762       // Indirect symbols in the non lazy symbol pointer section have some
763       // special handling.
764       const MCSectionMachO &Section =
765         static_cast<const MCSectionMachO&>(it->SectionData->getSection());
766       if (Section.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) {
767         // If this symbol is defined and internal, mark it as such.
768         if (it->Symbol->isDefined() &&
769             !Asm.getSymbolData(*it->Symbol).isExternal()) {
770           uint32_t Flags = macho::ISF_Local;
771           if (it->Symbol->isAbsolute())
772             Flags |= macho::ISF_Absolute;
773           Write32(Flags);
774           continue;
775         }
776       }
777 
778       Write32(Asm.getSymbolData(*it->Symbol).getIndex());
779     }
780 
781     // FIXME: Check that offsets match computed ones.
782 
783     // Write the symbol table entries.
784     for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
785       WriteNlist(LocalSymbolData[i], Layout);
786     for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
787       WriteNlist(ExternalSymbolData[i], Layout);
788     for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
789       WriteNlist(UndefinedSymbolData[i], Layout);
790 
791     // Write the string table.
792     OS << StringTable.str();
793   }
794 }
795 
createMachObjectWriter(MCMachObjectTargetWriter * MOTW,raw_ostream & OS,bool IsLittleEndian)796 MCObjectWriter *llvm::createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
797                                              raw_ostream &OS,
798                                              bool IsLittleEndian) {
799   return new MachObjectWriter(MOTW, OS, IsLittleEndian);
800 }
801