MachONormalizedFileFromAtoms.cpp revision 303239
1254885Sdumbbell//===- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp ------------===//
2254885Sdumbbell//
3254885Sdumbbell//                             The LLVM Linker
4254885Sdumbbell//
5254885Sdumbbell// This file is distributed under the University of Illinois Open Source
6254885Sdumbbell// License. See LICENSE.TXT for details.
7254885Sdumbbell//
8254885Sdumbbell//===----------------------------------------------------------------------===//
9254885Sdumbbell
10254885Sdumbbell///
11254885Sdumbbell/// \file Converts from in-memory Atoms to in-memory normalized mach-o.
12254885Sdumbbell///
13254885Sdumbbell///                  +------------+
14254885Sdumbbell///                  | normalized |
15254885Sdumbbell///                  +------------+
16254885Sdumbbell///                        ^
17254885Sdumbbell///                        |
18254885Sdumbbell///                        |
19254885Sdumbbell///                    +-------+
20254885Sdumbbell///                    | Atoms |
21254885Sdumbbell///                    +-------+
22254885Sdumbbell
23254885Sdumbbell#include "MachONormalizedFile.h"
24254885Sdumbbell#include "ArchHandler.h"
25254885Sdumbbell#include "MachONormalizedFileBinaryUtils.h"
26254885Sdumbbell#include "lld/Core/Error.h"
27254885Sdumbbell#include "lld/Core/LLVM.h"
28254885Sdumbbell#include "llvm/ADT/StringRef.h"
29254885Sdumbbell#include "llvm/ADT/StringSwitch.h"
30254885Sdumbbell#include "llvm/Support/Casting.h"
31254885Sdumbbell#include "llvm/Support/Debug.h"
32254885Sdumbbell#include "llvm/Support/ErrorHandling.h"
33254885Sdumbbell#include "llvm/Support/Format.h"
34254885Sdumbbell#include "llvm/Support/MachO.h"
35254885Sdumbbell#include <map>
36254885Sdumbbell#include <system_error>
37254885Sdumbbell
38254885Sdumbbellusing llvm::StringRef;
39254885Sdumbbellusing llvm::isa;
40254885Sdumbbellusing namespace llvm::MachO;
41254885Sdumbbellusing namespace lld::mach_o::normalized;
42254885Sdumbbellusing namespace lld;
43254885Sdumbbell
44254885Sdumbbellnamespace {
45254885Sdumbbell
46254885Sdumbbellstruct AtomInfo {
47254885Sdumbbell  const DefinedAtom  *atom;
48254885Sdumbbell  uint64_t            offsetInSection;
49254885Sdumbbell};
50254885Sdumbbell
51254885Sdumbbellstruct SectionInfo {
52254885Sdumbbell  SectionInfo(StringRef seg, StringRef sect, SectionType type,
53254885Sdumbbell              const MachOLinkingContext &ctxt, uint32_t attr,
54254885Sdumbbell              bool relocsToDefinedCanBeImplicit);
55254885Sdumbbell
56254885Sdumbbell  StringRef                 segmentName;
57254885Sdumbbell  StringRef                 sectionName;
58254885Sdumbbell  SectionType               type;
59254885Sdumbbell  uint32_t                  attributes;
60254885Sdumbbell  uint64_t                  address;
61254885Sdumbbell  uint64_t                  size;
62254885Sdumbbell  uint16_t                  alignment;
63254885Sdumbbell
64258780Seadler  /// If this is set, the any relocs in this section which point to defined
65254885Sdumbbell  /// addresses can be implicitly generated.  This is the case for the
66254885Sdumbbell  /// __eh_frame section where references to the function can be implicit if the
67254885Sdumbbell  /// function is defined.
68254885Sdumbbell  bool                      relocsToDefinedCanBeImplicit;
69254885Sdumbbell
70254885Sdumbbell
71254885Sdumbbell  std::vector<AtomInfo>     atomsAndOffsets;
72254885Sdumbbell  uint32_t                  normalizedSectionIndex;
73254885Sdumbbell  uint32_t                  finalSectionIndex;
74254885Sdumbbell};
75254885Sdumbbell
76254885SdumbbellSectionInfo::SectionInfo(StringRef sg, StringRef sct, SectionType t,
77254885Sdumbbell                         const MachOLinkingContext &ctxt, uint32_t attrs,
78254885Sdumbbell                         bool relocsToDefinedCanBeImplicit)
79254885Sdumbbell : segmentName(sg), sectionName(sct), type(t), attributes(attrs),
80254885Sdumbbell                 address(0), size(0), alignment(1),
81254885Sdumbbell                 relocsToDefinedCanBeImplicit(relocsToDefinedCanBeImplicit),
82254885Sdumbbell                 normalizedSectionIndex(0), finalSectionIndex(0) {
83254885Sdumbbell  uint16_t align = 1;
84254885Sdumbbell  if (ctxt.sectionAligned(segmentName, sectionName, align)) {
85254885Sdumbbell    alignment = align;
86254885Sdumbbell  }
87254885Sdumbbell}
88254885Sdumbbell
89254885Sdumbbellstruct SegmentInfo {
90254885Sdumbbell  SegmentInfo(StringRef name);
91254885Sdumbbell
92254885Sdumbbell  StringRef                  name;
93254885Sdumbbell  uint64_t                   address;
94254885Sdumbbell  uint64_t                   size;
95254885Sdumbbell  uint32_t                   init_access;
96254885Sdumbbell  uint32_t                   max_access;
97254885Sdumbbell  std::vector<SectionInfo*>  sections;
98254885Sdumbbell  uint32_t                   normalizedSegmentIndex;
99254885Sdumbbell};
100254885Sdumbbell
101254885SdumbbellSegmentInfo::SegmentInfo(StringRef n)
102254885Sdumbbell : name(n), address(0), size(0), init_access(0), max_access(0),
103254885Sdumbbell   normalizedSegmentIndex(0) {
104254885Sdumbbell}
105254885Sdumbbell
106254885Sdumbbellclass Util {
107254885Sdumbbellpublic:
108254885Sdumbbell  Util(const MachOLinkingContext &ctxt)
109254885Sdumbbell      : _ctx(ctxt), _archHandler(ctxt.archHandler()), _entryAtom(nullptr),
110254885Sdumbbell        _hasTLVDescriptors(false), _subsectionsViaSymbols(true) {}
111254885Sdumbbell  ~Util();
112254885Sdumbbell
113254885Sdumbbell  void      processDefinedAtoms(const lld::File &atomFile);
114254885Sdumbbell  void      processAtomAttributes(const DefinedAtom *atom);
115254885Sdumbbell  void      assignAtomToSection(const DefinedAtom *atom);
116254885Sdumbbell  void      organizeSections();
117254885Sdumbbell  void      assignAddressesToSections(const NormalizedFile &file);
118254885Sdumbbell  uint32_t  fileFlags();
119254885Sdumbbell  void      copySegmentInfo(NormalizedFile &file);
120254885Sdumbbell  void      copySectionInfo(NormalizedFile &file);
121254885Sdumbbell  void      updateSectionInfo(NormalizedFile &file);
122254885Sdumbbell  void      buildAtomToAddressMap();
123254885Sdumbbell  llvm::Error addSymbols(const lld::File &atomFile, NormalizedFile &file);
124254885Sdumbbell  void      addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file);
125254885Sdumbbell  void      addRebaseAndBindingInfo(const lld::File &, NormalizedFile &file);
126254885Sdumbbell  void      addExportInfo(const lld::File &, NormalizedFile &file);
127254885Sdumbbell  void      addSectionRelocs(const lld::File &, NormalizedFile &file);
128258780Seadler  void      addFunctionStarts(const lld::File &, NormalizedFile &file);
129254885Sdumbbell  void      buildDataInCodeArray(const lld::File &, NormalizedFile &file);
130254885Sdumbbell  void      addDependentDylibs(const lld::File &, NormalizedFile &file);
131254885Sdumbbell  void      copyEntryPointAddress(NormalizedFile &file);
132254885Sdumbbell  void      copySectionContent(NormalizedFile &file);
133254885Sdumbbell
134254885Sdumbbell  bool allSourceFilesHaveMinVersions() const {
135254885Sdumbbell    return _allSourceFilesHaveMinVersions;
136254885Sdumbbell  }
137254885Sdumbbell
138254885Sdumbbell  uint32_t minVersion() const {
139254885Sdumbbell    return _minVersion;
140254885Sdumbbell  }
141254885Sdumbbell
142254885Sdumbbell  LoadCommandType minVersionCommandType() const {
143254885Sdumbbell    return _minVersionCommandType;
144254885Sdumbbell  }
145254885Sdumbbell
146254885Sdumbbellprivate:
147254885Sdumbbell  typedef std::map<DefinedAtom::ContentType, SectionInfo*> TypeToSection;
148254885Sdumbbell  typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
149254885Sdumbbell
150254885Sdumbbell  struct DylibInfo { int ordinal; bool hasWeak; bool hasNonWeak; };
151254885Sdumbbell  typedef llvm::StringMap<DylibInfo> DylibPathToInfo;
152254885Sdumbbell
153254885Sdumbbell  SectionInfo *sectionForAtom(const DefinedAtom*);
154254885Sdumbbell  SectionInfo *getRelocatableSection(DefinedAtom::ContentType type);
155254885Sdumbbell  SectionInfo *getFinalSection(DefinedAtom::ContentType type);
156254885Sdumbbell  void         appendAtom(SectionInfo *sect, const DefinedAtom *atom);
157254885Sdumbbell  SegmentInfo *segmentForName(StringRef segName);
158254885Sdumbbell  void         layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr);
159254885Sdumbbell  void         layoutSectionsInTextSegment(size_t, SegmentInfo *, uint64_t &);
160254885Sdumbbell  void         copySectionContent(SectionInfo *si, ContentBytes &content);
161254885Sdumbbell  uint16_t     descBits(const DefinedAtom* atom);
162254885Sdumbbell  int          dylibOrdinal(const SharedLibraryAtom *sa);
163254885Sdumbbell  void         segIndexForSection(const SectionInfo *sect,
164254885Sdumbbell                             uint8_t &segmentIndex, uint64_t &segmentStartAddr);
165254885Sdumbbell  const Atom  *targetOfLazyPointer(const DefinedAtom *lpAtom);
166254885Sdumbbell  const Atom  *targetOfStub(const DefinedAtom *stubAtom);
167254885Sdumbbell  llvm::Error getSymbolTableRegion(const DefinedAtom* atom,
168254885Sdumbbell                                   bool &inGlobalsRegion,
169254885Sdumbbell                                   SymbolScope &symbolScope);
170254885Sdumbbell  void         appendSection(SectionInfo *si, NormalizedFile &file);
171254885Sdumbbell  uint32_t     sectionIndexForAtom(const Atom *atom);
172254885Sdumbbell
173254885Sdumbbell  typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;
174254885Sdumbbell  struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };
175254885Sdumbbell  struct AtomSorter {
176254885Sdumbbell    bool operator()(const AtomAndIndex &left, const AtomAndIndex &right);
177254885Sdumbbell  };
178254885Sdumbbell  struct SegmentSorter {
179254885Sdumbbell    bool operator()(const SegmentInfo *left, const SegmentInfo *right);
180254885Sdumbbell    static unsigned weight(const SegmentInfo *);
181254885Sdumbbell  };
182254885Sdumbbell  struct TextSectionSorter {
183254885Sdumbbell    bool operator()(const SectionInfo *left, const SectionInfo *right);
184254885Sdumbbell    static unsigned weight(const SectionInfo *);
185254885Sdumbbell  };
186254885Sdumbbell
187254885Sdumbbell  const MachOLinkingContext &_ctx;
188254885Sdumbbell  mach_o::ArchHandler          &_archHandler;
189254885Sdumbbell  llvm::BumpPtrAllocator        _allocator;
190258780Seadler  std::vector<SectionInfo*>     _sectionInfos;
191254885Sdumbbell  std::vector<SegmentInfo*>     _segmentInfos;
192254885Sdumbbell  TypeToSection                 _sectionMap;
193254885Sdumbbell  std::vector<SectionInfo*>     _customSections;
194254885Sdumbbell  AtomToAddress                 _atomToAddress;
195254885Sdumbbell  DylibPathToInfo               _dylibInfo;
196254885Sdumbbell  const DefinedAtom            *_entryAtom;
197254885Sdumbbell  AtomToIndex                   _atomToSymbolIndex;
198254885Sdumbbell  std::vector<const Atom *>     _machHeaderAliasAtoms;
199254885Sdumbbell  bool                          _hasTLVDescriptors;
200254885Sdumbbell  bool                          _subsectionsViaSymbols;
201254885Sdumbbell  bool                          _allSourceFilesHaveMinVersions = true;
202254885Sdumbbell  LoadCommandType               _minVersionCommandType = (LoadCommandType)0;
203254885Sdumbbell  uint32_t                      _minVersion = 0;
204254885Sdumbbell};
205254885Sdumbbell
206254885SdumbbellUtil::~Util() {
207254885Sdumbbell  // The SectionInfo structs are BumpPtr allocated, but atomsAndOffsets needs
208254885Sdumbbell  // to be deleted.
209254885Sdumbbell  for (SectionInfo *si : _sectionInfos) {
210254885Sdumbbell    // clear() destroys vector elements, but does not deallocate.
211254885Sdumbbell    // Instead use swap() to deallocate vector buffer.
212254885Sdumbbell    std::vector<AtomInfo> empty;
213254885Sdumbbell    si->atomsAndOffsets.swap(empty);
214254885Sdumbbell  }
215254885Sdumbbell  // The SegmentInfo structs are BumpPtr allocated, but sections needs
216254885Sdumbbell  // to be deleted.
217254885Sdumbbell  for (SegmentInfo *sgi : _segmentInfos) {
218254885Sdumbbell    std::vector<SectionInfo*> empty2;
219254885Sdumbbell    sgi->sections.swap(empty2);
220254885Sdumbbell  }
221254885Sdumbbell}
222254885Sdumbbell
223254885SdumbbellSectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
224254885Sdumbbell  StringRef segmentName;
225254885Sdumbbell  StringRef sectionName;
226254885Sdumbbell  SectionType sectionType;
227254885Sdumbbell  SectionAttr sectionAttrs;
228254885Sdumbbell  bool relocsToDefinedCanBeImplicit;
229254885Sdumbbell
230254885Sdumbbell  // Use same table used by when parsing .o files.
231254885Sdumbbell  relocatableSectionInfoForContentType(type, segmentName, sectionName,
232254885Sdumbbell                                       sectionType, sectionAttrs,
233254885Sdumbbell                                       relocsToDefinedCanBeImplicit);
234254885Sdumbbell  // If we already have a SectionInfo with this name, re-use it.
235254885Sdumbbell  // This can happen if two ContentType map to the same mach-o section.
236254885Sdumbbell  for (auto sect : _sectionMap) {
237254885Sdumbbell    if (sect.second->sectionName.equals(sectionName) &&
238254885Sdumbbell        sect.second->segmentName.equals(segmentName)) {
239254885Sdumbbell      return sect.second;
240254885Sdumbbell    }
241254885Sdumbbell  }
242254885Sdumbbell  // Otherwise allocate new SectionInfo object.
243254885Sdumbbell  auto *sect = new (_allocator)
244254885Sdumbbell      SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs,
245254885Sdumbbell                  relocsToDefinedCanBeImplicit);
246254885Sdumbbell  _sectionInfos.push_back(sect);
247254885Sdumbbell  _sectionMap[type] = sect;
248254885Sdumbbell  return sect;
249254885Sdumbbell}
250254885Sdumbbell
251254885Sdumbbell#define ENTRY(seg, sect, type, atomType) \
252254885Sdumbbell  {seg, sect, type, DefinedAtom::atomType }
253254885Sdumbbell
254254885Sdumbbellstruct MachOFinalSectionFromAtomType {
255254885Sdumbbell  StringRef                 segmentName;
256254885Sdumbbell  StringRef                 sectionName;
257254885Sdumbbell  SectionType               sectionType;
258254885Sdumbbell  DefinedAtom::ContentType  atomType;
259254885Sdumbbell};
260254885Sdumbbell
261254885Sdumbbellconst MachOFinalSectionFromAtomType sectsToAtomType[] = {
262254885Sdumbbell  ENTRY("__TEXT", "__text",           S_REGULAR,          typeCode),
263254885Sdumbbell  ENTRY("__TEXT", "__text",           S_REGULAR,          typeMachHeader),
264254885Sdumbbell  ENTRY("__TEXT", "__cstring",        S_CSTRING_LITERALS, typeCString),
265254885Sdumbbell  ENTRY("__TEXT", "__ustring",        S_REGULAR,          typeUTF16String),
266254885Sdumbbell  ENTRY("__TEXT", "__const",          S_REGULAR,          typeConstant),
267254885Sdumbbell  ENTRY("__TEXT", "__const",          S_4BYTE_LITERALS,   typeLiteral4),
268254885Sdumbbell  ENTRY("__TEXT", "__const",          S_8BYTE_LITERALS,   typeLiteral8),
269254885Sdumbbell  ENTRY("__TEXT", "__const",          S_16BYTE_LITERALS,  typeLiteral16),
270254885Sdumbbell  ENTRY("__TEXT", "__stubs",          S_SYMBOL_STUBS,     typeStub),
271254885Sdumbbell  ENTRY("__TEXT", "__stub_helper",    S_REGULAR,          typeStubHelper),
272254885Sdumbbell  ENTRY("__TEXT", "__gcc_except_tab", S_REGULAR,          typeLSDA),
273254885Sdumbbell  ENTRY("__TEXT", "__eh_frame",       S_COALESCED,        typeCFI),
274254885Sdumbbell  ENTRY("__TEXT", "__unwind_info",    S_REGULAR,          typeProcessedUnwindInfo),
275254885Sdumbbell  ENTRY("__DATA", "__data",           S_REGULAR,          typeData),
276254885Sdumbbell  ENTRY("__DATA", "__const",          S_REGULAR,          typeConstData),
277254885Sdumbbell  ENTRY("__DATA", "__cfstring",       S_REGULAR,          typeCFString),
278254885Sdumbbell  ENTRY("__DATA", "__la_symbol_ptr",  S_LAZY_SYMBOL_POINTERS,
279254885Sdumbbell                                                          typeLazyPointer),
280254885Sdumbbell  ENTRY("__DATA", "__mod_init_func",  S_MOD_INIT_FUNC_POINTERS,
281254885Sdumbbell                                                          typeInitializerPtr),
282254885Sdumbbell  ENTRY("__DATA", "__mod_term_func",  S_MOD_TERM_FUNC_POINTERS,
283254885Sdumbbell                                                          typeTerminatorPtr),
284254885Sdumbbell  ENTRY("__DATA", "__got",            S_NON_LAZY_SYMBOL_POINTERS,
285254885Sdumbbell                                                          typeGOT),
286254885Sdumbbell  ENTRY("__DATA", "__nl_symbol_ptr",  S_NON_LAZY_SYMBOL_POINTERS,
287254885Sdumbbell                                                          typeNonLazyPointer),
288254885Sdumbbell  ENTRY("__DATA", "__thread_vars",    S_THREAD_LOCAL_VARIABLES,
289254885Sdumbbell                                                          typeThunkTLV),
290254885Sdumbbell  ENTRY("__DATA", "__thread_data",    S_THREAD_LOCAL_REGULAR,
291254885Sdumbbell                                                          typeTLVInitialData),
292254885Sdumbbell  ENTRY("__DATA", "__thread_ptrs",    S_THREAD_LOCAL_VARIABLE_POINTERS,
293254885Sdumbbell                                                          typeTLVInitializerPtr),
294254885Sdumbbell  ENTRY("__DATA", "__thread_bss",     S_THREAD_LOCAL_ZEROFILL,
295254885Sdumbbell                                                         typeTLVInitialZeroFill),
296254885Sdumbbell  ENTRY("__DATA", "__bss",            S_ZEROFILL,         typeZeroFill),
297254885Sdumbbell  ENTRY("__DATA", "__interposing",    S_INTERPOSING,      typeInterposingTuples),
298254885Sdumbbell};
299254885Sdumbbell#undef ENTRY
300254885Sdumbbell
301254885SdumbbellSectionInfo *Util::getFinalSection(DefinedAtom::ContentType atomType) {
302254885Sdumbbell  for (auto &p : sectsToAtomType) {
303254885Sdumbbell    if (p.atomType != atomType)
304254885Sdumbbell      continue;
305254885Sdumbbell    SectionAttr sectionAttrs = 0;
306254885Sdumbbell    switch (atomType) {
307254885Sdumbbell    case DefinedAtom::typeMachHeader:
308254885Sdumbbell    case DefinedAtom::typeCode:
309254885Sdumbbell    case DefinedAtom::typeStub:
310254885Sdumbbell    case DefinedAtom::typeStubHelper:
311254885Sdumbbell      sectionAttrs = S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS;
312254885Sdumbbell      break;
313254885Sdumbbell    case DefinedAtom::typeThunkTLV:
314254885Sdumbbell      _hasTLVDescriptors = true;
315254885Sdumbbell      break;
316254885Sdumbbell    default:
317254885Sdumbbell      break;
318254885Sdumbbell    }
319254885Sdumbbell    // If we already have a SectionInfo with this name, re-use it.
320254885Sdumbbell    // This can happen if two ContentType map to the same mach-o section.
321254885Sdumbbell    for (auto sect : _sectionMap) {
322254885Sdumbbell      if (sect.second->sectionName.equals(p.sectionName) &&
323254885Sdumbbell          sect.second->segmentName.equals(p.segmentName)) {
324254885Sdumbbell        return sect.second;
325258780Seadler      }
326254885Sdumbbell    }
327254885Sdumbbell    // Otherwise allocate new SectionInfo object.
328254885Sdumbbell    auto *sect = new (_allocator) SectionInfo(
329254885Sdumbbell        p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs,
330254885Sdumbbell        /* relocsToDefinedCanBeImplicit */ false);
331254885Sdumbbell    _sectionInfos.push_back(sect);
332254885Sdumbbell    _sectionMap[atomType] = sect;
333254885Sdumbbell    return sect;
334254885Sdumbbell  }
335254885Sdumbbell  llvm_unreachable("content type not yet supported");
336254885Sdumbbell}
337254885Sdumbbell
338254885SdumbbellSectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
339254885Sdumbbell  if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
340254885Sdumbbell    // Section for this atom is derived from content type.
341254885Sdumbbell    DefinedAtom::ContentType type = atom->contentType();
342254885Sdumbbell    auto pos = _sectionMap.find(type);
343254885Sdumbbell    if ( pos != _sectionMap.end() )
344254885Sdumbbell      return pos->second;
345254885Sdumbbell    bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
346254885Sdumbbell    return rMode ? getRelocatableSection(type) : getFinalSection(type);
347254885Sdumbbell  } else {
348254885Sdumbbell    // This atom needs to be in a custom section.
349254885Sdumbbell    StringRef customName = atom->customSectionName();
350254885Sdumbbell    // Look to see if we have already allocated the needed custom section.
351254885Sdumbbell    for(SectionInfo *sect : _customSections) {
352254885Sdumbbell      const DefinedAtom *firstAtom = sect->atomsAndOffsets.front().atom;
353254885Sdumbbell      if (firstAtom->customSectionName().equals(customName)) {
354254885Sdumbbell        return sect;
355254885Sdumbbell      }
356254885Sdumbbell    }
357254885Sdumbbell    // Not found, so need to create a new custom section.
358254885Sdumbbell    size_t seperatorIndex = customName.find('/');
359254885Sdumbbell    assert(seperatorIndex != StringRef::npos);
360254885Sdumbbell    StringRef segName = customName.slice(0, seperatorIndex);
361254885Sdumbbell    StringRef sectName = customName.drop_front(seperatorIndex + 1);
362254885Sdumbbell    auto *sect =
363254885Sdumbbell        new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx,
364254885Sdumbbell                                     0, /* relocsToDefinedCanBeImplicit */ false);
365254885Sdumbbell    _customSections.push_back(sect);
366254885Sdumbbell    _sectionInfos.push_back(sect);
367254885Sdumbbell    return sect;
368254885Sdumbbell  }
369254885Sdumbbell}
370254885Sdumbbell
371254885Sdumbbellvoid Util::appendAtom(SectionInfo *sect, const DefinedAtom *atom) {
372254885Sdumbbell  // Figure out offset for atom in this section given alignment constraints.
373254885Sdumbbell  uint64_t offset = sect->size;
374254885Sdumbbell  DefinedAtom::Alignment atomAlign = atom->alignment();
375254885Sdumbbell  uint64_t align = atomAlign.value;
376254885Sdumbbell  uint64_t requiredModulus = atomAlign.modulus;
377254885Sdumbbell  uint64_t currentModulus = (offset % align);
378254885Sdumbbell  if ( currentModulus != requiredModulus ) {
379254885Sdumbbell    if ( requiredModulus > currentModulus )
380254885Sdumbbell      offset += requiredModulus-currentModulus;
381254885Sdumbbell    else
382254885Sdumbbell      offset += align+requiredModulus-currentModulus;
383254885Sdumbbell  }
384254885Sdumbbell  // Record max alignment of any atom in this section.
385254885Sdumbbell  if (align > sect->alignment)
386254885Sdumbbell    sect->alignment = atomAlign.value;
387254885Sdumbbell  // Assign atom to this section with this offset.
388254885Sdumbbell  AtomInfo ai = {atom, offset};
389254885Sdumbbell  sect->atomsAndOffsets.push_back(ai);
390254885Sdumbbell  // Update section size to include this atom.
391254885Sdumbbell  sect->size = offset + atom->size();
392254885Sdumbbell}
393254885Sdumbbell
394254885Sdumbbellvoid Util::processDefinedAtoms(const lld::File &atomFile) {
395254885Sdumbbell  for (const DefinedAtom *atom : atomFile.defined()) {
396254885Sdumbbell    processAtomAttributes(atom);
397254885Sdumbbell    assignAtomToSection(atom);
398254885Sdumbbell  }
399254885Sdumbbell}
400254885Sdumbbell
401254885Sdumbbellvoid Util::processAtomAttributes(const DefinedAtom *atom) {
402254885Sdumbbell  if (auto *machoFile = dyn_cast<mach_o::MachOFile>(&atom->file())) {
403254885Sdumbbell    // If the file doesn't use subsections via symbols, then make sure we don't
404254885Sdumbbell    // add that flag to the final output file if we have a relocatable file.
405254885Sdumbbell    if (!machoFile->subsectionsViaSymbols())
406254885Sdumbbell      _subsectionsViaSymbols = false;
407254885Sdumbbell
408254885Sdumbbell    // All the source files must have min versions for us to output an object
409258780Seadler    // file with a min version.
410254885Sdumbbell    if (auto v = machoFile->minVersion())
411254885Sdumbbell      _minVersion = std::max(_minVersion, v);
412254885Sdumbbell    else
413254885Sdumbbell      _allSourceFilesHaveMinVersions = false;
414254885Sdumbbell
415254885Sdumbbell    // If we don't have a platform load command, but one of the source files
416254885Sdumbbell    // does, then take the one from the file.
417254885Sdumbbell    if (!_minVersionCommandType)
418254885Sdumbbell      if (auto v = machoFile->minVersionLoadCommandKind())
419254885Sdumbbell        _minVersionCommandType = v;
420254885Sdumbbell  }
421254885Sdumbbell}
422254885Sdumbbell
423254885Sdumbbellvoid Util::assignAtomToSection(const DefinedAtom *atom) {
424254885Sdumbbell  if (atom->contentType() == DefinedAtom::typeMachHeader) {
425254885Sdumbbell    _machHeaderAliasAtoms.push_back(atom);
426254885Sdumbbell    // Assign atom to this section with this offset.
427254885Sdumbbell    AtomInfo ai = {atom, 0};
428254885Sdumbbell    sectionForAtom(atom)->atomsAndOffsets.push_back(ai);
429254885Sdumbbell  } else if (atom->contentType() == DefinedAtom::typeDSOHandle)
430254885Sdumbbell    _machHeaderAliasAtoms.push_back(atom);
431254885Sdumbbell  else
432254885Sdumbbell    appendAtom(sectionForAtom(atom), atom);
433254885Sdumbbell}
434254885Sdumbbell
435254885SdumbbellSegmentInfo *Util::segmentForName(StringRef segName) {
436254885Sdumbbell  for (SegmentInfo *si : _segmentInfos) {
437254885Sdumbbell    if ( si->name.equals(segName) )
438254885Sdumbbell      return si;
439254885Sdumbbell  }
440254885Sdumbbell  auto *info = new (_allocator) SegmentInfo(segName);
441254885Sdumbbell
442254885Sdumbbell  // Set the initial segment protection.
443254885Sdumbbell  if (segName.equals("__TEXT"))
444254885Sdumbbell    info->init_access = VM_PROT_READ | VM_PROT_EXECUTE;
445254885Sdumbbell  else if (segName.equals("__PAGEZERO"))
446254885Sdumbbell    info->init_access = 0;
447254885Sdumbbell  else if (segName.equals("__LINKEDIT"))
448254885Sdumbbell    info->init_access = VM_PROT_READ;
449254885Sdumbbell  else {
450254885Sdumbbell    // All others default to read-write
451254885Sdumbbell    info->init_access = VM_PROT_READ | VM_PROT_WRITE;
452254885Sdumbbell  }
453254885Sdumbbell
454254885Sdumbbell  // Set max segment protection
455258780Seadler  // Note, its overkill to use a switch statement here, but makes it so much
456254885Sdumbbell  // easier to use switch coverage to catch new cases.
457254885Sdumbbell  switch (_ctx.os()) {
458254885Sdumbbell    case lld::MachOLinkingContext::OS::unknown:
459254885Sdumbbell    case lld::MachOLinkingContext::OS::macOSX:
460254885Sdumbbell    case lld::MachOLinkingContext::OS::iOS_simulator:
461254885Sdumbbell      if (segName.equals("__PAGEZERO")) {
462254885Sdumbbell        info->max_access = 0;
463254885Sdumbbell        break;
464254885Sdumbbell      }
465254885Sdumbbell      // All others default to all
466254885Sdumbbell      info->max_access = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
467258780Seadler      break;
468254885Sdumbbell    case lld::MachOLinkingContext::OS::iOS:
469254885Sdumbbell      // iPhoneOS always uses same protection for max and initial
470254885Sdumbbell      info->max_access = info->init_access;
471254885Sdumbbell      break;
472254885Sdumbbell  }
473254885Sdumbbell  _segmentInfos.push_back(info);
474254885Sdumbbell  return info;
475254885Sdumbbell}
476254885Sdumbbell
477254885Sdumbbellunsigned Util::SegmentSorter::weight(const SegmentInfo *seg) {
478254885Sdumbbell return llvm::StringSwitch<unsigned>(seg->name)
479254885Sdumbbell    .Case("__PAGEZERO",  1)
480254885Sdumbbell    .Case("__TEXT",      2)
481254885Sdumbbell    .Case("__DATA",      3)
482254885Sdumbbell    .Default(100);
483254885Sdumbbell}
484254885Sdumbbell
485254885Sdumbbellbool Util::SegmentSorter::operator()(const SegmentInfo *left,
486254885Sdumbbell                                  const SegmentInfo *right) {
487254885Sdumbbell  return (weight(left) < weight(right));
488254885Sdumbbell}
489254885Sdumbbell
490254885Sdumbbellunsigned Util::TextSectionSorter::weight(const SectionInfo *sect) {
491254885Sdumbbell return llvm::StringSwitch<unsigned>(sect->sectionName)
492254885Sdumbbell    .Case("__text",         1)
493254885Sdumbbell    .Case("__stubs",        2)
494254885Sdumbbell    .Case("__stub_helper",  3)
495254885Sdumbbell    .Case("__const",        4)
496254885Sdumbbell    .Case("__cstring",      5)
497254885Sdumbbell    .Case("__unwind_info",  98)
498254885Sdumbbell    .Case("__eh_frame",     99)
499254885Sdumbbell    .Default(10);
500254885Sdumbbell}
501254885Sdumbbell
502254885Sdumbbellbool Util::TextSectionSorter::operator()(const SectionInfo *left,
503254885Sdumbbell                                         const SectionInfo *right) {
504254885Sdumbbell  return (weight(left) < weight(right));
505254885Sdumbbell}
506254885Sdumbbell
507254885Sdumbbellvoid Util::organizeSections() {
508254885Sdumbbell  // NOTE!: Keep this in sync with assignAddressesToSections.
509254885Sdumbbell  switch (_ctx.outputMachOType()) {
510254885Sdumbbell    case llvm::MachO::MH_EXECUTE:
511254885Sdumbbell      // Main executables, need a zero-page segment
512254885Sdumbbell      segmentForName("__PAGEZERO");
513254885Sdumbbell      // Fall into next case.
514254885Sdumbbell    case llvm::MachO::MH_DYLIB:
515254885Sdumbbell    case llvm::MachO::MH_BUNDLE:
516254885Sdumbbell      // All dynamic code needs TEXT segment to hold the load commands.
517254885Sdumbbell      segmentForName("__TEXT");
518254885Sdumbbell      break;
519254885Sdumbbell    default:
520254885Sdumbbell      break;
521254885Sdumbbell  }
522254885Sdumbbell  segmentForName("__LINKEDIT");
523254885Sdumbbell
524254885Sdumbbell  // Group sections into segments.
525254885Sdumbbell  for (SectionInfo *si : _sectionInfos) {
526254885Sdumbbell    SegmentInfo *seg = segmentForName(si->segmentName);
527254885Sdumbbell    seg->sections.push_back(si);
528254885Sdumbbell  }
529254885Sdumbbell  // Sort segments.
530254885Sdumbbell  std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
531254885Sdumbbell
532254885Sdumbbell  // Sort sections within segments.
533254885Sdumbbell  for (SegmentInfo *seg : _segmentInfos) {
534254885Sdumbbell    if (seg->name.equals("__TEXT")) {
535254885Sdumbbell      std::sort(seg->sections.begin(), seg->sections.end(),
536254885Sdumbbell                TextSectionSorter());
537254885Sdumbbell    }
538254885Sdumbbell  }
539254885Sdumbbell
540254885Sdumbbell  // Record final section indexes.
541254885Sdumbbell  uint32_t segmentIndex = 0;
542254885Sdumbbell  uint32_t sectionIndex = 1;
543254885Sdumbbell  for (SegmentInfo *seg : _segmentInfos) {
544254885Sdumbbell    seg->normalizedSegmentIndex = segmentIndex++;
545254885Sdumbbell    for (SectionInfo *sect : seg->sections)
546254885Sdumbbell      sect->finalSectionIndex = sectionIndex++;
547254885Sdumbbell  }
548254885Sdumbbell}
549254885Sdumbbell
550254885Sdumbbellvoid Util::layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr) {
551254885Sdumbbell  seg->address = addr;
552254885Sdumbbell  for (SectionInfo *sect : seg->sections) {
553254885Sdumbbell    sect->address = llvm::alignTo(addr, sect->alignment);
554254885Sdumbbell    addr = sect->address + sect->size;
555254885Sdumbbell  }
556254885Sdumbbell  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
557254885Sdumbbell}
558254885Sdumbbell
559254885Sdumbbell// __TEXT segment lays out backwards so padding is at front after load commands.
560254885Sdumbbellvoid Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
561254885Sdumbbell                                                               uint64_t &addr) {
562254885Sdumbbell  seg->address = addr;
563254885Sdumbbell  // Walks sections starting at end to calculate padding for start.
564254885Sdumbbell  int64_t taddr = 0;
565254885Sdumbbell  for (auto it = seg->sections.rbegin(); it != seg->sections.rend(); ++it) {
566254885Sdumbbell    SectionInfo *sect = *it;
567254885Sdumbbell    taddr -= sect->size;
568254885Sdumbbell    taddr = taddr & (0 - sect->alignment);
569254885Sdumbbell  }
570254885Sdumbbell  int64_t padding = taddr - hlcSize;
571254885Sdumbbell  while (padding < 0)
572254885Sdumbbell    padding += _ctx.pageSize();
573254885Sdumbbell  // Start assigning section address starting at padded offset.
574254885Sdumbbell  addr += (padding + hlcSize);
575254885Sdumbbell  for (SectionInfo *sect : seg->sections) {
576254885Sdumbbell    sect->address = llvm::alignTo(addr, sect->alignment);
577254885Sdumbbell    addr = sect->address + sect->size;
578254885Sdumbbell  }
579254885Sdumbbell  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
580254885Sdumbbell}
581254885Sdumbbell
582254885Sdumbbellvoid Util::assignAddressesToSections(const NormalizedFile &file) {
583254885Sdumbbell  // NOTE!: Keep this in sync with organizeSections.
584254885Sdumbbell  size_t hlcSize = headerAndLoadCommandsSize(file);
585254885Sdumbbell  uint64_t address = 0;
586254885Sdumbbell  for (SegmentInfo *seg : _segmentInfos) {
587254885Sdumbbell    if (seg->name.equals("__PAGEZERO")) {
588254885Sdumbbell      seg->size = _ctx.pageZeroSize();
589254885Sdumbbell      address += seg->size;
590254885Sdumbbell    }
591254885Sdumbbell    else if (seg->name.equals("__TEXT")) {
592254885Sdumbbell      // _ctx.baseAddress()  == 0 implies it was either unspecified or
593254885Sdumbbell      // pageZeroSize is also 0. In either case resetting address is safe.
594254885Sdumbbell      address = _ctx.baseAddress() ? _ctx.baseAddress() : address;
595254885Sdumbbell      layoutSectionsInTextSegment(hlcSize, seg, address);
596254885Sdumbbell    } else
597254885Sdumbbell      layoutSectionsInSegment(seg, address);
598254885Sdumbbell
599254885Sdumbbell    address = llvm::alignTo(address, _ctx.pageSize());
600254885Sdumbbell  }
601254885Sdumbbell  DEBUG_WITH_TYPE("WriterMachO-norm",
602254885Sdumbbell    llvm::dbgs() << "assignAddressesToSections()\n";
603254885Sdumbbell    for (SegmentInfo *sgi : _segmentInfos) {
604254885Sdumbbell      llvm::dbgs()  << "   address=" << llvm::format("0x%08llX", sgi->address)
605254885Sdumbbell                    << ", size="  << llvm::format("0x%08llX", sgi->size)
606254885Sdumbbell                    << ", segment-name='" << sgi->name
607254885Sdumbbell                    << "'\n";
608254885Sdumbbell      for (SectionInfo *si : sgi->sections) {
609254885Sdumbbell        llvm::dbgs()<< "      addr="  << llvm::format("0x%08llX", si->address)
610254885Sdumbbell                    << ", size="  << llvm::format("0x%08llX", si->size)
611254885Sdumbbell                    << ", section-name='" << si->sectionName
612254885Sdumbbell                    << "\n";
613254885Sdumbbell      }
614254885Sdumbbell    }
615254885Sdumbbell  );
616254885Sdumbbell}
617254885Sdumbbell
618254885Sdumbbellvoid Util::copySegmentInfo(NormalizedFile &file) {
619254885Sdumbbell  for (SegmentInfo *sgi : _segmentInfos) {
620254885Sdumbbell    Segment seg;
621254885Sdumbbell    seg.name    = sgi->name;
622254885Sdumbbell    seg.address = sgi->address;
623254885Sdumbbell    seg.size    = sgi->size;
624254885Sdumbbell    seg.init_access  = sgi->init_access;
625254885Sdumbbell    seg.max_access  = sgi->max_access;
626254885Sdumbbell    file.segments.push_back(seg);
627254885Sdumbbell  }
628254885Sdumbbell}
629254885Sdumbbell
630254885Sdumbbellvoid Util::appendSection(SectionInfo *si, NormalizedFile &file) {
631254885Sdumbbell   // Add new empty section to end of file.sections.
632254885Sdumbbell  Section temp;
633254885Sdumbbell  file.sections.push_back(std::move(temp));
634254885Sdumbbell  Section* normSect = &file.sections.back();
635254885Sdumbbell  // Copy fields to normalized section.
636254885Sdumbbell  normSect->segmentName   = si->segmentName;
637254885Sdumbbell  normSect->sectionName   = si->sectionName;
638254885Sdumbbell  normSect->type          = si->type;
639254885Sdumbbell  normSect->attributes    = si->attributes;
640254885Sdumbbell  normSect->address       = si->address;
641254885Sdumbbell  normSect->alignment     = si->alignment;
642254885Sdumbbell  // Record where normalized section is.
643254885Sdumbbell  si->normalizedSectionIndex = file.sections.size()-1;
644254885Sdumbbell}
645254885Sdumbbell
646254885Sdumbbellvoid Util::copySectionContent(NormalizedFile &file) {
647254885Sdumbbell  const bool r = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
648254885Sdumbbell
649254885Sdumbbell  // Utility function for ArchHandler to find address of atom in output file.
650254885Sdumbbell  auto addrForAtom = [&] (const Atom &atom) -> uint64_t {
651254885Sdumbbell    auto pos = _atomToAddress.find(&atom);
652254885Sdumbbell    assert(pos != _atomToAddress.end());
653254885Sdumbbell    return pos->second;
654254885Sdumbbell  };
655254885Sdumbbell
656254885Sdumbbell  auto sectionAddrForAtom = [&] (const Atom &atom) -> uint64_t {
657254885Sdumbbell    for (const SectionInfo *sectInfo : _sectionInfos)
658254885Sdumbbell      for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets)
659254885Sdumbbell        if (atomInfo.atom == &atom)
660254885Sdumbbell          return sectInfo->address;
661254885Sdumbbell    llvm_unreachable("atom not assigned to section");
662254885Sdumbbell  };
663254885Sdumbbell
664254885Sdumbbell  for (SectionInfo *si : _sectionInfos) {
665254885Sdumbbell    Section *normSect = &file.sections[si->normalizedSectionIndex];
666254885Sdumbbell    if (isZeroFillSection(si->type)) {
667254885Sdumbbell      const uint8_t *empty = nullptr;
668254885Sdumbbell      normSect->content = llvm::makeArrayRef(empty, si->size);
669254885Sdumbbell      continue;
670254885Sdumbbell    }
671254885Sdumbbell    // Copy content from atoms to content buffer for section.
672254885Sdumbbell    llvm::MutableArrayRef<uint8_t> sectionContent;
673254885Sdumbbell    if (si->size) {
674254885Sdumbbell      uint8_t *sectContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
675254885Sdumbbell      sectionContent = llvm::MutableArrayRef<uint8_t>(sectContent, si->size);
676254885Sdumbbell      normSect->content = sectionContent;
677254885Sdumbbell    }
678254885Sdumbbell    for (AtomInfo &ai : si->atomsAndOffsets) {
679254885Sdumbbell      if (!ai.atom->size()) {
680254885Sdumbbell        assert(ai.atom->begin() == ai.atom->end() &&
681254885Sdumbbell               "Cannot have references without content");
682254885Sdumbbell        continue;
683254885Sdumbbell      }
684254885Sdumbbell      auto atomContent = sectionContent.slice(ai.offsetInSection,
685254885Sdumbbell                                              ai.atom->size());
686254885Sdumbbell      _archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
687254885Sdumbbell                                       sectionAddrForAtom, _ctx.baseAddress(),
688254885Sdumbbell                                       atomContent);
689254885Sdumbbell    }
690254885Sdumbbell  }
691254885Sdumbbell}
692254885Sdumbbell
693254885Sdumbbellvoid Util::copySectionInfo(NormalizedFile &file) {
694254885Sdumbbell  file.sections.reserve(_sectionInfos.size());
695254885Sdumbbell  // Write sections grouped by segment.
696254885Sdumbbell  for (SegmentInfo *sgi : _segmentInfos) {
697254885Sdumbbell    for (SectionInfo *si : sgi->sections) {
698254885Sdumbbell      appendSection(si, file);
699254885Sdumbbell    }
700254885Sdumbbell  }
701254885Sdumbbell}
702254885Sdumbbell
703254885Sdumbbellvoid Util::updateSectionInfo(NormalizedFile &file) {
704254885Sdumbbell  file.sections.reserve(_sectionInfos.size());
705254885Sdumbbell  // sections grouped by segment.
706254885Sdumbbell  for (SegmentInfo *sgi : _segmentInfos) {
707254885Sdumbbell    Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
708254885Sdumbbell    normSeg->address = sgi->address;
709254885Sdumbbell    normSeg->size = sgi->size;
710254885Sdumbbell    for (SectionInfo *si : sgi->sections) {
711254885Sdumbbell      Section *normSect = &file.sections[si->normalizedSectionIndex];
712254885Sdumbbell      normSect->address = si->address;
713254885Sdumbbell    }
714254885Sdumbbell  }
715254885Sdumbbell}
716254885Sdumbbell
717254885Sdumbbellvoid Util::copyEntryPointAddress(NormalizedFile &nFile) {
718254885Sdumbbell  if (!_entryAtom) {
719254885Sdumbbell    nFile.entryAddress = 0;
720254885Sdumbbell    return;
721254885Sdumbbell  }
722254885Sdumbbell
723254885Sdumbbell  if (_ctx.outputTypeHasEntry()) {
724254885Sdumbbell    if (_archHandler.isThumbFunction(*_entryAtom))
725254885Sdumbbell      nFile.entryAddress = (_atomToAddress[_entryAtom] | 1);
726254885Sdumbbell    else
727254885Sdumbbell      nFile.entryAddress = _atomToAddress[_entryAtom];
728254885Sdumbbell  }
729254885Sdumbbell}
730254885Sdumbbell
731254885Sdumbbellvoid Util::buildAtomToAddressMap() {
732254885Sdumbbell  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
733254885Sdumbbell                   << "assign atom addresses:\n");
734254885Sdumbbell  const bool lookForEntry = _ctx.outputTypeHasEntry();
735254885Sdumbbell  for (SectionInfo *sect : _sectionInfos) {
736254885Sdumbbell    for (const AtomInfo &info : sect->atomsAndOffsets) {
737254885Sdumbbell      _atomToAddress[info.atom] = sect->address + info.offsetInSection;
738254885Sdumbbell      if (lookForEntry && (info.atom->contentType() == DefinedAtom::typeCode) &&
739254885Sdumbbell          (info.atom->size() != 0) &&
740254885Sdumbbell          info.atom->name() == _ctx.entrySymbolName()) {
741254885Sdumbbell        _entryAtom = info.atom;
742254885Sdumbbell      }
743254885Sdumbbell      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
744254885Sdumbbell                      << "   address="
745254885Sdumbbell                      << llvm::format("0x%016X", _atomToAddress[info.atom])
746254885Sdumbbell                      << llvm::format("    0x%09lX", info.atom)
747254885Sdumbbell                      << ", file=#"
748254885Sdumbbell                      << info.atom->file().ordinal()
749254885Sdumbbell                      << ", atom=#"
750254885Sdumbbell                      << info.atom->ordinal()
751254885Sdumbbell                      << ", name="
752254885Sdumbbell                      << info.atom->name()
753254885Sdumbbell                      << ", type="
754254885Sdumbbell                      << info.atom->contentType()
755254885Sdumbbell                      << "\n");
756254885Sdumbbell    }
757254885Sdumbbell  }
758254885Sdumbbell  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
759254885Sdumbbell                  << "assign header alias atom addresses:\n");
760254885Sdumbbell  for (const Atom *atom : _machHeaderAliasAtoms) {
761254885Sdumbbell    _atomToAddress[atom] = _ctx.baseAddress();
762254885Sdumbbell#ifndef NDEBUG
763254885Sdumbbell    if (auto *definedAtom = dyn_cast<DefinedAtom>(atom)) {
764254885Sdumbbell      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
765254885Sdumbbell                      << "   address="
766254885Sdumbbell                      << llvm::format("0x%016X", _atomToAddress[atom])
767254885Sdumbbell                      << llvm::format("    0x%09lX", atom)
768254885Sdumbbell                      << ", file=#"
769254885Sdumbbell                      << definedAtom->file().ordinal()
770254885Sdumbbell                      << ", atom=#"
771254885Sdumbbell                      << definedAtom->ordinal()
772254885Sdumbbell                      << ", name="
773254885Sdumbbell                      << definedAtom->name()
774258780Seadler                      << ", type="
775254885Sdumbbell                      << definedAtom->contentType()
776254885Sdumbbell                      << "\n");
777254885Sdumbbell    } else {
778254885Sdumbbell      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
779254885Sdumbbell                      << "   address="
780254885Sdumbbell                      << llvm::format("0x%016X", _atomToAddress[atom])
781254885Sdumbbell                      << " atom=" << atom
782254885Sdumbbell                      << " name=" << atom->name() << "\n");
783254885Sdumbbell    }
784254885Sdumbbell#endif
785254885Sdumbbell  }
786254885Sdumbbell}
787254885Sdumbbell
788254885Sdumbbelluint16_t Util::descBits(const DefinedAtom* atom) {
789254885Sdumbbell  uint16_t desc = 0;
790254885Sdumbbell  switch (atom->merge()) {
791254885Sdumbbell  case lld::DefinedAtom::mergeNo:
792254885Sdumbbell  case lld::DefinedAtom::mergeAsTentative:
793254885Sdumbbell    break;
794254885Sdumbbell  case lld::DefinedAtom::mergeAsWeak:
795254885Sdumbbell  case lld::DefinedAtom::mergeAsWeakAndAddressUsed:
796254885Sdumbbell    desc |= N_WEAK_DEF;
797254885Sdumbbell    break;
798254885Sdumbbell  case lld::DefinedAtom::mergeSameNameAndSize:
799254885Sdumbbell  case lld::DefinedAtom::mergeByLargestSection:
800258780Seadler  case lld::DefinedAtom::mergeByContent:
801254885Sdumbbell    llvm_unreachable("Unsupported DefinedAtom::merge()");
802254885Sdumbbell    break;
803254885Sdumbbell  }
804254885Sdumbbell  if (atom->contentType() == lld::DefinedAtom::typeResolver)
805254885Sdumbbell    desc |= N_SYMBOL_RESOLVER;
806258780Seadler  if (atom->contentType() == lld::DefinedAtom::typeMachHeader)
807254885Sdumbbell    desc |= REFERENCED_DYNAMICALLY;
808254885Sdumbbell  if (_archHandler.isThumbFunction(*atom))
809254885Sdumbbell    desc |= N_ARM_THUMB_DEF;
810254885Sdumbbell  if (atom->deadStrip() == DefinedAtom::deadStripNever) {
811254885Sdumbbell    if ((atom->contentType() != DefinedAtom::typeInitializerPtr)
812254885Sdumbbell     && (atom->contentType() != DefinedAtom::typeTerminatorPtr))
813254885Sdumbbell    desc |= N_NO_DEAD_STRIP;
814254885Sdumbbell  }
815254885Sdumbbell  return desc;
816254885Sdumbbell}
817254885Sdumbbell
818254885Sdumbbellbool Util::AtomSorter::operator()(const AtomAndIndex &left,
819254885Sdumbbell                                  const AtomAndIndex &right) {
820254885Sdumbbell  return (left.atom->name().compare(right.atom->name()) < 0);
821254885Sdumbbell}
822254885Sdumbbell
823254885Sdumbbellllvm::Error Util::getSymbolTableRegion(const DefinedAtom* atom,
824254885Sdumbbell                                       bool &inGlobalsRegion,
825254885Sdumbbell                                       SymbolScope &scope) {
826254885Sdumbbell  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
827254885Sdumbbell  switch (atom->scope()) {
828254885Sdumbbell  case Atom::scopeTranslationUnit:
829254885Sdumbbell    scope = 0;
830254885Sdumbbell    inGlobalsRegion = false;
831254885Sdumbbell    return llvm::Error();
832254885Sdumbbell  case Atom::scopeLinkageUnit:
833254885Sdumbbell    if ((_ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) &&
834254885Sdumbbell        _ctx.exportSymbolNamed(atom->name())) {
835254885Sdumbbell      return llvm::make_error<GenericError>(
836254885Sdumbbell                          Twine("cannot export hidden symbol ") + atom->name());
837254885Sdumbbell    }
838254885Sdumbbell    if (rMode) {
839254885Sdumbbell      if (_ctx.keepPrivateExterns()) {
840254885Sdumbbell        // -keep_private_externs means keep in globals region as N_PEXT.
841254885Sdumbbell        scope = N_PEXT | N_EXT;
842254885Sdumbbell        inGlobalsRegion = true;
843254885Sdumbbell        return llvm::Error();
844254885Sdumbbell      }
845254885Sdumbbell    }
846254885Sdumbbell    // scopeLinkageUnit symbols are no longer global once linked.
847254885Sdumbbell    scope = N_PEXT;
848254885Sdumbbell    inGlobalsRegion = false;
849254885Sdumbbell    return llvm::Error();
850254885Sdumbbell  case Atom::scopeGlobal:
851254885Sdumbbell    if (_ctx.exportRestrictMode()) {
852254885Sdumbbell      if (_ctx.exportSymbolNamed(atom->name())) {
853254885Sdumbbell        scope = N_EXT;
854254885Sdumbbell        inGlobalsRegion = true;
855254885Sdumbbell        return llvm::Error();
856254885Sdumbbell      } else {
857254885Sdumbbell        scope = N_PEXT;
858254885Sdumbbell        inGlobalsRegion = false;
859254885Sdumbbell        return llvm::Error();
860254885Sdumbbell      }
861254885Sdumbbell    } else {
862254885Sdumbbell      scope = N_EXT;
863254885Sdumbbell      inGlobalsRegion = true;
864254885Sdumbbell      return llvm::Error();
865254885Sdumbbell    }
866254885Sdumbbell    break;
867254885Sdumbbell  }
868254885Sdumbbell  llvm_unreachable("atom->scope() unknown enum value");
869254885Sdumbbell}
870254885Sdumbbell
871254885Sdumbbellllvm::Error Util::addSymbols(const lld::File &atomFile,
872254885Sdumbbell                             NormalizedFile &file) {
873254885Sdumbbell  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
874254885Sdumbbell  // Mach-O symbol table has three regions: locals, globals, undefs.
875254885Sdumbbell
876254885Sdumbbell  // Add all local (non-global) symbols in address order
877254885Sdumbbell  std::vector<AtomAndIndex> globals;
878254885Sdumbbell  globals.reserve(512);
879254885Sdumbbell  for (SectionInfo *sect : _sectionInfos) {
880254885Sdumbbell    for (const AtomInfo &info : sect->atomsAndOffsets) {
881254885Sdumbbell      const DefinedAtom *atom = info.atom;
882254885Sdumbbell      if (!atom->name().empty()) {
883254885Sdumbbell        SymbolScope symbolScope;
884254885Sdumbbell        bool inGlobalsRegion;
885254885Sdumbbell        if (auto ec = getSymbolTableRegion(atom, inGlobalsRegion, symbolScope)){
886254885Sdumbbell          return ec;
887254885Sdumbbell        }
888254885Sdumbbell        if (inGlobalsRegion) {
889254885Sdumbbell          AtomAndIndex ai = { atom, sect->finalSectionIndex, symbolScope };
890254885Sdumbbell          globals.push_back(ai);
891254885Sdumbbell        } else {
892254885Sdumbbell          Symbol sym;
893254885Sdumbbell          sym.name  = atom->name();
894254885Sdumbbell          sym.type  = N_SECT;
895254885Sdumbbell          sym.scope = symbolScope;
896254885Sdumbbell          sym.sect  = sect->finalSectionIndex;
897254885Sdumbbell          sym.desc  = descBits(atom);
898254885Sdumbbell          sym.value = _atomToAddress[atom];
899254885Sdumbbell          _atomToSymbolIndex[atom] = file.localSymbols.size();
900254885Sdumbbell          file.localSymbols.push_back(sym);
901254885Sdumbbell        }
902254885Sdumbbell      } else if (rMode && _archHandler.needsLocalSymbolInRelocatableFile(atom)){
903254885Sdumbbell        // Create 'Lxxx' labels for anonymous atoms if archHandler says so.
904254885Sdumbbell        static unsigned tempNum = 1;
905254885Sdumbbell        char tmpName[16];
906254885Sdumbbell        sprintf(tmpName, "L%04u", tempNum++);
907254885Sdumbbell        StringRef tempRef(tmpName);
908254885Sdumbbell        Symbol sym;
909254885Sdumbbell        sym.name  = tempRef.copy(file.ownedAllocations);
910254885Sdumbbell        sym.type  = N_SECT;
911254885Sdumbbell        sym.scope = 0;
912254885Sdumbbell        sym.sect  = sect->finalSectionIndex;
913254885Sdumbbell        sym.desc  = 0;
914254885Sdumbbell        sym.value = _atomToAddress[atom];
915254885Sdumbbell        _atomToSymbolIndex[atom] = file.localSymbols.size();
916254885Sdumbbell        file.localSymbols.push_back(sym);
917254885Sdumbbell      }
918254885Sdumbbell    }
919254885Sdumbbell  }
920254885Sdumbbell
921254885Sdumbbell  // Sort global symbol alphabetically, then add to symbol table.
922254885Sdumbbell  std::sort(globals.begin(), globals.end(), AtomSorter());
923254885Sdumbbell  const uint32_t globalStartIndex = file.localSymbols.size();
924254885Sdumbbell  for (AtomAndIndex &ai : globals) {
925254885Sdumbbell    Symbol sym;
926254885Sdumbbell    sym.name  = ai.atom->name();
927254885Sdumbbell    sym.type  = N_SECT;
928254885Sdumbbell    sym.scope = ai.scope;
929254885Sdumbbell    sym.sect  = ai.index;
930254885Sdumbbell    sym.desc  = descBits(static_cast<const DefinedAtom*>(ai.atom));
931254885Sdumbbell    sym.value = _atomToAddress[ai.atom];
932254885Sdumbbell    _atomToSymbolIndex[ai.atom] = globalStartIndex + file.globalSymbols.size();
933254885Sdumbbell    file.globalSymbols.push_back(sym);
934254885Sdumbbell  }
935254885Sdumbbell
936254885Sdumbbell  // Sort undefined symbol alphabetically, then add to symbol table.
937254885Sdumbbell  std::vector<AtomAndIndex> undefs;
938254885Sdumbbell  undefs.reserve(128);
939254885Sdumbbell  for (const UndefinedAtom *atom : atomFile.undefined()) {
940254885Sdumbbell    AtomAndIndex ai = { atom, 0, N_EXT };
941254885Sdumbbell    undefs.push_back(ai);
942254885Sdumbbell  }
943254885Sdumbbell  for (const SharedLibraryAtom *atom : atomFile.sharedLibrary()) {
944254885Sdumbbell    AtomAndIndex ai = { atom, 0, N_EXT };
945254885Sdumbbell    undefs.push_back(ai);
946254885Sdumbbell  }
947254885Sdumbbell  std::sort(undefs.begin(), undefs.end(), AtomSorter());
948254885Sdumbbell  const uint32_t start = file.globalSymbols.size() + file.localSymbols.size();
949254885Sdumbbell  for (AtomAndIndex &ai : undefs) {
950254885Sdumbbell    Symbol sym;
951254885Sdumbbell    uint16_t desc = 0;
952254885Sdumbbell    if (!rMode) {
953254885Sdumbbell      uint8_t ordinal = 0;
954254885Sdumbbell      if (!_ctx.useFlatNamespace())
955254885Sdumbbell        ordinal = dylibOrdinal(dyn_cast<SharedLibraryAtom>(ai.atom));
956254885Sdumbbell      llvm::MachO::SET_LIBRARY_ORDINAL(desc, ordinal);
957254885Sdumbbell    }
958254885Sdumbbell    sym.name  = ai.atom->name();
959254885Sdumbbell    sym.type  = N_UNDF;
960254885Sdumbbell    sym.scope = ai.scope;
961254885Sdumbbell    sym.sect  = 0;
962254885Sdumbbell    sym.desc  = desc;
963254885Sdumbbell    sym.value = 0;
964254885Sdumbbell    _atomToSymbolIndex[ai.atom] = file.undefinedSymbols.size() + start;
965254885Sdumbbell    file.undefinedSymbols.push_back(sym);
966254885Sdumbbell  }
967254885Sdumbbell
968254885Sdumbbell  return llvm::Error();
969254885Sdumbbell}
970254885Sdumbbell
971254885Sdumbbellconst Atom *Util::targetOfLazyPointer(const DefinedAtom *lpAtom) {
972254885Sdumbbell  for (const Reference *ref : *lpAtom) {
973254885Sdumbbell    if (_archHandler.isLazyPointer(*ref)) {
974254885Sdumbbell      return ref->target();
975254885Sdumbbell    }
976254885Sdumbbell  }
977254885Sdumbbell  return nullptr;
978254885Sdumbbell}
979254885Sdumbbell
980254885Sdumbbellconst Atom *Util::targetOfStub(const DefinedAtom *stubAtom) {
981254885Sdumbbell  for (const Reference *ref : *stubAtom) {
982254885Sdumbbell    if (const Atom *ta = ref->target()) {
983254885Sdumbbell      if (const DefinedAtom *lpAtom = dyn_cast<DefinedAtom>(ta)) {
984254885Sdumbbell        const Atom *target = targetOfLazyPointer(lpAtom);
985254885Sdumbbell        if (target)
986254885Sdumbbell          return target;
987254885Sdumbbell      }
988254885Sdumbbell    }
989254885Sdumbbell  }
990254885Sdumbbell  return nullptr;
991254885Sdumbbell}
992254885Sdumbbell
993254885Sdumbbellvoid Util::addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file) {
994254885Sdumbbell  for (SectionInfo *si : _sectionInfos) {
995254885Sdumbbell    Section &normSect = file.sections[si->normalizedSectionIndex];
996254885Sdumbbell    switch (si->type) {
997254885Sdumbbell    case llvm::MachO::S_NON_LAZY_SYMBOL_POINTERS:
998254885Sdumbbell      for (const AtomInfo &info : si->atomsAndOffsets) {
999254885Sdumbbell        bool foundTarget = false;
1000254885Sdumbbell        for (const Reference *ref : *info.atom) {
1001254885Sdumbbell          const Atom *target = ref->target();
1002254885Sdumbbell          if (target) {
1003254885Sdumbbell            if (isa<const SharedLibraryAtom>(target)) {
1004254885Sdumbbell              uint32_t index = _atomToSymbolIndex[target];
1005254885Sdumbbell              normSect.indirectSymbols.push_back(index);
1006254885Sdumbbell              foundTarget = true;
1007254885Sdumbbell            } else {
1008254885Sdumbbell              normSect.indirectSymbols.push_back(
1009254885Sdumbbell                                            llvm::MachO::INDIRECT_SYMBOL_LOCAL);
1010254885Sdumbbell            }
1011254885Sdumbbell          }
1012254885Sdumbbell        }
1013254885Sdumbbell        if (!foundTarget) {
1014254885Sdumbbell          normSect.indirectSymbols.push_back(
1015254885Sdumbbell                                             llvm::MachO::INDIRECT_SYMBOL_ABS);
1016254885Sdumbbell        }
1017254885Sdumbbell      }
1018254885Sdumbbell      break;
1019254885Sdumbbell    case llvm::MachO::S_LAZY_SYMBOL_POINTERS:
1020254885Sdumbbell      for (const AtomInfo &info : si->atomsAndOffsets) {
1021254885Sdumbbell        const Atom *target = targetOfLazyPointer(info.atom);
1022254885Sdumbbell        if (target) {
1023254885Sdumbbell          uint32_t index = _atomToSymbolIndex[target];
1024254885Sdumbbell          normSect.indirectSymbols.push_back(index);
1025254885Sdumbbell        }
1026254885Sdumbbell      }
1027254885Sdumbbell      break;
1028254885Sdumbbell    case llvm::MachO::S_SYMBOL_STUBS:
1029254885Sdumbbell      for (const AtomInfo &info : si->atomsAndOffsets) {
1030254885Sdumbbell        const Atom *target = targetOfStub(info.atom);
1031254885Sdumbbell        if (target) {
1032254885Sdumbbell          uint32_t index = _atomToSymbolIndex[target];
1033254885Sdumbbell          normSect.indirectSymbols.push_back(index);
1034254885Sdumbbell        }
1035254885Sdumbbell      }
1036254885Sdumbbell      break;
1037254885Sdumbbell    default:
1038254885Sdumbbell      break;
1039254885Sdumbbell    }
1040254885Sdumbbell  }
1041254885Sdumbbell}
1042254885Sdumbbell
1043254885Sdumbbellvoid Util::addDependentDylibs(const lld::File &atomFile,NormalizedFile &nFile) {
1044254885Sdumbbell  // Scan all imported symbols and build up list of dylibs they are from.
1045254885Sdumbbell  int ordinal = 1;
1046254885Sdumbbell  for (const SharedLibraryAtom *slAtom : atomFile.sharedLibrary()) {
1047254885Sdumbbell    StringRef loadPath = slAtom->loadName();
1048254885Sdumbbell    DylibPathToInfo::iterator pos = _dylibInfo.find(loadPath);
1049254885Sdumbbell    if (pos == _dylibInfo.end()) {
1050254885Sdumbbell      DylibInfo info;
1051254885Sdumbbell      bool flatNamespaceAtom = &slAtom->file() == _ctx.flatNamespaceFile();
1052254885Sdumbbell
1053254885Sdumbbell      // If we're in -flat_namespace mode (or this atom came from the flat
1054254885Sdumbbell      // namespace file under -undefined dynamic_lookup) then use the flat
1055254885Sdumbbell      // lookup ordinal.
1056254885Sdumbbell      if (flatNamespaceAtom || _ctx.useFlatNamespace())
1057254885Sdumbbell        info.ordinal = BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
1058254885Sdumbbell      else
1059254885Sdumbbell        info.ordinal = ordinal++;
1060254885Sdumbbell      info.hasWeak = slAtom->canBeNullAtRuntime();
1061254885Sdumbbell      info.hasNonWeak = !info.hasWeak;
1062254885Sdumbbell      _dylibInfo[loadPath] = info;
1063254885Sdumbbell
1064254885Sdumbbell      // Unless this was a flat_namespace atom, record the source dylib.
1065258780Seadler      if (!flatNamespaceAtom) {
1066254885Sdumbbell        DependentDylib depInfo;
1067254885Sdumbbell        depInfo.path = loadPath;
1068254885Sdumbbell        depInfo.kind = llvm::MachO::LC_LOAD_DYLIB;
1069254885Sdumbbell        depInfo.currentVersion = _ctx.dylibCurrentVersion(loadPath);
1070254885Sdumbbell        depInfo.compatVersion = _ctx.dylibCompatVersion(loadPath);
1071254885Sdumbbell        nFile.dependentDylibs.push_back(depInfo);
1072254885Sdumbbell      }
1073254885Sdumbbell    } else {
1074254885Sdumbbell      if ( slAtom->canBeNullAtRuntime() )
1075254885Sdumbbell        pos->second.hasWeak = true;
1076254885Sdumbbell      else
1077254885Sdumbbell        pos->second.hasNonWeak = true;
1078254885Sdumbbell    }
1079254885Sdumbbell  }
1080254885Sdumbbell  // Automatically weak link dylib in which all symbols are weak (canBeNull).
1081254885Sdumbbell  for (DependentDylib &dep : nFile.dependentDylibs) {
1082254885Sdumbbell    DylibInfo &info = _dylibInfo[dep.path];
1083254885Sdumbbell    if (info.hasWeak && !info.hasNonWeak)
1084254885Sdumbbell      dep.kind = llvm::MachO::LC_LOAD_WEAK_DYLIB;
1085254885Sdumbbell    else if (_ctx.isUpwardDylib(dep.path))
1086254885Sdumbbell      dep.kind = llvm::MachO::LC_LOAD_UPWARD_DYLIB;
1087254885Sdumbbell  }
1088254885Sdumbbell}
1089254885Sdumbbell
1090254885Sdumbbellint Util::dylibOrdinal(const SharedLibraryAtom *sa) {
1091254885Sdumbbell  return _dylibInfo[sa->loadName()].ordinal;
1092254885Sdumbbell}
1093254885Sdumbbell
1094254885Sdumbbellvoid Util::segIndexForSection(const SectionInfo *sect, uint8_t &segmentIndex,
1095254885Sdumbbell                                                  uint64_t &segmentStartAddr) {
1096254885Sdumbbell  segmentIndex = 0;
1097254885Sdumbbell  for (const SegmentInfo *seg : _segmentInfos) {
1098254885Sdumbbell    if ((seg->address <= sect->address)
1099254885Sdumbbell      && (seg->address+seg->size >= sect->address+sect->size)) {
1100254885Sdumbbell      segmentStartAddr = seg->address;
1101254885Sdumbbell      return;
1102254885Sdumbbell    }
1103254885Sdumbbell    ++segmentIndex;
1104254885Sdumbbell  }
1105254885Sdumbbell  llvm_unreachable("section not in any segment");
1106254885Sdumbbell}
1107254885Sdumbbell
1108254885Sdumbbelluint32_t Util::sectionIndexForAtom(const Atom *atom) {
1109254885Sdumbbell  uint64_t address = _atomToAddress[atom];
1110254885Sdumbbell  for (const SectionInfo *si : _sectionInfos) {
1111254885Sdumbbell    if ((si->address <= address) && (address < si->address+si->size))
1112254885Sdumbbell      return si->finalSectionIndex;
1113254885Sdumbbell  }
1114254885Sdumbbell  llvm_unreachable("atom not in any section");
1115254885Sdumbbell}
1116254885Sdumbbell
1117254885Sdumbbellvoid Util::addSectionRelocs(const lld::File &, NormalizedFile &file) {
1118254885Sdumbbell  if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
1119254885Sdumbbell    return;
1120254885Sdumbbell
1121254885Sdumbbell  // Utility function for ArchHandler to find symbol index for an atom.
1122254885Sdumbbell  auto symIndexForAtom = [&] (const Atom &atom) -> uint32_t {
1123254885Sdumbbell    auto pos = _atomToSymbolIndex.find(&atom);
1124254885Sdumbbell    assert(pos != _atomToSymbolIndex.end());
1125254885Sdumbbell    return pos->second;
1126254885Sdumbbell  };
1127254885Sdumbbell
1128254885Sdumbbell  // Utility function for ArchHandler to find section index for an atom.
1129254885Sdumbbell  auto sectIndexForAtom = [&] (const Atom &atom) -> uint32_t {
1130254885Sdumbbell    return sectionIndexForAtom(&atom);
1131254885Sdumbbell  };
1132254885Sdumbbell
1133254885Sdumbbell  // Utility function for ArchHandler to find address of atom in output file.
1134254885Sdumbbell  auto addressForAtom = [&] (const Atom &atom) -> uint64_t {
1135254885Sdumbbell    auto pos = _atomToAddress.find(&atom);
1136254885Sdumbbell    assert(pos != _atomToAddress.end());
1137254885Sdumbbell    return pos->second;
1138254885Sdumbbell  };
1139254885Sdumbbell
1140254885Sdumbbell  for (SectionInfo *si : _sectionInfos) {
1141254885Sdumbbell    Section &normSect = file.sections[si->normalizedSectionIndex];
1142254885Sdumbbell    for (const AtomInfo &info : si->atomsAndOffsets) {
1143254885Sdumbbell      const DefinedAtom *atom = info.atom;
1144254885Sdumbbell      for (const Reference *ref : *atom) {
1145254885Sdumbbell        // Skip emitting relocs for sections which are always able to be
1146254885Sdumbbell        // implicitly regenerated and where the relocation targets an address
1147254885Sdumbbell        // which is defined.
1148254885Sdumbbell        if (si->relocsToDefinedCanBeImplicit && isa<DefinedAtom>(ref->target()))
1149254885Sdumbbell          continue;
1150254885Sdumbbell        _archHandler.appendSectionRelocations(*atom, info.offsetInSection, *ref,
1151254885Sdumbbell                                              symIndexForAtom,
1152254885Sdumbbell                                              sectIndexForAtom,
1153254885Sdumbbell                                              addressForAtom,
1154254885Sdumbbell                                              normSect.relocations);
1155254885Sdumbbell      }
1156254885Sdumbbell    }
1157254885Sdumbbell  }
1158254885Sdumbbell}
1159254885Sdumbbell
1160254885Sdumbbellvoid Util::addFunctionStarts(const lld::File &, NormalizedFile &file) {
1161254885Sdumbbell  if (!_ctx.generateFunctionStartsLoadCommand())
1162254885Sdumbbell    return;
1163254885Sdumbbell  file.functionStarts.reserve(8192);
1164254885Sdumbbell  // Delta compress function starts, starting with the mach header symbol.
1165254885Sdumbbell  const uint64_t badAddress = ~0ULL;
1166254885Sdumbbell  uint64_t addr = badAddress;
1167254885Sdumbbell  for (SectionInfo *si : _sectionInfos) {
1168254885Sdumbbell    for (const AtomInfo &info : si->atomsAndOffsets) {
1169254885Sdumbbell      auto type = info.atom->contentType();
1170254885Sdumbbell      if (type == DefinedAtom::typeMachHeader) {
1171254885Sdumbbell        addr = _atomToAddress[info.atom];
1172254885Sdumbbell        continue;
1173254885Sdumbbell      }
1174254885Sdumbbell      if (type != DefinedAtom::typeCode)
1175254885Sdumbbell        continue;
1176254885Sdumbbell      assert(addr != badAddress && "Missing mach header symbol");
1177254885Sdumbbell      // Skip atoms which have 0 size.  This is so that LC_FUNCTION_STARTS
1178254885Sdumbbell      // can't spill in to the next section.
1179254885Sdumbbell      if (!info.atom->size())
1180254885Sdumbbell        continue;
1181254885Sdumbbell      uint64_t nextAddr = _atomToAddress[info.atom];
1182254885Sdumbbell      if (_archHandler.isThumbFunction(*info.atom))
1183254885Sdumbbell        nextAddr |= 1;
1184254885Sdumbbell      uint64_t delta = nextAddr - addr;
1185254885Sdumbbell      if (delta) {
1186254885Sdumbbell        ByteBuffer buffer;
1187254885Sdumbbell        buffer.append_uleb128(delta);
1188254885Sdumbbell        file.functionStarts.insert(file.functionStarts.end(), buffer.bytes(),
1189254885Sdumbbell                                   buffer.bytes() + buffer.size());
1190254885Sdumbbell      }
1191254885Sdumbbell      addr = nextAddr;
1192254885Sdumbbell    }
1193254885Sdumbbell  }
1194254885Sdumbbell
1195254885Sdumbbell  // Null terminate, and pad to pointer size for this arch.
1196254885Sdumbbell  file.functionStarts.push_back(0);
1197254885Sdumbbell
1198254885Sdumbbell  auto size = file.functionStarts.size();
1199254885Sdumbbell  for (unsigned i = size, e = llvm::alignTo(size, _ctx.is64Bit() ? 8 : 4);
1200254885Sdumbbell       i != e; ++i)
1201254885Sdumbbell    file.functionStarts.push_back(0);
1202254885Sdumbbell}
1203254885Sdumbbell
1204254885Sdumbbellvoid Util::buildDataInCodeArray(const lld::File &, NormalizedFile &file) {
1205254885Sdumbbell  if (!_ctx.generateDataInCodeLoadCommand())
1206254885Sdumbbell    return;
1207254885Sdumbbell  for (SectionInfo *si : _sectionInfos) {
1208254885Sdumbbell    for (const AtomInfo &info : si->atomsAndOffsets) {
1209254885Sdumbbell      // Atoms that contain data-in-code have "transition" references
1210254885Sdumbbell      // which mark a point where the embedded data starts of ends.
1211254885Sdumbbell      // This needs to be converted to the mach-o format which is an array
1212254885Sdumbbell      // of data-in-code ranges.
1213254885Sdumbbell      uint32_t startOffset = 0;
1214254885Sdumbbell      DataRegionType mode = DataRegionType(0);
1215254885Sdumbbell      for (const Reference *ref : *info.atom) {
1216254885Sdumbbell        if (ref->kindNamespace() != Reference::KindNamespace::mach_o)
1217254885Sdumbbell          continue;
1218254885Sdumbbell        if (_archHandler.isDataInCodeTransition(ref->kindValue())) {
1219254885Sdumbbell          DataRegionType nextMode = (DataRegionType)ref->addend();
1220254885Sdumbbell          if (mode != nextMode) {
1221254885Sdumbbell            if (mode != 0) {
1222254885Sdumbbell              // Found end data range, so make range entry.
1223254885Sdumbbell              DataInCode entry;
1224254885Sdumbbell              entry.offset = si->address + info.offsetInSection + startOffset;
1225254885Sdumbbell              entry.length = ref->offsetInAtom() - startOffset;
1226254885Sdumbbell              entry.kind   = mode;
1227254885Sdumbbell              file.dataInCode.push_back(entry);
1228254885Sdumbbell            }
1229254885Sdumbbell          }
1230254885Sdumbbell          mode = nextMode;
1231254885Sdumbbell          startOffset = ref->offsetInAtom();
1232254885Sdumbbell        }
1233254885Sdumbbell      }
1234254885Sdumbbell      if (mode != 0) {
1235254885Sdumbbell        // Function ends with data (no end transition).
1236254885Sdumbbell        DataInCode entry;
1237254885Sdumbbell        entry.offset = si->address + info.offsetInSection + startOffset;
1238254885Sdumbbell        entry.length = info.atom->size() - startOffset;
1239254885Sdumbbell        entry.kind   = mode;
1240254885Sdumbbell        file.dataInCode.push_back(entry);
1241254885Sdumbbell      }
1242254885Sdumbbell    }
1243254885Sdumbbell  }
1244254885Sdumbbell}
1245254885Sdumbbell
1246254885Sdumbbellvoid Util::addRebaseAndBindingInfo(const lld::File &atomFile,
1247254885Sdumbbell                                                        NormalizedFile &nFile) {
1248254885Sdumbbell  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1249254885Sdumbbell    return;
1250254885Sdumbbell
1251254885Sdumbbell  uint8_t segmentIndex;
1252254885Sdumbbell  uint64_t segmentStartAddr;
1253254885Sdumbbell  for (SectionInfo *sect : _sectionInfos) {
1254254885Sdumbbell    segIndexForSection(sect, segmentIndex, segmentStartAddr);
1255254885Sdumbbell    for (const AtomInfo &info : sect->atomsAndOffsets) {
1256254885Sdumbbell      const DefinedAtom *atom = info.atom;
1257254885Sdumbbell      for (const Reference *ref : *atom) {
1258254885Sdumbbell        uint64_t segmentOffset = _atomToAddress[atom] + ref->offsetInAtom()
1259254885Sdumbbell                                - segmentStartAddr;
1260254885Sdumbbell        const Atom* targ = ref->target();
1261254885Sdumbbell        if (_archHandler.isPointer(*ref)) {
1262254885Sdumbbell          // A pointer to a DefinedAtom requires rebasing.
1263254885Sdumbbell          if (isa<DefinedAtom>(targ)) {
1264254885Sdumbbell            RebaseLocation rebase;
1265254885Sdumbbell            rebase.segIndex = segmentIndex;
1266254885Sdumbbell            rebase.segOffset = segmentOffset;
1267254885Sdumbbell            rebase.kind = llvm::MachO::REBASE_TYPE_POINTER;
1268254885Sdumbbell            nFile.rebasingInfo.push_back(rebase);
1269254885Sdumbbell          }
1270254885Sdumbbell          // A pointer to an SharedLibraryAtom requires binding.
1271254885Sdumbbell          if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1272254885Sdumbbell            BindLocation bind;
1273254885Sdumbbell            bind.segIndex = segmentIndex;
1274254885Sdumbbell            bind.segOffset = segmentOffset;
1275254885Sdumbbell            bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1276254885Sdumbbell            bind.canBeNull = sa->canBeNullAtRuntime();
1277254885Sdumbbell            bind.ordinal = dylibOrdinal(sa);
1278254885Sdumbbell            bind.symbolName = targ->name();
1279254885Sdumbbell            bind.addend = ref->addend();
1280254885Sdumbbell            nFile.bindingInfo.push_back(bind);
1281254885Sdumbbell          }
1282254885Sdumbbell        }
1283254885Sdumbbell        else if (_archHandler.isLazyPointer(*ref)) {
1284254885Sdumbbell          BindLocation bind;
1285254885Sdumbbell          if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1286254885Sdumbbell            bind.ordinal = dylibOrdinal(sa);
1287254885Sdumbbell          } else {
1288254885Sdumbbell            bind.ordinal = llvm::MachO::BIND_SPECIAL_DYLIB_SELF;
1289254885Sdumbbell          }
1290254885Sdumbbell          bind.segIndex = segmentIndex;
1291254885Sdumbbell          bind.segOffset = segmentOffset;
1292254885Sdumbbell          bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1293254885Sdumbbell          bind.canBeNull = false; //sa->canBeNullAtRuntime();
1294254885Sdumbbell          bind.symbolName = targ->name();
1295254885Sdumbbell          bind.addend = ref->addend();
1296254885Sdumbbell          nFile.lazyBindingInfo.push_back(bind);
1297254885Sdumbbell        }
1298254885Sdumbbell      }
1299254885Sdumbbell    }
1300254885Sdumbbell  }
1301254885Sdumbbell}
1302254885Sdumbbell
1303254885Sdumbbellvoid Util::addExportInfo(const lld::File &atomFile, NormalizedFile &nFile) {
1304254885Sdumbbell  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1305254885Sdumbbell    return;
1306254885Sdumbbell
1307254885Sdumbbell  for (SectionInfo *sect : _sectionInfos) {
1308254885Sdumbbell    for (const AtomInfo &info : sect->atomsAndOffsets) {
1309254885Sdumbbell      const DefinedAtom *atom = info.atom;
1310254885Sdumbbell      if (atom->scope() != Atom::scopeGlobal)
1311254885Sdumbbell        continue;
1312254885Sdumbbell      if (_ctx.exportRestrictMode()) {
1313254885Sdumbbell        if (!_ctx.exportSymbolNamed(atom->name()))
1314254885Sdumbbell          continue;
1315254885Sdumbbell      }
1316254885Sdumbbell      Export exprt;
1317254885Sdumbbell      exprt.name = atom->name();
1318254885Sdumbbell      exprt.offset = _atomToAddress[atom] - _ctx.baseAddress();
1319254885Sdumbbell      exprt.kind = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
1320254885Sdumbbell      if (atom->merge() == DefinedAtom::mergeAsWeak)
1321254885Sdumbbell        exprt.flags = EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
1322254885Sdumbbell      else
1323254885Sdumbbell        exprt.flags = 0;
1324254885Sdumbbell      exprt.otherOffset = 0;
1325254885Sdumbbell      exprt.otherName = StringRef();
1326254885Sdumbbell      nFile.exportInfo.push_back(exprt);
1327254885Sdumbbell    }
1328254885Sdumbbell  }
1329254885Sdumbbell}
1330254885Sdumbbell
1331254885Sdumbbelluint32_t Util::fileFlags() {
1332254885Sdumbbell  // FIXME: these need to determined at runtime.
1333254885Sdumbbell  if (_ctx.outputMachOType() == MH_OBJECT) {
1334254885Sdumbbell    return _subsectionsViaSymbols ? MH_SUBSECTIONS_VIA_SYMBOLS : 0;
1335254885Sdumbbell  } else {
1336254885Sdumbbell    uint32_t flags = MH_DYLDLINK;
1337254885Sdumbbell    if (!_ctx.useFlatNamespace())
1338254885Sdumbbell        flags |= MH_TWOLEVEL | MH_NOUNDEFS;
1339254885Sdumbbell    if ((_ctx.outputMachOType() == MH_EXECUTE) && _ctx.PIE())
1340254885Sdumbbell      flags |= MH_PIE;
1341254885Sdumbbell    if (_hasTLVDescriptors)
1342254885Sdumbbell      flags |= (MH_PIE | MH_HAS_TLV_DESCRIPTORS);
1343254885Sdumbbell    return flags;
1344254885Sdumbbell  }
1345254885Sdumbbell}
1346254885Sdumbbell
1347254885Sdumbbell} // end anonymous namespace
1348254885Sdumbbell
1349254885Sdumbbellnamespace lld {
1350254885Sdumbbellnamespace mach_o {
1351254885Sdumbbellnamespace normalized {
1352254885Sdumbbell
1353254885Sdumbbell/// Convert a set of Atoms into a normalized mach-o file.
1354254885Sdumbbellllvm::Expected<std::unique_ptr<NormalizedFile>>
1355254885SdumbbellnormalizedFromAtoms(const lld::File &atomFile,
1356254885Sdumbbell                                           const MachOLinkingContext &context) {
1357254885Sdumbbell  // The util object buffers info until the normalized file can be made.
1358254885Sdumbbell  Util util(context);
1359254885Sdumbbell  util.processDefinedAtoms(atomFile);
1360254885Sdumbbell  util.organizeSections();
1361254885Sdumbbell
1362254885Sdumbbell  std::unique_ptr<NormalizedFile> f(new NormalizedFile());
1363254885Sdumbbell  NormalizedFile &normFile = *f.get();
1364254885Sdumbbell  normFile.arch = context.arch();
1365254885Sdumbbell  normFile.fileType = context.outputMachOType();
1366254885Sdumbbell  normFile.flags = util.fileFlags();
1367254885Sdumbbell  normFile.stackSize = context.stackSize();
1368254885Sdumbbell  normFile.installName = context.installName();
1369254885Sdumbbell  normFile.currentVersion = context.currentVersion();
1370254885Sdumbbell  normFile.compatVersion = context.compatibilityVersion();
1371254885Sdumbbell  normFile.os = context.os();
1372254885Sdumbbell
1373254885Sdumbbell  // If we are emitting an object file, then the min version is the maximum
1374254885Sdumbbell  // of the min's of all the source files and the cmdline.
1375254885Sdumbbell  if (normFile.fileType == llvm::MachO::MH_OBJECT)
1376254885Sdumbbell    normFile.minOSverson = std::max(context.osMinVersion(), util.minVersion());
1377254885Sdumbbell  else
1378254885Sdumbbell    normFile.minOSverson = context.osMinVersion();
1379254885Sdumbbell
1380254885Sdumbbell  normFile.minOSVersionKind = util.minVersionCommandType();
1381254885Sdumbbell
1382254885Sdumbbell  normFile.sdkVersion = context.sdkVersion();
1383254885Sdumbbell  normFile.sourceVersion = context.sourceVersion();
1384254885Sdumbbell
1385254885Sdumbbell  if (context.generateVersionLoadCommand() &&
1386254885Sdumbbell      context.os() != MachOLinkingContext::OS::unknown)
1387254885Sdumbbell    normFile.hasMinVersionLoadCommand = true;
1388254885Sdumbbell  else if (normFile.fileType == llvm::MachO::MH_OBJECT &&
1389254885Sdumbbell           util.allSourceFilesHaveMinVersions() &&
1390254885Sdumbbell           ((normFile.os != MachOLinkingContext::OS::unknown) ||
1391254885Sdumbbell            util.minVersionCommandType())) {
1392254885Sdumbbell    // If we emit an object file, then it should contain a min version load
1393254885Sdumbbell    // command if all of the source files also contained min version commands.
1394254885Sdumbbell    // Also, we either need to have a platform, or found a platform from the
1395254885Sdumbbell    // source object files.
1396254885Sdumbbell    normFile.hasMinVersionLoadCommand = true;
1397254885Sdumbbell  }
1398254885Sdumbbell  normFile.generateDataInCodeLoadCommand =
1399254885Sdumbbell    context.generateDataInCodeLoadCommand();
1400254885Sdumbbell  normFile.pageSize = context.pageSize();
1401254885Sdumbbell  normFile.rpaths = context.rpaths();
1402254885Sdumbbell  util.addDependentDylibs(atomFile, normFile);
1403254885Sdumbbell  util.copySegmentInfo(normFile);
1404254885Sdumbbell  util.copySectionInfo(normFile);
1405254885Sdumbbell  util.assignAddressesToSections(normFile);
1406254885Sdumbbell  util.buildAtomToAddressMap();
1407254885Sdumbbell  util.updateSectionInfo(normFile);
1408254885Sdumbbell  util.copySectionContent(normFile);
1409254885Sdumbbell  if (auto ec = util.addSymbols(atomFile, normFile)) {
1410254885Sdumbbell    return std::move(ec);
1411254885Sdumbbell  }
1412254885Sdumbbell  util.addIndirectSymbols(atomFile, normFile);
1413254885Sdumbbell  util.addRebaseAndBindingInfo(atomFile, normFile);
1414254885Sdumbbell  util.addExportInfo(atomFile, normFile);
1415254885Sdumbbell  util.addSectionRelocs(atomFile, normFile);
1416254885Sdumbbell  util.addFunctionStarts(atomFile, normFile);
1417254885Sdumbbell  util.buildDataInCodeArray(atomFile, normFile);
1418254885Sdumbbell  util.copyEntryPointAddress(normFile);
1419254885Sdumbbell
1420254885Sdumbbell  return std::move(f);
1421254885Sdumbbell}
1422254885Sdumbbell
1423254885Sdumbbell} // namespace normalized
1424254885Sdumbbell} // namespace mach_o
1425254885Sdumbbell} // namespace lld
1426254885Sdumbbell