MachONormalizedFileFromAtoms.cpp revision 293258
116009Sserb//===- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp ------------===//
216009Sserb//
316009Sserb//                             The LLVM Linker
416009Sserb//
516009Sserb// This file is distributed under the University of Illinois Open Source
616009Sserb// License. See LICENSE.TXT for details.
716009Sserb//
816009Sserb//===----------------------------------------------------------------------===//
916009Sserb
1016009Sserb///
1116009Sserb/// \file Converts from in-memory Atoms to in-memory normalized mach-o.
1216009Sserb///
1316009Sserb///                  +------------+
1416009Sserb///                  | normalized |
1516009Sserb///                  +------------+
1616009Sserb///                        ^
1716009Sserb///                        |
1816009Sserb///                        |
1916009Sserb///                    +-------+
2016009Sserb///                    | Atoms |
2116009Sserb///                    +-------+
2216009Sserb
2316009Sserb#include "MachONormalizedFile.h"
2416009Sserb#include "ArchHandler.h"
2516009Sserb#include "MachONormalizedFileBinaryUtils.h"
2616009Sserb#include "lld/Core/Error.h"
2716009Sserb#include "lld/Core/LLVM.h"
2816009Sserb#include "llvm/ADT/StringRef.h"
2916009Sserb#include "llvm/ADT/StringSwitch.h"
3016009Sserb#include "llvm/Support/Casting.h"
3116009Sserb#include "llvm/Support/Debug.h"
3216009Sserb#include "llvm/Support/ErrorHandling.h"
3316009Sserb#include "llvm/Support/Format.h"
3416009Sserb#include "llvm/Support/MachO.h"
3516009Sserb#include <map>
3616009Sserb#include <system_error>
3716009Sserb
3816009Sserbusing llvm::StringRef;
3916009Sserbusing llvm::isa;
4016009Sserbusing namespace llvm::MachO;
4116009Sserbusing namespace lld::mach_o::normalized;
4216009Sserbusing namespace lld;
4316009Sserb
4416009Sserbnamespace {
4516009Sserb
4616009Sserbstruct AtomInfo {
4716009Sserb  const DefinedAtom  *atom;
4816009Sserb  uint64_t            offsetInSection;
4916009Sserb};
5016009Sserb
5116009Sserbstruct SectionInfo {
5216009Sserb  SectionInfo(StringRef seg, StringRef sect, SectionType type,
5316009Sserb              const MachOLinkingContext &ctxt, uint32_t attr=0);
5416009Sserb
5516009Sserb  StringRef                 segmentName;
5616009Sserb  StringRef                 sectionName;
5716009Sserb  SectionType               type;
5816009Sserb  uint32_t                  attributes;
5916009Sserb  uint64_t                  address;
6016009Sserb  uint64_t                  size;
6116009Sserb  uint16_t                  alignment;
6216009Sserb  std::vector<AtomInfo>     atomsAndOffsets;
6316009Sserb  uint32_t                  normalizedSectionIndex;
6416009Sserb  uint32_t                  finalSectionIndex;
6516009Sserb};
6616009Sserb
6716009SserbSectionInfo::SectionInfo(StringRef sg, StringRef sct, SectionType t,
6816009Sserb                         const MachOLinkingContext &ctxt, uint32_t attrs)
6916009Sserb : segmentName(sg), sectionName(sct), type(t), attributes(attrs),
7016009Sserb                 address(0), size(0), alignment(1),
7116009Sserb                 normalizedSectionIndex(0), finalSectionIndex(0) {
7216009Sserb  uint16_t align = 1;
7316009Sserb  if (ctxt.sectionAligned(segmentName, sectionName, align)) {
7416009Sserb    alignment = align;
7516009Sserb  }
7616009Sserb}
7716009Sserb
7816009Sserbstruct SegmentInfo {
7916009Sserb  SegmentInfo(StringRef name);
8016009Sserb
8116009Sserb  StringRef                  name;
8216009Sserb  uint64_t                   address;
8316009Sserb  uint64_t                   size;
8416009Sserb  uint32_t                   access;
8516009Sserb  std::vector<SectionInfo*>  sections;
8616009Sserb  uint32_t                   normalizedSegmentIndex;
8716009Sserb};
8816009Sserb
8916009SserbSegmentInfo::SegmentInfo(StringRef n)
9016009Sserb : name(n), address(0), size(0), access(0), normalizedSegmentIndex(0) {
9116009Sserb}
9216009Sserb
9316009Sserbclass Util {
9416009Sserbpublic:
9516009Sserb  Util(const MachOLinkingContext &ctxt)
9616009Sserb      : _ctx(ctxt), _archHandler(ctxt.archHandler()), _entryAtom(nullptr),
9716009Sserb        _hasTLVDescriptors(false) {}
9816009Sserb  ~Util();
9916009Sserb
10016009Sserb  void      assignAtomsToSections(const lld::File &atomFile);
10116009Sserb  void      organizeSections();
10216009Sserb  void      assignAddressesToSections(const NormalizedFile &file);
10316009Sserb  uint32_t  fileFlags();
10416009Sserb  void      copySegmentInfo(NormalizedFile &file);
10516009Sserb  void      copySectionInfo(NormalizedFile &file);
10616009Sserb  void      updateSectionInfo(NormalizedFile &file);
10716009Sserb  void      buildAtomToAddressMap();
10816009Sserb  std::error_code addSymbols(const lld::File &atomFile, NormalizedFile &file);
10916009Sserb  void      addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file);
11016009Sserb  void      addRebaseAndBindingInfo(const lld::File &, NormalizedFile &file);
11116009Sserb  void      addExportInfo(const lld::File &, NormalizedFile &file);
11216009Sserb  void      addSectionRelocs(const lld::File &, NormalizedFile &file);
11316009Sserb  void      buildDataInCodeArray(const lld::File &, NormalizedFile &file);
11416009Sserb  void      addDependentDylibs(const lld::File &, NormalizedFile &file);
11516009Sserb  void      copyEntryPointAddress(NormalizedFile &file);
11616009Sserb  void      copySectionContent(NormalizedFile &file);
11716009Sserb
11816009Sserbprivate:
11916009Sserb  typedef std::map<DefinedAtom::ContentType, SectionInfo*> TypeToSection;
12016009Sserb  typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
12116009Sserb
12216009Sserb  struct DylibInfo { int ordinal; bool hasWeak; bool hasNonWeak; };
12316009Sserb  typedef llvm::StringMap<DylibInfo> DylibPathToInfo;
12416009Sserb
12516009Sserb  SectionInfo *sectionForAtom(const DefinedAtom*);
12616009Sserb  SectionInfo *getRelocatableSection(DefinedAtom::ContentType type);
12716009Sserb  SectionInfo *getFinalSection(DefinedAtom::ContentType type);
12816009Sserb  void         appendAtom(SectionInfo *sect, const DefinedAtom *atom);
12916009Sserb  SegmentInfo *segmentForName(StringRef segName);
13016009Sserb  void         layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr);
13116009Sserb  void         layoutSectionsInTextSegment(size_t, SegmentInfo *, uint64_t &);
13216009Sserb  void         copySectionContent(SectionInfo *si, ContentBytes &content);
13316009Sserb  uint16_t     descBits(const DefinedAtom* atom);
13416009Sserb  int          dylibOrdinal(const SharedLibraryAtom *sa);
13516009Sserb  void         segIndexForSection(const SectionInfo *sect,
13616009Sserb                             uint8_t &segmentIndex, uint64_t &segmentStartAddr);
13716009Sserb  const Atom  *targetOfLazyPointer(const DefinedAtom *lpAtom);
13816009Sserb  const Atom  *targetOfStub(const DefinedAtom *stubAtom);
13916009Sserb  std::error_code getSymbolTableRegion(const DefinedAtom* atom,
14016009Sserb                                       bool &inGlobalsRegion,
14116009Sserb                                       SymbolScope &symbolScope);
14216009Sserb  void         appendSection(SectionInfo *si, NormalizedFile &file);
14316009Sserb  uint32_t     sectionIndexForAtom(const Atom *atom);
14416009Sserb
14516009Sserb  typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;
14616009Sserb  struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };
14716009Sserb  struct AtomSorter {
14816009Sserb    bool operator()(const AtomAndIndex &left, const AtomAndIndex &right);
14916009Sserb  };
15016009Sserb  struct SegmentSorter {
15116009Sserb    bool operator()(const SegmentInfo *left, const SegmentInfo *right);
15216009Sserb    static unsigned weight(const SegmentInfo *);
15316009Sserb  };
15416009Sserb  struct TextSectionSorter {
15516009Sserb    bool operator()(const SectionInfo *left, const SectionInfo *right);
15616009Sserb    static unsigned weight(const SectionInfo *);
15716009Sserb  };
15816009Sserb
15916009Sserb  const MachOLinkingContext &_ctx;
16016009Sserb  mach_o::ArchHandler          &_archHandler;
16116009Sserb  llvm::BumpPtrAllocator        _allocator;
16216009Sserb  std::vector<SectionInfo*>     _sectionInfos;
16316009Sserb  std::vector<SegmentInfo*>     _segmentInfos;
16416009Sserb  TypeToSection                 _sectionMap;
16516009Sserb  std::vector<SectionInfo*>     _customSections;
16616009Sserb  AtomToAddress                 _atomToAddress;
16716009Sserb  DylibPathToInfo               _dylibInfo;
16816009Sserb  const DefinedAtom            *_entryAtom;
16916009Sserb  AtomToIndex                   _atomToSymbolIndex;
17016009Sserb  std::vector<const Atom *>     _machHeaderAliasAtoms;
17116009Sserb  bool                          _hasTLVDescriptors;
17216009Sserb};
17316009Sserb
17416009SserbUtil::~Util() {
17516009Sserb  // The SectionInfo structs are BumpPtr allocated, but atomsAndOffsets needs
17616009Sserb  // to be deleted.
17716009Sserb  for (SectionInfo *si : _sectionInfos) {
17816009Sserb    // clear() destroys vector elements, but does not deallocate.
17916009Sserb    // Instead use swap() to deallocate vector buffer.
18016009Sserb    std::vector<AtomInfo> empty;
18116009Sserb    si->atomsAndOffsets.swap(empty);
18216009Sserb  }
18316009Sserb  // The SegmentInfo structs are BumpPtr allocated, but sections needs
18416009Sserb  // to be deleted.
18516009Sserb  for (SegmentInfo *sgi : _segmentInfos) {
18616009Sserb    std::vector<SectionInfo*> empty2;
18716009Sserb    sgi->sections.swap(empty2);
18816009Sserb  }
18916009Sserb}
19016009Sserb
19116009SserbSectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
19216009Sserb  StringRef segmentName;
19316009Sserb  StringRef sectionName;
19416009Sserb  SectionType sectionType;
19516009Sserb  SectionAttr sectionAttrs;
19616009Sserb
19716009Sserb  // Use same table used by when parsing .o files.
19816009Sserb  relocatableSectionInfoForContentType(type, segmentName, sectionName,
19916009Sserb                                       sectionType, sectionAttrs);
20016009Sserb  // If we already have a SectionInfo with this name, re-use it.
20116009Sserb  // This can happen if two ContentType map to the same mach-o section.
20216009Sserb  for (auto sect : _sectionMap) {
20316009Sserb    if (sect.second->sectionName.equals(sectionName) &&
20416009Sserb        sect.second->segmentName.equals(segmentName)) {
20516009Sserb      return sect.second;
206    }
207  }
208  // Otherwise allocate new SectionInfo object.
209  auto *sect = new (_allocator)
210      SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs);
211  _sectionInfos.push_back(sect);
212  _sectionMap[type] = sect;
213  return sect;
214}
215
216#define ENTRY(seg, sect, type, atomType) \
217  {seg, sect, type, DefinedAtom::atomType }
218
219struct MachOFinalSectionFromAtomType {
220  StringRef                 segmentName;
221  StringRef                 sectionName;
222  SectionType               sectionType;
223  DefinedAtom::ContentType  atomType;
224};
225
226const MachOFinalSectionFromAtomType sectsToAtomType[] = {
227  ENTRY("__TEXT", "__text",           S_REGULAR,          typeCode),
228  ENTRY("__TEXT", "__cstring",        S_CSTRING_LITERALS, typeCString),
229  ENTRY("__TEXT", "__ustring",        S_REGULAR,          typeUTF16String),
230  ENTRY("__TEXT", "__const",          S_REGULAR,          typeConstant),
231  ENTRY("__TEXT", "__const",          S_4BYTE_LITERALS,   typeLiteral4),
232  ENTRY("__TEXT", "__const",          S_8BYTE_LITERALS,   typeLiteral8),
233  ENTRY("__TEXT", "__const",          S_16BYTE_LITERALS,  typeLiteral16),
234  ENTRY("__TEXT", "__stubs",          S_SYMBOL_STUBS,     typeStub),
235  ENTRY("__TEXT", "__stub_helper",    S_REGULAR,          typeStubHelper),
236  ENTRY("__TEXT", "__gcc_except_tab", S_REGULAR,          typeLSDA),
237  ENTRY("__TEXT", "__eh_frame",       S_COALESCED,        typeCFI),
238  ENTRY("__TEXT", "__unwind_info",    S_REGULAR,          typeProcessedUnwindInfo),
239  ENTRY("__DATA", "__data",           S_REGULAR,          typeData),
240  ENTRY("__DATA", "__const",          S_REGULAR,          typeConstData),
241  ENTRY("__DATA", "__cfstring",       S_REGULAR,          typeCFString),
242  ENTRY("__DATA", "__la_symbol_ptr",  S_LAZY_SYMBOL_POINTERS,
243                                                          typeLazyPointer),
244  ENTRY("__DATA", "__mod_init_func",  S_MOD_INIT_FUNC_POINTERS,
245                                                          typeInitializerPtr),
246  ENTRY("__DATA", "__mod_term_func",  S_MOD_TERM_FUNC_POINTERS,
247                                                          typeTerminatorPtr),
248  ENTRY("__DATA", "__got",            S_NON_LAZY_SYMBOL_POINTERS,
249                                                          typeGOT),
250  ENTRY("__DATA", "__thread_vars",    S_THREAD_LOCAL_VARIABLES,
251                                                          typeThunkTLV),
252  ENTRY("__DATA", "__thread_data",    S_THREAD_LOCAL_REGULAR,
253                                                          typeTLVInitialData),
254  ENTRY("__DATA", "__thread_ptrs",    S_THREAD_LOCAL_VARIABLE_POINTERS,
255                                                          typeTLVInitializerPtr),
256  ENTRY("__DATA", "__thread_bss",     S_THREAD_LOCAL_ZEROFILL,
257                                                         typeTLVInitialZeroFill),
258  ENTRY("__DATA", "__bss",            S_ZEROFILL,         typeZeroFill),
259  ENTRY("__DATA", "__interposing",    S_INTERPOSING,      typeInterposingTuples),
260};
261#undef ENTRY
262
263SectionInfo *Util::getFinalSection(DefinedAtom::ContentType atomType) {
264  for (auto &p : sectsToAtomType) {
265    if (p.atomType != atomType)
266      continue;
267    SectionAttr sectionAttrs = 0;
268    switch (atomType) {
269    case DefinedAtom::typeCode:
270    case DefinedAtom::typeStub:
271    case DefinedAtom::typeStubHelper:
272      sectionAttrs = S_ATTR_PURE_INSTRUCTIONS;
273      break;
274    case DefinedAtom::typeThunkTLV:
275      _hasTLVDescriptors = true;
276      break;
277    default:
278      break;
279    }
280    // If we already have a SectionInfo with this name, re-use it.
281    // This can happen if two ContentType map to the same mach-o section.
282    for (auto sect : _sectionMap) {
283      if (sect.second->sectionName.equals(p.sectionName) &&
284          sect.second->segmentName.equals(p.segmentName)) {
285        return sect.second;
286      }
287    }
288    // Otherwise allocate new SectionInfo object.
289    auto *sect = new (_allocator) SectionInfo(
290        p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs);
291    _sectionInfos.push_back(sect);
292    _sectionMap[atomType] = sect;
293    return sect;
294  }
295  llvm_unreachable("content type not yet supported");
296}
297
298SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
299  if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
300    // Section for this atom is derived from content type.
301    DefinedAtom::ContentType type = atom->contentType();
302    auto pos = _sectionMap.find(type);
303    if ( pos != _sectionMap.end() )
304      return pos->second;
305    bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
306    return rMode ? getRelocatableSection(type) : getFinalSection(type);
307  } else {
308    // This atom needs to be in a custom section.
309    StringRef customName = atom->customSectionName();
310    // Look to see if we have already allocated the needed custom section.
311    for(SectionInfo *sect : _customSections) {
312      const DefinedAtom *firstAtom = sect->atomsAndOffsets.front().atom;
313      if (firstAtom->customSectionName().equals(customName)) {
314        return sect;
315      }
316    }
317    // Not found, so need to create a new custom section.
318    size_t seperatorIndex = customName.find('/');
319    assert(seperatorIndex != StringRef::npos);
320    StringRef segName = customName.slice(0, seperatorIndex);
321    StringRef sectName = customName.drop_front(seperatorIndex + 1);
322    auto *sect =
323        new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx);
324    _customSections.push_back(sect);
325    _sectionInfos.push_back(sect);
326    return sect;
327  }
328}
329
330void Util::appendAtom(SectionInfo *sect, const DefinedAtom *atom) {
331  // Figure out offset for atom in this section given alignment constraints.
332  uint64_t offset = sect->size;
333  DefinedAtom::Alignment atomAlign = atom->alignment();
334  uint64_t align = atomAlign.value;
335  uint64_t requiredModulus = atomAlign.modulus;
336  uint64_t currentModulus = (offset % align);
337  if ( currentModulus != requiredModulus ) {
338    if ( requiredModulus > currentModulus )
339      offset += requiredModulus-currentModulus;
340    else
341      offset += align+requiredModulus-currentModulus;
342  }
343  // Record max alignment of any atom in this section.
344  if (align > sect->alignment)
345    sect->alignment = atomAlign.value;
346  // Assign atom to this section with this offset.
347  AtomInfo ai = {atom, offset};
348  sect->atomsAndOffsets.push_back(ai);
349  // Update section size to include this atom.
350  sect->size = offset + atom->size();
351}
352
353void Util::assignAtomsToSections(const lld::File &atomFile) {
354  for (const DefinedAtom *atom : atomFile.defined()) {
355    if (atom->contentType() == DefinedAtom::typeMachHeader)
356      _machHeaderAliasAtoms.push_back(atom);
357    else
358      appendAtom(sectionForAtom(atom), atom);
359  }
360}
361
362SegmentInfo *Util::segmentForName(StringRef segName) {
363  for (SegmentInfo *si : _segmentInfos) {
364    if ( si->name.equals(segName) )
365      return si;
366  }
367  auto *info = new (_allocator) SegmentInfo(segName);
368  if (segName.equals("__TEXT"))
369    info->access = VM_PROT_READ | VM_PROT_EXECUTE;
370  else if (segName.equals("__DATA"))
371    info->access = VM_PROT_READ | VM_PROT_WRITE;
372  else if (segName.equals("__PAGEZERO"))
373    info->access = 0;
374  _segmentInfos.push_back(info);
375  return info;
376}
377
378unsigned Util::SegmentSorter::weight(const SegmentInfo *seg) {
379 return llvm::StringSwitch<unsigned>(seg->name)
380    .Case("__PAGEZERO",  1)
381    .Case("__TEXT",      2)
382    .Case("__DATA",      3)
383    .Default(100);
384}
385
386bool Util::SegmentSorter::operator()(const SegmentInfo *left,
387                                  const SegmentInfo *right) {
388  return (weight(left) < weight(right));
389}
390
391unsigned Util::TextSectionSorter::weight(const SectionInfo *sect) {
392 return llvm::StringSwitch<unsigned>(sect->sectionName)
393    .Case("__text",         1)
394    .Case("__stubs",        2)
395    .Case("__stub_helper",  3)
396    .Case("__const",        4)
397    .Case("__cstring",      5)
398    .Case("__unwind_info",  98)
399    .Case("__eh_frame",     99)
400    .Default(10);
401}
402
403bool Util::TextSectionSorter::operator()(const SectionInfo *left,
404                                         const SectionInfo *right) {
405  return (weight(left) < weight(right));
406}
407
408void Util::organizeSections() {
409  // NOTE!: Keep this in sync with assignAddressesToSections.
410  switch (_ctx.outputMachOType()) {
411    case llvm::MachO::MH_EXECUTE:
412      // Main executables, need a zero-page segment
413      segmentForName("__PAGEZERO");
414      // Fall into next case.
415    case llvm::MachO::MH_DYLIB:
416    case llvm::MachO::MH_BUNDLE:
417      // All dynamic code needs TEXT segment to hold the load commands.
418      segmentForName("__TEXT");
419      break;
420    default:
421      break;
422  }
423  // Group sections into segments.
424  for (SectionInfo *si : _sectionInfos) {
425    SegmentInfo *seg = segmentForName(si->segmentName);
426    seg->sections.push_back(si);
427  }
428  // Sort segments.
429  std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
430
431  // Sort sections within segments.
432  for (SegmentInfo *seg : _segmentInfos) {
433    if (seg->name.equals("__TEXT")) {
434      std::sort(seg->sections.begin(), seg->sections.end(),
435                TextSectionSorter());
436    }
437  }
438
439  // Record final section indexes.
440  uint32_t segmentIndex = 0;
441  uint32_t sectionIndex = 1;
442  for (SegmentInfo *seg : _segmentInfos) {
443    seg->normalizedSegmentIndex = segmentIndex++;
444    for (SectionInfo *sect : seg->sections)
445      sect->finalSectionIndex = sectionIndex++;
446  }
447}
448
449void Util::layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr) {
450  seg->address = addr;
451  for (SectionInfo *sect : seg->sections) {
452    sect->address = llvm::RoundUpToAlignment(addr, sect->alignment);
453    addr = sect->address + sect->size;
454  }
455  seg->size = llvm::RoundUpToAlignment(addr - seg->address, _ctx.pageSize());
456}
457
458// __TEXT segment lays out backwards so padding is at front after load commands.
459void Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
460                                                               uint64_t &addr) {
461  seg->address = addr;
462  // Walks sections starting at end to calculate padding for start.
463  int64_t taddr = 0;
464  for (auto it = seg->sections.rbegin(); it != seg->sections.rend(); ++it) {
465    SectionInfo *sect = *it;
466    taddr -= sect->size;
467    taddr = taddr & (0 - sect->alignment);
468  }
469  int64_t padding = taddr - hlcSize;
470  while (padding < 0)
471    padding += _ctx.pageSize();
472  // Start assigning section address starting at padded offset.
473  addr += (padding + hlcSize);
474  for (SectionInfo *sect : seg->sections) {
475    sect->address = llvm::RoundUpToAlignment(addr, sect->alignment);
476    addr = sect->address + sect->size;
477  }
478  seg->size = llvm::RoundUpToAlignment(addr - seg->address, _ctx.pageSize());
479}
480
481void Util::assignAddressesToSections(const NormalizedFile &file) {
482  // NOTE!: Keep this in sync with organizeSections.
483  size_t hlcSize = headerAndLoadCommandsSize(file);
484  uint64_t address = 0;
485  for (SegmentInfo *seg : _segmentInfos) {
486    if (seg->name.equals("__PAGEZERO")) {
487      seg->size = _ctx.pageZeroSize();
488      address += seg->size;
489    }
490    else if (seg->name.equals("__TEXT")) {
491      // _ctx.baseAddress()  == 0 implies it was either unspecified or
492      // pageZeroSize is also 0. In either case resetting address is safe.
493      address = _ctx.baseAddress() ? _ctx.baseAddress() : address;
494      layoutSectionsInTextSegment(hlcSize, seg, address);
495    } else
496      layoutSectionsInSegment(seg, address);
497
498    address = llvm::RoundUpToAlignment(address, _ctx.pageSize());
499  }
500  DEBUG_WITH_TYPE("WriterMachO-norm",
501    llvm::dbgs() << "assignAddressesToSections()\n";
502    for (SegmentInfo *sgi : _segmentInfos) {
503      llvm::dbgs()  << "   address=" << llvm::format("0x%08llX", sgi->address)
504                    << ", size="  << llvm::format("0x%08llX", sgi->size)
505                    << ", segment-name='" << sgi->name
506                    << "'\n";
507      for (SectionInfo *si : sgi->sections) {
508        llvm::dbgs()<< "      addr="  << llvm::format("0x%08llX", si->address)
509                    << ", size="  << llvm::format("0x%08llX", si->size)
510                    << ", section-name='" << si->sectionName
511                    << "\n";
512      }
513    }
514  );
515}
516
517void Util::copySegmentInfo(NormalizedFile &file) {
518  for (SegmentInfo *sgi : _segmentInfos) {
519    Segment seg;
520    seg.name    = sgi->name;
521    seg.address = sgi->address;
522    seg.size    = sgi->size;
523    seg.access  = sgi->access;
524    file.segments.push_back(seg);
525  }
526}
527
528void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
529   // Add new empty section to end of file.sections.
530  Section temp;
531  file.sections.push_back(std::move(temp));
532  Section* normSect = &file.sections.back();
533  // Copy fields to normalized section.
534  normSect->segmentName   = si->segmentName;
535  normSect->sectionName   = si->sectionName;
536  normSect->type          = si->type;
537  normSect->attributes    = si->attributes;
538  normSect->address       = si->address;
539  normSect->alignment     = si->alignment;
540  // Record where normalized section is.
541  si->normalizedSectionIndex = file.sections.size()-1;
542}
543
544void Util::copySectionContent(NormalizedFile &file) {
545  const bool r = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
546
547  // Utility function for ArchHandler to find address of atom in output file.
548  auto addrForAtom = [&] (const Atom &atom) -> uint64_t {
549    auto pos = _atomToAddress.find(&atom);
550    assert(pos != _atomToAddress.end());
551    return pos->second;
552  };
553
554  auto sectionAddrForAtom = [&] (const Atom &atom) -> uint64_t {
555    for (const SectionInfo *sectInfo : _sectionInfos)
556      for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets)
557        if (atomInfo.atom == &atom)
558          return sectInfo->address;
559    llvm_unreachable("atom not assigned to section");
560  };
561
562  for (SectionInfo *si : _sectionInfos) {
563    Section *normSect = &file.sections[si->normalizedSectionIndex];
564    if (isZeroFillSection(si->type)) {
565      const uint8_t *empty = nullptr;
566      normSect->content = llvm::makeArrayRef(empty, si->size);
567      continue;
568    }
569    // Copy content from atoms to content buffer for section.
570    uint8_t *sectionContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
571    normSect->content = llvm::makeArrayRef(sectionContent, si->size);
572    for (AtomInfo &ai : si->atomsAndOffsets) {
573      uint8_t *atomContent = reinterpret_cast<uint8_t*>
574                                          (&sectionContent[ai.offsetInSection]);
575      _archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
576                                       sectionAddrForAtom, _ctx.baseAddress(),
577                                       atomContent);
578    }
579  }
580}
581
582void Util::copySectionInfo(NormalizedFile &file) {
583  file.sections.reserve(_sectionInfos.size());
584  // Write sections grouped by segment.
585  for (SegmentInfo *sgi : _segmentInfos) {
586    for (SectionInfo *si : sgi->sections) {
587      appendSection(si, file);
588    }
589  }
590}
591
592void Util::updateSectionInfo(NormalizedFile &file) {
593  file.sections.reserve(_sectionInfos.size());
594  // sections grouped by segment.
595  for (SegmentInfo *sgi : _segmentInfos) {
596    Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
597    normSeg->address = sgi->address;
598    normSeg->size = sgi->size;
599    for (SectionInfo *si : sgi->sections) {
600      Section *normSect = &file.sections[si->normalizedSectionIndex];
601      normSect->address = si->address;
602    }
603  }
604}
605
606void Util::copyEntryPointAddress(NormalizedFile &nFile) {
607  if (_ctx.outputTypeHasEntry()) {
608    if (_archHandler.isThumbFunction(*_entryAtom))
609      nFile.entryAddress = (_atomToAddress[_entryAtom] | 1);
610    else
611      nFile.entryAddress = _atomToAddress[_entryAtom];
612  }
613}
614
615void Util::buildAtomToAddressMap() {
616  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
617                   << "assign atom addresses:\n");
618  const bool lookForEntry = _ctx.outputTypeHasEntry();
619  for (SectionInfo *sect : _sectionInfos) {
620    for (const AtomInfo &info : sect->atomsAndOffsets) {
621      _atomToAddress[info.atom] = sect->address + info.offsetInSection;
622      if (lookForEntry && (info.atom->contentType() == DefinedAtom::typeCode) &&
623          (info.atom->size() != 0) &&
624          info.atom->name() == _ctx.entrySymbolName()) {
625        _entryAtom = info.atom;
626      }
627      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
628                      << "   address="
629                      << llvm::format("0x%016X", _atomToAddress[info.atom])
630                      << llvm::format("    0x%09lX", info.atom)
631                      << ", file=#"
632                      << info.atom->file().ordinal()
633                      << ", atom=#"
634                      << info.atom->ordinal()
635                      << ", name="
636                      << info.atom->name()
637                      << ", type="
638                      << info.atom->contentType()
639                      << "\n");
640    }
641  }
642  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
643                  << "assign header alias atom addresses:\n");
644  for (const Atom *atom : _machHeaderAliasAtoms) {
645    _atomToAddress[atom] = _ctx.baseAddress();
646#ifndef NDEBUG
647    if (auto *definedAtom = dyn_cast<DefinedAtom>(atom)) {
648      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
649                      << "   address="
650                      << llvm::format("0x%016X", _atomToAddress[atom])
651                      << llvm::format("    0x%09lX", atom)
652                      << ", file=#"
653                      << definedAtom->file().ordinal()
654                      << ", atom=#"
655                      << definedAtom->ordinal()
656                      << ", name="
657                      << definedAtom->name()
658                      << ", type="
659                      << definedAtom->contentType()
660                      << "\n");
661    } else {
662      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
663                      << "   address="
664                      << llvm::format("0x%016X", _atomToAddress[atom])
665                      << " atom=" << atom
666                      << " name=" << atom->name() << "\n");
667    }
668#endif
669  }
670}
671
672uint16_t Util::descBits(const DefinedAtom* atom) {
673  uint16_t desc = 0;
674  switch (atom->merge()) {
675  case lld::DefinedAtom::mergeNo:
676  case lld::DefinedAtom::mergeAsTentative:
677    break;
678  case lld::DefinedAtom::mergeAsWeak:
679  case lld::DefinedAtom::mergeAsWeakAndAddressUsed:
680    desc |= N_WEAK_DEF;
681    break;
682  case lld::DefinedAtom::mergeSameNameAndSize:
683  case lld::DefinedAtom::mergeByLargestSection:
684  case lld::DefinedAtom::mergeByContent:
685    llvm_unreachable("Unsupported DefinedAtom::merge()");
686    break;
687  }
688  if (atom->contentType() == lld::DefinedAtom::typeResolver)
689    desc |= N_SYMBOL_RESOLVER;
690  if (_archHandler.isThumbFunction(*atom))
691    desc |= N_ARM_THUMB_DEF;
692  if (atom->deadStrip() == DefinedAtom::deadStripNever) {
693    if ((atom->contentType() != DefinedAtom::typeInitializerPtr)
694     && (atom->contentType() != DefinedAtom::typeTerminatorPtr))
695    desc |= N_NO_DEAD_STRIP;
696  }
697  return desc;
698}
699
700bool Util::AtomSorter::operator()(const AtomAndIndex &left,
701                                  const AtomAndIndex &right) {
702  return (left.atom->name().compare(right.atom->name()) < 0);
703}
704
705std::error_code Util::getSymbolTableRegion(const DefinedAtom* atom,
706                                           bool &inGlobalsRegion,
707                                           SymbolScope &scope) {
708  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
709  switch (atom->scope()) {
710  case Atom::scopeTranslationUnit:
711    scope = 0;
712    inGlobalsRegion = false;
713    return std::error_code();
714  case Atom::scopeLinkageUnit:
715    if ((_ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) &&
716        _ctx.exportSymbolNamed(atom->name())) {
717      return make_dynamic_error_code(Twine("cannot export hidden symbol ")
718                                    + atom->name());
719    }
720    if (rMode) {
721      if (_ctx.keepPrivateExterns()) {
722        // -keep_private_externs means keep in globals region as N_PEXT.
723        scope = N_PEXT | N_EXT;
724        inGlobalsRegion = true;
725        return std::error_code();
726      }
727    }
728    // scopeLinkageUnit symbols are no longer global once linked.
729    scope = N_PEXT;
730    inGlobalsRegion = false;
731    return std::error_code();
732  case Atom::scopeGlobal:
733    if (_ctx.exportRestrictMode()) {
734      if (_ctx.exportSymbolNamed(atom->name())) {
735        scope = N_EXT;
736        inGlobalsRegion = true;
737        return std::error_code();
738      } else {
739        scope = N_PEXT;
740        inGlobalsRegion = false;
741        return std::error_code();
742      }
743    } else {
744      scope = N_EXT;
745      inGlobalsRegion = true;
746      return std::error_code();
747    }
748    break;
749  }
750  llvm_unreachable("atom->scope() unknown enum value");
751}
752
753std::error_code Util::addSymbols(const lld::File &atomFile,
754                                 NormalizedFile &file) {
755  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
756  // Mach-O symbol table has three regions: locals, globals, undefs.
757
758  // Add all local (non-global) symbols in address order
759  std::vector<AtomAndIndex> globals;
760  globals.reserve(512);
761  for (SectionInfo *sect : _sectionInfos) {
762    for (const AtomInfo &info : sect->atomsAndOffsets) {
763      const DefinedAtom *atom = info.atom;
764      if (!atom->name().empty()) {
765        SymbolScope symbolScope;
766        bool inGlobalsRegion;
767        if (auto ec = getSymbolTableRegion(atom, inGlobalsRegion, symbolScope)){
768          return ec;
769        }
770        if (inGlobalsRegion) {
771          AtomAndIndex ai = { atom, sect->finalSectionIndex, symbolScope };
772          globals.push_back(ai);
773        } else {
774          Symbol sym;
775          sym.name  = atom->name();
776          sym.type  = N_SECT;
777          sym.scope = symbolScope;
778          sym.sect  = sect->finalSectionIndex;
779          sym.desc  = descBits(atom);
780          sym.value = _atomToAddress[atom];
781          _atomToSymbolIndex[atom] = file.localSymbols.size();
782          file.localSymbols.push_back(sym);
783        }
784      } else if (rMode && _archHandler.needsLocalSymbolInRelocatableFile(atom)){
785        // Create 'Lxxx' labels for anonymous atoms if archHandler says so.
786        static unsigned tempNum = 1;
787        char tmpName[16];
788        sprintf(tmpName, "L%04u", tempNum++);
789        StringRef tempRef(tmpName);
790        Symbol sym;
791        sym.name  = tempRef.copy(file.ownedAllocations);
792        sym.type  = N_SECT;
793        sym.scope = 0;
794        sym.sect  = sect->finalSectionIndex;
795        sym.desc  = 0;
796        sym.value = _atomToAddress[atom];
797        _atomToSymbolIndex[atom] = file.localSymbols.size();
798        file.localSymbols.push_back(sym);
799      }
800    }
801  }
802
803  // Sort global symbol alphabetically, then add to symbol table.
804  std::sort(globals.begin(), globals.end(), AtomSorter());
805  const uint32_t globalStartIndex = file.localSymbols.size();
806  for (AtomAndIndex &ai : globals) {
807    Symbol sym;
808    sym.name  = ai.atom->name();
809    sym.type  = N_SECT;
810    sym.scope = ai.scope;
811    sym.sect  = ai.index;
812    sym.desc  = descBits(static_cast<const DefinedAtom*>(ai.atom));
813    sym.value = _atomToAddress[ai.atom];
814    _atomToSymbolIndex[ai.atom] = globalStartIndex + file.globalSymbols.size();
815    file.globalSymbols.push_back(sym);
816  }
817
818  // Sort undefined symbol alphabetically, then add to symbol table.
819  std::vector<AtomAndIndex> undefs;
820  undefs.reserve(128);
821  for (const UndefinedAtom *atom : atomFile.undefined()) {
822    AtomAndIndex ai = { atom, 0, N_EXT };
823    undefs.push_back(ai);
824  }
825  for (const SharedLibraryAtom *atom : atomFile.sharedLibrary()) {
826    AtomAndIndex ai = { atom, 0, N_EXT };
827    undefs.push_back(ai);
828  }
829  std::sort(undefs.begin(), undefs.end(), AtomSorter());
830  const uint32_t start = file.globalSymbols.size() + file.localSymbols.size();
831  for (AtomAndIndex &ai : undefs) {
832    Symbol sym;
833    uint16_t desc = 0;
834    if (!rMode) {
835      uint8_t ordinal = 0;
836      if (!_ctx.useFlatNamespace())
837        ordinal = dylibOrdinal(dyn_cast<SharedLibraryAtom>(ai.atom));
838      llvm::MachO::SET_LIBRARY_ORDINAL(desc, ordinal);
839    }
840    sym.name  = ai.atom->name();
841    sym.type  = N_UNDF;
842    sym.scope = ai.scope;
843    sym.sect  = 0;
844    sym.desc  = desc;
845    sym.value = 0;
846    _atomToSymbolIndex[ai.atom] = file.undefinedSymbols.size() + start;
847    file.undefinedSymbols.push_back(sym);
848  }
849
850  return std::error_code();
851}
852
853const Atom *Util::targetOfLazyPointer(const DefinedAtom *lpAtom) {
854  for (const Reference *ref : *lpAtom) {
855    if (_archHandler.isLazyPointer(*ref)) {
856      return ref->target();
857    }
858  }
859  return nullptr;
860}
861
862const Atom *Util::targetOfStub(const DefinedAtom *stubAtom) {
863  for (const Reference *ref : *stubAtom) {
864    if (const Atom *ta = ref->target()) {
865      if (const DefinedAtom *lpAtom = dyn_cast<DefinedAtom>(ta)) {
866        const Atom *target = targetOfLazyPointer(lpAtom);
867        if (target)
868          return target;
869      }
870    }
871  }
872  return nullptr;
873}
874
875void Util::addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file) {
876  for (SectionInfo *si : _sectionInfos) {
877    Section &normSect = file.sections[si->normalizedSectionIndex];
878    switch (si->type) {
879    case llvm::MachO::S_NON_LAZY_SYMBOL_POINTERS:
880      for (const AtomInfo &info : si->atomsAndOffsets) {
881        bool foundTarget = false;
882        for (const Reference *ref : *info.atom) {
883          const Atom *target = ref->target();
884          if (target) {
885            if (isa<const SharedLibraryAtom>(target)) {
886              uint32_t index = _atomToSymbolIndex[target];
887              normSect.indirectSymbols.push_back(index);
888              foundTarget = true;
889            } else {
890              normSect.indirectSymbols.push_back(
891                                            llvm::MachO::INDIRECT_SYMBOL_LOCAL);
892            }
893          }
894        }
895        if (!foundTarget) {
896          normSect.indirectSymbols.push_back(
897                                             llvm::MachO::INDIRECT_SYMBOL_ABS);
898        }
899      }
900      break;
901    case llvm::MachO::S_LAZY_SYMBOL_POINTERS:
902      for (const AtomInfo &info : si->atomsAndOffsets) {
903        const Atom *target = targetOfLazyPointer(info.atom);
904        if (target) {
905          uint32_t index = _atomToSymbolIndex[target];
906          normSect.indirectSymbols.push_back(index);
907        }
908      }
909      break;
910    case llvm::MachO::S_SYMBOL_STUBS:
911      for (const AtomInfo &info : si->atomsAndOffsets) {
912        const Atom *target = targetOfStub(info.atom);
913        if (target) {
914          uint32_t index = _atomToSymbolIndex[target];
915          normSect.indirectSymbols.push_back(index);
916        }
917      }
918      break;
919    default:
920      break;
921    }
922  }
923}
924
925void Util::addDependentDylibs(const lld::File &atomFile,NormalizedFile &nFile) {
926  // Scan all imported symbols and build up list of dylibs they are from.
927  int ordinal = 1;
928  for (const SharedLibraryAtom *slAtom : atomFile.sharedLibrary()) {
929    StringRef loadPath = slAtom->loadName();
930    DylibPathToInfo::iterator pos = _dylibInfo.find(loadPath);
931    if (pos == _dylibInfo.end()) {
932      DylibInfo info;
933      bool flatNamespaceAtom = &slAtom->file() == _ctx.flatNamespaceFile();
934
935      // If we're in -flat_namespace mode (or this atom came from the flat
936      // namespace file under -undefined dynamic_lookup) then use the flat
937      // lookup ordinal.
938      if (flatNamespaceAtom || _ctx.useFlatNamespace())
939        info.ordinal = BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
940      else
941        info.ordinal = ordinal++;
942      info.hasWeak = slAtom->canBeNullAtRuntime();
943      info.hasNonWeak = !info.hasWeak;
944      _dylibInfo[loadPath] = info;
945
946      // Unless this was a flat_namespace atom, record the source dylib.
947      if (!flatNamespaceAtom) {
948        DependentDylib depInfo;
949        depInfo.path = loadPath;
950        depInfo.kind = llvm::MachO::LC_LOAD_DYLIB;
951        depInfo.currentVersion = _ctx.dylibCurrentVersion(loadPath);
952        depInfo.compatVersion = _ctx.dylibCompatVersion(loadPath);
953        nFile.dependentDylibs.push_back(depInfo);
954      }
955    } else {
956      if ( slAtom->canBeNullAtRuntime() )
957        pos->second.hasWeak = true;
958      else
959        pos->second.hasNonWeak = true;
960    }
961  }
962  // Automatically weak link dylib in which all symbols are weak (canBeNull).
963  for (DependentDylib &dep : nFile.dependentDylibs) {
964    DylibInfo &info = _dylibInfo[dep.path];
965    if (info.hasWeak && !info.hasNonWeak)
966      dep.kind = llvm::MachO::LC_LOAD_WEAK_DYLIB;
967    else if (_ctx.isUpwardDylib(dep.path))
968      dep.kind = llvm::MachO::LC_LOAD_UPWARD_DYLIB;
969  }
970}
971
972int Util::dylibOrdinal(const SharedLibraryAtom *sa) {
973  return _dylibInfo[sa->loadName()].ordinal;
974}
975
976void Util::segIndexForSection(const SectionInfo *sect, uint8_t &segmentIndex,
977                                                  uint64_t &segmentStartAddr) {
978  segmentIndex = 0;
979  for (const SegmentInfo *seg : _segmentInfos) {
980    if ((seg->address <= sect->address)
981      && (seg->address+seg->size >= sect->address+sect->size)) {
982      segmentStartAddr = seg->address;
983      return;
984    }
985    ++segmentIndex;
986  }
987  llvm_unreachable("section not in any segment");
988}
989
990uint32_t Util::sectionIndexForAtom(const Atom *atom) {
991  uint64_t address = _atomToAddress[atom];
992  for (const SectionInfo *si : _sectionInfos) {
993    if ((si->address <= address) && (address < si->address+si->size))
994      return si->finalSectionIndex;
995  }
996  llvm_unreachable("atom not in any section");
997}
998
999void Util::addSectionRelocs(const lld::File &, NormalizedFile &file) {
1000  if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
1001    return;
1002
1003  // Utility function for ArchHandler to find symbol index for an atom.
1004  auto symIndexForAtom = [&] (const Atom &atom) -> uint32_t {
1005    auto pos = _atomToSymbolIndex.find(&atom);
1006    assert(pos != _atomToSymbolIndex.end());
1007    return pos->second;
1008  };
1009
1010  // Utility function for ArchHandler to find section index for an atom.
1011  auto sectIndexForAtom = [&] (const Atom &atom) -> uint32_t {
1012    return sectionIndexForAtom(&atom);
1013  };
1014
1015  // Utility function for ArchHandler to find address of atom in output file.
1016  auto addressForAtom = [&] (const Atom &atom) -> uint64_t {
1017    auto pos = _atomToAddress.find(&atom);
1018    assert(pos != _atomToAddress.end());
1019    return pos->second;
1020  };
1021
1022  for (SectionInfo *si : _sectionInfos) {
1023    Section &normSect = file.sections[si->normalizedSectionIndex];
1024    for (const AtomInfo &info : si->atomsAndOffsets) {
1025      const DefinedAtom *atom = info.atom;
1026      for (const Reference *ref : *atom) {
1027        _archHandler.appendSectionRelocations(*atom, info.offsetInSection, *ref,
1028                                              symIndexForAtom,
1029                                              sectIndexForAtom,
1030                                              addressForAtom,
1031                                              normSect.relocations);
1032      }
1033    }
1034  }
1035}
1036
1037void Util::buildDataInCodeArray(const lld::File &, NormalizedFile &file) {
1038  for (SectionInfo *si : _sectionInfos) {
1039    for (const AtomInfo &info : si->atomsAndOffsets) {
1040      // Atoms that contain data-in-code have "transition" references
1041      // which mark a point where the embedded data starts of ends.
1042      // This needs to be converted to the mach-o format which is an array
1043      // of data-in-code ranges.
1044      uint32_t startOffset = 0;
1045      DataRegionType mode = DataRegionType(0);
1046      for (const Reference *ref : *info.atom) {
1047        if (ref->kindNamespace() != Reference::KindNamespace::mach_o)
1048          continue;
1049        if (_archHandler.isDataInCodeTransition(ref->kindValue())) {
1050          DataRegionType nextMode = (DataRegionType)ref->addend();
1051          if (mode != nextMode) {
1052            if (mode != 0) {
1053              // Found end data range, so make range entry.
1054              DataInCode entry;
1055              entry.offset = si->address + info.offsetInSection + startOffset;
1056              entry.length = ref->offsetInAtom() - startOffset;
1057              entry.kind   = mode;
1058              file.dataInCode.push_back(entry);
1059            }
1060          }
1061          mode = nextMode;
1062          startOffset = ref->offsetInAtom();
1063        }
1064      }
1065      if (mode != 0) {
1066        // Function ends with data (no end transition).
1067        DataInCode entry;
1068        entry.offset = si->address + info.offsetInSection + startOffset;
1069        entry.length = info.atom->size() - startOffset;
1070        entry.kind   = mode;
1071        file.dataInCode.push_back(entry);
1072      }
1073    }
1074  }
1075}
1076
1077void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
1078                                                        NormalizedFile &nFile) {
1079  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1080    return;
1081
1082  uint8_t segmentIndex;
1083  uint64_t segmentStartAddr;
1084  for (SectionInfo *sect : _sectionInfos) {
1085    segIndexForSection(sect, segmentIndex, segmentStartAddr);
1086    for (const AtomInfo &info : sect->atomsAndOffsets) {
1087      const DefinedAtom *atom = info.atom;
1088      for (const Reference *ref : *atom) {
1089        uint64_t segmentOffset = _atomToAddress[atom] + ref->offsetInAtom()
1090                                - segmentStartAddr;
1091        const Atom* targ = ref->target();
1092        if (_archHandler.isPointer(*ref)) {
1093          // A pointer to a DefinedAtom requires rebasing.
1094          if (isa<DefinedAtom>(targ)) {
1095            RebaseLocation rebase;
1096            rebase.segIndex = segmentIndex;
1097            rebase.segOffset = segmentOffset;
1098            rebase.kind = llvm::MachO::REBASE_TYPE_POINTER;
1099            nFile.rebasingInfo.push_back(rebase);
1100          }
1101          // A pointer to an SharedLibraryAtom requires binding.
1102          if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1103            BindLocation bind;
1104            bind.segIndex = segmentIndex;
1105            bind.segOffset = segmentOffset;
1106            bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1107            bind.canBeNull = sa->canBeNullAtRuntime();
1108            bind.ordinal = dylibOrdinal(sa);
1109            bind.symbolName = targ->name();
1110            bind.addend = ref->addend();
1111            nFile.bindingInfo.push_back(bind);
1112          }
1113        }
1114        else if (_archHandler.isLazyPointer(*ref)) {
1115          BindLocation bind;
1116          if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1117            bind.ordinal = dylibOrdinal(sa);
1118          } else {
1119            bind.ordinal = llvm::MachO::BIND_SPECIAL_DYLIB_SELF;
1120          }
1121          bind.segIndex = segmentIndex;
1122          bind.segOffset = segmentOffset;
1123          bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1124          bind.canBeNull = false; //sa->canBeNullAtRuntime();
1125          bind.symbolName = targ->name();
1126          bind.addend = ref->addend();
1127          nFile.lazyBindingInfo.push_back(bind);
1128        }
1129      }
1130    }
1131  }
1132}
1133
1134void Util::addExportInfo(const lld::File &atomFile, NormalizedFile &nFile) {
1135  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1136    return;
1137
1138  for (SectionInfo *sect : _sectionInfos) {
1139    for (const AtomInfo &info : sect->atomsAndOffsets) {
1140      const DefinedAtom *atom = info.atom;
1141      if (atom->scope() != Atom::scopeGlobal)
1142        continue;
1143      if (_ctx.exportRestrictMode()) {
1144        if (!_ctx.exportSymbolNamed(atom->name()))
1145          continue;
1146      }
1147      Export exprt;
1148      exprt.name = atom->name();
1149      exprt.offset = _atomToAddress[atom] - _ctx.baseAddress();
1150      exprt.kind = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
1151      if (atom->merge() == DefinedAtom::mergeAsWeak)
1152        exprt.flags = EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
1153      else
1154        exprt.flags = 0;
1155      exprt.otherOffset = 0;
1156      exprt.otherName = StringRef();
1157      nFile.exportInfo.push_back(exprt);
1158    }
1159  }
1160}
1161
1162uint32_t Util::fileFlags() {
1163  // FIXME: these need to determined at runtime.
1164  if (_ctx.outputMachOType() == MH_OBJECT) {
1165    return MH_SUBSECTIONS_VIA_SYMBOLS;
1166  } else {
1167    uint32_t flags = MH_DYLDLINK;
1168    if (!_ctx.useFlatNamespace())
1169        flags |= MH_TWOLEVEL | MH_NOUNDEFS;
1170    if ((_ctx.outputMachOType() == MH_EXECUTE) && _ctx.PIE())
1171      flags |= MH_PIE;
1172    if (_hasTLVDescriptors)
1173      flags |= (MH_PIE | MH_HAS_TLV_DESCRIPTORS);
1174    return flags;
1175  }
1176}
1177
1178} // end anonymous namespace
1179
1180namespace lld {
1181namespace mach_o {
1182namespace normalized {
1183
1184/// Convert a set of Atoms into a normalized mach-o file.
1185ErrorOr<std::unique_ptr<NormalizedFile>>
1186normalizedFromAtoms(const lld::File &atomFile,
1187                                           const MachOLinkingContext &context) {
1188  // The util object buffers info until the normalized file can be made.
1189  Util util(context);
1190  util.assignAtomsToSections(atomFile);
1191  util.organizeSections();
1192
1193  std::unique_ptr<NormalizedFile> f(new NormalizedFile());
1194  NormalizedFile &normFile = *f.get();
1195  normFile.arch = context.arch();
1196  normFile.fileType = context.outputMachOType();
1197  normFile.flags = util.fileFlags();
1198  normFile.stackSize = context.stackSize();
1199  normFile.installName = context.installName();
1200  normFile.currentVersion = context.currentVersion();
1201  normFile.compatVersion = context.compatibilityVersion();
1202  normFile.pageSize = context.pageSize();
1203  normFile.rpaths = context.rpaths();
1204  util.addDependentDylibs(atomFile, normFile);
1205  util.copySegmentInfo(normFile);
1206  util.copySectionInfo(normFile);
1207  util.assignAddressesToSections(normFile);
1208  util.buildAtomToAddressMap();
1209  util.updateSectionInfo(normFile);
1210  util.copySectionContent(normFile);
1211  if (auto ec = util.addSymbols(atomFile, normFile)) {
1212    return ec;
1213  }
1214  util.addIndirectSymbols(atomFile, normFile);
1215  util.addRebaseAndBindingInfo(atomFile, normFile);
1216  util.addExportInfo(atomFile, normFile);
1217  util.addSectionRelocs(atomFile, normFile);
1218  util.buildDataInCodeArray(atomFile, normFile);
1219  util.copyEntryPointAddress(normFile);
1220
1221  return std::move(f);
1222}
1223
1224} // namespace normalized
1225} // namespace mach_o
1226} // namespace lld
1227