Coverage Report

Created: 2018-10-20 06:24

/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
//                             The LLVM Linker
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
///
11
/// \file Converts from in-memory Atoms to in-memory normalized mach-o.
12
///
13
///                  +------------+
14
///                  | normalized |
15
///                  +------------+
16
///                        ^
17
///                        |
18
///                        |
19
///                    +-------+
20
///                    | Atoms |
21
///                    +-------+
22
23
#include "ArchHandler.h"
24
#include "DebugInfo.h"
25
#include "MachONormalizedFile.h"
26
#include "MachONormalizedFileBinaryUtils.h"
27
#include "lld/Common/LLVM.h"
28
#include "lld/Core/Error.h"
29
#include "llvm/ADT/StringRef.h"
30
#include "llvm/ADT/StringSwitch.h"
31
#include "llvm/BinaryFormat/MachO.h"
32
#include "llvm/Support/Casting.h"
33
#include "llvm/Support/Debug.h"
34
#include "llvm/Support/ErrorHandling.h"
35
#include "llvm/Support/Format.h"
36
#include <map>
37
#include <system_error>
38
#include <unordered_set>
39
40
using llvm::StringRef;
41
using llvm::isa;
42
using namespace llvm::MachO;
43
using namespace lld::mach_o::normalized;
44
using namespace lld;
45
46
namespace {
47
48
struct AtomInfo {
49
  const DefinedAtom  *atom;
50
  uint64_t            offsetInSection;
51
};
52
53
struct SectionInfo {
54
  SectionInfo(StringRef seg, StringRef sect, SectionType type,
55
              const MachOLinkingContext &ctxt, uint32_t attr,
56
              bool relocsToDefinedCanBeImplicit);
57
58
  StringRef                 segmentName;
59
  StringRef                 sectionName;
60
  SectionType               type;
61
  uint32_t                  attributes;
62
  uint64_t                  address;
63
  uint64_t                  size;
64
  uint16_t                  alignment;
65
66
  /// If this is set, the any relocs in this section which point to defined
67
  /// addresses can be implicitly generated.  This is the case for the
68
  /// __eh_frame section where references to the function can be implicit if the
69
  /// function is defined.
70
  bool                      relocsToDefinedCanBeImplicit;
71
72
73
  std::vector<AtomInfo>     atomsAndOffsets;
74
  uint32_t                  normalizedSectionIndex;
75
  uint32_t                  finalSectionIndex;
76
};
77
78
SectionInfo::SectionInfo(StringRef sg, StringRef sct, SectionType t,
79
                         const MachOLinkingContext &ctxt, uint32_t attrs,
80
                         bool relocsToDefinedCanBeImplicit)
81
 : segmentName(sg), sectionName(sct), type(t), attributes(attrs),
82
                 address(0), size(0), alignment(1),
83
                 relocsToDefinedCanBeImplicit(relocsToDefinedCanBeImplicit),
84
375
                 normalizedSectionIndex(0), finalSectionIndex(0) {
85
375
  uint16_t align = 1;
86
375
  if (ctxt.sectionAligned(segmentName, sectionName, align)) {
87
3
    alignment = align;
88
3
  }
89
375
}
90
91
struct SegmentInfo {
92
  SegmentInfo(StringRef name);
93
94
  StringRef                  name;
95
  uint64_t                   address;
96
  uint64_t                   size;
97
  uint32_t                   init_access;
98
  uint32_t                   max_access;
99
  std::vector<SectionInfo*>  sections;
100
  uint32_t                   normalizedSegmentIndex;
101
};
102
103
SegmentInfo::SegmentInfo(StringRef n)
104
 : name(n), address(0), size(0), init_access(0), max_access(0),
105
467
   normalizedSegmentIndex(0) {
106
467
}
107
108
class Util {
109
public:
110
  Util(const MachOLinkingContext &ctxt)
111
      : _ctx(ctxt), _archHandler(ctxt.archHandler()), _entryAtom(nullptr),
112
168
        _hasTLVDescriptors(false), _subsectionsViaSymbols(true) {}
113
  ~Util();
114
115
  void      processDefinedAtoms(const lld::File &atomFile);
116
  void      processAtomAttributes(const DefinedAtom *atom);
117
  void      assignAtomToSection(const DefinedAtom *atom);
118
  void      organizeSections();
119
  void      assignAddressesToSections(const NormalizedFile &file);
120
  uint32_t  fileFlags();
121
  void      copySegmentInfo(NormalizedFile &file);
122
  void      copySectionInfo(NormalizedFile &file);
123
  void      updateSectionInfo(NormalizedFile &file);
124
  void      buildAtomToAddressMap();
125
  llvm::Error synthesizeDebugNotes(NormalizedFile &file);
126
  llvm::Error addSymbols(const lld::File &atomFile, NormalizedFile &file);
127
  void      addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file);
128
  void      addRebaseAndBindingInfo(const lld::File &, NormalizedFile &file);
129
  void      addExportInfo(const lld::File &, NormalizedFile &file);
130
  void      addSectionRelocs(const lld::File &, NormalizedFile &file);
131
  void      addFunctionStarts(const lld::File &, NormalizedFile &file);
132
  void      buildDataInCodeArray(const lld::File &, NormalizedFile &file);
133
  void      addDependentDylibs(const lld::File &, NormalizedFile &file);
134
  void      copyEntryPointAddress(NormalizedFile &file);
135
  void      copySectionContent(NormalizedFile &file);
136
137
73
  bool allSourceFilesHaveMinVersions() const {
138
73
    return _allSourceFilesHaveMinVersions;
139
73
  }
140
141
73
  uint32_t minVersion() const {
142
73
    return _minVersion;
143
73
  }
144
145
171
  LoadCommandType minVersionCommandType() const {
146
171
    return _minVersionCommandType;
147
171
  }
148
149
private:
150
  typedef std::map<DefinedAtom::ContentType, SectionInfo*> TypeToSection;
151
  typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
152
153
  struct DylibInfo { int ordinal; bool hasWeak; bool hasNonWeak; };
154
  typedef llvm::StringMap<DylibInfo> DylibPathToInfo;
155
156
  SectionInfo *sectionForAtom(const DefinedAtom*);
157
  SectionInfo *getRelocatableSection(DefinedAtom::ContentType type);
158
  SectionInfo *getFinalSection(DefinedAtom::ContentType type);
159
  void         appendAtom(SectionInfo *sect, const DefinedAtom *atom);
160
  SegmentInfo *segmentForName(StringRef segName);
161
  void         layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr);
162
  void         layoutSectionsInTextSegment(size_t, SegmentInfo *, uint64_t &);
163
  void         copySectionContent(SectionInfo *si, ContentBytes &content);
164
  uint16_t     descBits(const DefinedAtom* atom);
165
  int          dylibOrdinal(const SharedLibraryAtom *sa);
166
  void         segIndexForSection(const SectionInfo *sect,
167
                             uint8_t &segmentIndex, uint64_t &segmentStartAddr);
