Coverage Report

Created: 2019-05-19 14:56

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp ------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
///
10
/// \file Converts from in-memory Atoms to in-memory normalized mach-o.
11
///
12
///                  +------------+
13
///                  | normalized |
14
///                  +------------+
15
///                        ^
16
///                        |
17
///                        |
18
///                    +-------+
19
///                    | Atoms |
20
///                    +-------+
21
22
#include "ArchHandler.h"
23
#include "DebugInfo.h"
24
#include "MachONormalizedFile.h"
25
#include "MachONormalizedFileBinaryUtils.h"
26
#include "lld/Common/LLVM.h"
27
#include "lld/Core/Error.h"
28
#include "llvm/ADT/StringRef.h"
29
#include "llvm/ADT/StringSwitch.h"
30
#include "llvm/BinaryFormat/MachO.h"
31
#include "llvm/Support/Casting.h"
32
#include "llvm/Support/Debug.h"
33
#include "llvm/Support/ErrorHandling.h"
34
#include "llvm/Support/Format.h"
35
#include <map>
36
#include <system_error>
37
#include <unordered_set>
38
39
using llvm::StringRef;
40
using llvm::isa;
41
using namespace llvm::MachO;
42
using namespace lld::mach_o::normalized;
43
using namespace lld;
44
45
namespace {
46
47
struct AtomInfo {
48
  const DefinedAtom  *atom;
49
  uint64_t            offsetInSection;
50
};
51
52
struct SectionInfo {
53
  SectionInfo(StringRef seg, StringRef sect, SectionType type,
54
              const MachOLinkingContext &ctxt, uint32_t attr,
55
              bool relocsToDefinedCanBeImplicit);
56
57
  StringRef                 segmentName;
58
  StringRef                 sectionName;
59
  SectionType               type;
60
  uint32_t                  attributes;
61
  uint64_t                  address;
62
  uint64_t                  size;
63
  uint16_t                  alignment;
64
65
  /// If this is set, the any relocs in this section which point to defined
66
  /// addresses can be implicitly generated.  This is the case for the
67
  /// __eh_frame section where references to the function can be implicit if the
68
  /// function is defined.
69
  bool                      relocsToDefinedCanBeImplicit;
70
71
72
  std::vector<AtomInfo>     atomsAndOffsets;
73
  uint32_t                  normalizedSectionIndex;
74
  uint32_t                  finalSectionIndex;
75
};
76
77
SectionInfo::SectionInfo(StringRef sg, StringRef sct, SectionType t,
78
                         const MachOLinkingContext &ctxt, uint32_t attrs,
79
                         bool relocsToDefinedCanBeImplicit)
80
 : segmentName(sg), sectionName(sct), type(t), attributes(attrs),
81
                 address(0), size(0), alignment(1),
82
                 relocsToDefinedCanBeImplicit(relocsToDefinedCanBeImplicit),
83
377
                 normalizedSectionIndex(0), finalSectionIndex(0) {
84
377
  uint16_t align = 1;
85
377
  if (ctxt.sectionAligned(segmentName, sectionName, align)) {
86
3
    alignment = align;
87
3
  }
88
377
}
89
90
struct SegmentInfo {
91
  SegmentInfo(StringRef name);
92
93
  StringRef                  name;
94
  uint64_t                   address;
95
  uint64_t                   size;
96
  uint32_t                   init_access;
97
  uint32_t                   max_access;
98
  std::vector<SectionInfo*>  sections;
99
  uint32_t                   normalizedSegmentIndex;
100
};
101
102
SegmentInfo::SegmentInfo(StringRef n)
103
 : name(n), address(0), size(0), init_access(0), max_access(0),
104
469
   normalizedSegmentIndex(0) {
105
469
}
106
107
class Util {
108
public:
109
  Util(const MachOLinkingContext &ctxt)
110
      : _ctx(ctxt), _archHandler(ctxt.archHandler()), _entryAtom(nullptr),
111
169
        _hasTLVDescriptors(false), _subsectionsViaSymbols(true) {}
112
  ~Util();
113
114
  void      processDefinedAtoms(const lld::File &atomFile);
115
  void      processAtomAttributes(const DefinedAtom *atom);
116
  void      assignAtomToSection(const DefinedAtom *atom);
117
  void      organizeSections();
118
  void      assignAddressesToSections(const NormalizedFile &file);
119
  uint32_t  fileFlags();
120
  void      copySegmentInfo(NormalizedFile &file);
121
  void      copySectionInfo(NormalizedFile &file);
122
  void      updateSectionInfo(NormalizedFile &file);
123
  void      buildAtomToAddressMap();
124
  llvm::Error synthesizeDebugNotes(NormalizedFile &file);
125
  llvm::Error addSymbols(const lld::File &atomFile, NormalizedFile &file);
126
  void      addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file);
127
  void      addRebaseAndBindingInfo(const lld::File &, NormalizedFile &file);
128
  void      addExportInfo(const lld::File &, NormalizedFile &file);
129
  void      addSectionRelocs(const lld::File &, NormalizedFile &file);
130
  void      addFunctionStarts(const lld::File &, NormalizedFile &file);
131
  void      buildDataInCodeArray(const lld::File &, NormalizedFile &file);
132
  void      addDependentDylibs(const lld::File &, NormalizedFile &file);
133
  void      copyEntryPointAddress(NormalizedFile &file);
134
  void      copySectionContent(NormalizedFile &file);
135
136
73
  bool allSourceFilesHaveMinVersions() const {
137
73
    return _allSourceFilesHaveMinVersions;
138
73
  }
139
140
73
  uint32_t minVersion() const {
141
73
    return _minVersion;
142
73
  }
143
144
172
  LoadCommandType minVersionCommandType() const {
145
172
    return _minVersionCommandType;
146
172
  }
147
148
private:
149
  typedef std::map<DefinedAtom::ContentType, SectionInfo*> TypeToSection;
150
  typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
151
152
  struct DylibInfo { int ordinal; bool hasWeak; bool hasNonWeak; };
153
  typedef llvm::StringMap<DylibInfo> DylibPathToInfo;
154
155
  SectionInfo *sectionForAtom(const DefinedAtom*);
156
  SectionInfo *getRelocatableSection(DefinedAtom::ContentType type);
157
  SectionInfo *getFinalSection(DefinedAtom::ContentType type);
158
  void         appendAtom(SectionInfo *sect, const DefinedAtom *atom);
159
  SegmentInfo *segmentForName(StringRef segName);
160
  void         layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr);
161
  void         layoutSectionsInTextSegment(size_t, SegmentInfo *, uint64_t &);
162
  void         copySectionContent(SectionInfo *si, ContentBytes &content);
163
  uint16_t     descBits(const DefinedAtom* atom);
164
  int          dylibOrdinal(const SharedLibraryAtom *sa);
165
  void         segIndexForSection(const SectionInfo *sect,
166
                             uint8_t &segmentIndex, uint64_t &segmentStartAddr);
167
  const Atom  *targetOfLazyPointer(const DefinedAtom *lpAtom);
168
  const Atom  *targetOfStub(const DefinedAtom *stubAtom);
169
  llvm::Error getSymbolTableRegion(const DefinedAtom* atom,
170
                                   bool &inGlobalsRegion,
171
                                   SymbolScope &symbolScope);
172
  void         appendSection(SectionInfo *si, NormalizedFile &file);
173
  uint32_t     sectionIndexForAtom(const Atom *atom);
174
  void fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
175
                           NormalizedFile &file);
176
177
  typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;
178
  struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };
179
  struct AtomSorter {
180
    bool operator()(const AtomAndIndex &left, const AtomAndIndex &right);
181
  };
182
  struct SegmentSorter {
183
    bool operator()(const SegmentInfo *left, const SegmentInfo *right);
184
    static unsigned weight(const SegmentInfo *);
185
  };
186
  struct TextSectionSorter {
187
    bool operator()(const SectionInfo *left, const SectionInfo *right);
188
    static unsigned weight(const SectionInfo *);
189
  };
190
191
  const MachOLinkingContext &_ctx;
192
  mach_o::ArchHandler          &_archHandler;
193
  llvm::BumpPtrAllocator        _allocator;
194
  std::vector<SectionInfo*>     _sectionInfos;
195
  std::vector<SegmentInfo*>     _segmentInfos;
196
  TypeToSection                 _sectionMap;
197
  std::vector<SectionInfo*>     _customSections;
198
  AtomToAddress                 _atomToAddress;
199
  DylibPathToInfo               _dylibInfo;
200
  const DefinedAtom            *_entryAtom;
201
  AtomToIndex                   _atomToSymbolIndex;
202
  std::vector<const Atom *>     _machHeaderAliasAtoms;
203
  bool                          _hasTLVDescriptors;
204
  bool                          _subsectionsViaSymbols;
205
  bool                          _allSourceFilesHaveMinVersions = true;
206
  LoadCommandType               _minVersionCommandType = (LoadCommandType)0;
207
  uint32_t                      _minVersion = 0;
208
  std::vector<lld::mach_o::Stab> _stabs;
209
};
210
211
169
Util::~Util() {
212
169
  // The SectionInfo structs are BumpPtr allocated, but atomsAndOffsets needs
213
169
  // to be deleted.
214
377
  for (SectionInfo *si : _sectionInfos) {
215
377
    // clear() destroys vector elements, but does not deallocate.
216
377
    // Instead use swap() to deallocate vector buffer.
217
377
    std::vector<AtomInfo> empty;
218
377
    si->atomsAndOffsets.swap(empty);
219
377
  }
220
169
  // The SegmentInfo structs are BumpPtr allocated, but sections needs
221
169
  // to be deleted.
222
469
  for (SegmentInfo *sgi : _segmentInfos) {
223
469
    std::vector<SectionInfo*> empty2;
224
469
    sgi->sections.swap(empty2);
225
469
  }
226
169
}
227
228
139
SectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
229
139
  StringRef segmentName;
230
139
  StringRef sectionName;
231
139
  SectionType sectionType;
232
139
  SectionAttr sectionAttrs;
