LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MachObjectWriter.cpp
Go to the documentation of this file.
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 
11 #include "llvm/ADT/StringMap.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCAsmBackend.h"
14 #include "llvm/MC/MCAsmLayout.h"
15 #include "llvm/MC/MCAssembler.h"
16 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSectionMachO.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/MachO.h"
26 #include <vector>
27 using namespace llvm;
28 
30  Relocations.clear();
31  IndirectSymBase.clear();
32  StringTable.clear();
33  LocalSymbolData.clear();
34  ExternalSymbolData.clear();
35  UndefinedSymbolData.clear();
37 }
38 
41  // Undefined symbols are always extern.
42  if (SD->Symbol->isUndefined())
43  return true;
44 
45  // References to weak definitions require external relocation entries; the
46  // definition may not always be the one in the same object file.
47  if (SD->getFlags() & SF_WeakDefinition)
48  return true;
49 
50  // Otherwise, we can use an internal relocation.
51  return false;
52 }
53 
55 MachSymbolData::operator<(const MachSymbolData &RHS) const {
56  return SymbolData->getSymbol().getName() <
57  RHS.SymbolData->getSymbol().getName();
58 }
59 
61  const MCFixupKindInfo &FKI = Asm.getBackend().getFixupKindInfo(
62  (MCFixupKind) Kind);
63 
65 }
66 
68  const MCAsmLayout &Layout) const {
69  return getSectionAddress(Fragment->getParent()) +
70  Layout.getFragmentOffset(Fragment);
71 }
72 
74  const MCAsmLayout &Layout) const {
75  const MCSymbol &S = SD->getSymbol();
76 
77  // If this is a variable, then recursively evaluate now.
78  if (S.isVariable()) {
79  if (const MCConstantExpr *C =
80  dyn_cast<const MCConstantExpr>(S.getVariableValue()))
81  return C->getValue();
82 
83 
85  if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout))
86  report_fatal_error("unable to evaluate offset for variable '" +
87  S.getName() + "'");
88 
89  // Verify that any used symbols are defined.
90  if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined())
91  report_fatal_error("unable to evaluate offset to undefined symbol '" +
92  Target.getSymA()->getSymbol().getName() + "'");
93  if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined())
94  report_fatal_error("unable to evaluate offset to undefined symbol '" +
95  Target.getSymB()->getSymbol().getName() + "'");
96 
97  uint64_t Address = Target.getConstant();
98  if (Target.getSymA())
99  Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
100  Target.getSymA()->getSymbol()), Layout);
101  if (Target.getSymB())
102  Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
103  Target.getSymB()->getSymbol()), Layout);
104  return Address;
105  }
106 
107  return getSectionAddress(SD->getFragment()->getParent()) +
108  Layout.getSymbolOffset(SD);
109 }
110 
112  const MCAsmLayout &Layout) const {
113  uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD);
114  unsigned Next = SD->getLayoutOrder() + 1;
115  if (Next >= Layout.getSectionOrder().size())
116  return 0;
117 
118  const MCSectionData &NextSD = *Layout.getSectionOrder()[Next];
119  if (NextSD.getSection().isVirtualSection())
120  return 0;
121  return OffsetToAlignment(EndAddr, NextSD.getAlignment());
122 }
123 
124 void MachObjectWriter::WriteHeader(unsigned NumLoadCommands,
125  unsigned LoadCommandsSize,
126  bool SubsectionsViaSymbols) {
127  uint32_t Flags = 0;
128 
129  if (SubsectionsViaSymbols)
131 
132  // struct mach_header (28 bytes) or
133  // struct mach_header_64 (32 bytes)
134 
135  uint64_t Start = OS.tell();
136  (void) Start;
137 
138  Write32(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC);
139 
140  Write32(TargetObjectWriter->getCPUType());
141  Write32(TargetObjectWriter->getCPUSubtype());
142 
144  Write32(NumLoadCommands);
145  Write32(LoadCommandsSize);
146  Write32(Flags);
147  if (is64Bit())
148  Write32(0); // reserved
149 
150  assert(OS.tell() - Start ==
151  (is64Bit()?sizeof(MachO::mach_header_64): sizeof(MachO::mach_header)));
152 }
153 
154 /// WriteSegmentLoadCommand - Write a segment load command.
155 ///
156 /// \param NumSections The number of sections in this segment.
157 /// \param SectionDataSize The total size of the sections.
159  uint64_t VMSize,
160  uint64_t SectionDataStartOffset,
161  uint64_t SectionDataSize) {
162  // struct segment_command (56 bytes) or
163  // struct segment_command_64 (72 bytes)
164 
165  uint64_t Start = OS.tell();
166  (void) Start;
167 
168  unsigned SegmentLoadCommandSize =
170  sizeof(MachO::segment_command);
171  Write32(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT);
172  Write32(SegmentLoadCommandSize +
173  NumSections * (is64Bit() ? sizeof(MachO::section_64) :
174  sizeof(MachO::section)));
175 
176  WriteBytes("", 16);
177  if (is64Bit()) {
178  Write64(0); // vmaddr
179  Write64(VMSize); // vmsize
180  Write64(SectionDataStartOffset); // file offset
181  Write64(SectionDataSize); // file size
182  } else {
183  Write32(0); // vmaddr
184  Write32(VMSize); // vmsize
185  Write32(SectionDataStartOffset); // file offset
186  Write32(SectionDataSize); // file size
187  }
188  // maxprot
190  // initprot
192  Write32(NumSections);
193  Write32(0); // flags
194 
195  assert(OS.tell() - Start == SegmentLoadCommandSize);
196 }
197 
199  const MCAsmLayout &Layout,
200  const MCSectionData &SD,
201  uint64_t FileOffset,
202  uint64_t RelocationsStart,
203  unsigned NumRelocations) {
204  uint64_t SectionSize = Layout.getSectionAddressSize(&SD);
205 
206  // The offset is unused for virtual sections.
207  if (SD.getSection().isVirtualSection()) {
208  assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!");
209  FileOffset = 0;
210  }
211 
212  // struct section (68 bytes) or
213  // struct section_64 (80 bytes)
214 
215  uint64_t Start = OS.tell();
216  (void) Start;
217 
218  const MCSectionMachO &Section = cast<MCSectionMachO>(SD.getSection());
219  WriteBytes(Section.getSectionName(), 16);
220  WriteBytes(Section.getSegmentName(), 16);
221  if (is64Bit()) {
222  Write64(getSectionAddress(&SD)); // address
223  Write64(SectionSize); // size
224  } else {
225  Write32(getSectionAddress(&SD)); // address
226  Write32(SectionSize); // size
227  }
228  Write32(FileOffset);
229 
230  unsigned Flags = Section.getTypeAndAttributes();
231  if (SD.hasInstructions())
232  Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS;
233 
234  assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
236  Write32(NumRelocations ? RelocationsStart : 0);
237  Write32(NumRelocations);
238  Write32(Flags);
239  Write32(IndirectSymBase.lookup(&SD)); // reserved1
240  Write32(Section.getStubSize()); // reserved2
241  if (is64Bit())
242  Write32(0); // reserved3
243 
244  assert(OS.tell() - Start == (is64Bit() ? sizeof(MachO::section_64) :
245  sizeof(MachO::section)));
246 }
247 
248 void MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset,
249  uint32_t NumSymbols,
250  uint32_t StringTableOffset,
251  uint32_t StringTableSize) {
252  // struct symtab_command (24 bytes)
253 
254  uint64_t Start = OS.tell();
255  (void) Start;
256 
257  Write32(MachO::LC_SYMTAB);
259  Write32(SymbolOffset);
260  Write32(NumSymbols);
261  Write32(StringTableOffset);
262  Write32(StringTableSize);
263 
264  assert(OS.tell() - Start == sizeof(MachO::symtab_command));
265 }
266 
267 void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
268  uint32_t NumLocalSymbols,
269  uint32_t FirstExternalSymbol,
270  uint32_t NumExternalSymbols,
271  uint32_t FirstUndefinedSymbol,
272  uint32_t NumUndefinedSymbols,
273  uint32_t IndirectSymbolOffset,
274  uint32_t NumIndirectSymbols) {
275  // struct dysymtab_command (80 bytes)
276 
277  uint64_t Start = OS.tell();
278  (void) Start;
279 
280  Write32(MachO::LC_DYSYMTAB);
282  Write32(FirstLocalSymbol);
283  Write32(NumLocalSymbols);
284  Write32(FirstExternalSymbol);
285  Write32(NumExternalSymbols);
286  Write32(FirstUndefinedSymbol);
287  Write32(NumUndefinedSymbols);
288  Write32(0); // tocoff
289  Write32(0); // ntoc
290  Write32(0); // modtaboff
291  Write32(0); // nmodtab
292  Write32(0); // extrefsymoff
293  Write32(0); // nextrefsyms
294  Write32(IndirectSymbolOffset);
295  Write32(NumIndirectSymbols);
296  Write32(0); // extreloff
297  Write32(0); // nextrel
298  Write32(0); // locreloff
299  Write32(0); // nlocrel
300 
301  assert(OS.tell() - Start == sizeof(MachO::dysymtab_command));
302 }
303 
304 void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
305  const MCAsmLayout &Layout) {
306  MCSymbolData &Data = *MSD.SymbolData;
307  const MCSymbol &Symbol = Data.getSymbol();
308  uint8_t Type = 0;
309  uint16_t Flags = Data.getFlags();
310  uint64_t Address = 0;
311 
312  // Set the N_TYPE bits. See <mach-o/nlist.h>.
313  //
314  // FIXME: Are the prebound or indirect fields possible here?
315  if (Symbol.isUndefined())
316  Type = MachO::N_UNDF;
317  else if (Symbol.isAbsolute())
318  Type = MachO::N_ABS;
319  else
320  Type = MachO::N_SECT;
321 
322  // FIXME: Set STAB bits.
323 
324  if (Data.isPrivateExtern())
325  Type |= MachO::N_PEXT;
326 
327  // Set external bit.
328  if (Data.isExternal() || Symbol.isUndefined())
329  Type |= MachO::N_EXT;
330 
331  // Compute the symbol address.
332  if (Symbol.isDefined()) {
333  Address = getSymbolAddress(&Data, Layout);
334  } else if (Data.isCommon()) {
335  // Common symbols are encoded with the size in the address
336  // field, and their alignment in the flags.
337  Address = Data.getCommonSize();
338 
339  // Common alignment is packed into the 'desc' bits.
340  if (unsigned Align = Data.getCommonAlignment()) {
341  unsigned Log2Size = Log2_32(Align);
342  assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
343  if (Log2Size > 15)
344  report_fatal_error("invalid 'common' alignment '" +
345  Twine(Align) + "' for '" + Symbol.getName() + "'",
346  false);
347  // FIXME: Keep this mask with the SymbolFlags enumeration.
348  Flags = (Flags & 0xF0FF) | (Log2Size << 8);
349  }
350  }
351 
352  // struct nlist (12 bytes)
353 
354  Write32(MSD.StringIndex);
355  Write8(Type);
356  Write8(MSD.SectionIndex);
357 
358  // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
359  // value.
360  Write16(Flags);
361  if (is64Bit())
362  Write64(Address);
363  else
364  Write32(Address);
365 }
366 
368  uint32_t DataOffset,
369  uint32_t DataSize) {
370  uint64_t Start = OS.tell();
371  (void) Start;
372 
373  Write32(Type);
375  Write32(DataOffset);
376  Write32(DataSize);
377 
378  assert(OS.tell() - Start == sizeof(MachO::linkedit_data_command));
379 }
380 
382  const std::vector<std::string> &Options, bool is64Bit)
383 {
384  unsigned Size = sizeof(MachO::linker_options_command);
385  for (unsigned i = 0, e = Options.size(); i != e; ++i)
386  Size += Options[i].size() + 1;
387  return RoundUpToAlignment(Size, is64Bit ? 8 : 4);
388 }
389 
391  const std::vector<std::string> &Options)
392 {
393  unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
394  uint64_t Start = OS.tell();
395  (void) Start;
396 
397  Write32(MachO::LC_LINKER_OPTIONS);
398  Write32(Size);
399  Write32(Options.size());
400  uint64_t BytesWritten = sizeof(MachO::linker_options_command);
401  for (unsigned i = 0, e = Options.size(); i != e; ++i) {
402  // Write each string, including the null byte.
403  const std::string &Option = Options[i];
404  WriteBytes(Option.c_str(), Option.size() + 1);
405  BytesWritten += Option.size() + 1;
406  }
407 
408  // Pad to a multiple of the pointer size.
409  WriteBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
410 
411  assert(OS.tell() - Start == Size);
412 }
413 
414 
416  const MCAsmLayout &Layout,
417  const MCFragment *Fragment,
418  const MCFixup &Fixup,
419  MCValue Target,
420  uint64_t &FixedValue) {
421  TargetObjectWriter->RecordRelocation(this, Asm, Layout, Fragment, Fixup,
422  Target, FixedValue);
423 }
424 
426  // This is the point where 'as' creates actual symbols for indirect symbols
427  // (in the following two passes). It would be easier for us to do this sooner
428  // when we see the attribute, but that makes getting the order in the symbol
429  // table much more complicated than it is worth.
430  //
431  // FIXME: Revisit this when the dust settles.
432 
433  // Report errors for use of .indirect_symbol not in a symbol pointer section
434  // or stub section.
436  ie = Asm.indirect_symbol_end(); it != ie; ++it) {
437  const MCSectionMachO &Section =
438  cast<MCSectionMachO>(it->SectionData->getSection());
439 
443  MCSymbol &Symbol = *it->Symbol;
444  report_fatal_error("indirect symbol '" + Symbol.getName() +
445  "' not in a symbol pointer or stub section");
446  }
447  }
448 
449  // Bind non lazy symbol pointers first.
450  unsigned IndirectIndex = 0;
452  ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
453  const MCSectionMachO &Section =
454  cast<MCSectionMachO>(it->SectionData->getSection());
455 
457  continue;
458 
459  // Initialize the section indirect symbol base, if necessary.
460  IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex));
461 
462  Asm.getOrCreateSymbolData(*it->Symbol);
463  }
464 
465  // Then lazy symbol pointers and symbol stubs.
466  IndirectIndex = 0;
468  ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
469  const MCSectionMachO &Section =
470  cast<MCSectionMachO>(it->SectionData->getSection());
471 
474  continue;
475 
476  // Initialize the section indirect symbol base, if necessary.
477  IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex));
478 
479  // Set the symbol type to undefined lazy, but only on construction.
480  //
481  // FIXME: Do not hardcode.
482  bool Created;
483  MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created);
484  if (Created)
485  Entry.setFlags(Entry.getFlags() | 0x0001);
486  }
487 }
488 
489 /// ComputeSymbolTable - Compute the symbol table data
490 ///
491 /// \param StringTable [out] - The string table data.
492 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
493 /// string table.
496  std::vector<MachSymbolData> &LocalSymbolData,
497  std::vector<MachSymbolData> &ExternalSymbolData,
498  std::vector<MachSymbolData> &UndefinedSymbolData) {
499  // Build section lookup table.
500  DenseMap<const MCSection*, uint8_t> SectionIndexMap;
501  unsigned Index = 1;
502  for (MCAssembler::iterator it = Asm.begin(),
503  ie = Asm.end(); it != ie; ++it, ++Index)
504  SectionIndexMap[&it->getSection()] = Index;
505  assert(Index <= 256 && "Too many sections!");
506 
507  // Index 0 is always the empty string.
508  StringMap<uint64_t> StringIndexMap;
509  StringTable += '\x00';
510 
511  // Build the symbol arrays and the string table, but only for non-local
512  // symbols.
513  //
514  // The particular order that we collect the symbols and create the string
515  // table, then sort the symbols is chosen to match 'as'. Even though it
516  // doesn't matter for correctness, this is important for letting us diff .o
517  // files.
519  ie = Asm.symbol_end(); it != ie; ++it) {
520  const MCSymbol &Symbol = it->getSymbol();
521 
522  // Ignore non-linker visible symbols.
523  if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
524  continue;
525 
526  if (!it->isExternal() && !Symbol.isUndefined())
527  continue;
528 
529  uint64_t &Entry = StringIndexMap[Symbol.getName()];
530  if (!Entry) {
531  Entry = StringTable.size();
532  StringTable += Symbol.getName();
533  StringTable += '\x00';
534  }
535 
536  MachSymbolData MSD;
537  MSD.SymbolData = it;
538  MSD.StringIndex = Entry;
539 
540  if (Symbol.isUndefined()) {
541  MSD.SectionIndex = 0;
542  UndefinedSymbolData.push_back(MSD);
543  } else if (Symbol.isAbsolute()) {
544  MSD.SectionIndex = 0;
545  ExternalSymbolData.push_back(MSD);
546  } else {
547  MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
548  assert(MSD.SectionIndex && "Invalid section index!");
549  ExternalSymbolData.push_back(MSD);
550  }
551  }
552 
553  // Now add the data for local symbols.
555  ie = Asm.symbol_end(); it != ie; ++it) {
556  const MCSymbol &Symbol = it->getSymbol();
557 
558  // Ignore non-linker visible symbols.
559  if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
560  continue;
561 
562  if (it->isExternal() || Symbol.isUndefined())
563  continue;
564 
565  uint64_t &Entry = StringIndexMap[Symbol.getName()];
566  if (!Entry) {
567  Entry = StringTable.size();
568  StringTable += Symbol.getName();
569  StringTable += '\x00';
570  }
571 
572  MachSymbolData MSD;
573  MSD.SymbolData = it;
574  MSD.StringIndex = Entry;
575 
576  if (Symbol.isAbsolute()) {
577  MSD.SectionIndex = 0;
578  LocalSymbolData.push_back(MSD);
579  } else {
580  MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
581  assert(MSD.SectionIndex && "Invalid section index!");
582  LocalSymbolData.push_back(MSD);
583  }
584  }
585 
586  // External and undefined symbols are required to be in lexicographic order.
587  std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
588  std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
589 
590  // Set the symbol indices.
591  Index = 0;
592  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
593  LocalSymbolData[i].SymbolData->setIndex(Index++);
594  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
595  ExternalSymbolData[i].SymbolData->setIndex(Index++);
596  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
597  UndefinedSymbolData[i].SymbolData->setIndex(Index++);
598 
599  // The string table is padded to a multiple of 4.
600  while (StringTable.size() % 4)
601  StringTable += '\x00';
602 }
603 
605  const MCAsmLayout &Layout) {
606  uint64_t StartAddress = 0;
607  const SmallVectorImpl<MCSectionData*> &Order = Layout.getSectionOrder();
608  for (int i = 0, n = Order.size(); i != n ; ++i) {
609  const MCSectionData *SD = Order[i];
610  StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment());
611  SectionAddress[SD] = StartAddress;
612  StartAddress += Layout.getSectionAddressSize(SD);
613 
614  // Explicitly pad the section to match the alignment requirements of the
615  // following one. This is for 'gas' compatibility, it shouldn't
616  /// strictly be necessary.
617  StartAddress += getPaddingSize(SD, Layout);
618  }
619 }
620 
622  const MCAsmLayout &Layout) {
624  e = Asm.symbol_end();
625  i != e; ++i) {
626  MCSymbolData &SD = *i;
627  if (!SD.getSymbol().isVariable())
628  continue;
629 
630  // Is the variable is a symbol difference (SA - SB + C) expression,
631  // and neither symbol is external, mark the variable as absolute.
632  const MCExpr *Expr = SD.getSymbol().getVariableValue();
633  MCValue Value;
634  if (Expr->EvaluateAsRelocatable(Value, Layout)) {
635  if (Value.getSymA() && Value.getSymB())
636  const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute();
637  }
638  }
639 }
640 
642  const MCAsmLayout &Layout) {
643  computeSectionAddresses(Asm, Layout);
644 
645  // Create symbol data for any indirect symbols.
646  BindIndirectSymbols(Asm);
647 
648  // Mark symbol difference expressions in variables (from .set or = directives)
649  // as absolute.
650  markAbsoluteVariableSymbols(Asm, Layout);
651 
652  // Compute symbol table information and bind symbol indices.
653  ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
654  UndefinedSymbolData);
655 }
656 
659  const MCSymbolData &DataA,
660  const MCFragment &FB,
661  bool InSet,
662  bool IsPCRel) const {
663  if (InSet)
664  return true;
665 
666  // The effective address is
667  // addr(atom(A)) + offset(A)
668  // - addr(atom(B)) - offset(B)
669  // and the offsets are not relocatable, so the fixup is fully resolved when
670  // addr(atom(A)) - addr(atom(B)) == 0.
671  const MCSymbolData *A_Base = 0, *B_Base = 0;
672 
673  const MCSymbol &SA = DataA.getSymbol().AliasedSymbol();
674  const MCSection &SecA = SA.getSection();
675  const MCSection &SecB = FB.getParent()->getSection();
676 
677  if (IsPCRel) {
678  // The simple (Darwin, except on x86_64) way of dealing with this was to
679  // assume that any reference to a temporary symbol *must* be a temporary
680  // symbol in the same atom, unless the sections differ. Therefore, any PCrel
681  // relocation to a temporary symbol (in the same section) is fully
682  // resolved. This also works in conjunction with absolutized .set, which
683  // requires the compiler to use .set to absolutize the differences between
684  // symbols which the compiler knows to be assembly time constants, so we
685  // don't need to worry about considering symbol differences fully resolved.
686  //
687  // If the file isn't using sub-sections-via-symbols, we can make the
688  // same assumptions about any symbol that we normally make about
689  // assembler locals.
690 
692  if (!SA.isInSection() || &SecA != &SecB ||
693  (!SA.isTemporary() &&
694  FB.getAtom() != Asm.getSymbolData(SA).getFragment()->getAtom() &&
696  return false;
697  return true;
698  }
699  // For Darwin x86_64, there is one special case when the reference IsPCRel.
700  // If the fragment with the reference does not have a base symbol but meets
701  // the simple way of dealing with this, in that it is a temporary symbol in
702  // the same atom then it is assumed to be fully resolved. This is needed so
703  // a relocation entry is not created and so the static linker does not
704  // mess up the reference later.
705  else if(!FB.getAtom() &&
706  SA.isTemporary() && SA.isInSection() && &SecA == &SecB){
707  return true;
708  }
709  } else {
710  if (!TargetObjectWriter->useAggressiveSymbolFolding())
711  return false;
712  }
713 
714  const MCFragment *FA = Asm.getSymbolData(SA).getFragment();
715 
716  // Bail if the symbol has no fragment.
717  if (!FA)
718  return false;
719 
720  A_Base = FA->getAtom();
721  if (!A_Base)
722  return false;
723 
724  B_Base = FB.getAtom();
725  if (!B_Base)
726  return false;
727 
728  // If the atoms are the same, they are guaranteed to have the same address.
729  if (A_Base == B_Base)
730  return true;
731 
732  // Otherwise, we can't prove this is fully resolved.
733  return false;
734 }
735 
737  const MCAsmLayout &Layout) {
738  unsigned NumSections = Asm.size();
739 
740  // The section data starts after the header, the segment load command (and
741  // section headers) and the symbol table.
742  unsigned NumLoadCommands = 1;
743  uint64_t LoadCommandsSize = is64Bit() ?
744  sizeof(MachO::segment_command_64) + NumSections * sizeof(MachO::section_64):
745  sizeof(MachO::segment_command) + NumSections * sizeof(MachO::section);
746 
747  // Add the data-in-code load command size, if used.
748  unsigned NumDataRegions = Asm.getDataRegions().size();
749  if (NumDataRegions) {
750  ++NumLoadCommands;
751  LoadCommandsSize += sizeof(MachO::linkedit_data_command);
752  }
753 
754  // Add the symbol table load command sizes, if used.
755  unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
756  UndefinedSymbolData.size();
757  if (NumSymbols) {
758  NumLoadCommands += 2;
759  LoadCommandsSize += (sizeof(MachO::symtab_command) +
760  sizeof(MachO::dysymtab_command));
761  }
762 
763  // Add the linker option load commands sizes.
764  const std::vector<std::vector<std::string> > &LinkerOptions =
765  Asm.getLinkerOptions();
766  for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
767  ++NumLoadCommands;
768  LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(LinkerOptions[i],
769  is64Bit());
770  }
771 
772  // Compute the total size of the section data, as well as its file size and vm
773  // size.
774  uint64_t SectionDataStart = (is64Bit() ? sizeof(MachO::mach_header_64) :
775  sizeof(MachO::mach_header)) + LoadCommandsSize;
776  uint64_t SectionDataSize = 0;
777  uint64_t SectionDataFileSize = 0;
778  uint64_t VMSize = 0;
779  for (MCAssembler::const_iterator it = Asm.begin(),
780  ie = Asm.end(); it != ie; ++it) {
781  const MCSectionData &SD = *it;
782  uint64_t Address = getSectionAddress(&SD);
783  uint64_t Size = Layout.getSectionAddressSize(&SD);
784  uint64_t FileSize = Layout.getSectionFileSize(&SD);
785  FileSize += getPaddingSize(&SD, Layout);
786 
787  VMSize = std::max(VMSize, Address + Size);
788 
789  if (SD.getSection().isVirtualSection())
790  continue;
791 
792  SectionDataSize = std::max(SectionDataSize, Address + Size);
793  SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
794  }
795 
796  // The section data is padded to 4 bytes.
797  //
798  // FIXME: Is this machine dependent?
799  unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
800  SectionDataFileSize += SectionDataPadding;
801 
802  // Write the prolog, starting with the header and load command...
803  WriteHeader(NumLoadCommands, LoadCommandsSize,
805  WriteSegmentLoadCommand(NumSections, VMSize,
806  SectionDataStart, SectionDataSize);
807 
808  // ... and then the section headers.
809  uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
810  for (MCAssembler::const_iterator it = Asm.begin(),
811  ie = Asm.end(); it != ie; ++it) {
812  std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
813  unsigned NumRelocs = Relocs.size();
814  uint64_t SectionStart = SectionDataStart + getSectionAddress(it);
815  WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs);
816  RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
817  }
818 
819  // Write the data-in-code load command, if used.
820  uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
821  if (NumDataRegions) {
822  uint64_t DataRegionsOffset = RelocTableEnd;
823  uint64_t DataRegionsSize = NumDataRegions * 8;
824  WriteLinkeditLoadCommand(MachO::LC_DATA_IN_CODE, DataRegionsOffset,
825  DataRegionsSize);
826  }
827 
828  // Write the symbol table load command, if used.
829  if (NumSymbols) {
830  unsigned FirstLocalSymbol = 0;
831  unsigned NumLocalSymbols = LocalSymbolData.size();
832  unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
833  unsigned NumExternalSymbols = ExternalSymbolData.size();
834  unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
835  unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
836  unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
837  unsigned NumSymTabSymbols =
838  NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
839  uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
840  uint64_t IndirectSymbolOffset = 0;
841 
842  // If used, the indirect symbols are written after the section data.
843  if (NumIndirectSymbols)
844  IndirectSymbolOffset = DataInCodeTableEnd;
845 
846  // The symbol table is written after the indirect symbol data.
847  uint64_t SymbolTableOffset = DataInCodeTableEnd + IndirectSymbolSize;
848 
849  // The string table is written after symbol table.
850  uint64_t StringTableOffset =
851  SymbolTableOffset + NumSymTabSymbols * (is64Bit() ?
852  sizeof(MachO::nlist_64) :
853  sizeof(MachO::nlist));
854  WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
855  StringTableOffset, StringTable.size());
856 
857  WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
858  FirstExternalSymbol, NumExternalSymbols,
859  FirstUndefinedSymbol, NumUndefinedSymbols,
860  IndirectSymbolOffset, NumIndirectSymbols);
861  }
862 
863  // Write the linker options load commands.
864  for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
865  WriteLinkerOptionsLoadCommand(LinkerOptions[i]);
866  }
867 
868  // Write the actual section data.
869  for (MCAssembler::const_iterator it = Asm.begin(),
870  ie = Asm.end(); it != ie; ++it) {
871  Asm.writeSectionData(it, Layout);
872 
873  uint64_t Pad = getPaddingSize(it, Layout);
874  for (unsigned int i = 0; i < Pad; ++i)
875  Write8(0);
876  }
877 
878  // Write the extra padding.
879  WriteZeros(SectionDataPadding);
880 
881  // Write the relocation entries.
882  for (MCAssembler::const_iterator it = Asm.begin(),
883  ie = Asm.end(); it != ie; ++it) {
884  // Write the section relocation entries, in reverse order to match 'as'
885  // (approximately, the exact algorithm is more complicated than this).
886  std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
887  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
888  Write32(Relocs[e - i - 1].r_word0);
889  Write32(Relocs[e - i - 1].r_word1);
890  }
891  }
892 
893  // Write out the data-in-code region payload, if there is one.
895  it = Asm.data_region_begin(), ie = Asm.data_region_end();
896  it != ie; ++it) {
897  const DataRegionData *Data = &(*it);
898  uint64_t Start =
900  Layout);
901  uint64_t End =
903  Layout);
904  DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind
905  << " start: " << Start << "(" << Data->Start->getName() << ")"
906  << " end: " << End << "(" << Data->End->getName() << ")"
907  << " size: " << End - Start
908  << "\n");
909  Write32(Start);
910  Write16(End - Start);
911  Write16(Data->Kind);
912  }
913 
914  // Write the symbol table data, if used.
915  if (NumSymbols) {
916  // Write the indirect symbol entries.
918  it = Asm.indirect_symbol_begin(),
919  ie = Asm.indirect_symbol_end(); it != ie; ++it) {
920  // Indirect symbols in the non lazy symbol pointer section have some
921  // special handling.
922  const MCSectionMachO &Section =
923  static_cast<const MCSectionMachO&>(it->SectionData->getSection());
925  // If this symbol is defined and internal, mark it as such.
926  if (it->Symbol->isDefined() &&
927  !Asm.getSymbolData(*it->Symbol).isExternal()) {
928  uint32_t Flags = MachO::INDIRECT_SYMBOL_LOCAL;
929  if (it->Symbol->isAbsolute())
930  Flags |= MachO::INDIRECT_SYMBOL_ABS;
931  Write32(Flags);
932  continue;
933  }
934  }
935 
936  Write32(Asm.getSymbolData(*it->Symbol).getIndex());
937  }
938 
939  // FIXME: Check that offsets match computed ones.
940 
941  // Write the symbol table entries.
942  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
943  WriteNlist(LocalSymbolData[i], Layout);
944  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
945  WriteNlist(ExternalSymbolData[i], Layout);
946  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
947  WriteNlist(UndefinedSymbolData[i], Layout);
948 
949  // Write the string table.
950  OS << StringTable.str();
951  }
952 }
953 
955  raw_ostream &OS,
956  bool IsLittleEndian) {
957  return new MachObjectWriter(MOTW, OS, IsLittleEndian);
958 }
size_t indirect_symbol_size() const
Definition: MCAssembler.h:1087
void markAbsoluteVariableSymbols(MCAssembler &Asm, const MCAsmLayout &Layout)
void push_back(const T &Elt)
Definition: SmallVector.h:236
virtual void reset()
lifetime management
void WriteZeros(unsigned N)
void setFlags(uint32_t Value)
setFlags - Set the (implementation defined) symbol flags.
Definition: MCAssembler.h:773
void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout)
const MCSymbol & getSymbol() const
Definition: MCExpr.h:283
void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout)
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
iterator begin()
Definition: MCAssembler.h:1039
void 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)
void operator<(const Optional< T > &X, const Optional< U > &Y)
Poison comparison between two Optional objects. Clients needs to explicitly compare the underlying va...
void Write32(uint32_t Value)
void WriteSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize)
bool hasInstructions() const
Definition: MCAssembler.h:610
const MCSymbol & getSymbol() const
Definition: MCAssembler.h:718
void WriteBytes(const SmallVectorImpl< char > &ByteVec, unsigned ZeroFillSize=0)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
symbol_iterator symbol_begin()
Definition: MCAssembler.h:1054
enum llvm::DataRegionData::KindTy Kind
void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize)
void WriteLinkerOptionsLoadCommand(const std::vector< std::string > &Options)
uint64_t getIndex() const
getIndex - Get the (implementation defined) index.
Definition: MCAssembler.h:781
const MCSection & getSection() const
Definition: MCSymbol.h:111
uint64_t getSymbolAddress(const MCSymbolData *SD, const MCAsmLayout &Layout) const
std::vector< DataRegionData >::const_iterator const_data_region_iterator
Definition: MCAssembler.h:828
const MCExpr * getVariableValue() const
getVariableValue() - Get the value for variable symbols.
Definition: MCSymbol.h:137
uint64_t getCommonSize() const
getCommonSize - Return the size of a 'common' symbol.
Definition: MCAssembler.h:749
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:85
bool isInSection() const
Definition: MCSymbol.h:95
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind)
uint64_t getSectionAddress(const MCSectionData *SD) const
void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCSectionData &SD, uint64_t FileOffset, uint64_t RelocationsStart, unsigned NumRelocations)
StringRef getSectionName() const
bool isExternal() const
Definition: MCAssembler.h:730
MCFragment * getFragment() const
Definition: MCAssembler.h:720
unsigned getStubSize() const
std::vector< IndirectSymbolData >::const_iterator const_indirect_symbol_iterator
Definition: MCAssembler.h:824
const MCSection & getSection() const
Definition: MCAssembler.h:605
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout)
Write the object file.
MCSectionData * getParent() const
Definition: MCAssembler.h:95
void Write8(uint8_t Value)
unsigned getLayoutOrder() const
Definition: MCAssembler.h:616
void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout)
uint32_t getFlags() const
getFlags - Get the (implementation defined) symbol flags.
Definition: MCAssembler.h:770
virtual void reset()
lifetime management
MCFixupKind
MCFixupKind - Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:22
MCSymbolData * getAtom() const
Definition: MCAssembler.h:98
void Write64(uint64_t Value)
size_t size() const
Definition: MCAssembler.h:1045
llvm::SmallVectorImpl< MCSectionData * > & getSectionOrder()
Definition: MCAsmLayout.h:76
uint64_t getSectionFileSize(const MCSectionData *SD) const
Get the data size of the given section, as emitted to the object file. This may include additional pa...
data_region_iterator data_region_begin()
Definition: MCAssembler.h:1108
const MCSymbolRefExpr * getSymB() const
Definition: MCValue.h:44
bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const
Definition: MCExpr.cpp:603
bool isAbsolute() const
isAbsolute - Check if this is an absolute symbol.
Definition: MCSymbol.h:105
MCSymbolData & getOrCreateSymbolData(const MCSymbol &Symbol, bool *Created=0)
Definition: MCAssembler.h:1151
bool isSymbolLinkerVisible(const MCSymbol &SD) const
bool isDefined() const
Definition: MCSymbol.h:89
MCSymbolData & getSymbolData(const MCSymbol &Symbol) const
Definition: MCAssembler.h:1145
void Write16(uint16_t Value)
std::vector< std::vector< std::string > > & getLinkerOptions()
Definition: MCAssembler.h:1093
indirect_symbol_iterator indirect_symbol_begin()
Definition: MCAssembler.h:1073
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:43
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, bool InSet, bool IsPCRel) const
unsigned getCommonAlignment() const
getCommonAlignment - Return the alignment of a 'common' symbol.
Definition: MCAssembler.h:764
virtual bool isVirtualSection() const =0
unsigned getAlignment() const
Definition: MCAssembler.h:607
uint64_t getPaddingSize(const MCSectionData *SD, const MCAsmLayout &Layout) const
bool isCommon() const
isCommon - Is this a 'common' symbol.
Definition: MCAssembler.h:737
uint64_t getFragmentAddress(const MCFragment *Fragment, const MCAsmLayout &Layout) const
static unsigned ComputeLinkerOptionsLoadCommandSize(const std::vector< std::string > &Options, bool is64Bit)
uint64_t getSymbolOffset(const MCSymbolData *SD) const
Get the offset of the given symbol, as computed in the current layout.
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
Definition: Debug.cpp:101
uint64_t getSectionAddressSize(const MCSectionData *SD) const
Get the address space size of the given section, as it effects layout. This may differ from the size ...
unsigned Log2_32(uint32_t Value)
Definition: MathExtras.h:443
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:270
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition: MCSymbol.h:76
StringRef getSegmentName() const
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
Definition: MathExtras.h:565
bool doesSymbolRequireExternRelocation(const MCSymbolData *SD)
bool getSubsectionsViaSymbols() const
Definition: MCAssembler.h:1006
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:70
const MCSymbol & AliasedSymbol() const
Definition: MCSymbol.cpp:42
void BindIndirectSymbols(MCAssembler &Asm)
MCAsmBackend & getBackend() const
Definition: MCAssembler.h:994
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
bool hasReliableSymbolDifference() const
Definition: MCAsmBackend.h:71
data_region_iterator data_region_end()
Definition: MCAssembler.h:1115
MCFixupKindInfo - Target independent information on a fixup kind.
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:132
int64_t getConstant() const
Definition: MCValue.h:42
unsigned getTypeAndAttributes() const
LLVM Value Representation.
Definition: Value.h:66
bool isPrivateExtern() const
Definition: MCAssembler.h:733
indirect_symbol_iterator indirect_symbol_end()
Definition: MCAssembler.h:1080
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:61
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Definition: MathExtras.h:572
void writeSectionData(const MCSectionData *Section, const MCAsmLayout &Layout) const
Emit the section contents using the given object writer.
unsigned getType() const
#define DEBUG(X)
Definition: Debug.h:97
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)
Record a relocation entry.
bool isPowerOf2_32(uint32_t Value)
Definition: MathExtras.h:354
void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize)
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:100
void ComputeSymbolTable(MCAssembler &Asm, SmallString< 256 > &StringTable, std::vector< MachSymbolData > &LocalSymbolData, std::vector< MachSymbolData > &ExternalSymbolData, std::vector< MachSymbolData > &UndefinedSymbolData)
std::vector< DataRegionData > & getDataRegions()
Definition: MCAssembler.h:1104
std::vector< IndirectSymbolData >::iterator indirect_symbol_iterator
Definition: MCAssembler.h:825
const MCSymbol * Symbol
Definition: MCAssembler.h:671
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
getFixupKindInfo - Get information on a fixup kind.
void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols)
MCObjectWriter * createMachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &OS, bool IsLittleEndian)
Construct a new Mach-O writer instance.
unsigned Flags
Flags describing additional information on this fixup kind.
symbol_iterator symbol_end()
Definition: MCAssembler.h:1057