168
  const Atom  *targetOfLazyPointer(const DefinedAtom *lpAtom);
169
  const Atom  *targetOfStub(const DefinedAtom *stubAtom);
170
  llvm::Error getSymbolTableRegion(const DefinedAtom* atom,
171
                                   bool &inGlobalsRegion,
172
                                   SymbolScope &symbolScope);
173
  void         appendSection(SectionInfo *si, NormalizedFile &file);
174
  uint32_t     sectionIndexForAtom(const Atom *atom);
175
  void fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
176
                           NormalizedFile &file);
177
178
  typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;
179
  struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };
180
  struct AtomSorter {
181
    bool operator()(const AtomAndIndex &left, const AtomAndIndex &right);
182
  };
183
  struct SegmentSorter {
184
    bool operator()(const SegmentInfo *left, const SegmentInfo *right);
185
    static unsigned weight(const SegmentInfo *);
186
  };
187
  struct TextSectionSorter {
188
    bool operator()(const SectionInfo *left, const SectionInfo *right);
189
    static unsigned weight(const SectionInfo *);
190
  };
191
192
  const MachOLinkingContext &_ctx;
193
  mach_o::ArchHandler          &_archHandler;
194
  llvm::BumpPtrAllocator        _allocator;
195
  std::vector<SectionInfo*>     _sectionInfos;
196
  std::vector<SegmentInfo*>     _segmentInfos;
197
  TypeToSection                 _sectionMap;
198
  std::vector<SectionInfo*>     _customSections;
199
  AtomToAddress                 _atomToAddress;
200
  DylibPathToInfo               _dylibInfo;
201
  const DefinedAtom            *_entryAtom;
202
  AtomToIndex                   _atomToSymbolIndex;
203
  std::vector<const Atom *>     _machHeaderAliasAtoms;
204
  bool                          _hasTLVDescriptors;
205
  bool                          _subsectionsViaSymbols;
206
  bool                          _allSourceFilesHaveMinVersions = true;
207
  LoadCommandType               _minVersionCommandType = (LoadCommandType)0;
208
  uint32_t                      _minVersion = 0;
209
  std::vector<lld::mach_o::Stab> _stabs;
210
};
211
212
168
Util::~Util() {
213
168
  // The SectionInfo structs are BumpPtr allocated, but atomsAndOffsets needs
214
168
  // to be deleted.
215
375
  for (SectionInfo *si : _sectionInfos) {
216
375
    // clear() destroys vector elements, but does not deallocate.
217
375
    // Instead use swap() to deallocate vector buffer.
218
375
    std::vector<AtomInfo> empty;
219
375
    si->atomsAndOffsets.swap(empty);
220
375
  }
221
168
  // The SegmentInfo structs are BumpPtr allocated, but sections needs
222
168
  // to be deleted.
223
467
  for (SegmentInfo *sgi : _segmentInfos) {
224
467
    std::vector<SectionInfo*> empty2;
225
467
    sgi->sections.swap(empty2);
226
467
  }
227
168
}
228
229
139
SectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
230
139
  StringRef segmentName;
231
139
  StringRef sectionName;
232
139
  SectionType sectionType;
233
139
  SectionAttr sectionAttrs;
234
139
  bool relocsToDefinedCanBeImplicit;
235
139
236
139
  // Use same table used by when parsing .o files.
237
139
  relocatableSectionInfoForContentType(type, segmentName, sectionName,
238
139
                                       sectionType, sectionAttrs,
239
139
                                       relocsToDefinedCanBeImplicit);
240
139
  // If we already have a SectionInfo with this name, re-use it.
241
139
  // This can happen if two ContentType map to the same mach-o section.
242
139
  for (auto sect : _sectionMap) {
243
108
    if (sect.second->sectionName.equals(sectionName) &&
244
108
        
sect.second->segmentName.equals(segmentName)2
) {
245
2
      return sect.second;
246
2
    }
247
108
  }
248
139
  // Otherwise allocate new SectionInfo object.
249
139
  auto *sect = new (_allocator)
250
137
      SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs,
251
137
                  relocsToDefinedCanBeImplicit);
252
137
  _sectionInfos.push_back(sect);
253
137
  _sectionMap[type] = sect;
254
137
  return sect;
255
139
}
256
257
#define ENTRY(seg, sect, type, atomType) \
258
  {seg, sect, type, DefinedAtom::atomType }
259
260
struct MachOFinalSectionFromAtomType {
261
  StringRef                 segmentName;
262
  StringRef                 sectionName;
263
  SectionType               sectionType;
264
  DefinedAtom::ContentType  atomType;
265
};
266
267
const MachOFinalSectionFromAtomType sectsToAtomType[] = {
268
  ENTRY("__TEXT", "__text",           S_REGULAR,          typeCode),
269
  ENTRY("__TEXT", "__text",           S_REGULAR,          typeMachHeader),
270
  ENTRY("__TEXT", "__cstring",        S_CSTRING_LITERALS, typeCString),
271
  ENTRY("__TEXT", "__ustring",        S_REGULAR,          typeUTF16String),
272
  ENTRY("__TEXT", "__const",          S_REGULAR,          typeConstant),
273
  ENTRY("__TEXT", "__const",          S_4BYTE_LITERALS,   typeLiteral4),
274
  ENTRY("__TEXT", "__const",          S_8BYTE_LITERALS,   typeLiteral8),
275
  ENTRY("__TEXT", "__const",          S_16BYTE_LITERALS,  typeLiteral16),
276
  ENTRY("__TEXT", "__stubs",          S_SYMBOL_STUBS,     typeStub),
277
  ENTRY("__TEXT", "__stub_helper",    S_REGULAR,          typeStubHelper),
278
  ENTRY("__TEXT", "__gcc_except_tab", S_REGULAR,          typeLSDA),
279
  ENTRY("__TEXT", "__eh_frame",       S_COALESCED,        typeCFI),
280
  ENTRY("__TEXT", "__unwind_info",    S_REGULAR,          typeProcessedUnwindInfo),
281
  ENTRY("__DATA", "__data",           S_REGULAR,          typeData),
282
  ENTRY("__DATA", "__const",          S_REGULAR,          typeConstData),
283
  ENTRY("__DATA", "__cfstring",       S_REGULAR,          typeCFString),
284
  ENTRY("__DATA", "__la_symbol_ptr",  S_LAZY_SYMBOL_POINTERS,
285
                                                          typeLazyPointer),
286
  ENTRY("__DATA", "__mod_init_func",  S_MOD_INIT_FUNC_POINTERS,
287
                                                          typeInitializerPtr),
288
  ENTRY("__DATA", "__mod_term_func",  S_MOD_TERM_FUNC_POINTERS,
289
                                                          typeTerminatorPtr),
290
  ENTRY("__DATA", "__got",            S_NON_LAZY_SYMBOL_POINTERS,
291
                                                          typeGOT),
292
  ENTRY("__DATA", "__nl_symbol_ptr",  S_NON_LAZY_SYMBOL_POINTERS,
293
                                                          typeNonLazyPointer),
294
  ENTRY("__DATA", "__thread_vars",    S_THREAD_LOCAL_VARIABLES,
295
                                                          typeThunkTLV),
296
  ENTRY("__DATA", "__thread_data",    S_THREAD_LOCAL_REGULAR,
297
                                                          typeTLVInitialData),
298
  ENTRY("__DATA", "__thread_ptrs",    S_THREAD_LOCAL_VARIABLE_POINTERS,
299
                                                          typeTLVInitializerPtr),
300
  ENTRY("__DATA", "__thread_bss",     S_THREAD_LOCAL_ZEROFILL,
301
                                                         typeTLVInitialZeroFill),
302
  ENTRY("__DATA", "__bss",            S_ZEROFILL,         typeZeroFill),
303
  ENTRY("__DATA", "__interposing",    S_INTERPOSING,      typeInterposingTuples),
304
};
305
#undef ENTRY
306
307
375
SectionInfo *Util::getFinalSection(DefinedAtom::ContentType atomType) {
308
2.14k
  for (auto &p : sectsToAtomType) {
309
2.14k
    if (p.atomType != atomType)
310
1.76k
      continue;
311
375
    SectionAttr sectionAttrs = 0;
312
375
    switch (atomType) {
313
375
    case DefinedAtom::typeMachHeader:
314
276
    case DefinedAtom::typeCode:
315
276
    case DefinedAtom::typeStub:
316
276
    case DefinedAtom::typeStubHelper:
317
276
      sectionAttrs = S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS;
318
276
      break;
319
276
    case DefinedAtom::typeThunkTLV:
320
1
      _hasTLVDescriptors = true;
321
1
      break;
322
276
    default:
323
98
      break;
324
375
    }
325
375
    // If we already have a SectionInfo with this name, re-use it.
326
375
    // This can happen if two ContentType map to the same mach-o section.
327
542
    
for (auto sect : _sectionMap)375
{
328
542
      if (sect.second->sectionName.equals(p.sectionName) &&
329
542
          
sect.second->segmentName.equals(p.segmentName)151
) {
330
150
        return sect.second;
331
150
      }
332
542
    }
333
375
    // Otherwise allocate new SectionInfo object.
334
375
    auto *sect = new (_allocator) SectionInfo(
335
225
        p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs,
336
225
        /* relocsToDefinedCanBeImplicit */ false);
337
225
    _sectionInfos.push_back(sect);
338
225
    _sectionMap[atomType] = sect;
339
225
    return sect;
340
375
  }
341
375
  
llvm_unreachable0
("content type not yet supported");
342
375
}
343
344
744
SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
345
744
  if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