233
139
  bool relocsToDefinedCanBeImplicit;
234
139
235
139
  // Use same table used by when parsing .o files.
236
139
  relocatableSectionInfoForContentType(type, segmentName, sectionName,
237
139
                                       sectionType, sectionAttrs,
238
139
                                       relocsToDefinedCanBeImplicit);
239
139
  // If we already have a SectionInfo with this name, re-use it.
240
139
  // This can happen if two ContentType map to the same mach-o section.
241
139
  for (auto sect : _sectionMap) {
242
108
    if (sect.second->sectionName.equals(sectionName) &&
243
108
        
sect.second->segmentName.equals(segmentName)2
) {
244
2
      return sect.second;
245
2
    }
246
108
  }
247
139
  // Otherwise allocate new SectionInfo object.
248
139
  auto *sect = new (_allocator)
249
137
      SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs,
250
137
                  relocsToDefinedCanBeImplicit);
251
137
  _sectionInfos.push_back(sect);
252
137
  _sectionMap[type] = sect;
253
137
  return sect;
254
139
}
255
256
#define ENTRY(seg, sect, type, atomType) \
257
  {seg, sect, type, DefinedAtom::atomType }
258
259
struct MachOFinalSectionFromAtomType {
260
  StringRef                 segmentName;
261
  StringRef                 sectionName;
262
  SectionType               sectionType;
263
  DefinedAtom::ContentType  atomType;
264
};
265
266
const MachOFinalSectionFromAtomType sectsToAtomType[] = {
267
  ENTRY("__TEXT", "__text",           S_REGULAR,          typeCode),
268
  ENTRY("__TEXT", "__text",           S_REGULAR,          typeMachHeader),
269
  ENTRY("__TEXT", "__cstring",        S_CSTRING_LITERALS, typeCString),
270
  ENTRY("__TEXT", "__ustring",        S_REGULAR,          typeUTF16String),
271
  ENTRY("__TEXT", "__const",          S_REGULAR,          typeConstant),
272
  ENTRY("__TEXT", "__const",          S_4BYTE_LITERALS,   typeLiteral4),
273
  ENTRY("__TEXT", "__const",          S_8BYTE_LITERALS,   typeLiteral8),
274
  ENTRY("__TEXT", "__const",          S_16BYTE_LITERALS,  typeLiteral16),
275
  ENTRY("__TEXT", "__stubs",          S_SYMBOL_STUBS,     typeStub),
276
  ENTRY("__TEXT", "__stub_helper",    S_REGULAR,          typeStubHelper),
277
  ENTRY("__TEXT", "__gcc_except_tab", S_REGULAR,          typeLSDA),
278
  ENTRY("__TEXT", "__eh_frame",       S_COALESCED,        typeCFI),
279
  ENTRY("__TEXT", "__unwind_info",    S_REGULAR,          typeProcessedUnwindInfo),
280
  ENTRY("__DATA", "__data",           S_REGULAR,          typeData),
281
  ENTRY("__DATA", "__const",          S_REGULAR,          typeConstData),
282
  ENTRY("__DATA", "__cfstring",       S_REGULAR,          typeCFString),
283
  ENTRY("__DATA", "__la_symbol_ptr",  S_LAZY_SYMBOL_POINTERS,
284
                                                          typeLazyPointer),
285
  ENTRY("__DATA", "__mod_init_func",  S_MOD_INIT_FUNC_POINTERS,
286
                                                          typeInitializerPtr),
287
  ENTRY("__DATA", "__mod_term_func",  S_MOD_TERM_FUNC_POINTERS,
288
                                                          typeTerminatorPtr),
289
  ENTRY("__DATA", "__got",            S_NON_LAZY_SYMBOL_POINTERS,
290
                                                          typeGOT),
291
  ENTRY("__DATA", "__nl_symbol_ptr",  S_NON_LAZY_SYMBOL_POINTERS,
292
                                                          typeNonLazyPointer),
293
  ENTRY("__DATA", "__thread_vars",    S_THREAD_LOCAL_VARIABLES,
294
                                                          typeThunkTLV),
295
  ENTRY("__DATA", "__thread_data",    S_THREAD_LOCAL_REGULAR,
296
                                                          typeTLVInitialData),
297
  ENTRY("__DATA", "__thread_ptrs",    S_THREAD_LOCAL_VARIABLE_POINTERS,
298
                                                          typeTLVInitializerPtr),
299
  ENTRY("__DATA", "__thread_bss",     S_THREAD_LOCAL_ZEROFILL,
300
                                                         typeTLVInitialZeroFill),
301
  ENTRY("__DATA", "__bss",            S_ZEROFILL,         typeZeroFill),
302
  ENTRY("__DATA", "__interposing",    S_INTERPOSING,      typeInterposingTuples),
303
};
304
#undef ENTRY
305
306
376
SectionInfo *Util::getFinalSection(DefinedAtom::ContentType atomType) {
307
2.14k
  for (auto &p : sectsToAtomType) {
308
2.14k
    if (p.atomType != atomType)
309
1.76k
      continue;
310
376
    SectionAttr sectionAttrs = 0;
311
376
    switch (atomType) {
312
376
    case DefinedAtom::typeMachHeader:
313
277
    case DefinedAtom::typeCode:
314
277
    case DefinedAtom::typeStub:
315
277
    case DefinedAtom::typeStubHelper:
316
277
      sectionAttrs = S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS;
317
277
      break;
318
277
    case DefinedAtom::typeThunkTLV:
319
1
      _hasTLVDescriptors = true;
320
1
      break;
321
277
    default:
322
98
      break;
323
376
    }
324
376
    // If we already have a SectionInfo with this name, re-use it.
325
376
    // This can happen if two ContentType map to the same mach-o section.
326
542
    
for (auto sect : _sectionMap)376
{
327
542
      if (sect.second->sectionName.equals(p.sectionName) &&
328
542
          
sect.second->segmentName.equals(p.segmentName)151
) {
329
150
        return sect.second;
330
150
      }
331
542
    }
332
376
    // Otherwise allocate new SectionInfo object.
333
376
    auto *sect = new (_allocator) SectionInfo(
334
226
        p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs,
335
226
        /* relocsToDefinedCanBeImplicit */ false);
336
226
    _sectionInfos.push_back(sect);
337
226
    _sectionMap[atomType] = sect;
338
226
    return sect;
339
376
  }
340
376
  
llvm_unreachable0
("content type not yet supported");
341
376
}
342
343
746
SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
344
746
  if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
345
726
    // Section for this atom is derived from content type.
346
726
    DefinedAtom::ContentType type = atom->contentType();
347
726
    auto pos = _sectionMap.find(type);
348
726
    if ( pos != _sectionMap.end() )
349
211
      return pos->second;
350
515
    bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
351
515
    return rMode ? 
getRelocatableSection(type)139
:
getFinalSection(type)376
;
352
515
  } else {
353
20
    // This atom needs to be in a custom section.
354
20
    StringRef customName = atom->customSectionName();
355
20
    // Look to see if we have already allocated the needed custom section.
356
20
    for(SectionInfo *sect : _customSections) {
357
8
      const DefinedAtom *firstAtom = sect->atomsAndOffsets.front().atom;
358
8
      if (firstAtom->customSectionName().equals(customName)) {
359
6
        return sect;
360
6
      }
361
8
    }
362
20
    // Not found, so need to create a new custom section.
363
20
    size_t seperatorIndex = customName.find('/');
364
14
    assert(seperatorIndex != StringRef::npos);
365
14
    StringRef segName = customName.slice(0, seperatorIndex);
366
14
    StringRef sectName = customName.drop_front(seperatorIndex + 1);
367
14
    auto *sect =
368
14
        new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx,
369
14
                                     0, /* relocsToDefinedCanBeImplicit */ false);
370
14
    _customSections.push_back(sect);
371
14
    _sectionInfos.push_back(sect);
372
14
    return sect;
373
20
  }
