LLVM  3.7.0
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"
18 #include "llvm/MC/MCObjectWriter.h"
19 #include "llvm/MC/MCSectionMachO.h"
20 #include "llvm/MC/MCSymbolMachO.h"
21 #include "llvm/MC/MCValue.h"
22 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/MachO.h"
26 #include <vector>
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "mc"
30 
32  Relocations.clear();
33  IndirectSymBase.clear();
34  StringTable.clear();
35  LocalSymbolData.clear();
36  ExternalSymbolData.clear();
37  UndefinedSymbolData.clear();
39 }
40 
42  // Undefined symbols are always extern.
43  if (S.isUndefined())
44  return true;
45 
46  // References to weak definitions require external relocation entries; the
47  // definition may not always be the one in the same object file.
48  if (cast<MCSymbolMachO>(S).isWeakDefinition())
49  return true;
50 
51  // Otherwise, we can use an internal relocation.
52  return false;
53 }
54 
56 MachSymbolData::operator<(const MachSymbolData &RHS) const {
57  return Symbol->getName() < RHS.Symbol->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  // If this is a variable, then recursively evaluate now.
76  if (S.isVariable()) {
77  if (const MCConstantExpr *C =
78  dyn_cast<const MCConstantExpr>(S.getVariableValue()))
79  return C->getValue();
80 
81 
83  if (!S.getVariableValue()->evaluateAsRelocatable(Target, &Layout, nullptr))
84  report_fatal_error("unable to evaluate offset for variable '" +
85  S.getName() + "'");
86 
87  // Verify that any used symbols are defined.
88  if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined())
89  report_fatal_error("unable to evaluate offset to undefined symbol '" +
90  Target.getSymA()->getSymbol().getName() + "'");
91  if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined())
92  report_fatal_error("unable to evaluate offset to undefined symbol '" +
93  Target.getSymB()->getSymbol().getName() + "'");
94 
95  uint64_t Address = Target.getConstant();
96  if (Target.getSymA())
97  Address += getSymbolAddress(Target.getSymA()->getSymbol(), Layout);
98  if (Target.getSymB())
99  Address += getSymbolAddress(Target.getSymB()->getSymbol(), Layout);
100  return Address;
101  }
102 
103  return getSectionAddress(S.getFragment()->getParent()) +
104  Layout.getSymbolOffset(S);
105 }
106 
108  const MCAsmLayout &Layout) const {
109  uint64_t EndAddr = getSectionAddress(Sec) + Layout.getSectionAddressSize(Sec);
110  unsigned Next = Sec->getLayoutOrder() + 1;
111  if (Next >= Layout.getSectionOrder().size())
112  return 0;
113 
114  const MCSection &NextSec = *Layout.getSectionOrder()[Next];
115  if (NextSec.isVirtualSection())
116  return 0;
117  return OffsetToAlignment(EndAddr, NextSec.getAlignment());
118 }
119 
120 void MachObjectWriter::writeHeader(unsigned NumLoadCommands,
121  unsigned LoadCommandsSize,
122  bool SubsectionsViaSymbols) {
123  uint32_t Flags = 0;
124 
125  if (SubsectionsViaSymbols)
127 
128  // struct mach_header (28 bytes) or
129  // struct mach_header_64 (32 bytes)
130 
131  uint64_t Start = OS.tell();
132  (void) Start;
133 
135 
136  write32(TargetObjectWriter->getCPUType());
137  write32(TargetObjectWriter->getCPUSubtype());
138 
140  write32(NumLoadCommands);
141  write32(LoadCommandsSize);
142  write32(Flags);
143  if (is64Bit())
144  write32(0); // reserved
145 
146  assert(OS.tell() - Start ==
147  (is64Bit()?sizeof(MachO::mach_header_64): sizeof(MachO::mach_header)));
148 }
149 
150 /// writeSegmentLoadCommand - Write a segment load command.
151 ///
152 /// \param NumSections The number of sections in this segment.
153 /// \param SectionDataSize The total size of the sections.
155  uint64_t VMSize,
156  uint64_t SectionDataStartOffset,
157  uint64_t SectionDataSize) {
158  // struct segment_command (56 bytes) or
159  // struct segment_command_64 (72 bytes)
160 
161  uint64_t Start = OS.tell();
162  (void) Start;
163 
164  unsigned SegmentLoadCommandSize =
166  sizeof(MachO::segment_command);
168  write32(SegmentLoadCommandSize +
169  NumSections * (is64Bit() ? sizeof(MachO::section_64) :
170  sizeof(MachO::section)));
171 
172  writeBytes("", 16);
173  if (is64Bit()) {
174  write64(0); // vmaddr
175  write64(VMSize); // vmsize
176  write64(SectionDataStartOffset); // file offset
177  write64(SectionDataSize); // file size
178  } else {
179  write32(0); // vmaddr
180  write32(VMSize); // vmsize
181  write32(SectionDataStartOffset); // file offset
182  write32(SectionDataSize); // file size
183  }
184  // maxprot
186  // initprot
188  write32(NumSections);
189  write32(0); // flags
190 
191  assert(OS.tell() - Start == SegmentLoadCommandSize);
192 }
193 
195  const MCAsmLayout &Layout,
196  const MCSection &Sec, uint64_t FileOffset,
197  uint64_t RelocationsStart,
198  unsigned NumRelocations) {
199  uint64_t SectionSize = Layout.getSectionAddressSize(&Sec);
200  const MCSectionMachO &Section = cast<MCSectionMachO>(Sec);
201 
202  // The offset is unused for virtual sections.
203  if (Section.isVirtualSection()) {
204  assert(Layout.getSectionFileSize(&Sec) == 0 && "Invalid file size!");
205  FileOffset = 0;
206  }
207 
208  // struct section (68 bytes) or
209  // struct section_64 (80 bytes)
210 
211  uint64_t Start = OS.tell();
212  (void) Start;
213 
214  writeBytes(Section.getSectionName(), 16);
215  writeBytes(Section.getSegmentName(), 16);
216  if (is64Bit()) {
217  write64(getSectionAddress(&Sec)); // address
218  write64(SectionSize); // size
219  } else {
220  write32(getSectionAddress(&Sec)); // address
221  write32(SectionSize); // size
222  }
223  write32(FileOffset);
224 
225  unsigned Flags = Section.getTypeAndAttributes();
226  if (Section.hasInstructions())
228 
229  assert(isPowerOf2_32(Section.getAlignment()) && "Invalid alignment!");
230  write32(Log2_32(Section.getAlignment()));
231  write32(NumRelocations ? RelocationsStart : 0);
232  write32(NumRelocations);
233  write32(Flags);
234  write32(IndirectSymBase.lookup(&Sec)); // reserved1
235  write32(Section.getStubSize()); // reserved2
236  if (is64Bit())
237  write32(0); // reserved3
238 
239  assert(OS.tell() - Start == (is64Bit() ? sizeof(MachO::section_64) :
240  sizeof(MachO::section)));
241 }
242 
243 void MachObjectWriter::writeSymtabLoadCommand(uint32_t SymbolOffset,
244  uint32_t NumSymbols,
245  uint32_t StringTableOffset,
246  uint32_t StringTableSize) {
247  // struct symtab_command (24 bytes)
248 
249  uint64_t Start = OS.tell();
250  (void) Start;
251 
254  write32(SymbolOffset);
255  write32(NumSymbols);
256  write32(StringTableOffset);
257  write32(StringTableSize);
258 
259  assert(OS.tell() - Start == sizeof(MachO::symtab_command));
260 }
261 
262 void MachObjectWriter::writeDysymtabLoadCommand(uint32_t FirstLocalSymbol,
263  uint32_t NumLocalSymbols,
264  uint32_t FirstExternalSymbol,
265  uint32_t NumExternalSymbols,
266  uint32_t FirstUndefinedSymbol,
267  uint32_t NumUndefinedSymbols,
268  uint32_t IndirectSymbolOffset,
269  uint32_t NumIndirectSymbols) {
270  // struct dysymtab_command (80 bytes)
271 
272  uint64_t Start = OS.tell();
273  (void) Start;
274 
277  write32(FirstLocalSymbol);
278  write32(NumLocalSymbols);
279  write32(FirstExternalSymbol);
280  write32(NumExternalSymbols);
281  write32(FirstUndefinedSymbol);
282  write32(NumUndefinedSymbols);
283  write32(0); // tocoff
284  write32(0); // ntoc
285  write32(0); // modtaboff
286  write32(0); // nmodtab
287  write32(0); // extrefsymoff
288  write32(0); // nextrefsyms
289  write32(IndirectSymbolOffset);
290  write32(NumIndirectSymbols);
291  write32(0); // extreloff
292  write32(0); // nextrel
293  write32(0); // locreloff
294  write32(0); // nlocrel
295 
296  assert(OS.tell() - Start == sizeof(MachO::dysymtab_command));
297 }
298 
299 MachObjectWriter::MachSymbolData *
300 MachObjectWriter::findSymbolData(const MCSymbol &Sym) {
301  for (auto *SymbolData :
302  {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
303  for (MachSymbolData &Entry : *SymbolData)
304  if (Entry.Symbol == &Sym)
305  return &Entry;
306 
307  return nullptr;
308 }
309 
311  const MCSymbol *S = &Sym;
312  while (S->isVariable()) {
313  const MCExpr *Value = S->getVariableValue();
314  const auto *Ref = dyn_cast<MCSymbolRefExpr>(Value);
315  if (!Ref)
316  return *S;
317  S = &Ref->getSymbol();
318  }
319  return *S;
320 }
321 
322 void MachObjectWriter::writeNlist(MachSymbolData &MSD,
323  const MCAsmLayout &Layout) {
324  const MCSymbol *Symbol = MSD.Symbol;
325  const MCSymbol &Data = *Symbol;
326  const MCSymbol *AliasedSymbol = &findAliasedSymbol(*Symbol);
327  uint8_t SectionIndex = MSD.SectionIndex;
328  uint8_t Type = 0;
329  uint64_t Address = 0;
330  bool IsAlias = Symbol != AliasedSymbol;
331 
332  const MCSymbol &OrigSymbol = *Symbol;
333  MachSymbolData *AliaseeInfo;
334  if (IsAlias) {
335  AliaseeInfo = findSymbolData(*AliasedSymbol);
336  if (AliaseeInfo)
337  SectionIndex = AliaseeInfo->SectionIndex;
338  Symbol = AliasedSymbol;
339  // FIXME: Should this update Data as well? Do we need OrigSymbol at all?
340  }
341 
342  // Set the N_TYPE bits. See <mach-o/nlist.h>.
343  //
344  // FIXME: Are the prebound or indirect fields possible here?
345  if (IsAlias && Symbol->isUndefined())
346  Type = MachO::N_INDR;
347  else if (Symbol->isUndefined())
348  Type = MachO::N_UNDF;
349  else if (Symbol->isAbsolute())
350  Type = MachO::N_ABS;
351  else
352  Type = MachO::N_SECT;
353 
354  // FIXME: Set STAB bits.
355 
356  if (Data.isPrivateExtern())
357  Type |= MachO::N_PEXT;
358 
359  // Set external bit.
360  if (Data.isExternal() || (!IsAlias && Symbol->isUndefined()))
361  Type |= MachO::N_EXT;
362 
363  // Compute the symbol address.
364  if (IsAlias && Symbol->isUndefined())
365  Address = AliaseeInfo->StringIndex;
366  else if (Symbol->isDefined())
367  Address = getSymbolAddress(OrigSymbol, Layout);
368  else if (Symbol->isCommon()) {
369  // Common symbols are encoded with the size in the address
370  // field, and their alignment in the flags.
371  Address = Symbol->getCommonSize();
372  }
373 
374  // struct nlist (12 bytes)
375 
376  write32(MSD.StringIndex);
377  write8(Type);
378  write8(SectionIndex);
379 
380  // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
381  // value.
382  write16(cast<MCSymbolMachO>(Symbol)->getEncodedFlags());
383  if (is64Bit())
384  write64(Address);
385  else
386  write32(Address);
387 }
388 
390  uint32_t DataOffset,
391  uint32_t DataSize) {
392  uint64_t Start = OS.tell();
393  (void) Start;
394 
395  write32(Type);
397  write32(DataOffset);
398  write32(DataSize);
399 
400  assert(OS.tell() - Start == sizeof(MachO::linkedit_data_command));
401 }
402 
404  const std::vector<std::string> &Options, bool is64Bit)
405 {
406  unsigned Size = sizeof(MachO::linker_option_command);
407  for (const std::string &Option : Options)
408  Size += Option.size() + 1;
409  return RoundUpToAlignment(Size, is64Bit ? 8 : 4);
410 }
411 
413  const std::vector<std::string> &Options)
414 {
415  unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
416  uint64_t Start = OS.tell();
417  (void) Start;
418 
420  write32(Size);
421  write32(Options.size());
422  uint64_t BytesWritten = sizeof(MachO::linker_option_command);
423  for (const std::string &Option : Options) {
424  // Write each string, including the null byte.
425  writeBytes(Option.c_str(), Option.size() + 1);
426  BytesWritten += Option.size() + 1;
427  }
428 
429  // Pad to a multiple of the pointer size.
430  writeBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
431 
432  assert(OS.tell() - Start == Size);
433 }
434 
436  const MCAsmLayout &Layout,
437  const MCFragment *Fragment,
438  const MCFixup &Fixup, MCValue Target,
439  bool &IsPCRel, uint64_t &FixedValue) {
440  TargetObjectWriter->recordRelocation(this, Asm, Layout, Fragment, Fixup,
441  Target, FixedValue);
442 }
443 
445  // This is the point where 'as' creates actual symbols for indirect symbols
446  // (in the following two passes). It would be easier for us to do this sooner
447  // when we see the attribute, but that makes getting the order in the symbol
448  // table much more complicated than it is worth.
449  //
450  // FIXME: Revisit this when the dust settles.
451 
452  // Report errors for use of .indirect_symbol not in a symbol pointer section
453  // or stub section.
455  ie = Asm.indirect_symbol_end(); it != ie; ++it) {
456  const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section);
457 
458  if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
459  Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
460  Section.getType() != MachO::S_SYMBOL_STUBS) {
461  MCSymbol &Symbol = *it->Symbol;
462  report_fatal_error("indirect symbol '" + Symbol.getName() +
463  "' not in a symbol pointer or stub section");
464  }
465  }
466 
467  // Bind non-lazy symbol pointers first.
468  unsigned IndirectIndex = 0;
470  ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
471  const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section);
472 
474  continue;
475 
476  // Initialize the section indirect symbol base, if necessary.
477  IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
478 
479  Asm.registerSymbol(*it->Symbol);
480  }
481 
482  // Then lazy symbol pointers and symbol stubs.
483  IndirectIndex = 0;
485  ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
486  const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section);
487 
488  if (Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
489  Section.getType() != MachO::S_SYMBOL_STUBS)
490  continue;
491 
492  // Initialize the section indirect symbol base, if necessary.
493  IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
494 
495  // Set the symbol type to undefined lazy, but only on construction.
496  //
497  // FIXME: Do not hardcode.
498  bool Created;
499  Asm.registerSymbol(*it->Symbol, &Created);
500  if (Created)
501  cast<MCSymbolMachO>(it->Symbol)->setReferenceTypeUndefinedLazy(true);
502  }
503 }
504 
505 /// computeSymbolTable - Compute the symbol table data
507  MCAssembler &Asm, std::vector<MachSymbolData> &LocalSymbolData,
508  std::vector<MachSymbolData> &ExternalSymbolData,
509  std::vector<MachSymbolData> &UndefinedSymbolData) {
510  // Build section lookup table.
511  DenseMap<const MCSection*, uint8_t> SectionIndexMap;
512  unsigned Index = 1;
513  for (MCAssembler::iterator it = Asm.begin(),
514  ie = Asm.end(); it != ie; ++it, ++Index)
515  SectionIndexMap[&*it] = Index;
516  assert(Index <= 256 && "Too many sections!");
517 
518  // Build the string table.
519  for (const MCSymbol &Symbol : Asm.symbols()) {
520  if (!Asm.isSymbolLinkerVisible(Symbol))
521  continue;
522 
523  StringTable.add(Symbol.getName());
524  }
525  StringTable.finalize(StringTableBuilder::MachO);
526 
527  // Build the symbol arrays but only for non-local symbols.
528  //
529  // The particular order that we collect and then sort the symbols is chosen to
530  // match 'as'. Even though it doesn't matter for correctness, this is
531  // important for letting us diff .o files.
532  for (const MCSymbol &Symbol : Asm.symbols()) {
533  // Ignore non-linker visible symbols.
534  if (!Asm.isSymbolLinkerVisible(Symbol))
535  continue;
536 
537  if (!Symbol.isExternal() && !Symbol.isUndefined())
538  continue;
539 
540  MachSymbolData MSD;
541  MSD.Symbol = &Symbol;
542  MSD.StringIndex = StringTable.getOffset(Symbol.getName());
543 
544  if (Symbol.isUndefined()) {
545  MSD.SectionIndex = 0;
546  UndefinedSymbolData.push_back(MSD);
547  } else if (Symbol.isAbsolute()) {
548  MSD.SectionIndex = 0;
549  ExternalSymbolData.push_back(MSD);
550  } else {
551  MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
552  assert(MSD.SectionIndex && "Invalid section index!");
553  ExternalSymbolData.push_back(MSD);
554  }
555  }
556 
557  // Now add the data for local symbols.
558  for (const MCSymbol &Symbol : Asm.symbols()) {
559  // Ignore non-linker visible symbols.
560  if (!Asm.isSymbolLinkerVisible(Symbol))
561  continue;
562 
563  if (Symbol.isExternal() || Symbol.isUndefined())
564  continue;
565 
566  MachSymbolData MSD;
567  MSD.Symbol = &Symbol;
568  MSD.StringIndex = StringTable.getOffset(Symbol.getName());
569 
570  if (Symbol.isAbsolute()) {
571  MSD.SectionIndex = 0;
572  LocalSymbolData.push_back(MSD);
573  } else {
574  MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
575  assert(MSD.SectionIndex && "Invalid section index!");
576  LocalSymbolData.push_back(MSD);
577  }
578  }
579 
580  // External and undefined symbols are required to be in lexicographic order.
581  std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
582  std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
583 
584  // Set the symbol indices.
585  Index = 0;
586  for (auto *SymbolData :
587  {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
588  for (MachSymbolData &Entry : *SymbolData)
589  Entry.Symbol->setIndex(Index++);
590 
591  for (const MCSection &Section : Asm) {
592  for (RelAndSymbol &Rel : Relocations[&Section]) {
593  if (!Rel.Sym)
594  continue;
595 
596  // Set the Index and the IsExtern bit.
597  unsigned Index = Rel.Sym->getIndex();
598  assert(isInt<24>(Index));
599  if (IsLittleEndian)
600  Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (~0U << 24)) | Index | (1 << 27);
601  else
602  Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4);
603  }
604  }
605 }
606 
608  const MCAsmLayout &Layout) {
609  uint64_t StartAddress = 0;
610  for (const MCSection *Sec : Layout.getSectionOrder()) {
611  StartAddress = RoundUpToAlignment(StartAddress, Sec->getAlignment());
612  SectionAddress[Sec] = StartAddress;
613  StartAddress += Layout.getSectionAddressSize(Sec);
614 
615  // Explicitly pad the section to match the alignment requirements of the
616  // following one. This is for 'gas' compatibility, it shouldn't
617  /// strictly be necessary.
618  StartAddress += getPaddingSize(Sec, Layout);
619  }
620 }
621 
623  const MCAsmLayout &Layout) {
624  computeSectionAddresses(Asm, Layout);
625 
626  // Create symbol data for any indirect symbols.
627  bindIndirectSymbols(Asm);
628 }
629 
631  const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
632  bool InSet, bool IsPCRel) const {
633  if (InSet)
634  return true;
635 
636  // The effective address is
637  // addr(atom(A)) + offset(A)
638  // - addr(atom(B)) - offset(B)
639  // and the offsets are not relocatable, so the fixup is fully resolved when
640  // addr(atom(A)) - addr(atom(B)) == 0.
641  const MCSymbol &SA = findAliasedSymbol(SymA);
642  const MCSection &SecA = SA.getSection();
643  const MCSection &SecB = *FB.getParent();
644 
645  if (IsPCRel) {
646  // The simple (Darwin, except on x86_64) way of dealing with this was to
647  // assume that any reference to a temporary symbol *must* be a temporary
648  // symbol in the same atom, unless the sections differ. Therefore, any PCrel
649  // relocation to a temporary symbol (in the same section) is fully
650  // resolved. This also works in conjunction with absolutized .set, which
651  // requires the compiler to use .set to absolutize the differences between
652  // symbols which the compiler knows to be assembly time constants, so we
653  // don't need to worry about considering symbol differences fully resolved.
654  //
655  // If the file isn't using sub-sections-via-symbols, we can make the
656  // same assumptions about any symbol that we normally make about
657  // assembler locals.
658 
659  bool hasReliableSymbolDifference = isX86_64();
660  if (!hasReliableSymbolDifference) {
661  if (!SA.isInSection() || &SecA != &SecB ||
662  (!SA.isTemporary() && FB.getAtom() != SA.getFragment()->getAtom() &&
664  return false;
665  return true;
666  }
667  // For Darwin x86_64, there is one special case when the reference IsPCRel.
668  // If the fragment with the reference does not have a base symbol but meets
669  // the simple way of dealing with this, in that it is a temporary symbol in
670  // the same atom then it is assumed to be fully resolved. This is needed so
671  // a relocation entry is not created and so the static linker does not
672  // mess up the reference later.
673  else if(!FB.getAtom() &&
674  SA.isTemporary() && SA.isInSection() && &SecA == &SecB){
675  return true;
676  }
677  }
678 
679  // If they are not in the same section, we can't compute the diff.
680  if (&SecA != &SecB)
681  return false;
682 
683  const MCFragment *FA = SA.getFragment();
684 
685  // Bail if the symbol has no fragment.
686  if (!FA)
687  return false;
688 
689  // If the atoms are the same, they are guaranteed to have the same address.
690  if (FA->getAtom() == FB.getAtom())
691  return true;
692 
693  // Otherwise, we can't prove this is fully resolved.
694  return false;
695 }
696 
698  const MCAsmLayout &Layout) {
699  // Compute symbol table information and bind symbol indices.
700  computeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData,
701  UndefinedSymbolData);
702 
703  unsigned NumSections = Asm.size();
705  Layout.getAssembler().getVersionMinInfo();
706 
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 = is64Bit() ?
711  sizeof(MachO::segment_command_64) + NumSections * sizeof(MachO::section_64):
712  sizeof(MachO::segment_command) + NumSections * sizeof(MachO::section);
713 
714  // Add the deployment target version info load command size, if used.
715  if (VersionInfo.Major != 0) {
716  ++NumLoadCommands;
717  LoadCommandsSize += sizeof(MachO::version_min_command);
718  }
719 
720  // Add the data-in-code load command size, if used.
721  unsigned NumDataRegions = Asm.getDataRegions().size();
722  if (NumDataRegions) {
723  ++NumLoadCommands;
724  LoadCommandsSize += sizeof(MachO::linkedit_data_command);
725  }
726 
727  // Add the loh load command size, if used.
728  uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout);
729  uint64_t LOHSize = RoundUpToAlignment(LOHRawSize, is64Bit() ? 8 : 4);
730  if (LOHSize) {
731  ++NumLoadCommands;
732  LoadCommandsSize += sizeof(MachO::linkedit_data_command);
733  }
734 
735  // Add the symbol table load command sizes, if used.
736  unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
737  UndefinedSymbolData.size();
738  if (NumSymbols) {
739  NumLoadCommands += 2;
740  LoadCommandsSize += (sizeof(MachO::symtab_command) +
741  sizeof(MachO::dysymtab_command));
742  }
743 
744  // Add the linker option load commands sizes.
745  for (const auto &Option : Asm.getLinkerOptions()) {
746  ++NumLoadCommands;
747  LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(Option, is64Bit());
748  }
749 
750  // Compute the total size of the section data, as well as its file size and vm
751  // size.
752  uint64_t SectionDataStart = (is64Bit() ? sizeof(MachO::mach_header_64) :
753  sizeof(MachO::mach_header)) + LoadCommandsSize;
754  uint64_t SectionDataSize = 0;
755  uint64_t SectionDataFileSize = 0;
756  uint64_t VMSize = 0;
757  for (const MCSection &Sec : Asm) {
758  uint64_t Address = getSectionAddress(&Sec);
759  uint64_t Size = Layout.getSectionAddressSize(&Sec);
760  uint64_t FileSize = Layout.getSectionFileSize(&Sec);
761  FileSize += getPaddingSize(&Sec, Layout);
762 
763  VMSize = std::max(VMSize, Address + Size);
764 
765  if (Sec.isVirtualSection())
766  continue;
767 
768  SectionDataSize = std::max(SectionDataSize, Address + Size);
769  SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
770  }
771 
772  // The section data is padded to 4 bytes.
773  //
774  // FIXME: Is this machine dependent?
775  unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
776  SectionDataFileSize += SectionDataPadding;
777 
778  // Write the prolog, starting with the header and load command...
779  writeHeader(NumLoadCommands, LoadCommandsSize,
780  Asm.getSubsectionsViaSymbols());
781  writeSegmentLoadCommand(NumSections, VMSize,
782  SectionDataStart, SectionDataSize);
783 
784  // ... and then the section headers.
785  uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
786  for (const MCSection &Sec : Asm) {
787  std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
788  unsigned NumRelocs = Relocs.size();
789  uint64_t SectionStart = SectionDataStart + getSectionAddress(&Sec);
790  writeSection(Asm, Layout, Sec, SectionStart, RelocTableEnd, NumRelocs);
791  RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
792  }
793 
794  // Write out the deployment target information, if it's available.
795  if (VersionInfo.Major != 0) {
796  assert(VersionInfo.Update < 256 && "unencodable update target version");
797  assert(VersionInfo.Minor < 256 && "unencodable minor target version");
798  assert(VersionInfo.Major < 65536 && "unencodable major target version");
799  uint32_t EncodedVersion = VersionInfo.Update | (VersionInfo.Minor << 8) |
800  (VersionInfo.Major << 16);
804  write32(EncodedVersion);
805  write32(0); // reserved.
806  }
807 
808  // Write the data-in-code load command, if used.
809  uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
810  if (NumDataRegions) {
811  uint64_t DataRegionsOffset = RelocTableEnd;
812  uint64_t DataRegionsSize = NumDataRegions * 8;
814  DataRegionsSize);
815  }
816 
817  // Write the loh load command, if used.
818  uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
819  if (LOHSize)
821  DataInCodeTableEnd, LOHSize);
822 
823  // Write the symbol table load command, if used.
824  if (NumSymbols) {
825  unsigned FirstLocalSymbol = 0;
826  unsigned NumLocalSymbols = LocalSymbolData.size();
827  unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
828  unsigned NumExternalSymbols = ExternalSymbolData.size();
829  unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
830  unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
831  unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
832  unsigned NumSymTabSymbols =
833  NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
834  uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
835  uint64_t IndirectSymbolOffset = 0;
836 
837  // If used, the indirect symbols are written after the section data.
838  if (NumIndirectSymbols)
839  IndirectSymbolOffset = LOHTableEnd;
840 
841  // The symbol table is written after the indirect symbol data.
842  uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
843 
844  // The string table is written after symbol table.
845  uint64_t StringTableOffset =
846  SymbolTableOffset + NumSymTabSymbols * (is64Bit() ?
847  sizeof(MachO::nlist_64) :
848  sizeof(MachO::nlist));
849  writeSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
850  StringTableOffset, StringTable.data().size());
851 
852  writeDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
853  FirstExternalSymbol, NumExternalSymbols,
854  FirstUndefinedSymbol, NumUndefinedSymbols,
855  IndirectSymbolOffset, NumIndirectSymbols);
856  }
857 
858  // Write the linker options load commands.
859  for (const auto &Option : Asm.getLinkerOptions())
861 
862  // Write the actual section data.
863  for (const MCSection &Sec : Asm) {
864  Asm.writeSectionData(&Sec, Layout);
865 
866  uint64_t Pad = getPaddingSize(&Sec, Layout);
867  WriteZeros(Pad);
868  }
869 
870  // Write the extra padding.
871  WriteZeros(SectionDataPadding);
872 
873  // Write the relocation entries.
874  for (const MCSection &Sec : Asm) {
875  // Write the section relocation entries, in reverse order to match 'as'
876  // (approximately, the exact algorithm is more complicated than this).
877  std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
878  for (const RelAndSymbol &Rel : make_range(Relocs.rbegin(), Relocs.rend())) {
879  write32(Rel.MRE.r_word0);
880  write32(Rel.MRE.r_word1);
881  }
882  }
883 
884  // Write out the data-in-code region payload, if there is one.
886  it = Asm.data_region_begin(), ie = Asm.data_region_end();
887  it != ie; ++it) {
888  const DataRegionData *Data = &(*it);
889  uint64_t Start = getSymbolAddress(*Data->Start, Layout);
890  uint64_t End = getSymbolAddress(*Data->End, Layout);
891  DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind
892  << " start: " << Start << "(" << Data->Start->getName() << ")"
893  << " end: " << End << "(" << Data->End->getName() << ")"
894  << " size: " << End - Start
895  << "\n");
896  write32(Start);
897  write16(End - Start);
898  write16(Data->Kind);
899  }
900 
901  // Write out the loh commands, if there is one.
902  if (LOHSize) {
903 #ifndef NDEBUG
904  unsigned Start = OS.tell();
905 #endif
906  Asm.getLOHContainer().emit(*this, Layout);
907  // Pad to a multiple of the pointer size.
908  writeBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));
909  assert(OS.tell() - Start == LOHSize);
910  }
911 
912  // Write the symbol table data, if used.
913  if (NumSymbols) {
914  // Write the indirect symbol entries.
916  it = Asm.indirect_symbol_begin(),
917  ie = Asm.indirect_symbol_end(); it != ie; ++it) {
918  // Indirect symbols in the non-lazy symbol pointer section have some
919  // special handling.
920  const MCSectionMachO &Section =
921  static_cast<const MCSectionMachO &>(*it->Section);
922  if (Section.getType() == MachO::S_NON_LAZY_SYMBOL_POINTERS) {
923  // If this symbol is defined and internal, mark it as such.
924  if (it->Symbol->isDefined() && !it->Symbol->isExternal()) {
926  if (it->Symbol->isAbsolute())
928  write32(Flags);
929  continue;
930  }
931  }
932 
933  write32(it->Symbol->getIndex());
934  }
935 
936  // FIXME: Check that offsets match computed ones.
937 
938  // Write the symbol table entries.
939  for (auto *SymbolData :
940  {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
941  for (MachSymbolData &Entry : *SymbolData)
942  writeNlist(Entry, Layout);
943 
944  // Write the string table.
945  OS << StringTable.data();
946  }
947 }
948 
950  raw_pwrite_stream &OS,
951  bool IsLittleEndian) {
952  return new MachObjectWriter(MOTW, OS, IsLittleEndian);
953 }
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:48
S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in the Reserved2 field.
void WriteZeros(unsigned N)
MCSectionMachO - This represents a section on a Mach-O system (used by Mac OS X). ...
void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout)
const MCSymbol & getSymbol() const
Definition: MCExpr.h:328
bool hasInstructions() const
Definition: MCSection.h:144
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
bool doesSymbolRequireExternRelocation(const MCSymbol &S)
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:159
void write64(uint64_t Value)
This represents an "assembler immediate".
Definition: MCValue.h:44
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
iterator begin()
Definition: MCAssembler.h:764
uint64_t getSectionAddress(const MCSection *Sec) const
void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
uint64_t getEmitSize(const MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const
Get the size of the directives if emitted.
const VersionMinInfoType & getVersionMinInfo() const
MachO deployment target version information.
Definition: MCAssembler.h:704
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
void registerSymbol(const MCSymbol &Symbol, bool *Created=nullptr)
.macosx_version_min
Definition: MCDirectives.h:65
bool isExternal() const
Definition: MCSymbol.h:389
unsigned getAlignment() const
Definition: MCSection.h:124
void finalize(Kind kind)
Analyze the strings and build the final table.
void writeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCSection &Sec, uint64_t FileOffset, uint64_t RelocationsStart, unsigned NumRelocations)
Defines the object file and target independent interfaces used by the assembler backend to write nati...
void write8(uint8_t Value)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:62
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
enum llvm::DataRegionData::KindTy Kind
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 writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override
Write the object file.
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
std::vector< DataRegionData >::const_iterator const_data_region_iterator
Definition: MCAssembler.h:553
const MCExpr * getVariableValue() const
getVariableValue() - Get the value for variable symbols.
Definition: MCSymbol.h:299
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:33
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:159
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:92
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
Definition: MCSymbol.h:255
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind)
StringRef getSectionName() const
void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize)
unsigned getStubSize() const
std::vector< IndirectSymbolData >::const_iterator const_indirect_symbol_iterator
Definition: MCAssembler.h:549
iterator end()
Definition: MCAssembler.h:767
void writeLinkerOptionsLoadCommand(const std::vector< std::string > &Options)
void writeHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols)
void write32(uint32_t Value)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void writeSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize)
Write a segment load command.
static bool is64Bit(const char *name)
virtual void reset()
lifetime management
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:23
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
MCFragment * getFragment() const
Definition: MCSymbol.h:382
size_t size() const
Definition: MCAssembler.h:770
llvm::SmallVectorImpl< MCSection * > & getSectionOrder()
Definition: MCAsmLayout.h:66
raw_pwrite_stream & OS
StringRef add(StringRef s)
Add a string to the builder.
const MCSymbolRefExpr * getSymB() const
Definition: MCValue.h:52
bool isAbsolute() const
isAbsolute - Check if this is an absolute symbol.
Definition: MCSymbol.h:261
void write16(uint16_t Value)
bool isSymbolLinkerVisible(const MCSymbol &SD) const
Check whether a particular symbol is visible to the linker and is required in the symbol table...
PowerPC TLS Dynamic Call Fixup
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
Definition: MCSymbol.h:251
S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers.
std::vector< std::vector< std::string > > & getLinkerOptions()
Definition: MCAssembler.h:819
void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize)
indirect_symbol_iterator indirect_symbol_begin()
Definition: MCAssembler.h:799
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:51
virtual bool isVirtualSection() const =0
Check whether this section is "virtual", that is has no actual object file contents.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:264
An iterator type that allows iterating over the pointees via some other iterator. ...
Definition: iterator.h:231
MachO::SectionType getType() const
uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const
uint64_t getFragmentAddress(const MCFragment *Fragment, const MCAsmLayout &Layout) const
MCLOHContainer & getLOHContainer()
Definition: MCAssembler.h:851
static unsigned ComputeLinkerOptionsLoadCommandSize(const std::vector< std::string > &Options, bool is64Bit)
MCSection * getParent() const
Definition: MCAssembler.h:118
size_t getOffset(StringRef s)
Get the offest of a string in the string table.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
Definition: MathExtras.h:468
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Definition: MCExpr.cpp:595
Target - Wrapper for Target specific information.
MachO specific deployment target version info.
Definition: MCAssembler.h:559
MCObjectWriter * createMachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
Construct a new Mach-O writer instance.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition: MCSymbol.h:222
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:285
StringRef getSegmentName() const
uint64_t getCommonSize() const
Return the size of a 'common' symbol.
Definition: MCSymbol.h:334
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:609
StringRef data()
Retrieve the string table data.
bool getSubsectionsViaSymbols() const
Definition: MCAssembler.h:745
void computeSymbolTable(MCAssembler &Asm, std::vector< MachSymbolData > &LocalSymbolData, std::vector< MachSymbolData > &ExternalSymbolData, std::vector< MachSymbolData > &UndefinedSymbolData)
Compute the symbol table data.
const MCSymbol * getAtom() const
Definition: MCAssembler.h:121
void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) override
Record a relocation entry.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
unsigned getLayoutOrder() const
Definition: MCSection.h:130
MCAsmBackend & getBackend() const
Definition: MCAssembler.h:733
bool isCommon() const
Is this a 'common' symbol.
Definition: MCSymbol.h:378
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
symbol_range symbols()
Definition: MCAssembler.h:781
Target independent information on a fixup kind.
void writeBytes(const SmallVectorImpl< char > &ByteVec, unsigned ZeroFillSize=0)
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:294
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:321
void reset() override
lifetime management
bool isVirtualSection() const override
Check whether this section is "virtual", that is has no actual object file contents.
int64_t getConstant() const
Definition: MCValue.h:50
const ARM::ArchExtKind Kind
bool isPrivateExtern() const
Definition: MCSymbol.h:392
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:332
unsigned getTypeAndAttributes() const
LLVM Value Representation.
Definition: Value.h:69
indirect_symbol_iterator indirect_symbol_end()
Definition: MCAssembler.h:806
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:51
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition: MathExtras.h:616
#define DEBUG(X)
Definition: Debug.h:92
uint64_t getSectionFileSize(const MCSection *Sec) const
Get the data size of the given section, as emitted to the object file.
bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
Definition: MathExtras.h:354
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:258
void bindIndirectSymbols(MCAssembler &Asm)
std::vector< DataRegionData > & getDataRegions()
Definition: MCAssembler.h:830
uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const
std::vector< IndirectSymbolData >::iterator indirect_symbol_iterator
Definition: MCAssembler.h:550
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
const MCSymbol & findAliasedSymbol(const MCSymbol &Sym) const
void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout)
unsigned Flags
Flags describing additional information on this fixup kind.