346
725
    // Section for this atom is derived from content type.
347
725
    DefinedAtom::ContentType type = atom->contentType();
348
725
    auto pos = _sectionMap.find(type);
349
725
    if ( pos != _sectionMap.end() )
350
211
      return pos->second;
351
514
    bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
352
514
    return rMode ? 
getRelocatableSection(type)139
:
getFinalSection(type)375
;
353
514
  } else {
354
19
    // This atom needs to be in a custom section.
355
19
    StringRef customName = atom->customSectionName();
356
19
    // Look to see if we have already allocated the needed custom section.
357
19
    for(SectionInfo *sect : _customSections) {
358
8
      const DefinedAtom *firstAtom = sect->atomsAndOffsets.front().atom;
359
8
      if (firstAtom->customSectionName().equals(customName)) {
360
6
        return sect;
361
6
      }
362
8
    }
363
19
    // Not found, so need to create a new custom section.
364
19
    size_t seperatorIndex = customName.find('/');
365
13
    assert(seperatorIndex != StringRef::npos);
366
13
    StringRef segName = customName.slice(0, seperatorIndex);
367
13
    StringRef sectName = customName.drop_front(seperatorIndex + 1);
368
13
    auto *sect =
369
13
        new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx,
370
13
                                     0, /* relocsToDefinedCanBeImplicit */ false);
371
13
    _customSections.push_back(sect);
372
13
    _sectionInfos.push_back(sect);
373
13
    return sect;
374
19
  }