374
746
}
375
376
650
void Util::appendAtom(SectionInfo *sect, const DefinedAtom *atom) {
377
650
  // Figure out offset for atom in this section given alignment constraints.
378
650
  uint64_t offset = sect->size;
379
650
  DefinedAtom::Alignment atomAlign = atom->alignment();
380
650
  uint64_t align = atomAlign.value;
381
650
  uint64_t requiredModulus = atomAlign.modulus;
382
650
  uint64_t currentModulus = (offset % align);
383
650
  if ( currentModulus != requiredModulus ) {
384
9
    if ( requiredModulus > currentModulus )
385
0
      offset += requiredModulus-currentModulus;
386
9
    else
387
9
      offset += align+requiredModulus-currentModulus;
388
9
  }
389
650
  // Record max alignment of any atom in this section.
390
650
  if (align > sect->alignment)
391
206
    sect->alignment = atomAlign.value;
392
650
  // Assign atom to this section with this offset.
393
650
  AtomInfo ai = {atom, offset};
394
650
  sect->atomsAndOffsets.push_back(ai);
395
650
  // Update section size to include this atom.
396
650
  sect->size = offset + atom->size();
397
650
}
398
399
169
void Util::processDefinedAtoms(const lld::File &atomFile) {
400
842
  for (const DefinedAtom *atom : atomFile.defined()) {
401
842
    processAtomAttributes(atom);
402
842
    assignAtomToSection(atom);
403
842
  }
404
169
}
405
406
842
void Util::processAtomAttributes(const DefinedAtom *atom) {
407
842
  if (auto *machoFile = dyn_cast<mach_o::MachOFile>(&atom->file())) {
408
596
    // If the file doesn't use subsections via symbols, then make sure we don't
409
596
    // add that flag to the final output file if we have a relocatable file.
410
596
    if (!machoFile->subsectionsViaSymbols())
411
23
      _subsectionsViaSymbols = false;
412
596
413
596
    // All the source files must have min versions for us to output an object
414
596
    // file with a min version.
415
596
    if (auto v = machoFile->minVersion())
416
3
      _minVersion = std::max(_minVersion, v);
417
593
    else
418
593
      _allSourceFilesHaveMinVersions = false;
419
596
420
596
    // If we don't have a platform load command, but one of the source files
421
596
    // does, then take the one from the file.
422
596
    if (!_minVersionCommandType)
423
585
      if (auto v = machoFile->minVersionLoadCommandKind())
424
9
        _minVersionCommandType = v;
425
596
  }
426
842
}
427
428
842
void Util::assignAtomToSection(const DefinedAtom *atom) {
429
842
  if (atom->contentType() == DefinedAtom::typeMachHeader) {
430
96
    _machHeaderAliasAtoms.push_back(atom);
431
96
    // Assign atom to this section with this offset.
432
96
    AtomInfo ai = {atom, 0};
433
96
    sectionForAtom(atom)->atomsAndOffsets.push_back(ai);
434
746
  } else if (atom->contentType() == DefinedAtom::typeDSOHandle)
435
96
    _machHeaderAliasAtoms.push_back(atom);
436
650
  else
437
650
    appendAtom(sectionForAtom(atom), atom);
438
842
}
439
440
693
SegmentInfo *Util::segmentForName(StringRef segName) {
441
904
  for (SegmentInfo *si : _segmentInfos) {
442
904
    if ( si->name.equals(segName) )
443
224
      return si;
444
904
  }
445
693
  auto *info = new (_allocator) SegmentInfo(segName);
446
469
447
469
  // Set the initial segment protection.
448
469
  if (segName.equals("__TEXT"))
449
161
    info->init_access = VM_PROT_READ | VM_PROT_EXECUTE;
450
308
  else if (segName.equals("__PAGEZERO"))
451
51
    info->init_access = 0;
452
257
  else if (segName.equals("__LINKEDIT"))
453
169
    info->init_access = VM_PROT_READ;
454
88
  else {
455
88
    // All others default to read-write
456
88
    info->init_access = VM_PROT_READ | VM_PROT_WRITE;
457
88
  }
458
469
459
469
  // Set max segment protection
460
469
  // Note, its overkill to use a switch statement here, but makes it so much
461
469
  // easier to use switch coverage to catch new cases.
462
469
  switch (_ctx.os()) {
463
469
    case lld::MachOLinkingContext::OS::unknown:
464
434
    case lld::MachOLinkingContext::OS::macOSX:
465
434
    case lld::MachOLinkingContext::OS::iOS_simulator:
466
434
      if (segName.equals("__PAGEZERO")) {
467
45
        info->max_access = 0;
468
45
        break;
469
45
      }
470
389
      // All others default to all
471
389
      info->max_access = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
472
389
      break;
473
389
    case lld::MachOLinkingContext::OS::iOS:
474
35
      // iPhoneOS always uses same protection for max and initial
475
35
      info->max_access = info->init_access;
476
35
      break;
477
469
  }
478
469
  _segmentInfos.push_back(info);
479
469
  return info;
480
469
}
481
482
716
unsigned Util::SegmentSorter::weight(const SegmentInfo *seg) {
483
716
 return llvm::StringSwitch<unsigned>(seg->name)
484
716
    .Case("__PAGEZERO",  1)
485
716
    .Case("__TEXT",      2)
486
716
    .Case("__DATA",      3)
487
716
    .Default(100);
488
716
}
489
490
bool Util::SegmentSorter::operator()(const SegmentInfo *left,
491
358
                                  const SegmentInfo *right) {
492
358
  return (weight(left) < weight(right));
493
358
}
494
495
286
unsigned Util::TextSectionSorter::weight(const SectionInfo *sect) {
496
286
 return llvm::StringSwitch<unsigned>(sect->sectionName)
497
286
    .Case("__text",         1)
498
286
    .Case("__stubs",        2)
499
286
    .Case("__stub_helper",  3)
500
286
    .Case("__const",        4)
501
286
    .Case("__cstring",      5)
502
286
    .Case("__unwind_info",  98)
503
286
    .Case("__eh_frame",     99)
504
286
    .Default(10);
505
286
}
506
507
bool Util::TextSectionSorter::operator()(const SectionInfo *left,
508
143
                                         const SectionInfo *right) {
509
143
  return (weight(left) < weight(right));
510
143
}
511
512
169
void Util::organizeSections() {
513
169
  // NOTE!: Keep this in sync with assignAddressesToSections.
514
169
  switch (_ctx.outputMachOType()) {
515
169
    case llvm::MachO::MH_EXECUTE:
516
51
      // Main executables, need a zero-page segment
517
51
      segmentForName("__PAGEZERO");
518
51
      // Fall into next case.
519
51
      LLVM_FALLTHROUGH;
520
96
    case llvm::MachO::MH_DYLIB:
521
96
    case llvm::MachO::MH_BUNDLE:
522
96
      // All dynamic code needs TEXT segment to hold the load commands.
523
96
      segmentForName("__TEXT");
524
96
      break;
525
96
    default:
526
73
      break;
527
169
  }
528
169
  segmentForName("__LINKEDIT");
529
169
530
169
  // Group sections into segments.
531
377
  for (SectionInfo *si : _sectionInfos) {
532
377
    SegmentInfo *seg = segmentForName(si->segmentName);
533
377
    seg->sections.push_back(si);
534
377
  }
535
169
  // Sort segments.
536
169
  std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
537
169
538
169
  // Sort sections within segments.
539
469
  for (SegmentInfo *seg : _segmentInfos) {
540
469
    if (seg->name.equals("__TEXT")) {
541
161
      std::sort(seg->sections.begin(), seg->sections.end(),
542
161
                TextSectionSorter());
543
161
    }
544
469
  }
545
169
546
169
  // Record final section indexes.
547
169
  uint32_t segmentIndex = 0;
548
169
  uint32_t sectionIndex = 1;
549
469
  for (SegmentInfo *seg : _segmentInfos) {
550
469
    seg->normalizedSegmentIndex = segmentIndex++;
551
469
    for (SectionInfo *sect : seg->sections)
552
377
      sect->finalSectionIndex = sectionIndex++;
553
469
  }
554
169
}
555
556
257
void Util::layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr) {
557
257
  seg->address = addr;
558
257
  for (SectionInfo *sect : seg->sections) {
559
127
    sect->address = llvm::alignTo(addr, sect->alignment);
560
127
    addr = sect->address + sect->size;
561
127
  }
562
257
  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
563
257
}
564
565
// __TEXT segment lays out backwards so padding is at front after load commands.
566
void Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
567
161
                                                               uint64_t &addr) {
568
161
  seg->address = addr;
569
161
  // Walks sections starting at end to calculate padding for start.
570
161
  int64_t taddr = 0;
571
411
  for (auto it = seg->sections.rbegin(); it != seg->sections.rend(); 
++it250
) {
572
250
    SectionInfo *sect = *it;
573
250
    taddr -= sect->size;
574
250
    taddr = taddr & (0 - sect->alignment);
575
250
  }
576
161
  int64_t padding = taddr - hlcSize;
577
324
  while (padding < 0)
578
163
    padding += _ctx.pageSize();
579
161
  // Start assigning section address starting at padded offset.
580
161
  addr += (padding + hlcSize);
581
250
  for (SectionInfo *sect : seg->sections) {
582
250
    sect->address = llvm::alignTo(addr, sect->alignment);
583
250
    addr = sect->address + sect->size;
584
250
  }
585
161
  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
586
161
}
587
588
169
void Util::assignAddressesToSections(const NormalizedFile &file) {
589
169
  // NOTE!: Keep this in sync with organizeSections.
590
169
  size_t hlcSize = headerAndLoadCommandsSize(file,
591
169
                                      _ctx.generateFunctionStartsLoadCommand());
592
169
  uint64_t address = 0;
593
469
  for (SegmentInfo *seg : _segmentInfos) {
594
469
    if (seg->name.equals("__PAGEZERO")) {
595
51
      seg->size = _ctx.pageZeroSize();
596
51
      address += seg->size;
597
51
    }
598
418
    else if (seg->name.equals("__TEXT")) {
599
161
      // _ctx.baseAddress()  == 0 implies it was either unspecified or
600
161
      // pageZeroSize is also 0. In either case resetting address is safe.
601
161
      address = _ctx.baseAddress() ? 
_ctx.baseAddress()51
:
address110
;
602
161
      layoutSectionsInTextSegment(hlcSize, seg, address);
603
161
    } else
604
257
      layoutSectionsInSegment(seg, address);
605
469
606
469
    address = llvm::alignTo(address, _ctx.pageSize());
607
469
  }
608
169
  DEBUG_WITH_TYPE("WriterMachO-norm",
609
169
    llvm::dbgs() << "assignAddressesToSections()\n";
610
169
    for (SegmentInfo *sgi : _segmentInfos) {
611
169
      llvm::dbgs()  << "   address=" << llvm::format("0x%08llX", sgi->address)
612
169
                    << ", size="  << llvm::format("0x%08llX", sgi->size)
613
169
                    << ", segment-name='" << sgi->name
614
169
                    << "'\n";
615
169
      for (SectionInfo *si : sgi->sections) {
616
169
        llvm::dbgs()<< "      addr="  << llvm::format("0x%08llX", si->address)
617
169
                    << ", size="  << llvm::format("0x%08llX", si->size)
618
169
                    << ", section-name='" << si->sectionName
619
169
                    << "\n";
620
169
      }
621
169
    }
622
169
  );
623
169
}
624
625
169
void Util::copySegmentInfo(NormalizedFile &file) {
626
469
  for (SegmentInfo *sgi : _segmentInfos) {
627
469
    Segment seg;
628
469
    seg.name    = sgi->name;
629
469
    seg.address = sgi->address;
630
469
    seg.size    = sgi->size;
631
469
    seg.init_access  = sgi->init_access;
632
469
    seg.max_access  = sgi->max_access;
633
469
    file.segments.push_back(seg);
634
469
  }
635
169
}
636
637
377
void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
638
377
   // Add new empty section to end of file.sections.
639
377
  Section temp;
640
377
  file.sections.push_back(std::move(temp));
641
377
  Section* normSect = &file.sections.back();