375
744
}
376
377
649
void Util::appendAtom(SectionInfo *sect, const DefinedAtom *atom) {
378
649
  // Figure out offset for atom in this section given alignment constraints.
379
649
  uint64_t offset = sect->size;
380
649
  DefinedAtom::Alignment atomAlign = atom->alignment();
381
649
  uint64_t align = atomAlign.value;
382
649
  uint64_t requiredModulus = atomAlign.modulus;
383
649
  uint64_t currentModulus = (offset % align);
384
649
  if ( currentModulus != requiredModulus ) {
385
9
    if ( requiredModulus > currentModulus )
386
0
      offset += requiredModulus-currentModulus;
387
9
    else
388
9
      offset += align+requiredModulus-currentModulus;
389
9
  }
390
649
  // Record max alignment of any atom in this section.
391
649
  if (align > sect->alignment)
392
205
    sect->alignment = atomAlign.value;
393
649
  // Assign atom to this section with this offset.
394
649
  AtomInfo ai = {atom, offset};
395
649
  sect->atomsAndOffsets.push_back(ai);
396
649
  // Update section size to include this atom.
397
649
  sect->size = offset + atom->size();
398
649
}
399
400
168
void Util::processDefinedAtoms(const lld::File &atomFile) {
401
839
  for (const DefinedAtom *atom : atomFile.defined()) {
402
839
    processAtomAttributes(atom);
403
839
    assignAtomToSection(atom);
404
839
  }
405
168
}
406
407
839
void Util::processAtomAttributes(const DefinedAtom *atom) {
408
839
  if (auto *machoFile = dyn_cast<mach_o::MachOFile>(&atom->file())) {
409
596
    // If the file doesn't use subsections via symbols, then make sure we don't
410
596
    // add that flag to the final output file if we have a relocatable file.
411
596
    if (!machoFile->subsectionsViaSymbols())
412
23
      _subsectionsViaSymbols = false;
413
596
414
596
    // All the source files must have min versions for us to output an object
415
596
    // file with a min version.
416
596
    if (auto v = machoFile->minVersion())
417
3
      _minVersion = std::max(_minVersion, v);
418
593
    else
419
593
      _allSourceFilesHaveMinVersions = false;
420
596
421
596
    // If we don't have a platform load command, but one of the source files
422
596
    // does, then take the one from the file.
423
596
    if (!_minVersionCommandType)
424
585
      if (auto v = machoFile->minVersionLoadCommandKind())
425
9
        _minVersionCommandType = v;
426
596
  }
427
839
}
428
429
839
void Util::assignAtomToSection(const DefinedAtom *atom) {
430
839
  if (atom->contentType() == DefinedAtom::typeMachHeader) {
431
95
    _machHeaderAliasAtoms.push_back(atom);
432
95
    // Assign atom to this section with this offset.
433
95
    AtomInfo ai = {atom, 0};
434
95
    sectionForAtom(atom)->atomsAndOffsets.push_back(ai);
435
744
  } else if (atom->contentType() == DefinedAtom::typeDSOHandle)
436
95
    _machHeaderAliasAtoms.push_back(atom);
437
649
  else
438
649
    appendAtom(sectionForAtom(atom), atom);
439
839
}
440
441
689
SegmentInfo *Util::segmentForName(StringRef segName) {
442
901
  for (SegmentInfo *si : _segmentInfos) {
443
901
    if ( si->name.equals(segName) )
444
222
      return si;
445
901
  }
446
689
  auto *info = new (_allocator) SegmentInfo(segName);
447
467
448
467
  // Set the initial segment protection.
449
467
  if (segName.equals("__TEXT"))
450
160
    info->init_access = VM_PROT_READ | VM_PROT_EXECUTE;
451
307
  else if (segName.equals("__PAGEZERO"))
452
51
    info->init_access = 0;
453
256
  else if (segName.equals("__LINKEDIT"))
454
168
    info->init_access = VM_PROT_READ;
455
88
  else {
456
88
    // All others default to read-write
457
88
    info->init_access = VM_PROT_READ | VM_PROT_WRITE;
458
88
  }
459
467
460
467
  // Set max segment protection
461
467
  // Note, its overkill to use a switch statement here, but makes it so much
462
467
  // easier to use switch coverage to catch new cases.
463
467
  switch (_ctx.os()) {
464
467
    case lld::MachOLinkingContext::OS::unknown:
465
432
    case lld::MachOLinkingContext::OS::macOSX:
466
432
    case lld::MachOLinkingContext::OS::iOS_simulator:
467
432
      if (segName.equals("__PAGEZERO")) {
468
45
        info->max_access = 0;
469
45
        break;
470
45
      }
471
387
      // All others default to all
472
387
      info->max_access = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
473
387
      break;
474
387
    case lld::MachOLinkingContext::OS::iOS:
475
35
      // iPhoneOS always uses same protection for max and initial
476
35
      info->max_access = info->init_access;
477
35
      break;
478
467
  }
479
467
  _segmentInfos.push_back(info);
480
467
  return info;
481
467
}
482
483
714
unsigned Util::SegmentSorter::weight(const SegmentInfo *seg) {
484
714
 return llvm::StringSwitch<unsigned>(seg->name)
485
714
    .Case("__PAGEZERO",  1)
486
714
    .Case("__TEXT",      2)
487
714
    .Case("__DATA",      3)
488
714
    .Default(100);
489
714
}
490
491
bool Util::SegmentSorter::operator()(const SegmentInfo *left,
492
357
                                  const SegmentInfo *right) {
493
357
  return (weight(left) < weight(right));
494
357
}
495
496
284
unsigned Util::TextSectionSorter::weight(const SectionInfo *sect) {
497
284
 return llvm::StringSwitch<unsigned>(sect->sectionName)
498
284
    .Case("__text",         1)
499
284
    .Case("__stubs",        2)
500
284
    .Case("__stub_helper",  3)
501
284
    .Case("__const",        4)
502
284
    .Case("__cstring",      5)
503
284
    .Case("__unwind_info",  98)
504
284
    .Case("__eh_frame",     99)
505
284
    .Default(10);
506
284
}
507
508
bool Util::TextSectionSorter::operator()(const SectionInfo *left,
509
142
                                         const SectionInfo *right) {
510
142
  return (weight(left) < weight(right));
511
142
}
512
513
168
void Util::organizeSections() {
514
168
  // NOTE!: Keep this in sync with assignAddressesToSections.
515
168
  switch (_ctx.outputMachOType()) {
516
168
    case llvm::MachO::MH_EXECUTE:
517
51
      // Main executables, need a zero-page segment
518
51
      segmentForName("__PAGEZERO");
519
51
      // Fall into next case.
520
51
      LLVM_FALLTHROUGH;
521
95
    case llvm::MachO::MH_DYLIB:
522
95
    case llvm::MachO::MH_BUNDLE:
523
95
      // All dynamic code needs TEXT segment to hold the load commands.
524
95
      segmentForName("__TEXT");
525
95
      break;
526
95
    default:
527
73
      break;
528
168
  }
529
168
  segmentForName("__LINKEDIT");
530
168
531
168
  // Group sections into segments.
532
375
  for (SectionInfo *si : _sectionInfos) {
533
375
    SegmentInfo *seg = segmentForName(si->segmentName);
534
375
    seg->sections.push_back(si);
535
375
  }
536
168
  // Sort segments.
537
168
  std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
538
168
539
168
  // Sort sections within segments.
540
467
  for (SegmentInfo *seg : _segmentInfos) {
541
467
    if (seg->name.equals("__TEXT")) {
542
160
      std::sort(seg->sections.begin(), seg->sections.end(),
543
160
                TextSectionSorter());
544
160
    }
545
467
  }
546
168
547
168
  // Record final section indexes.
548
168
  uint32_t segmentIndex = 0;
549
168
  uint32_t sectionIndex = 1;
550
467
  for (SegmentInfo *seg : _segmentInfos) {
551
467
    seg->normalizedSegmentIndex = segmentIndex++;
552
467
    for (SectionInfo *sect : seg->sections)
553
375
      sect->finalSectionIndex = sectionIndex++;
554
467
  }
555
168
}
556
557
256
void Util::layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr) {
558
256
  seg->address = addr;
559
256
  for (SectionInfo *sect : seg->sections) {
560
127
    sect->address = llvm::alignTo(addr, sect->alignment);
561
127
    addr = sect->address + sect->size;
562
127
  }
563
256
  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
564
256
}
565
566
// __TEXT segment lays out backwards so padding is at front after load commands.
567
void Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
568
160
                                                               uint64_t &addr) {
569
160
  seg->address = addr;
570
160
  // Walks sections starting at end to calculate padding for start.
571
160
  int64_t taddr = 0;
572
408
  for (auto it = seg->sections.rbegin(); it != seg->sections.rend(); 
++it248
) {
573
248
    SectionInfo *sect = *it;
574
248
    taddr -= sect->size;
575
248
    taddr = taddr & (0 - sect->alignment);
576
248
  }
577
160
  int64_t padding = taddr - hlcSize;
578
321
  while (padding < 0)
579
161
    padding += _ctx.pageSize();
580
160
  // Start assigning section address starting at padded offset.
581
160
  addr += (padding + hlcSize);
582
248
  for (SectionInfo *sect : seg->sections) {
583
248
    sect->address = llvm::alignTo(addr, sect->alignment);
584
248
    addr = sect->address + sect->size;
585
248
  }
586
160
  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
587
160
}
588
589
168
void Util::assignAddressesToSections(const NormalizedFile &file) {
590
168
  // NOTE!: Keep this in sync with organizeSections.
591
168
  size_t hlcSize = headerAndLoadCommandsSize(file);
592
168
  uint64_t address = 0;
593
467
  for (SegmentInfo *seg : _segmentInfos) {
594
467
    if (seg->name.equals("__PAGEZERO")) {
595
51
      seg->size = _ctx.pageZeroSize();
596
51
      address += seg->size;
597
51
    }
598
416
    else if (seg->name.equals("__TEXT")) {
599
160
      // _ctx.baseAddress()  == 0 implies it was either unspecified or
600
160
      // pageZeroSize is also 0. In either case resetting address is safe.
601
160
      address = _ctx.baseAddress() ? 
_ctx.baseAddress()51
:
address109
;
602
160
      layoutSectionsInTextSegment(hlcSize, seg, address);
603
160
    } else
604
256
      layoutSectionsInSegment(seg, address);
605
467
606
467
    address = llvm::alignTo(address, _ctx.pageSize());
607
467
  }
608
168
  DEBUG_WITH_TYPE("WriterMachO-norm",
609
168
    llvm::dbgs() << "assignAddressesToSections()\n";
610
168
    for (SegmentInfo *sgi : _segmentInfos) {
611
168
      llvm::dbgs()  << "   address=" << llvm::format("0x%08llX", sgi->address)
612
168
                    << ", size="  << llvm::format("0x%08llX", sgi->size)
613
168
                    << ", segment-name='" << sgi->name
614
168
                    << "'\n";
615
168
      for (SectionInfo *si : sgi->sections) {
616
168
        llvm::dbgs()<< "      addr="  << llvm::format("0x%08llX", si->address)
617
168
                    << ", size="  << llvm::format("0x%08llX", si->size)
618
168
                    << ", section-name='" << si->sectionName
619
168
                    << "\n";
620
168
      }
621
168
    }
622
168
  );
623
168
}
624
625
168
void Util::copySegmentInfo(NormalizedFile &file) {
626
467
  for (SegmentInfo *sgi : _segmentInfos) {
627
467
    Segment seg;
628
467
    seg.name    = sgi->name;
629
467
    seg.address = sgi->address;
630
467
    seg.size    = sgi->size;
631
467
    seg.init_access  = sgi->init_access;
632
467
    seg.max_access  = sgi->max_access;
633
467
    file.segments.push_back(seg);
634
467
  }
635
168
}
636
637
375
void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
638
375
   // Add new empty section to end of file.sections.