642
377
  // Copy fields to normalized section.
643
377
  normSect->segmentName   = si->segmentName;
644
377
  normSect->sectionName   = si->sectionName;
645
377
  normSect->type          = si->type;
646
377
  normSect->attributes    = si->attributes;
647
377
  normSect->address       = si->address;
648
377
  normSect->alignment     = si->alignment;
649
377
  // Record where normalized section is.
650
377
  si->normalizedSectionIndex = file.sections.size()-1;
651
377
}
652
653
169
void Util::copySectionContent(NormalizedFile &file) {
654
169
  const bool r = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
655
169
656
169
  // Utility function for ArchHandler to find address of atom in output file.
657
1.50k
  auto addrForAtom = [&] (const Atom &atom) -> uint64_t {
658
1.50k
    auto pos = _atomToAddress.find(&atom);
659
1.50k
    assert(pos != _atomToAddress.end());
660
1.50k
    return pos->second;
661
1.50k
  };
662
169
663
169
  auto sectionAddrForAtom = [&] (const Atom &atom) -> uint64_t {
664
4
    for (const SectionInfo *sectInfo : _sectionInfos)
665
8
      for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets)
666
15
        if (atomInfo.atom == &atom)
667
4
          return sectInfo->address;
668
4
    
llvm_unreachable0
("atom not assigned to section");
669
4
  };
670
169
671
377
  for (SectionInfo *si : _sectionInfos) {
672
377
    Section *normSect = &file.sections[si->normalizedSectionIndex];
673
377
    if (isZeroFillSection(si->type)) {
674
5
      const uint8_t *empty = nullptr;
675
5
      normSect->content = llvm::makeArrayRef(empty, si->size);
676
5
      continue;
677
5
    }
678
372
    // Copy content from atoms to content buffer for section.
679
372
    llvm::MutableArrayRef<uint8_t> sectionContent;
680
372
    if (si->size) {
681
361
      uint8_t *sectContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
682
361
      sectionContent = llvm::MutableArrayRef<uint8_t>(sectContent, si->size);
683
361
      normSect->content = sectionContent;
684
361
    }
685
736
    for (AtomInfo &ai : si->atomsAndOffsets) {
686
736
      if (!ai.atom->size()) {
687
115
        assert(ai.atom->begin() == ai.atom->end() &&
688
115
               "Cannot have references without content");
689
115
        continue;
690
115
      }
691
621
      auto atomContent = sectionContent.slice(ai.offsetInSection,
692
621
                                              ai.atom->size());
693
621
      _archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
694
621
                                       sectionAddrForAtom, _ctx.baseAddress(),
695
621
                                       atomContent);
696
621
    }
697
372
  }
698
169
}
699
700
169
void Util::copySectionInfo(NormalizedFile &file) {
701
169
  file.sections.reserve(_sectionInfos.size());
702
169
  // Write sections grouped by segment.
703
469
  for (SegmentInfo *sgi : _segmentInfos) {
704
469
    for (SectionInfo *si : sgi->sections) {
705
377
      appendSection(si, file);
706
377
    }
707
469
  }
708
169
}
709
710
169
void Util::updateSectionInfo(NormalizedFile &file) {
711
169
  file.sections.reserve(_sectionInfos.size());
712
169
  // sections grouped by segment.
713
469
  for (SegmentInfo *sgi : _segmentInfos) {
714
469
    Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
715
469
    normSeg->address = sgi->address;
716
469
    normSeg->size = sgi->size;
717
469
    for (SectionInfo *si : sgi->sections) {
718
377
      Section *normSect = &file.sections[si->normalizedSectionIndex];
719
377
      normSect->address = si->address;
720
377
    }
721
469
  }
722
169
}
723
724
168
void Util::copyEntryPointAddress(NormalizedFile &nFile) {
725
168
  if (!_entryAtom) {
726
121
    nFile.entryAddress = 0;
727
121
    return;
728
121
  }
729
47
730
47
  if (_ctx.outputTypeHasEntry()) {
731
47
    if (_archHandler.isThumbFunction(*_entryAtom))
732
1
      nFile.entryAddress = (_atomToAddress[_entryAtom] | 1);
733
46
    else
734
46
      nFile.entryAddress = _atomToAddress[_entryAtom];
735
47
  }
736
47
}
737
738
169
void Util::buildAtomToAddressMap() {
739
169
  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
740
169
                   << "assign atom addresses:\n");
741
169
  const bool lookForEntry = _ctx.outputTypeHasEntry();
742
377
  for (SectionInfo *sect : _sectionInfos) {
743
746
    for (const AtomInfo &info : sect->atomsAndOffsets) {
744
746
      _atomToAddress[info.atom] = sect->address + info.offsetInSection;
745
746
      if (lookForEntry && 
(info.atom->contentType() == DefinedAtom::typeCode)293
&&
746
746
          
(info.atom->size() != 0)77
&&
747
746
          
info.atom->name() == _ctx.entrySymbolName()74
) {
748
47
        _entryAtom = info.atom;
749
47
      }
750
746
      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
751
746
                      << "   address="
752
746
                      << llvm::format("0x%016X", _atomToAddress[info.atom])
753
746
                      << llvm::format("    0x%09lX", info.atom)
754
746
                      << ", file=#"
755
746
                      << info.atom->file().ordinal()
756
746
                      << ", atom=#"
757
746
                      << info.atom->ordinal()
758
746
                      << ", name="
759
746
                      << info.atom->name()
760
746
                      << ", type="
761
746
                      << info.atom->contentType()
762
746
                      << "\n");
763
746
    }
764
377
  }
765
169
  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
766
169
                  << "assign header alias atom addresses:\n");
767
192
  for (const Atom *atom : _machHeaderAliasAtoms) {
768
192
    _atomToAddress[atom] = _ctx.baseAddress();
769
#ifndef NDEBUG
770
    if (auto *definedAtom = dyn_cast<DefinedAtom>(atom)) {
771
      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
772
                      << "   address="
773
                      << llvm::format("0x%016X", _atomToAddress[atom])
774
                      << llvm::format("    0x%09lX", atom)
775
                      << ", file=#"
776
                      << definedAtom->file().ordinal()
777
                      << ", atom=#"
778
                      << definedAtom->ordinal()
779
                      << ", name="
780
                      << definedAtom->name()
781
                      << ", type="
782
                      << definedAtom->contentType()
783
                      << "\n");
784
    } else {
785
      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
786
                      << "   address="
787
                      << llvm::format("0x%016X", _atomToAddress[atom])
788
                      << " atom=" << atom
789
                      << " name=" << atom->name() << "\n");
790
    }
791
#endif
792
  }
793
169
}
794
795
169
llvm::Error Util::synthesizeDebugNotes(NormalizedFile &file) {
796
169
797
169
  // Bail out early if we don't need to generate a debug map.
798
169
  if (_ctx.debugInfoMode() == MachOLinkingContext::DebugInfoMode::noDebugMap)
799
0
    return llvm::Error::success();
800
169
801
169
  std::vector<const DefinedAtom*> atomsNeedingDebugNotes;
802
169
  std::set<const mach_o::MachOFile*> filesWithStabs;
803
169
  bool objFileHasDwarf = false;
804
169
  const File *objFile = nullptr;
805
169
806
377
  for (SectionInfo *sect : _sectionInfos) {
807
746
    for (const AtomInfo &info : sect->atomsAndOffsets) {
808
746
      if (const DefinedAtom *atom = dyn_cast<DefinedAtom>(info.atom)) {
809
746
810
746
        // FIXME: No stabs/debug-notes for symbols that wouldn't be in the
811
746
        //        symbol table.
812
746
        // FIXME: No stabs/debug-notes for kernel dtrace probes.
813
746
814
746
        if (atom->contentType() == DefinedAtom::typeCFI ||
815
746
            
atom->contentType() == DefinedAtom::typeCString711
)
816
62
          continue;
817
684
818
684
        // Whenever we encounter a new file, update the 'objfileHasDwarf' flag.
819
684
        if (&info.atom->file() != objFile) {
820
684
          objFileHasDwarf = false;
821
684
          if (const mach_o::MachOFile *atomFile =
822
540
              dyn_cast<mach_o::MachOFile>(&info.atom->file())) {
823
540
            if (atomFile->debugInfo()) {
824
1
              if (isa<mach_o::DwarfDebugInfo>(atomFile->debugInfo()))
825
1
                objFileHasDwarf = true;
826
0
              else if (isa<mach_o::StabsDebugInfo>(atomFile->debugInfo()))
827
0
                filesWithStabs.insert(atomFile);
828
1
            }
829
540
          }
830
684
        }
831
684
832
684
        // If this atom is from a file that needs dwarf, add it to the list.
833
684
        if (objFileHasDwarf)
834
1
          atomsNeedingDebugNotes.push_back(info.atom);
835
684
      }
836
746
    }
837
377
  }
838
169
839
169
  // Sort atoms needing debug notes by file ordinal, then atom ordinal.
840
169
  std::sort(atomsNeedingDebugNotes.begin(), atomsNeedingDebugNotes.end(),
841
169
            [](const DefinedAtom *lhs, const DefinedAtom *rhs) {
842
0
              if (lhs->file().ordinal() != rhs->file().ordinal())
843
0
                return (lhs->file().ordinal() < rhs->file().ordinal());
844
0
              return (lhs->ordinal() < rhs->ordinal());
845
0
            });
846
169
847
169
  // FIXME: Handle <rdar://problem/17689030>: Add -add_ast_path option to \
848
169
  //        linker which add N_AST stab entry to output
849
169
  // See OutputFile::synthesizeDebugNotes in ObjectFile.cpp in ld64.
850
169
851
169
  StringRef oldFileName = "";
852
169
  StringRef oldDirPath = "";
853
169
  bool wroteStartSO = false;
854
169
  std::unordered_set<std::string> seenFiles;
855
169
  for (const DefinedAtom *atom : atomsNeedingDebugNotes) {
856
1
    const auto &atomFile = cast<mach_o::MachOFile>(atom->file());
857
1
    assert(dyn_cast_or_null<lld::mach_o::DwarfDebugInfo>(atomFile.debugInfo())
858
1
           && "file for atom needing debug notes does not contain dwarf");
859
1
    auto &dwarf = cast<lld::mach_o::DwarfDebugInfo>(*atomFile.debugInfo());
860
1
861
1
    auto &tu = dwarf.translationUnitSource();
862
1
    StringRef newFileName = tu.name;
863
1
    StringRef newDirPath = tu.path;
864
1
865
1
    // Add an SO whenever the TU source file changes.
866
1
    if (newFileName != oldFileName || 
newDirPath != oldDirPath0
) {
867
1
      // Translation unit change, emit ending SO
868
1
      if (oldFileName != "")
869
0
        _stabs.push_back(mach_o::Stab(nullptr, N_SO, 1, 0, 0, ""));
870
1
871
1
      oldFileName = newFileName;
872
1
      oldDirPath = newDirPath;
873
1
874
1
      // If newDirPath doesn't end with a '/' we need to add one:
875
1
      if (newDirPath.back() != '/') {
876
1
        char *p =
877
1
          file.ownedAllocations.Allocate<char>(newDirPath.size() + 2);
878
1
        memcpy(p, newDirPath.data(), newDirPath.size());
879
1
        p[newDirPath.size()] = '/';
880
1
        p[newDirPath.size() + 1] = '\0';
881
1
        newDirPath = p;
882
1
      }
883
1
884
1
      // New translation unit, emit start SOs:
885
1
      _stabs.push_back(mach_o::Stab(nullptr, N_SO, 0, 0, 0, newDirPath));
886
1
      _stabs.push_back(mach_o::Stab(nullptr, N_SO, 0, 0, 0, newFileName));
887
1
888
1
      // Synthesize OSO for start of file.
889
1
      char *fullPath = nullptr;
890
1
      {
891
1
        SmallString<1024> pathBuf(atomFile.path());
892
1
        if (auto EC = llvm::sys::fs::make_absolute(pathBuf))
893
0
          return llvm::errorCodeToError(EC);
894
1
        fullPath = file.ownedAllocations.Allocate<char>(pathBuf.size() + 1);
895
1
        memcpy(fullPath, pathBuf.c_str(), pathBuf.size() + 1);
896
1
      }
897
1
898
1
      // Get mod time.
899
1
      uint32_t modTime = 0;
900
1
      llvm::sys::fs::file_status stat;
901
1
      if (!llvm::sys::fs::status(fullPath, stat))
902
1
        if (llvm::sys::fs::exists(stat))
903
1
          modTime = llvm::sys::toTimeT(stat.getLastModificationTime());
904
1
905
1
      _stabs.push_back(mach_o::Stab(nullptr, N_OSO, _ctx.getCPUSubType(), 1,
906
1
                                    modTime, fullPath));
907
1
      // <rdar://problem/6337329> linker should put cpusubtype in n_sect field
908
1
      // of nlist entry for N_OSO debug note entries.
909
1
      wroteStartSO = true;
910
1
    }
911
1
912
1
    if (atom->contentType() == DefinedAtom::typeCode) {
913
1
      // Synthesize BNSYM and start FUN stabs.
914
1
      _stabs.push_back(mach_o::Stab(atom, N_BNSYM, 1, 0, 0, ""));
915
1
      _stabs.push_back(mach_o::Stab(atom, N_FUN, 1, 0, 0, atom->name()));
916
1
      // Synthesize any SOL stabs needed
917
1
      // FIXME: add SOL stabs.
918
1
      _stabs.push_back(mach_o::Stab(nullptr, N_FUN, 0, 0,
919
1
                                    atom->rawContent().size(), ""));
920
1
      _stabs.push_back(mach_o::Stab(nullptr, N_ENSYM, 1, 0,
921
1
                                    atom->rawContent().size(), ""));
922
1
    } else {
923
0
      if (atom->scope() == Atom::scopeTranslationUnit)
924
0
        _stabs.push_back(mach_o::Stab(atom, N_STSYM, 1, 0, 0, atom->name()));
925
0
      else
926
0
        _stabs.push_back(mach_o::Stab(nullptr, N_GSYM, 1, 0, 0, atom->name()));
927
0
    }
928
1
  }
929
169
930
169
  // Emit ending SO if necessary.
931
169
  if (wroteStartSO)
932
1
    _stabs.push_back(mach_o::Stab(nullptr, N_SO, 1, 0, 0, ""));
933
169
934
169
  // Copy any stabs from .o file.
935
169
  for (const auto *objFile : filesWithStabs) {
936
0
    const auto &stabsList =
937
0
      cast<mach_o::StabsDebugInfo>(objFile->debugInfo())->stabs();
938
0
    for (auto &stab : stabsList) {
939
0
      // FIXME: Drop stabs whose atoms have been dead-stripped.
940
0
      _stabs.push_back(stab);
941
0
    }
942
0
  }
943
169
944
169
  return llvm::Error::success();
945
169
}
946
947
464
uint16_t Util::descBits(const DefinedAtom* atom) {
948
464
  uint16_t desc = 0;
949
464
  switch (atom->merge()) {
950
464
  case lld::DefinedAtom::mergeNo:
951
456
  case lld::DefinedAtom::mergeAsTentative:
952
456
    break;
953
456
  case lld::DefinedAtom::mergeAsWeak:
954
8
  case lld::DefinedAtom::mergeAsWeakAndAddressUsed:
955
8
    desc |= N_WEAK_DEF;
956
8
    break;
957
8
  case lld::DefinedAtom::mergeSameNameAndSize:
958
0
  case lld::DefinedAtom::mergeByLargestSection:
959
0
  case lld::DefinedAtom::mergeByContent:
960
0
    llvm_unreachable("Unsupported DefinedAtom::merge()");
961
0
    break;
962
464
  }
963
464
  if (atom->contentType() == lld::DefinedAtom::typeResolver)
964
2
    desc |= N_SYMBOL_RESOLVER;
965
464
  if (atom->contentType() == lld::DefinedAtom::typeMachHeader)
966
96
    desc |= REFERENCED_DYNAMICALLY;
967
464
  if (_archHandler.isThumbFunction(*atom))
968
22
    desc |= N_ARM_THUMB_DEF;
969
464
  if (atom->deadStrip() == DefinedAtom::deadStripNever &&
970
464
      
_ctx.outputMachOType() == llvm::MachO::MH_OBJECT125
) {
971
19
    if ((atom->contentType() != DefinedAtom::typeInitializerPtr)
972
19
     && (atom->contentType() != DefinedAtom::typeTerminatorPtr))
973
19
    desc |= N_NO_DEAD_STRIP;
974
19
  }
975
464
  return desc;
976
464
}
977
978
bool Util::AtomSorter::operator()(const AtomAndIndex &left,
979
287
                                  const AtomAndIndex &right) {
980
287
  return (left.atom->name().compare(right.atom->name()) < 0);
981
287
}
982
983
llvm::Error Util::getSymbolTableRegion(const DefinedAtom* atom,
984
                                       bool &inGlobalsRegion,
985
465
                                       SymbolScope &scope) {
986
465
  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
987
465
  switch (atom->scope()) {
988
465
  case Atom::scopeTranslationUnit:
989
98
    scope = 0;
990
98
    inGlobalsRegion = false;
991
98
    return llvm::Error::success();
992
465
  case Atom::scopeLinkageUnit:
993
70
    if ((_ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) &&
994
70
        
_ctx.exportSymbolNamed(atom->name())10
) {
995
1
      return llvm::make_error<GenericError>(
996
1
                          Twine("cannot export hidden symbol ") + atom->name());
997
1
    }
998
69
    if (rMode) {
999
17
      if (_ctx.keepPrivateExterns()) {
1000
4
        // -keep_private_externs means keep in globals region as N_PEXT.
1001
4
        scope = N_PEXT | N_EXT;
1002
4
        inGlobalsRegion = true;
1003
4
        return llvm::Error::success();
1004
4
      }
1005
65
    }
1006
65
    // scopeLinkageUnit symbols are no longer global once linked.
1007
65
    scope = N_PEXT;
1008
65
    inGlobalsRegion = false;
1009
65
    return llvm::Error::success();
1010
297
  case Atom::scopeGlobal:
1011
297
    if (_ctx.exportRestrictMode()) {
1012
21
      if (_ctx.exportSymbolNamed(atom->name())) {
1013
12
        scope = N_EXT;
1014
12
        inGlobalsRegion = true;
1015
12
        return llvm::Error::success();
1016
12
      } else {
1017
9
        scope = N_PEXT;
1018
9
        inGlobalsRegion = false;
1019
9
        return llvm::Error::success();
1020
9
      }
1021
276
    } else {
1022
276
      scope = N_EXT;
1023
276
      inGlobalsRegion = true;
1024
276
      return llvm::Error::success();
1025
276
    }
1026
0
    break;
1027
0
  }
1028
0
  llvm_unreachable("atom->scope() unknown enum value");
1029
0
}
1030
1031
1032
1033
llvm::Error Util::addSymbols(const lld::File &atomFile,
1034
169
                             NormalizedFile &file) {
1035
169
  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
1036
169
  // Mach-O symbol table has four regions: stabs, locals, globals, undefs.
1037
169
1038
169
  // Add all stabs.
1039
169
  for (auto &stab : _stabs) {
1040
8
    Symbol sym;
1041
8
    sym.type = static_cast<NListType>(stab.type);
1042
8
    sym.scope = 0;
1043
8
    sym.sect = stab.other;
1044
8
    sym.desc = stab.desc;
1045
8
    if (stab.atom)
1046
2
      sym.value = _atomToAddress[stab.atom];
1047
6
    else
1048
6
      sym.value = stab.value;
1049
8
    sym.name = stab.str;
1050
8
    file.stabsSymbols.push_back(sym);
1051
8
  }
1052
169
1053
169
  // Add all local (non-global) symbols in address order
1054
169
  std::vector<AtomAndIndex> globals;
1055
169
  globals.reserve(512);
1056
377
  for (SectionInfo *sect : _sectionInfos) {
1057
745
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1058
745
      const DefinedAtom *atom = info.atom;
1059
745
      if (!atom->name().empty()) {
1060
465
        SymbolScope symbolScope;
1061
465
        bool inGlobalsRegion;
1062
465
        if (auto ec = getSymbolTableRegion(atom, inGlobalsRegion, symbolScope)){
1063
1
          return ec;
1064
1
        }
1065
464
        if (inGlobalsRegion) {
1066
292
          AtomAndIndex ai = { atom, sect->finalSectionIndex, symbolScope };
1067
292
          globals.push_back(ai);
1068
292
        } else {
1069
172
          Symbol sym;
1070
172
          sym.name  = atom->name();
1071
172
          sym.type  = N_SECT;
1072
172
          sym.scope = symbolScope;
1073
172
          sym.sect  = sect->finalSectionIndex;
1074
172
          sym.desc  = descBits(atom);
1075
172
          sym.value = _atomToAddress[atom];
1076
172
          _atomToSymbolIndex[atom] = file.localSymbols.size();
1077
172
          file.localSymbols.push_back(sym);
1078
172
        }
1079
464
      } else 
if (280
rMode280
&&
_archHandler.needsLocalSymbolInRelocatableFile(atom)106
){
1080
15
        // Create 'Lxxx' labels for anonymous atoms if archHandler says so.
1081
15
        static unsigned tempNum = 1;
1082
15
        char tmpName[16];
1083
15
        sprintf(tmpName, "L%04u", tempNum++);
1084
15
        StringRef tempRef(tmpName);
1085
15
        Symbol sym;
1086
15
        sym.name  = tempRef.copy(file.ownedAllocations);
1087
15
        sym.type  = N_SECT;
1088
15
        sym.scope = 0;
1089
15
        sym.sect  = sect->finalSectionIndex;
1090
15
        sym.desc  = 0;
1091
15
        sym.value = _atomToAddress[atom];
1092
15
        _atomToSymbolIndex[atom] = file.localSymbols.size();
1093
15
        file.localSymbols.push_back(sym);
1094
15
      }
1095
745
    }
1096
377
  }