639
375
  Section temp;
640
375
  file.sections.push_back(std::move(temp));
641
375
  Section* normSect = &file.sections.back();
642
375
  // Copy fields to normalized section.
643
375
  normSect->segmentName   = si->segmentName;
644
375
  normSect->sectionName   = si->sectionName;
645
375
  normSect->type          = si->type;
646
375
  normSect->attributes    = si->attributes;
647
375
  normSect->address       = si->address;
648
375
  normSect->alignment     = si->alignment;
649
375
  // Record where normalized section is.
650
375
  si->normalizedSectionIndex = file.sections.size()-1;
651
375
}
652
653
168
void Util::copySectionContent(NormalizedFile &file) {
654
168
  const bool r = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
655
168
656
168
  // 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
168
663
168
  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
168
671
375
  for (SectionInfo *si : _sectionInfos) {
672
375
    Section *normSect = &file.sections[si->normalizedSectionIndex];
673
375
    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
370
    // Copy content from atoms to content buffer for section.
679
370
    llvm::MutableArrayRef<uint8_t> sectionContent;
680
370
    if (si->size) {
681
360
      uint8_t *sectContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
682
360
      sectionContent = llvm::MutableArrayRef<uint8_t>(sectContent, si->size);
683
360
      normSect->content = sectionContent;
684
360
    }
685
734
    for (AtomInfo &ai : si->atomsAndOffsets) {
686
734
      if (!ai.atom->size()) {
687
114
        assert(ai.atom->begin() == ai.atom->end() &&
688
114
               "Cannot have references without content");
689
114
        continue;
690
114
      }
691
620
      auto atomContent = sectionContent.slice(ai.offsetInSection,
692
620
                                              ai.atom->size());
693
620
      _archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
694
620
                                       sectionAddrForAtom, _ctx.baseAddress(),
695
620
                                       atomContent);
696
620
    }
697
370
  }
698
168
}
699
700
168
void Util::copySectionInfo(NormalizedFile &file) {
701
168
  file.sections.reserve(_sectionInfos.size());
702
168
  // Write sections grouped by segment.
703
467
  for (SegmentInfo *sgi : _segmentInfos) {
704
467
    for (SectionInfo *si : sgi->sections) {
705
375
      appendSection(si, file);
706
375
    }
707
467
  }
708
168
}
709
710
168
void Util::updateSectionInfo(NormalizedFile &file) {
711
168
  file.sections.reserve(_sectionInfos.size());
712
168
  // sections grouped by segment.
713
467
  for (SegmentInfo *sgi : _segmentInfos) {
714
467
    Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
715
467
    normSeg->address = sgi->address;
716
467
    normSeg->size = sgi->size;
717
467
    for (SectionInfo *si : sgi->sections) {
718
375
      Section *normSect = &file.sections[si->normalizedSectionIndex];
719
375
      normSect->address = si->address;
720
375
    }
721
467
  }
722
168
}
723
724
167
void Util::copyEntryPointAddress(NormalizedFile &nFile) {
725
167
  if (!_entryAtom) {
726
120
    nFile.entryAddress = 0;
727
120
    return;
728
120
  }
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
168
void Util::buildAtomToAddressMap() {
739
168
  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
740
168
                   << "assign atom addresses:\n");
741
168
  const bool lookForEntry = _ctx.outputTypeHasEntry();
742
375
  for (SectionInfo *sect : _sectionInfos) {
743
744
    for (const AtomInfo &info : sect->atomsAndOffsets) {
744
744
      _atomToAddress[info.atom] = sect->address + info.offsetInSection;
745
744
      if (lookForEntry && 
(info.atom->contentType() == DefinedAtom::typeCode)293
&&
746
744
          
(info.atom->size() != 0)77
&&
747
744
          
info.atom->name() == _ctx.entrySymbolName()74
) {
748
47
        _entryAtom = info.atom;
749
47
      }
750
744
      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
751
744
                      << "   address="
752
744
                      << llvm::format("0x%016X", _atomToAddress[info.atom])
753
744
                      << llvm::format("    0x%09lX", info.atom)
754
744
                      << ", file=#"
755
744
                      << info.atom->file().ordinal()
756
744
                      << ", atom=#"
757
744
                      << info.atom->ordinal()
758
744
                      << ", name="
759
744
                      << info.atom->name()
760
744
                      << ", type="
761
744
                      << info.atom->contentType()
762
744
                      << "\n");
763
744
    }
764
375
  }
765
168
  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
766
168
                  << "assign header alias atom addresses:\n");