1097
169
1098
169
  // Sort global symbol alphabetically, then add to symbol table.
1099
169
  std::sort(globals.begin(), globals.end(), AtomSorter());
1100
168
  const uint32_t globalStartIndex = file.localSymbols.size();
1101
292
  for (AtomAndIndex &ai : globals) {
1102
292
    Symbol sym;
1103
292
    sym.name  = ai.atom->name();
1104
292
    sym.type  = N_SECT;
1105
292
    sym.scope = ai.scope;
1106
292
    sym.sect  = ai.index;
1107
292
    sym.desc  = descBits(static_cast<const DefinedAtom*>(ai.atom));
1108
292
    sym.value = _atomToAddress[ai.atom];
1109
292
    _atomToSymbolIndex[ai.atom] = globalStartIndex + file.globalSymbols.size();
1110
292
    file.globalSymbols.push_back(sym);
1111
292
  }
1112
168
1113
168
  // Sort undefined symbol alphabetically, then add to symbol table.
1114
168
  std::vector<AtomAndIndex> undefs;
1115
168
  undefs.reserve(128);
1116
168
  for (const UndefinedAtom *atom : atomFile.undefined()) {
1117
44
    AtomAndIndex ai = { atom, 0, N_EXT };
1118
44
    undefs.push_back(ai);
1119
44
  }
1120
168
  for (const SharedLibraryAtom *atom : atomFile.sharedLibrary()) {
1121
139
    AtomAndIndex ai = { atom, 0, N_EXT };
1122
139
    undefs.push_back(ai);
1123
139
  }
1124
168
  std::sort(undefs.begin(), undefs.end(), AtomSorter());
1125
168
  const uint32_t start = file.globalSymbols.size() + file.localSymbols.size();
1126
183
  for (AtomAndIndex &ai : undefs) {
1127
183
    Symbol sym;
1128
183
    uint16_t desc = 0;
1129
183
    if (!rMode) {
1130
133
      uint8_t ordinal = 0;
1131
133
      if (!_ctx.useFlatNamespace())
1132
131
        ordinal = dylibOrdinal(dyn_cast<SharedLibraryAtom>(ai.atom));
1133
133
      llvm::MachO::SET_LIBRARY_ORDINAL(desc, ordinal);
1134
133
    }
1135
183
    sym.name  = ai.atom->name();
1136
183
    sym.type  = N_UNDF;
1137
183
    sym.scope = ai.scope;
1138
183
    sym.sect  = 0;
1139
183
    sym.desc  = desc;
1140
183
    sym.value = 0;
1141
183
    _atomToSymbolIndex[ai.atom] = file.undefinedSymbols.size() + start;
1142
183
    file.undefinedSymbols.push_back(sym);
1143
183
  }
1144
168
1145
168
  return llvm::Error::success();