767
190
  for (const Atom *atom : _machHeaderAliasAtoms) {
768
190
    _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
168
}
794
795
168
llvm::Error Util::synthesizeDebugNotes(NormalizedFile &file) {
796
168
797
168
  // Bail out early if we don't need to generate a debug map.
798
168
  if (_ctx.debugInfoMode() == MachOLinkingContext::DebugInfoMode::noDebugMap)
799
0
    return llvm::Error::success();
800
168
801
168
  std::vector<const DefinedAtom*> atomsNeedingDebugNotes;
802
168
  std::set<const mach_o::MachOFile*> filesWithStabs;
803
168
  bool objFileHasDwarf = false;
804
168
  const File *objFile = nullptr;
805
168
806
375
  for (SectionInfo *sect : _sectionInfos) {
807
744
    for (const AtomInfo &info : sect->atomsAndOffsets) {
808
744
      if (const DefinedAtom *atom = dyn_cast<DefinedAtom>(info.atom)) {
809
744
810
744
        // FIXME: No stabs/debug-notes for symbols that wouldn't be in the
811
744
        //        symbol table.
812
744
        // FIXME: No stabs/debug-notes for kernel dtrace probes.
813
744
814
744
        if (atom->contentType() == DefinedAtom::typeCFI ||
815
744
            
atom->contentType() == DefinedAtom::typeCString709
)
816
62
          continue;
817
682
818
682
        // Whenever we encounter a new file, update the 'objfileHasDwarf' flag.
819
682
        if (&info.atom->file() != objFile) {
820
682
          objFileHasDwarf = false;
821
682
          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
682
        }
831
682
832
682
        // If this atom is from a file that needs dwarf, add it to the list.
833
682
        if (objFileHasDwarf)
834
1
          atomsNeedingDebugNotes.push_back(info.atom);
835
682
      }
836
744
    }
837
375
  }
838
168
839
168
  // Sort atoms needing debug notes by file ordinal, then atom ordinal.
840
168
  std::sort(atomsNeedingDebugNotes.begin(), atomsNeedingDebugNotes.end(),
841
168
            [](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
168
847
168
  // FIXME: Handle <rdar://problem/17689030>: Add -add_ast_path option to \
848
168
  //        linker which add N_AST stab entry to output
849
168
  // See OutputFile::synthesizeDebugNotes in ObjectFile.cpp in ld64.
850
168
851
168
  StringRef oldFileName = "";
852
168
  StringRef oldDirPath = "";
853
168
  bool wroteStartSO = false;
854
168
  std::unordered_set<std::string> seenFiles;
855
168
  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
168
930
168
  // Emit ending SO if necessary.
931
168
  if (wroteStartSO)
932
1
    _stabs.push_back(mach_o::Stab(nullptr, N_SO, 1, 0, 0, ""));
933
168
934
168
  // Copy any stabs from .o file.
935
168
  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
168
944
168
  return llvm::Error::success();
945
168
}
946
947
462
uint16_t Util::descBits(const DefinedAtom* atom) {
948
462
  uint16_t desc = 0;
949
462
  switch (atom->merge()) {
950
462
  case lld::DefinedAtom::mergeNo:
951
454
  case lld::DefinedAtom::mergeAsTentative:
952
454
    break;
953
454
  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
462
  }
963
462
  if (atom->contentType() == lld::DefinedAtom::typeResolver)
964
2
    desc |= N_SYMBOL_RESOLVER;
965
462
  if (atom->contentType() == lld::DefinedAtom::typeMachHeader)
966
95
    desc |= REFERENCED_DYNAMICALLY;
967
462
  if (_archHandler.isThumbFunction(*atom))
968
22
    desc |= N_ARM_THUMB_DEF;
969
462
  if (atom->deadStrip() == DefinedAtom::deadStripNever &&
970
462
      
_ctx.outputMachOType() == llvm::MachO::MH_OBJECT124
) {
971
19
    if ((atom->contentType() != DefinedAtom::typeInitializerPtr)
972
19
     && (atom->contentType() != DefinedAtom::typeTerminatorPtr))
973
19
    desc |= N_NO_DEAD_STRIP;
974
19
  }
975
462
  return desc;
976
462
}
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
463
                                       SymbolScope &scope) {
986
463
  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
987
463
  switch (atom->scope()) {
988
463
  case Atom::scopeTranslationUnit:
989
98
    scope = 0;
990
98
    inGlobalsRegion = false;
991
98
    return llvm::Error::success();
992
463
  case Atom::scopeLinkageUnit:
993
69
    if ((_ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) &&
994
69
        
_ctx.exportSymbolNamed(atom->name())10
) {
995
1
      return llvm::make_error<GenericError>(
996
1
                          Twine("cannot export hidden symbol ") + atom->name());
997
1
    }
998
68
    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
64
    }
1006
64
    // scopeLinkageUnit symbols are no longer global once linked.
1007
64
    scope = N_PEXT;
1008
64
    inGlobalsRegion = false;
1009
64
    return llvm::Error::success();
1010
296
  case Atom::scopeGlobal:
1011
296
    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
275
    } else {
1022
275
      scope = N_EXT;
1023
275
      inGlobalsRegion = true;
1024
275
      return llvm::Error::success();
1025
275
    }
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
168
                             NormalizedFile &file) {
1035
168
  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
1036
168
  // Mach-O symbol table has four regions: stabs, locals, globals, undefs.
1037
168
1038
168
  // Add all stabs.
1039
168
  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
168
1053
168
  // Add all local (non-global) symbols in address order
1054
168
  std::vector<AtomAndIndex> globals;
1055
168
  globals.reserve(512);
1056
375
  for (SectionInfo *sect : _sectionInfos) {
1057
743
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1058
743
      const DefinedAtom *atom = info.atom;
1059
743
      if (!atom->name().empty()) {
1060
463
        SymbolScope symbolScope;
1061
463
        bool inGlobalsRegion;
1062
463
        if (auto ec = getSymbolTableRegion(atom, inGlobalsRegion, symbolScope)){
1063
1
          return ec;
1064
1
        }
1065
462
        if (inGlobalsRegion) {
1066
291
          AtomAndIndex ai = { atom, sect->finalSectionIndex, symbolScope };
1067
291
          globals.push_back(ai);
1068
291
        } else {
1069
171
          Symbol sym;
1070
171
          sym.name  = atom->name();
1071
171
          sym.type  = N_SECT;
1072
171
          sym.scope = symbolScope;
1073
171
          sym.sect  = sect->finalSectionIndex;
1074
171
          sym.desc  = descBits(atom);
1075
171
          sym.value = _atomToAddress[atom];
1076
171
          _atomToSymbolIndex[atom] = file.localSymbols.size();
1077
171
          file.localSymbols.push_back(sym);
1078
171
        }
1079
462
      } 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
743
    }
1096
375
  }
1097
168
1098
168
  // Sort global symbol alphabetically, then add to symbol table.
1099
168
  std::sort(globals.begin(), globals.end(), AtomSorter());
1100
167
  const uint32_t globalStartIndex = file.localSymbols.size();
1101
291
  for (AtomAndIndex &ai : globals) {
1102
291
    Symbol sym;
1103
291
    sym.name  = ai.atom->name();
1104
291
    sym.type  = N_SECT;
1105
291
    sym.scope = ai.scope;
1106
291
    sym.sect  = ai.index;
1107
291
    sym.desc  = descBits(static_cast<const DefinedAtom*>(ai.atom));
1108
291
    sym.value = _atomToAddress[ai.atom];
1109
291
    _atomToSymbolIndex[ai.atom] = globalStartIndex + file.globalSymbols.size();
1110
291
    file.globalSymbols.push_back(sym);
1111
291
  }