1146
169
}
1147
1148
46
const Atom *Util::targetOfLazyPointer(const DefinedAtom *lpAtom) {
1149
92
  for (const Reference *ref : *lpAtom) {
1150
92
    if (_archHandler.isLazyPointer(*ref)) {
1151
46
      return ref->target();
1152
46
    }
1153
92
  }
1154
46
  
return nullptr0
;
1155
46
}
1156
1157
23
const Atom *Util::targetOfStub(const DefinedAtom *stubAtom) {
1158
23
  for (const Reference *ref : *stubAtom) {
1159
23
    if (const Atom *ta = ref->target()) {
1160
23
      if (const DefinedAtom *lpAtom = dyn_cast<DefinedAtom>(ta)) {
1161
23
        const Atom *target = targetOfLazyPointer(lpAtom);
1162
23
        if (target)
1163
23
          return target;
1164
23
      }
1165
23
    }
1166
23
  }
1167
23
  
return nullptr0
;
1168
23
}
1169
1170
168
void Util::addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file) {
1171
375
  for (SectionInfo *si : _sectionInfos) {
1172
375
    Section &normSect = file.sections[si->normalizedSectionIndex];
1173
375
    switch (si->type) {
1174
375
    case llvm::MachO::S_NON_LAZY_SYMBOL_POINTERS:
1175
50
      for (const AtomInfo &info : si->atomsAndOffsets) {
1176
50
        bool foundTarget = false;
1177
50
        for (const Reference *ref : *info.atom) {
1178
32
          const Atom *target = ref->target();
1179
32
          if (target) {
1180
32
            if (isa<const SharedLibraryAtom>(target)) {
1181
31
              uint32_t index = _atomToSymbolIndex[target];
1182
31
              normSect.indirectSymbols.push_back(index);
1183
31
              foundTarget = true;
1184
31
            } else {
1185
1
              normSect.indirectSymbols.push_back(
1186
1
                                            llvm::MachO::INDIRECT_SYMBOL_LOCAL);
1187
1
            }
1188
32
          }
1189
32
        }
1190
50
        if (!foundTarget) {
1191
19
          normSect.indirectSymbols.push_back(
1192
19
                                             llvm::MachO::INDIRECT_SYMBOL_ABS);
1193
19
        }
1194
50
      }
1195
23
      break;
1196
375
    case llvm::MachO::S_LAZY_SYMBOL_POINTERS:
1197
23
      for (const AtomInfo &info : si->atomsAndOffsets) {
1198
23
        const Atom *target = targetOfLazyPointer(info.atom);
1199
23
        if (target) {
1200
23
          uint32_t index = _atomToSymbolIndex[target];
1201
23
          normSect.indirectSymbols.push_back(index);
1202
23
        }
1203
23
      }
1204
17
      break;
1205
375
    case llvm::MachO::S_SYMBOL_STUBS:
1206
23
      for (const AtomInfo &info : si->atomsAndOffsets) {
1207
23
        const Atom *target = targetOfStub(info.atom);
1208
23
        if (target) {
1209
23
          uint32_t index = _atomToSymbolIndex[target];
1210
23
          normSect.indirectSymbols.push_back(index);
1211
23
        }
1212
23
      }
1213
17
      break;
1214
375
    default:
1215
318
      break;
1216
375
    }
1217
375
  }
1218
168
}
1219
1220
void Util::addDependentDylibs(const lld::File &atomFile,
1221
169
                              NormalizedFile &nFile) {
1222
169
  // Scan all imported symbols and build up list of dylibs they are from.
1223
169
  int ordinal = 1;
1224
169
  for (const auto *dylib : _ctx.allDylibs()) {
1225
112
    DylibPathToInfo::iterator pos = _dylibInfo.find(dylib->installName());
1226
112
    if (pos == _dylibInfo.end()) {
1227
111
      DylibInfo info;
1228
111
      bool flatNamespaceAtom = dylib == _ctx.flatNamespaceFile();
1229
111
1230
111
      // If we're in -flat_namespace mode (or this atom came from the flat
1231
111
      // namespace file under -undefined dynamic_lookup) then use the flat
1232
111
      // lookup ordinal.
1233
111
      if (flatNamespaceAtom || _ctx.useFlatNamespace())
1234
1
        info.ordinal = BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
1235
110
      else
1236
110
        info.ordinal = ordinal++;
1237
111
      info.hasWeak = false;
1238
111
      info.hasNonWeak = !info.hasWeak;
1239
111
      _dylibInfo[dylib->installName()] = info;
1240
111
1241
111
      // Unless this was a flat_namespace atom, record the source dylib.
1242
111
      if (!flatNamespaceAtom) {
1243
111
        DependentDylib depInfo;
1244
111
        depInfo.path = dylib->installName();
1245
111
        depInfo.kind = llvm::MachO::LC_LOAD_DYLIB;
1246
111
        depInfo.currentVersion = _ctx.dylibCurrentVersion(dylib->path());
1247
111
        depInfo.compatVersion = _ctx.dylibCompatVersion(dylib->path());
1248
111
        nFile.dependentDylibs.push_back(depInfo);
1249
111
      }
1250
111
    } else {
1251
1
      pos->second.hasWeak = false;
1252
1
      pos->second.hasNonWeak = !pos->second.hasWeak;
1253
1
    }
1254
112
  }
1255
169
  // Automatically weak link dylib in which all symbols are weak (canBeNull).
1256
169
  for (DependentDylib &dep : nFile.dependentDylibs) {
1257
111
    DylibInfo &info = _dylibInfo[dep.path];
1258
111
    if (info.hasWeak && 
!info.hasNonWeak0
)
1259
0
      dep.kind = llvm::MachO::LC_LOAD_WEAK_DYLIB;
1260
111
    else if (_ctx.isUpwardDylib(dep.path))
1261
1
      dep.kind = llvm::MachO::LC_LOAD_UPWARD_DYLIB;
1262
111
  }
1263
169
}
1264
1265
186
int Util::dylibOrdinal(const SharedLibraryAtom *sa) {
1266
186
  return _dylibInfo[sa->loadName()].ordinal;
1267
186
}
1268
1269
void Util::segIndexForSection(const SectionInfo *sect, uint8_t &segmentIndex,
1270
231
                                                  uint64_t &segmentStartAddr) {
1271
231
  segmentIndex = 0;
1272
454
  for (const SegmentInfo *seg : _segmentInfos) {
1273
454
    if ((seg->address <= sect->address)
1274
454
      && (seg->address+seg->size >= sect->address+sect->size)) {
1275
231
      segmentStartAddr = seg->address;
1276
231
      return;
1277
231
    }
1278
223
    ++segmentIndex;
1279
223
  }
1280
231
  
llvm_unreachable0
("section not in any segment");
1281
231
}
1282
1283
77
uint32_t Util::sectionIndexForAtom(const Atom *atom) {
1284
77
  uint64_t address = _atomToAddress[atom];
1285
132
  for (const SectionInfo *si : _sectionInfos) {
1286
132
    if ((si->address <= address) && 
(address < si->address+si->size)93
)
1287
77
      return si->finalSectionIndex;
1288
132
  }
1289
77
  
llvm_unreachable0
("atom not in any section");
1290
77
}
1291
1292
168
void Util::addSectionRelocs(const lld::File &, NormalizedFile &file) {
1293
168
  if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
1294
96
    return;
1295
72
1296
72
  // Utility function for ArchHandler to find symbol index for an atom.
1297
207
  
auto symIndexForAtom = [&] (const Atom &atom) -> uint32_t 72
{
1298
207
    auto pos = _atomToSymbolIndex.find(&atom);
1299
207
    assert(pos != _atomToSymbolIndex.end());
1300
207
    return pos->second;
1301
207
  };
1302
72
1303
72
  // Utility function for ArchHandler to find section index for an atom.
1304
77
  auto sectIndexForAtom = [&] (const Atom &atom) -> uint32_t {
1305
77
    return sectionIndexForAtom(&atom);
1306
77
  };
1307
72
1308
72
  // Utility function for ArchHandler to find address of atom in output file.
1309
139
  auto addressForAtom = [&] (const Atom &atom) -> uint64_t {
1310
139
    auto pos = _atomToAddress.find(&atom);
1311
139
    assert(pos != _atomToAddress.end());
1312
139
    return pos->second;
1313
139
  };
1314
72
1315
144
  for (SectionInfo *si : _sectionInfos) {
1316
144
    Section &normSect = file.sections[si->normalizedSectionIndex];
1317
285
    for (const AtomInfo &info : si->atomsAndOffsets) {
1318
285
      const DefinedAtom *atom = info.atom;
1319
416
      for (const Reference *ref : *atom) {
1320
416
        // Skip emitting relocs for sections which are always able to be
1321
416
        // implicitly regenerated and where the relocation targets an address
1322
416
        // which is defined.
1323
416
        if (si->relocsToDefinedCanBeImplicit && 
isa<DefinedAtom>(ref->target())49
)
1324
48
          continue;
1325
368
        _archHandler.appendSectionRelocations(*atom, info.offsetInSection, *ref,
1326
368
                                              symIndexForAtom,
1327
368
                                              sectIndexForAtom,
1328
368
                                              addressForAtom,
1329
368
                                              normSect.relocations);
1330
368
      }
1331
285
    }
1332
144
  }
1333
72
}
1334
1335
168
void Util::addFunctionStarts(const lld::File &, NormalizedFile &file) {
1336
168
  if (!_ctx.generateFunctionStartsLoadCommand())
1337
81
    return;
1338
87
  file.functionStarts.reserve(8192);
1339
87
  // Delta compress function starts, starting with the mach header symbol.
1340
87
  const uint64_t badAddress = ~0ULL;
1341
87
  uint64_t addr = badAddress;
1342
222
  for (SectionInfo *si : _sectionInfos) {
1343
439
    for (const AtomInfo &info : si->atomsAndOffsets) {
1344
439
      auto type = info.atom->contentType();
1345
439
      if (type == DefinedAtom::typeMachHeader) {
1346
87
        addr = _atomToAddress[info.atom];
1347
87
        continue;
1348
87
      }
1349
352
      if (type != DefinedAtom::typeCode)
1350
214
        continue;
1351
138
      assert(addr != badAddress && "Missing mach header symbol");
1352
138
      // Skip atoms which have 0 size.  This is so that LC_FUNCTION_STARTS
1353
138
      // can't spill in to the next section.
1354
138
      if (!info.atom->size())
1355
10
        continue;
1356
128
      uint64_t nextAddr = _atomToAddress[info.atom];
1357
128
      if (_archHandler.isThumbFunction(*info.atom))
1358
11
        nextAddr |= 1;
1359
128
      uint64_t delta = nextAddr - addr;
1360
128
      if (delta) {
1361
128
        ByteBuffer buffer;
1362
128
        buffer.append_uleb128(delta);
1363
128
        file.functionStarts.insert(file.functionStarts.end(), buffer.bytes(),
1364
128
                                   buffer.bytes() + buffer.size());
1365
128
      }
1366
128
      addr = nextAddr;
1367
128
    }
1368
222
  }
1369
87
1370
87
  // Null terminate, and pad to pointer size for this arch.
1371
87
  file.functionStarts.push_back(0);
1372
87
1373
87
  auto size = file.functionStarts.size();
1374
87
  for (unsigned i = size, e = llvm::alignTo(size, _ctx.is64Bit() ? 
877
:
410
);
1375
467
       i != e; 
++i380
)
1376
380
    file.functionStarts.push_back(0);
1377
87
}
1378
1379
168
void Util::buildDataInCodeArray(const lld::File &, NormalizedFile &file) {
1380
168
  if (!_ctx.generateDataInCodeLoadCommand())
1381
10
    return;
1382
365
  
for (SectionInfo *si : _sectionInfos)158
{
1383
723
    for (const AtomInfo &info : si->atomsAndOffsets) {
1384
723
      // Atoms that contain data-in-code have "transition" references
1385
723
      // which mark a point where the embedded data starts of ends.
1386
723
      // This needs to be converted to the mach-o format which is an array
1387
723
      // of data-in-code ranges.
1388
723
      uint32_t startOffset = 0;
1389
723
      DataRegionType mode = DataRegionType(0);
1390
835
      for (const Reference *ref : *info.atom) {
1391
835
        if (ref->kindNamespace() != Reference::KindNamespace::mach_o)
1392
4
          continue;
1393
831
        if (_archHandler.isDataInCodeTransition(ref->kindValue())) {
1394
58
          DataRegionType nextMode = (DataRegionType)ref->addend();
1395
58
          if (mode != nextMode) {
1396
36
            if (mode != 0) {
1397
26
              // Found end data range, so make range entry.
1398
26
              DataInCode entry;
1399
26
              entry.offset = si->address + info.offsetInSection + startOffset;
1400
26
              entry.length = ref->offsetInAtom() - startOffset;
1401
26
              entry.kind   = mode;
1402
26
              file.dataInCode.push_back(entry);
1403
26
            }
1404
36
          }
1405
58
          mode = nextMode;
1406
58
          startOffset = ref->offsetInAtom();
1407
58
        }
1408
831
      }
1409
723
      if (mode != 0) {
1410
2
        // Function ends with data (no end transition).
1411
2
        DataInCode entry;
1412
2
        entry.offset = si->address + info.offsetInSection + startOffset;
1413
2
        entry.length = info.atom->size() - startOffset;
1414
2
        entry.kind   = mode;
1415
2
        file.dataInCode.push_back(entry);
1416
2
      }
1417
723
    }
1418
365
  }
1419
158
}
1420
1421
void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
1422
168
                                                        NormalizedFile &nFile) {
1423
168
  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1424
72
    return;
1425
96
1426
96
  uint8_t segmentIndex;
1427
96
  uint64_t segmentStartAddr;
1428
96
  uint32_t offsetInBindInfo = 0;
1429
96
1430
231
  for (SectionInfo *sect : _sectionInfos) {
1431
231
    segIndexForSection(sect, segmentIndex, segmentStartAddr);
1432
457
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1433
457
      const DefinedAtom *atom = info.atom;
1434
457
      for (const Reference *ref : *atom) {
1435
419
        uint64_t segmentOffset = _atomToAddress[atom] + ref->offsetInAtom()
1436
419
                                - segmentStartAddr;
1437
419
        const Atom* targ = ref->target();
1438
419
        if (_archHandler.isPointer(*ref)) {
1439
71
          // A pointer to a DefinedAtom requires rebasing.
1440
71
          if (isa<DefinedAtom>(targ)) {
1441
39
            RebaseLocation rebase;
1442
39
            rebase.segIndex = segmentIndex;
1443
39
            rebase.segOffset = segmentOffset;
1444
39
            rebase.kind = llvm::MachO::REBASE_TYPE_POINTER;
1445
39
            nFile.rebasingInfo.push_back(rebase);
1446
39
          }
1447
71
          // A pointer to an SharedLibraryAtom requires binding.
1448
71
          if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1449
32
            BindLocation bind;
1450
32
            bind.segIndex = segmentIndex;
1451
32
            bind.segOffset = segmentOffset;
1452
32
            bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1453
32
            bind.canBeNull = sa->canBeNullAtRuntime();
1454
32
            bind.ordinal = dylibOrdinal(sa);
1455
32
            bind.symbolName = targ->name();
1456
32
            bind.addend = ref->addend();
1457
32
            nFile.bindingInfo.push_back(bind);
1458
32
          }
1459
71
        }
1460
348
        else if (_archHandler.isLazyPointer(*ref)) {
1461
23
          BindLocation bind;
1462
23
          if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1463
23
            bind.ordinal = dylibOrdinal(sa);
1464
23
          } else {
1465
0
            bind.ordinal = llvm::MachO::BIND_SPECIAL_DYLIB_SELF;
1466
0
          }
1467
23
          bind.segIndex = segmentIndex;
1468
23
          bind.segOffset = segmentOffset;
1469
23
          bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1470
23
          bind.canBeNull = false; //sa->canBeNullAtRuntime();
1471
23
          bind.symbolName = targ->name();
1472
23
          bind.addend = ref->addend();
1473
23
          nFile.lazyBindingInfo.push_back(bind);
1474
23
1475
23
          // Now that we know the segmentOffset and the ordinal attribute,
1476
23
          // we can fix the helper's code
1477
23
1478
23
          fixLazyReferenceImm(atom, offsetInBindInfo, nFile);
1479
23
1480
23
          // 5 bytes for opcodes + variable sizes (target name + \0 and offset
1481
23
          // encode's size)
1482
23
          offsetInBindInfo +=
1483
23
              6 + targ->name().size() + llvm::getULEB128Size(bind.segOffset);
1484
23
          if (bind.ordinal > BIND_IMMEDIATE_MASK)
1485
0
            offsetInBindInfo += llvm::getULEB128Size(bind.ordinal);
1486
23
        }
1487
419
      }