1112
167
1113
167
  // Sort undefined symbol alphabetically, then add to symbol table.
1114
167
  std::vector<AtomAndIndex> undefs;
1115
167
  undefs.reserve(128);
1116
167
  for (const UndefinedAtom *atom : atomFile.undefined()) {
1117
44
    AtomAndIndex ai = { atom, 0, N_EXT };
1118
44
    undefs.push_back(ai);
1119
44
  }
1120
167
  for (const SharedLibraryAtom *atom : atomFile.sharedLibrary()) {
1121
138
    AtomAndIndex ai = { atom, 0, N_EXT };
1122
138
    undefs.push_back(ai);
1123
138
  }
1124
167
  std::sort(undefs.begin(), undefs.end(), AtomSorter());
1125
167
  const uint32_t start = file.globalSymbols.size() + file.localSymbols.size();
1126
182
  for (AtomAndIndex &ai : undefs) {
1127
182
    Symbol sym;
1128
182
    uint16_t desc = 0;
1129
182
    if (!rMode) {
1130
132
      uint8_t ordinal = 0;
1131
132
      if (!_ctx.useFlatNamespace())
1132
130
        ordinal = dylibOrdinal(dyn_cast<SharedLibraryAtom>(ai.atom));
1133
132
      llvm::MachO::SET_LIBRARY_ORDINAL(desc, ordinal);
1134
132
    }
1135
182
    sym.name  = ai.atom->name();
1136
182
    sym.type  = N_UNDF;
1137
182
    sym.scope = ai.scope;
1138
182
    sym.sect  = 0;
1139
182
    sym.desc  = desc;
1140
182
    sym.value = 0;
1141
182
    _atomToSymbolIndex[ai.atom] = file.undefinedSymbols.size() + start;
1142
182
    file.undefinedSymbols.push_back(sym);
1143
182
  }
1144
167
1145
167
  return llvm::Error::success();
1146
168
}
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
167
void Util::addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file) {
1171
373
  for (SectionInfo *si : _sectionInfos) {
1172
373
    Section &normSect = file.sections[si->normalizedSectionIndex];
1173
373
    switch (si->type) {
1174
373
    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
373
    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
373
    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
373
    default:
1215
316
      break;
1216
373
    }
1217
373
  }
1218
167
}
1219
1220
void Util::addDependentDylibs(const lld::File &atomFile,
1221
168
                              NormalizedFile &nFile) {
1222
168
  // Scan all imported symbols and build up list of dylibs they are from.
1223
168
  int ordinal = 1;
1224
168
  for (const auto *dylib : _ctx.allDylibs()) {
1225
111
    DylibPathToInfo::iterator pos = _dylibInfo.find(dylib->installName());
1226
111
    if (pos == _dylibInfo.end()) {
1227
110
      DylibInfo info;
1228
110
      bool flatNamespaceAtom = dylib == _ctx.flatNamespaceFile();
1229
110
1230
110
      // If we're in -flat_namespace mode (or this atom came from the flat
1231
110
      // namespace file under -undefined dynamic_lookup) then use the flat
1232
110
      // lookup ordinal.
1233
110
      if (flatNamespaceAtom || _ctx.useFlatNamespace())
1234
1
        info.ordinal = BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
1235
109
      else
1236
109
        info.ordinal = ordinal++;
1237
110
      info.hasWeak = false;
1238
110
      info.hasNonWeak = !info.hasWeak;
1239
110
      _dylibInfo[dylib->installName()] = info;
1240
110
1241
110
      // Unless this was a flat_namespace atom, record the source dylib.
1242
110
      if (!flatNamespaceAtom) {
1243
110
        DependentDylib depInfo;
1244
110
        depInfo.path = dylib->installName();
1245
110
        depInfo.kind = llvm::MachO::LC_LOAD_DYLIB;
1246
110
        depInfo.currentVersion = _ctx.dylibCurrentVersion(dylib->path());
1247
110
        depInfo.compatVersion = _ctx.dylibCompatVersion(dylib->path());
1248
110
        nFile.dependentDylibs.push_back(depInfo);
1249
110
      }
1250
110
    } else {
1251
1
      pos->second.hasWeak = false;
1252
1
      pos->second.hasNonWeak = !pos->second.hasWeak;
1253
1
    }
1254
111
  }
1255
168
  // Automatically weak link dylib in which all symbols are weak (canBeNull).
1256
168
  for (DependentDylib &dep : nFile.dependentDylibs) {
1257
110
    DylibInfo &info = _dylibInfo[dep.path];
1258
110
    if (info.hasWeak && 
!info.hasNonWeak0
)
1259
0
      dep.kind = llvm::MachO::LC_LOAD_WEAK_DYLIB;
1260
110
    else if (_ctx.isUpwardDylib(dep.path))
1261
1
      dep.kind = llvm::MachO::LC_LOAD_UPWARD_DYLIB;
1262
110
  }
1263
168
}
1264
1265
185
int Util::dylibOrdinal(const SharedLibraryAtom *sa) {
1266
185
  return _dylibInfo[sa->loadName()].ordinal;
1267
185
}
1268
1269
void Util::segIndexForSection(const SectionInfo *sect, uint8_t &segmentIndex,
1270
229
                                                  uint64_t &segmentStartAddr) {
1271
229
  segmentIndex = 0;
1272
452
  for (const SegmentInfo *seg : _segmentInfos) {
1273
452
    if ((seg->address <= sect->address)
1274
452
      && (seg->address+seg->size >= sect->address+sect->size)) {
1275
229
      segmentStartAddr = seg->address;
1276
229
      return;
1277
229
    }
1278
223
    ++segmentIndex;
1279
223
  }
1280
229
  
llvm_unreachable0
("section not in any segment");
1281
229
}
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
167
void Util::addSectionRelocs(const lld::File &, NormalizedFile &file) {
1293
167
  if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
1294
95
    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
167
void Util::addFunctionStarts(const lld::File &, NormalizedFile &file) {
1336
167
  if (!_ctx.generateFunctionStartsLoadCommand())
1337
81
    return;
1338
86
  file.functionStarts.reserve(8192);
1339
86
  // Delta compress function starts, starting with the mach header symbol.
1340
86
  const uint64_t badAddress = ~0ULL;
1341
86
  uint64_t addr = badAddress;
1342
220
  for (SectionInfo *si : _sectionInfos) {
1343
437
    for (const AtomInfo &info : si->atomsAndOffsets) {
1344
437
      auto type = info.atom->contentType();
1345
437
      if (type == DefinedAtom::typeMachHeader) {
1346
86
        addr = _atomToAddress[info.atom];
1347
86
        continue;
1348
86
      }
1349
351
      if (type != DefinedAtom::typeCode)
1350
213
        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
220
  }
1369
86
1370
86
  // Null terminate, and pad to pointer size for this arch.
1371
86
  file.functionStarts.push_back(0);
1372
86
1373
86
  auto size = file.functionStarts.size();
1374
86
  for (unsigned i = size, e = llvm::alignTo(size, _ctx.is64Bit() ? 
876
:
410
);
1375
459
       i != e; 
++i373
)
1376
373
    file.functionStarts.push_back(0);
1377
86
}
1378
1379
167
void Util::buildDataInCodeArray(const lld::File &, NormalizedFile &file) {
1380
167
  if (!_ctx.generateDataInCodeLoadCommand())
1381
10
    return;
1382
363
  
for (SectionInfo *si : _sectionInfos)157
{
1383
721
    for (const AtomInfo &info : si->atomsAndOffsets) {
1384
721
      // Atoms that contain data-in-code have "transition" references
1385
721
      // which mark a point where the embedded data starts of ends.
1386
721
      // This needs to be converted to the mach-o format which is an array
1387
721
      // of data-in-code ranges.
1388
721
      uint32_t startOffset = 0;
1389
721
      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
721
      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
721
    }
1418
363
  }
1419
157
}
1420
1421
void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
1422
167
                                                        NormalizedFile &nFile) {
1423
167
  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1424
72
    return;
1425
95
1426
95
  uint8_t segmentIndex;
1427
95
  uint64_t segmentStartAddr;
1428
95
  uint32_t offsetInBindInfo = 0;
1429
95
1430
229
  for (SectionInfo *sect : _sectionInfos) {
1431
229
    segIndexForSection(sect, segmentIndex, segmentStartAddr);
1432
455
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1433
455
      const DefinedAtom *atom = info.atom;
1434
455
      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
455
    }
1489
229
  }
1490
95
}
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
167
void Util::addExportInfo(const lld::File &atomFile, NormalizedFile &nFile) {
1534
167
  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1535
72
    return;
1536
95
1537
229
  
for (SectionInfo *sect : _sectionInfos)95
{
1538
455
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1539
455
      const DefinedAtom *atom = info.atom;
1540
455
      if (atom->scope() != Atom::scopeGlobal)
1541
253
        continue;
1542
202
      if (_ctx.exportRestrictMode()) {
1543
16
        if (!_ctx.exportSymbolNamed(atom->name()))
1544
6
          continue;
1545
196
      }
1546
196
      Export exprt;
1547
196
      exprt.name = atom->name();
1548
196
      exprt.offset = _atomToAddress[atom] - _ctx.baseAddress();
1549
196
      exprt.kind = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
1550
196
      if (atom->merge() == DefinedAtom::mergeAsWeak)
1551
1
        exprt.flags = EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
1552
195
      else
1553
195
        exprt.flags = 0;
1554
196
      exprt.otherOffset = 0;
1555
196
      exprt.otherName = StringRef();
1556
196
      nFile.exportInfo.push_back(exprt);
1557
196
    }
1558
229
  }