1488
457
    }
1489
231
  }
1490
96
}
1491
1492
void Util::fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
1493
23
                               NormalizedFile &file) {
1494
46
  for (const auto &ref : *atom) {
1495
46
    const DefinedAtom *da = dyn_cast<DefinedAtom>(ref->target());
1496
46
    if (da == nullptr)
1497
23
      return;
1498
23
1499
23
    const Reference *helperRef = nullptr;
1500
23
    for (const Reference *hr : *da) {
1501
23
      if (hr->kindValue() == _archHandler.lazyImmediateLocationKind()) {
1502
23
        helperRef = hr;
1503
23
        break;
1504
23
      }
1505
23
    }
1506
23
    if (helperRef == nullptr)
1507
0
      continue;
1508
23
1509
23
    // TODO: maybe get the fixed atom content from _archHandler ?
1510
138
    
for (SectionInfo *sectInfo : _sectionInfos)23
{
1511
312
      for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) {
1512
312
        if (atomInfo.atom == helperRef->target()) {
1513
23
          auto sectionContent =
1514
23
              file.sections[sectInfo->normalizedSectionIndex].content;
1515
23
          uint8_t *rawb =
1516
23
              file.ownedAllocations.Allocate<uint8_t>(sectionContent.size());
1517
23
          llvm::MutableArrayRef<uint8_t> newContent{rawb,
1518
23
                                                    sectionContent.size()};
1519
23
          std::copy(sectionContent.begin(), sectionContent.end(),
1520
23
                    newContent.begin());
1521
23
          llvm::support::ulittle32_t *loc =
1522
23
              reinterpret_cast<llvm::support::ulittle32_t *>(
1523
23
                  &newContent[atomInfo.offsetInSection +
1524
23
                              helperRef->offsetInAtom()]);
1525
23
          *loc = offset;
1526
23
          file.sections[sectInfo->normalizedSectionIndex].content = newContent;
1527
23
        }
1528
312
      }
1529
138
    }
1530
23
  }
1531
23
}
1532
1533
168
void Util::addExportInfo(const lld::File &atomFile, NormalizedFile &nFile) {
1534
168
  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1535
72
    return;
1536
96
1537
231
  
for (SectionInfo *sect : _sectionInfos)96
{
1538
457
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1539
457
      const DefinedAtom *atom = info.atom;
1540
457
      if (atom->scope() != Atom::scopeGlobal)
1541
254
        continue;
1542
203
      if (_ctx.exportRestrictMode()) {
1543
16
        if (!_ctx.exportSymbolNamed(atom->name()))
1544
6
          continue;
1545
197
      }
1546
197
      Export exprt;
1547
197
      exprt.name = atom->name();
1548
197
      exprt.offset = _atomToAddress[atom] - _ctx.baseAddress();
1549
197
      exprt.kind = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
1550
197
      if (atom->merge() == DefinedAtom::mergeAsWeak)
1551
1
        exprt.flags = EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
1552
196
      else
1553
196
        exprt.flags = 0;
1554
197
      exprt.otherOffset = 0;
1555
197
      exprt.otherName = StringRef();
1556
197
      nFile.exportInfo.push_back(exprt);
1557
197
    }
1558
231
  }
1559
96
}
1560
1561
169
uint32_t Util::fileFlags() {
1562
169
  // FIXME: these need to determined at runtime.
1563
169
  if (_ctx.outputMachOType() == MH_OBJECT) {
1564
73
    return _subsectionsViaSymbols ? 
MH_SUBSECTIONS_VIA_SYMBOLS65
:
08
;
1565
96
  } else {
1566
96
    uint32_t flags = MH_DYLDLINK;
1567
96
    if (!_ctx.useFlatNamespace())
1568
95
        flags |= MH_TWOLEVEL | MH_NOUNDEFS;
1569
96
    if ((_ctx.outputMachOType() == MH_EXECUTE) && 
_ctx.PIE()51
)
1570
23
      flags |= MH_PIE;
1571
96
    if (_hasTLVDescriptors)
1572
1
      flags |= (MH_PIE | MH_HAS_TLV_DESCRIPTORS);
1573
96
    return flags;
1574
96
  }
1575
169
}
1576
1577
} // end anonymous namespace
1578
1579
namespace lld {
1580
namespace mach_o {
1581
namespace normalized {
1582
1583
/// Convert a set of Atoms into a normalized mach-o file.
1584
llvm::Expected<std::unique_ptr<NormalizedFile>>
1585
normalizedFromAtoms(const lld::File &atomFile,
1586
169
                                           const MachOLinkingContext &context) {
1587
169
  // The util object buffers info until the normalized file can be made.
1588
169
  Util util(context);
1589
169
  util.processDefinedAtoms(atomFile);
1590
169
  util.organizeSections();
1591
169
1592
169
  std::unique_ptr<NormalizedFile> f(new NormalizedFile());
1593
169
  NormalizedFile &normFile = *f.get();
1594
169
  normFile.arch = context.arch();
1595
169
  normFile.fileType = context.outputMachOType();
1596
169
  normFile.flags = util.fileFlags();
1597
169
  normFile.stackSize = context.stackSize();
1598
169
  normFile.installName = context.installName();
1599
169
  normFile.currentVersion = context.currentVersion();
1600
169
  normFile.compatVersion = context.compatibilityVersion();
1601
169
  normFile.os = context.os();
1602
169
1603
169
  // If we are emitting an object file, then the min version is the maximum
1604
169
  // of the min's of all the source files and the cmdline.
1605
169
  if (normFile.fileType == llvm::MachO::MH_OBJECT)
1606
73
    normFile.minOSverson = std::max(context.osMinVersion(), util.minVersion());
1607
96
  else
1608
96
    normFile.minOSverson = context.osMinVersion();
1609
169
1610
169
  normFile.minOSVersionKind = util.minVersionCommandType();
1611
169
1612
169
  normFile.sdkVersion = context.sdkVersion();
1613
169
  normFile.sourceVersion = context.sourceVersion();
1614
169
1615
169
  if (context.generateVersionLoadCommand() &&
1616
169
      
context.os() != MachOLinkingContext::OS::unknown87
)
1617
87
    normFile.hasMinVersionLoadCommand = true;
1618
82
  else if (normFile.fileType == llvm::MachO::MH_OBJECT &&
1619
82
           
util.allSourceFilesHaveMinVersions()73
&&
1620
82
           
(4
(normFile.os != MachOLinkingContext::OS::unknown)4
||
1621
4
            
util.minVersionCommandType()3
)) {
1622
2
    // If we emit an object file, then it should contain a min version load
1623
2
    // command if all of the source files also contained min version commands.
1624
2
    // Also, we either need to have a platform, or found a platform from the
1625
2
    // source object files.
1626
2
    normFile.hasMinVersionLoadCommand = true;
1627
2
  }
1628
169
  normFile.generateDataInCodeLoadCommand =
1629
169
    context.generateDataInCodeLoadCommand();
1630
169
  normFile.pageSize = context.pageSize();
1631
169
  normFile.rpaths = context.rpaths();
1632
169
  util.addDependentDylibs(atomFile, normFile);
1633
169
  util.copySegmentInfo(normFile);
1634
169
  util.copySectionInfo(normFile);
1635
169
  util.assignAddressesToSections(normFile);
1636
169
  util.buildAtomToAddressMap();
1637
169
  if (auto err = util.synthesizeDebugNotes(normFile))
1638
0
    return std::move(err);
1639
169
  util.updateSectionInfo(normFile);
1640
169
  util.copySectionContent(normFile);
1641
169
  if (auto ec = util.addSymbols(atomFile, normFile)) {
1642
1
    return std::move(ec);
1643
1
  }
1644
168
  util.addIndirectSymbols(atomFile, normFile);
1645
168
  util.addRebaseAndBindingInfo(atomFile, normFile);
1646
168
  util.addExportInfo(atomFile, normFile);
1647
168
  util.addSectionRelocs(atomFile, normFile);
1648
168
  util.addFunctionStarts(atomFile, normFile);
1649
168
  util.buildDataInCodeArray(atomFile, normFile);
1650
168
  util.copyEntryPointAddress(normFile);
1651
168
1652
168
  return std::move(f);
1653
168
}
1654
1655
} // namespace normalized
1656
} // namespace mach_o
1657
} // namespace lld