1559
95
}
1560
1561
168
uint32_t Util::fileFlags() {
1562
168
  // FIXME: these need to determined at runtime.
1563
168
  if (_ctx.outputMachOType() == MH_OBJECT) {
1564
73
    return _subsectionsViaSymbols ? 
MH_SUBSECTIONS_VIA_SYMBOLS65
:
08
;
1565
95
  } else {
1566
95
    uint32_t flags = MH_DYLDLINK;
1567
95
    if (!_ctx.useFlatNamespace())
1568
94
        flags |= MH_TWOLEVEL | MH_NOUNDEFS;
1569
95
    if ((_ctx.outputMachOType() == MH_EXECUTE) && 
_ctx.PIE()51
)
1570
23
      flags |= MH_PIE;
1571
95
    if (_hasTLVDescriptors)
1572
1
      flags |= (MH_PIE | MH_HAS_TLV_DESCRIPTORS);
1573
95
    return flags;
1574
95
  }
1575
168
}
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
168
                                           const MachOLinkingContext &context) {
1587
168
  // The util object buffers info until the normalized file can be made.
1588
168
  Util util(context);
1589
168
  util.processDefinedAtoms(atomFile);
1590
168
  util.organizeSections();
1591
168
1592
168
  std::unique_ptr<NormalizedFile> f(new NormalizedFile());
1593
168
  NormalizedFile &normFile = *f.get();
1594
168
  normFile.arch = context.arch();
1595
168
  normFile.fileType = context.outputMachOType();
1596
168
  normFile.flags = util.fileFlags();
1597
168
  normFile.stackSize = context.stackSize();
1598
168
  normFile.installName = context.installName();
1599
168
  normFile.currentVersion = context.currentVersion();
1600
168
  normFile.compatVersion = context.compatibilityVersion();
1601
168
  normFile.os = context.os();
1602
168
1603
168
  // If we are emitting an object file, then the min version is the maximum
1604
168
  // of the min's of all the source files and the cmdline.
1605
168
  if (normFile.fileType == llvm::MachO::MH_OBJECT)
1606
73
    normFile.minOSverson = std::max(context.osMinVersion(), util.minVersion());
1607
95
  else
1608
95
    normFile.minOSverson = context.osMinVersion();
1609
168
1610
168
  normFile.minOSVersionKind = util.minVersionCommandType();
1611
168
1612
168
  normFile.sdkVersion = context.sdkVersion();
1613
168
  normFile.sourceVersion = context.sourceVersion();
1614
168
1615
168
  if (context.generateVersionLoadCommand() &&
1616
168
      
context.os() != MachOLinkingContext::OS::unknown86
)
1617
86
    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
168
  normFile.generateDataInCodeLoadCommand =
1629
168
    context.generateDataInCodeLoadCommand();
1630
168
  normFile.pageSize = context.pageSize();
1631
168
  normFile.rpaths = context.rpaths();
1632
168
  util.addDependentDylibs(atomFile, normFile);
1633
168
  util.copySegmentInfo(normFile);
1634
168
  util.copySectionInfo(normFile);
1635
168
  util.assignAddressesToSections(normFile);
1636
168
  util.buildAtomToAddressMap();
1637
168
  if (auto err = util.synthesizeDebugNotes(normFile))
1638
0
    return std::move(err);
1639
168
  util.updateSectionInfo(normFile);
1640
168
  util.copySectionContent(normFile);
1641
168
  if (auto ec = util.addSymbols(atomFile, normFile)) {
1642
1
    return std::move(ec);
1643
1
  }
1644
167
  util.addIndirectSymbols(atomFile, normFile);
1645
167
  util.addRebaseAndBindingInfo(atomFile, normFile);
1646
167
  util.addExportInfo(atomFile, normFile);
1647
167
  util.addSectionRelocs(atomFile, normFile);
1648
167
  util.addFunctionStarts(atomFile, normFile);
1649
167
  util.buildDataInCodeArray(atomFile, normFile);
1650
167
  util.copyEntryPointAddress(normFile);
1651
167
1652
167
  return std::move(f);
1653
167
}
1654
1655
} // namespace normalized
1656
} // namespace mach_o
1657
} // namespace lld