Coverage Report

Created: 2018-01-17 21:32

/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
187
                 normalizedSectionIndex(0), finalSectionIndex(0) {
85
187
  uint16_t align = 1;
86
187
  if (ctxt.sectionAligned(segmentName, sectionName, align)) {
87
2
    alignment = align;
88
2
  }
89
187
}
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
221
   normalizedSegmentIndex(0) {
106
221
}
107
108
class Util {
109
public:
110
  Util(const MachOLinkingContext &ctxt)
111
      : _ctx(ctxt), _archHandler(ctxt.archHandler()), _entryAtom(nullptr),
112
79
        _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
30
  bool allSourceFilesHaveMinVersions() const {
138
30
    return _allSourceFilesHaveMinVersions;
139
30
  }
140
141
30
  uint32_t minVersion() const {
142
30
    return _minVersion;
143
30
  }
144
145
80
  LoadCommandType minVersionCommandType() const {
146
80
    return _minVersionCommandType;
147
80
  }
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
79
Util::~Util() {
213
79
  // The SectionInfo structs are BumpPtr allocated, but atomsAndOffsets needs
214
79
  // to be deleted.
215
187
  for (SectionInfo *si : _sectionInfos) {
216
187
    // clear() destroys vector elements, but does not deallocate.
217
187
    // Instead use swap() to deallocate vector buffer.
218
187
    std::vector<AtomInfo> empty;
219
187
    si->atomsAndOffsets.swap(empty);
220
187
  }
221
79
  // The SegmentInfo structs are BumpPtr allocated, but sections needs
222
79
  // to be deleted.
223
221
  for (SegmentInfo *sgi : _segmentInfos) {
224
221
    std::vector<SectionInfo*> empty2;
225
221
    sgi->sections.swap(empty2);
226
221
  }
227
79
}
228
229
62
SectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
230
62
  StringRef segmentName;
231
62
  StringRef sectionName;
232
62
  SectionType sectionType;
233
62
  SectionAttr sectionAttrs;
234
62
  bool relocsToDefinedCanBeImplicit;
235
62
236
62
  // Use same table used by when parsing .o files.
237
62
  relocatableSectionInfoForContentType(type, segmentName, sectionName,
238
62
                                       sectionType, sectionAttrs,
239
62
                                       relocsToDefinedCanBeImplicit);
240
62
  // If we already have a SectionInfo with this name, re-use it.
241
62
  // This can happen if two ContentType map to the same mach-o section.
242
62
  for (auto sect : _sectionMap) {
243
53
    if (sect.second->sectionName.equals(sectionName) &&
244
53
        
sect.second->segmentName.equals(segmentName)0
) {
245
0
      return sect.second;
246
0
    }
247
53
  }
248
62
  // Otherwise allocate new SectionInfo object.
249
62
  auto *sect = new (_allocator)
250
62
      SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs,
251
62
                  relocsToDefinedCanBeImplicit);
252
62
  _sectionInfos.push_back(sect);
253
62
  _sectionMap[type] = sect;
254
62
  return sect;
255
62
}
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
195
SectionInfo *Util::getFinalSection(DefinedAtom::ContentType atomType) {
308
1.17k
  for (auto &p : sectsToAtomType) {
309
1.17k
    if (p.atomType != atomType)
310
984
      continue;
311
195
    SectionAttr sectionAttrs = 0;
312
195
    switch (atomType) {
313
195
    case DefinedAtom::typeMachHeader:
314
140
    case DefinedAtom::typeCode:
315
140
    case DefinedAtom::typeStub:
316
140
    case DefinedAtom::typeStubHelper:
317
140
      sectionAttrs = S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS;
318
140
      break;
319
140
    case DefinedAtom::typeThunkTLV:
320
0
      _hasTLVDescriptors = true;
321
0
      break;
322
140
    default:
323
55
      break;
324
195
    }
325
195
    // If we already have a SectionInfo with this name, re-use it.
326
195
    // This can happen if two ContentType map to the same mach-o section.
327
325
    
for (auto sect : _sectionMap)195
{
328
325
      if (sect.second->sectionName.equals(p.sectionName) &&
329
325
          
sect.second->segmentName.equals(p.segmentName)75
) {
330
74
        return sect.second;
331
74
      }
332
325
    }
333
195
    // Otherwise allocate new SectionInfo object.
334
195
    auto *sect = new (_allocator) SectionInfo(
335
121
        p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs,
336
121
        /* relocsToDefinedCanBeImplicit */ false);
337
121
    _sectionInfos.push_back(sect);
338
121
    _sectionMap[atomType] = sect;
339
121
    return sect;
340
195
  }
341
195
  
llvm_unreachable0
("content type not yet supported");
342
0
}
343
344
340
SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
345
340
  if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
346
336
    // Section for this atom is derived from content type.
347
336
    DefinedAtom::ContentType type = atom->contentType();
348
336
    auto pos = _sectionMap.find(type);
349
336
    if ( pos != _sectionMap.end() )
350
79
      return pos->second;
351
257
    bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
352
257
    return rMode ? 
getRelocatableSection(type)62
:
getFinalSection(type)195
;
353
257
  } else {
354
4
    // This atom needs to be in a custom section.
355
4
    StringRef customName = atom->customSectionName();
356
4
    // Look to see if we have already allocated the needed custom section.
357
4
    for(SectionInfo *sect : _customSections) {
358
0
      const DefinedAtom *firstAtom = sect->atomsAndOffsets.front().atom;
359
0
      if (firstAtom->customSectionName().equals(customName)) {
360
0
        return sect;
361
0
      }
362
0
    }
363
4
    // Not found, so need to create a new custom section.
364
4
    size_t seperatorIndex = customName.find('/');
365
4
    assert(seperatorIndex != StringRef::npos);
366
4
    StringRef segName = customName.slice(0, seperatorIndex);
367
4
    StringRef sectName = customName.drop_front(seperatorIndex + 1);
368
4
    auto *sect =
369
4
        new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx,
370
4
                                     0, /* relocsToDefinedCanBeImplicit */ false);
371
4
    _customSections.push_back(sect);
372
4
    _sectionInfos.push_back(sect);
373
4
    return sect;
374
4
  }
375
340
}
376
377
291
void Util::appendAtom(SectionInfo *sect, const DefinedAtom *atom) {
378
291
  // Figure out offset for atom in this section given alignment constraints.
379
291
  uint64_t offset = sect->size;
380
291
  DefinedAtom::Alignment atomAlign = atom->alignment();
381
291
  uint64_t align = atomAlign.value;
382
291
  uint64_t requiredModulus = atomAlign.modulus;
383
291
  uint64_t currentModulus = (offset % align);
384
291
  if ( currentModulus != requiredModulus ) {
385
3
    if ( requiredModulus > currentModulus )
386
0
      offset += requiredModulus-currentModulus;
387
3
    else
388
3
      offset += align+requiredModulus-currentModulus;
389
3
  }
390
291
  // Record max alignment of any atom in this section.
391
291
  if (align > sect->alignment)
392
96
    sect->alignment = atomAlign.value;
393
291
  // Assign atom to this section with this offset.
394
291
  AtomInfo ai = {atom, offset};
395
291
  sect->atomsAndOffsets.push_back(ai);
396
291
  // Update section size to include this atom.
397
291
  sect->size = offset + atom->size();
398
291
}
399
400
79
void Util::processDefinedAtoms(const lld::File &atomFile) {
401
389
  for (const DefinedAtom *atom : atomFile.defined()) {
402
389
    processAtomAttributes(atom);
403
389
    assignAtomToSection(atom);
404
389
  }
405
79
}
406
407
389
void Util::processAtomAttributes(const DefinedAtom *atom) {
408
389
  if (auto *machoFile = dyn_cast<mach_o::MachOFile>(&atom->file())) {
409
261
    // If the file doesn't use subsections via symbols, then make sure we don't
410
261
    // add that flag to the final output file if we have a relocatable file.
411
261
    if (!machoFile->subsectionsViaSymbols())
412
9
      _subsectionsViaSymbols = false;
413
261
414
261
    // All the source files must have min versions for us to output an object
415
261
    // file with a min version.
416
261
    if (auto v = machoFile->minVersion())
417
3
      _minVersion = std::max(_minVersion, v);
418
258
    else
419
258
      _allSourceFilesHaveMinVersions = false;
420
261
421
261
    // If we don't have a platform load command, but one of the source files
422
261
    // does, then take the one from the file.
423
261
    if (!_minVersionCommandType)
424
256
      if (auto v = machoFile->minVersionLoadCommandKind())
425
6
        _minVersionCommandType = v;
426
261
  }
427
389
}
428
429
389
void Util::assignAtomToSection(const DefinedAtom *atom) {
430
389
  if (atom->contentType() == DefinedAtom::typeMachHeader) {
431
49
    _machHeaderAliasAtoms.push_back(atom);
432
49
    // Assign atom to this section with this offset.
433
49
    AtomInfo ai = {atom, 0};
434
49
    sectionForAtom(atom)->atomsAndOffsets.push_back(ai);
435
340
  } else if (atom->contentType() == DefinedAtom::typeDSOHandle)
436
49
    _machHeaderAliasAtoms.push_back(atom);
437
291
  else
438
291
    appendAtom(sectionForAtom(atom), atom);
439
389
}
440
441
341
SegmentInfo *Util::segmentForName(StringRef segName) {
442
466
  for (SegmentInfo *si : _segmentInfos) {
443
466
    if ( si->name.equals(segName) )
444
120
      return si;
445
466
  }
446
341
  auto *info = new (_allocator) SegmentInfo(segName);
447
221
448
221
  // Set the initial segment protection.
449
221
  if (segName.equals("__TEXT"))
450
76
    info->init_access = VM_PROT_READ | VM_PROT_EXECUTE;
451
145
  else if (segName.equals("__PAGEZERO"))
452
26
    info->init_access = 0;
453
119
  else if (segName.equals("__LINKEDIT"))
454
79
    info->init_access = VM_PROT_READ;
455
40
  else {
456
40
    // All others default to read-write
457
40
    info->init_access = VM_PROT_READ | VM_PROT_WRITE;
458
40
  }
459
221
460
221
  // Set max segment protection
461
221
  // Note, its overkill to use a switch statement here, but makes it so much
462
221
  // easier to use switch coverage to catch new cases.
463
221
  switch (_ctx.os()) {
464
221
    case lld::MachOLinkingContext::OS::unknown:
465
210
    case lld::MachOLinkingContext::OS::macOSX:
466
210
    case lld::MachOLinkingContext::OS::iOS_simulator:
467
210
      if (segName.equals("__PAGEZERO")) {
468
25
        info->max_access = 0;
469
25
        break;
470
25
      }
471
185
      // All others default to all
472
185
      info->max_access = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
473
185
      break;
474
185
    case lld::MachOLinkingContext::OS::iOS:
475
11
      // iPhoneOS always uses same protection for max and initial
476
11
      info->max_access = info->init_access;
477
11
      break;
478
221
  }
479
221
  _segmentInfos.push_back(info);
480
221
  return info;
481
221
}
482
483
336
unsigned Util::SegmentSorter::weight(const SegmentInfo *seg) {
484
336
 return llvm::StringSwitch<unsigned>(seg->name)
485
336
    .Case("__PAGEZERO",  1)
486
336
    .Case("__TEXT",      2)
487
336
    .Case("__DATA",      3)
488
336
    .Default(100);
489
336
}
490
491
bool Util::SegmentSorter::operator()(const SegmentInfo *left,
492
168
                                  const SegmentInfo *right) {
493
168
  return (weight(left) < weight(right));
494
168
}
495
496
156
unsigned Util::TextSectionSorter::weight(const SectionInfo *sect) {
497
156
 return llvm::StringSwitch<unsigned>(sect->sectionName)
498
156
    .Case("__text",         1)
499
156
    .Case("__stubs",        2)
500
156
    .Case("__stub_helper",  3)
501
156
    .Case("__const",        4)
502
156
    .Case("__cstring",      5)
503
156
    .Case("__unwind_info",  98)
504
156
    .Case("__eh_frame",     99)
505
156
    .Default(10);
506
156
}
507
508
bool Util::TextSectionSorter::operator()(const SectionInfo *left,
509
78
                                         const SectionInfo *right) {
510
78
  return (weight(left) < weight(right));
511
78
}
512
513
79
void Util::organizeSections() {
514
79
  // NOTE!: Keep this in sync with assignAddressesToSections.
515
79
  switch (_ctx.outputMachOType()) {
516
79
    case llvm::MachO::MH_EXECUTE:
517
26
      // Main executables, need a zero-page segment
518
26
      segmentForName("__PAGEZERO");
519
26
      // Fall into next case.
520
26
      LLVM_FALLTHROUGH;
521
49
    case llvm::MachO::MH_DYLIB:
522
49
    case llvm::MachO::MH_BUNDLE:
523
49
      // All dynamic code needs TEXT segment to hold the load commands.
524
49
      segmentForName("__TEXT");
525
49
      break;
526
49
    default:
527
30
      break;
528
79
  }
529
79
  segmentForName("__LINKEDIT");
530
79
531
79
  // Group sections into segments.
532
187
  for (SectionInfo *si : _sectionInfos) {
533
187
    SegmentInfo *seg = segmentForName(si->segmentName);
534
187
    seg->sections.push_back(si);
535
187
  }
536
79
  // Sort segments.
537
79
  std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
538
79
539
79
  // Sort sections within segments.
540
221
  for (SegmentInfo *seg : _segmentInfos) {
541
221
    if (seg->name.equals("__TEXT")) {
542
76
      std::sort(seg->sections.begin(), seg->sections.end(),
543
76
                TextSectionSorter());
544
76
    }
545
221
  }
546
79
547
79
  // Record final section indexes.
548
79
  uint32_t segmentIndex = 0;
549
79
  uint32_t sectionIndex = 1;
550
221
  for (SegmentInfo *seg : _segmentInfos) {
551
221
    seg->normalizedSegmentIndex = segmentIndex++;
552
221
    for (SectionInfo *sect : seg->sections)
553
187
      sect->finalSectionIndex = sectionIndex++;
554
221
  }
555
79
}
556
557
119
void Util::layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr) {
558
119
  seg->address = addr;
559
119
  for (SectionInfo *sect : seg->sections) {
560
65
    sect->address = llvm::alignTo(addr, sect->alignment);
561
65
    addr = sect->address + sect->size;
562
65
  }
563
119
  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
564
119
}
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
76
                                                               uint64_t &addr) {
569
76
  seg->address = addr;
570
76
  // Walks sections starting at end to calculate padding for start.
571
76
  int64_t taddr = 0;
572
198
  for (auto it = seg->sections.rbegin(); it != seg->sections.rend(); 
++it122
) {
573
122
    SectionInfo *sect = *it;
574
122
    taddr -= sect->size;
575
122
    taddr = taddr & (0 - sect->alignment);
576
122
  }
577
76
  int64_t padding = taddr - hlcSize;
578
152
  while (padding < 0)
579
76
    padding += _ctx.pageSize();
580
76
  // Start assigning section address starting at padded offset.
581
76
  addr += (padding + hlcSize);
582
122
  for (SectionInfo *sect : seg->sections) {
583
122
    sect->address = llvm::alignTo(addr, sect->alignment);
584
122
    addr = sect->address + sect->size;
585
122
  }
586
76
  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
587
76
}
588
589
79
void Util::assignAddressesToSections(const NormalizedFile &file) {
590
79
  // NOTE!: Keep this in sync with organizeSections.
591
79
  size_t hlcSize = headerAndLoadCommandsSize(file);
592
79
  uint64_t address = 0;
593
221
  for (SegmentInfo *seg : _segmentInfos) {
594
221
    if (seg->name.equals("__PAGEZERO")) {
595
26
      seg->size = _ctx.pageZeroSize();
596
26
      address += seg->size;
597
26
    }
598
195
    else if (seg->name.equals("__TEXT")) {
599
76
      // _ctx.baseAddress()  == 0 implies it was either unspecified or
600
76
      // pageZeroSize is also 0. In either case resetting address is safe.
601
76
      address = _ctx.baseAddress() ? 
_ctx.baseAddress()26
:
address50
;
602
76
      layoutSectionsInTextSegment(hlcSize, seg, address);
603
76
    } else
604
119
      layoutSectionsInSegment(seg, address);
605
221
606
221
    address = llvm::alignTo(address, _ctx.pageSize());
607
221
  }
608
79
  DEBUG_WITH_TYPE("WriterMachO-norm",
609
79
    llvm::dbgs() << "assignAddressesToSections()\n";
610
79
    for (SegmentInfo *sgi : _segmentInfos) {
611
79
      llvm::dbgs()  << "   address=" << llvm::format("0x%08llX", sgi->address)
612
79
                    << ", size="  << llvm::format("0x%08llX", sgi->size)
613
79
                    << ", segment-name='" << sgi->name
614
79
                    << "'\n";
615
79
      for (SectionInfo *si : sgi->sections) {
616
79
        llvm::dbgs()<< "      addr="  << llvm::format("0x%08llX", si->address)
617
79
                    << ", size="  << llvm::format("0x%08llX", si->size)
618
79
                    << ", section-name='" << si->sectionName
619
79
                    << "\n";
620
79
      }
621
79
    }
622
79
  );
623
79
}
624
625
79
void Util::copySegmentInfo(NormalizedFile &file) {
626
221
  for (SegmentInfo *sgi : _segmentInfos) {
627
221
    Segment seg;
628
221
    seg.name    = sgi->name;
629
221
    seg.address = sgi->address;
630
221
    seg.size    = sgi->size;
631
221
    seg.init_access  = sgi->init_access;
632
221
    seg.max_access  = sgi->max_access;
633
221
    file.segments.push_back(seg);
634
221
  }
635
79
}
636
637
187
void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
638
187
   // Add new empty section to end of file.sections.
639
187
  Section temp;
640
187
  file.sections.push_back(std::move(temp));
641
187
  Section* normSect = &file.sections.back();
642
187
  // Copy fields to normalized section.
643
187
  normSect->segmentName   = si->segmentName;
644
187
  normSect->sectionName   = si->sectionName;
645
187
  normSect->type          = si->type;
646
187
  normSect->attributes    = si->attributes;
647
187
  normSect->address       = si->address;
648
187
  normSect->alignment     = si->alignment;
649
187
  // Record where normalized section is.
650
187
  si->normalizedSectionIndex = file.sections.size()-1;
651
187
}
652
653
79
void Util::copySectionContent(NormalizedFile &file) {
654
79
  const bool r = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
655
79
656
79
  // Utility function for ArchHandler to find address of atom in output file.
657
739
  auto addrForAtom = [&] (const Atom &atom) -> uint64_t {
658
739
    auto pos = _atomToAddress.find(&atom);
659
739
    assert(pos != _atomToAddress.end());
660
739
    return pos->second;
661
739
  };
662
79
663
79
  auto sectionAddrForAtom = [&] (const Atom &atom) -> uint64_t {
664
1
    for (const SectionInfo *sectInfo : _sectionInfos)
665
4
      for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets)
666
8
        if (atomInfo.atom == &atom)
667
1
          return sectInfo->address;
668
1
    
llvm_unreachable0
("atom not assigned to section");
669
0
  };
670
79
671
187
  for (SectionInfo *si : _sectionInfos) {
672
187
    Section *normSect = &file.sections[si->normalizedSectionIndex];
673
187
    if (isZeroFillSection(si->type)) {
674
2
      const uint8_t *empty = nullptr;
675
2
      normSect->content = llvm::makeArrayRef(empty, si->size);
676
2
      continue;
677
2
    }
678
185
    // Copy content from atoms to content buffer for section.
679
185
    llvm::MutableArrayRef<uint8_t> sectionContent;
680
185
    if (si->size) {
681
179
      uint8_t *sectContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
682
179
      sectionContent = llvm::MutableArrayRef<uint8_t>(sectContent, si->size);
683
179
      normSect->content = sectionContent;
684
179
    }
685
337
    for (AtomInfo &ai : si->atomsAndOffsets) {
686
337
      if (!ai.atom->size()) {
687
55
        assert(ai.atom->begin() == ai.atom->end() &&
688
55
               "Cannot have references without content");
689
55
        continue;
690
55
      }
691
282
      auto atomContent = sectionContent.slice(ai.offsetInSection,
692
282
                                              ai.atom->size());
693
282
      _archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
694
282
                                       sectionAddrForAtom, _ctx.baseAddress(),
695
282
                                       atomContent);
696
282
    }
697
185
  }
698
79
}
699
700
79
void Util::copySectionInfo(NormalizedFile &file) {
701
79
  file.sections.reserve(_sectionInfos.size());
702
79
  // Write sections grouped by segment.
703
221
  for (SegmentInfo *sgi : _segmentInfos) {
704
221
    for (SectionInfo *si : sgi->sections) {
705
187
      appendSection(si, file);
706
187
    }
707
221
  }
708
79
}
709
710
79
void Util::updateSectionInfo(NormalizedFile &file) {
711
79
  file.sections.reserve(_sectionInfos.size());
712
79
  // sections grouped by segment.
713
221
  for (SegmentInfo *sgi : _segmentInfos) {
714
221
    Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
715
221
    normSeg->address = sgi->address;
716
221
    normSeg->size = sgi->size;
717
221
    for (SectionInfo *si : sgi->sections) {
718
187
      Section *normSect = &file.sections[si->normalizedSectionIndex];
719
187
      normSect->address = si->address;
720
187
    }
721
221
  }
722
79
}
723
724
79
void Util::copyEntryPointAddress(NormalizedFile &nFile) {
725
79
  if (!_entryAtom) {
726
56
    nFile.entryAddress = 0;
727
56
    return;
728
56
  }
729
23
730
23
  if (_ctx.outputTypeHasEntry()) {
731
23
    if (_archHandler.isThumbFunction(*_entryAtom))
732
1
      nFile.entryAddress = (_atomToAddress[_entryAtom] | 1);
733
22
    else
734
22
      nFile.entryAddress = _atomToAddress[_entryAtom];
735
23
  }
736
23
}
737
738
79
void Util::buildAtomToAddressMap() {
739
79
  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
740
79
                   << "assign atom addresses:\n");
741
79
  const bool lookForEntry = _ctx.outputTypeHasEntry();
742
187
  for (SectionInfo *sect : _sectionInfos) {
743
340
    for (const AtomInfo &info : sect->atomsAndOffsets) {
744
340
      _atomToAddress[info.atom] = sect->address + info.offsetInSection;
745
340
      if (lookForEntry && 
(info.atom->contentType() == DefinedAtom::typeCode)144
&&
746
340
          
(info.atom->size() != 0)33
&&
747
340
          
info.atom->name() == _ctx.entrySymbolName()30
) {
748
23
        _entryAtom = info.atom;
749
23
      }
750
340
      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
751
340
                      << "   address="
752
340
                      << llvm::format("0x%016X", _atomToAddress[info.atom])
753
340
                      << llvm::format("    0x%09lX", info.atom)
754
340
                      << ", file=#"
755
340
                      << info.atom->file().ordinal()
756
340
                      << ", atom=#"
757
340
                      << info.atom->ordinal()
758
340
                      << ", name="
759
340
                      << info.atom->name()
760
340
                      << ", type="
761
340
                      << info.atom->contentType()
762
340
                      << "\n");
763
340
    }
764
187
  }
765
79
  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
766
79
                  << "assign header alias atom addresses:\n");
767
98
  for (const Atom *atom : _machHeaderAliasAtoms) {
768
98
    _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
79
}
794
795
79
llvm::Error Util::synthesizeDebugNotes(NormalizedFile &file) {
796
79
797
79
  // Bail out early if we don't need to generate a debug map.
798
79
  if (_ctx.debugInfoMode() == MachOLinkingContext::DebugInfoMode::noDebugMap)
799
0
    return llvm::Error::success();
800
79
801
79
  std::vector<const DefinedAtom*> atomsNeedingDebugNotes;
802
79
  std::set<const mach_o::MachOFile*> filesWithStabs;
803
79
  bool objFileHasDwarf = false;
804
79
  const File *objFile = nullptr;
805
79
806
187
  for (SectionInfo *sect : _sectionInfos) {
807
340
    for (const AtomInfo &info : sect->atomsAndOffsets) {
808
340
      if (const DefinedAtom *atom = dyn_cast<DefinedAtom>(info.atom)) {
809
340
810
340
        // FIXME: No stabs/debug-notes for symbols that wouldn't be in the
811
340
        //        symbol table.
812
340
        // FIXME: No stabs/debug-notes for kernel dtrace probes.
813
340
814
340
        if (atom->contentType() == DefinedAtom::typeCFI ||
815
340
            
atom->contentType() == DefinedAtom::typeCString322
)
816
28
          continue;
817
312
818
312
        // Whenever we encounter a new file, update the 'objfileHasDwarf' flag.
819
312
        if (&info.atom->file() != objFile) {
820
312
          objFileHasDwarf = false;
821
312
          if (const mach_o::MachOFile *atomFile =
822
236
              dyn_cast<mach_o::MachOFile>(&info.atom->file())) {
823
236
            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
236
          }
830
312
        }
831
312
832
312
        // If this atom is from a file that needs dwarf, add it to the list.
833
312
        if (objFileHasDwarf)
834
1
          atomsNeedingDebugNotes.push_back(info.atom);
835
312
      }
836
340
    }
837
187
  }
838
79
839
79
  // Sort atoms needing debug notes by file ordinal, then atom ordinal.
840
79
  std::sort(atomsNeedingDebugNotes.begin(), atomsNeedingDebugNotes.end(),
841
79
            [](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
79
847
79
  // FIXME: Handle <rdar://problem/17689030>: Add -add_ast_path option to \
848
79
  //        linker which add N_AST stab entry to output
849
79
  // See OutputFile::synthesizeDebugNotes in ObjectFile.cpp in ld64.
850
79
851
79
  StringRef oldFileName = "";
852
79
  StringRef oldDirPath = "";
853
79
  bool wroteStartSO = false;
854
79
  std::unordered_set<std::string> seenFiles;
855
79
  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
79
930
79
  // Emit ending SO if necessary.
931
79
  if (wroteStartSO)
932
1
    _stabs.push_back(mach_o::Stab(nullptr, N_SO, 1, 0, 0, ""));
933
79
934
79
  // Copy any stabs from .o file.
935
79
  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
79
944
79
  return llvm::Error::success();
945
79
}
946
947
205
uint16_t Util::descBits(const DefinedAtom* atom) {
948
205
  uint16_t desc = 0;
949
205
  switch (atom->merge()) {
950
205
  case lld::DefinedAtom::mergeNo:
951
204
  case lld::DefinedAtom::mergeAsTentative:
952
204
    break;
953
204
  case lld::DefinedAtom::mergeAsWeak:
954
1
  case lld::DefinedAtom::mergeAsWeakAndAddressUsed:
955
1
    desc |= N_WEAK_DEF;
956
1
    break;
957
1
  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
205
  }
963
205
  if (atom->contentType() == lld::DefinedAtom::typeResolver)
964
0
    desc |= N_SYMBOL_RESOLVER;
965
205
  if (atom->contentType() == lld::DefinedAtom::typeMachHeader)
966
49
    desc |= REFERENCED_DYNAMICALLY;
967
205
  if (_archHandler.isThumbFunction(*atom))
968
13
    desc |= N_ARM_THUMB_DEF;
969
205
  if (atom->deadStrip() == DefinedAtom::deadStripNever &&
970
205
      
_ctx.outputMachOType() == llvm::MachO::MH_OBJECT62
) {
971
7
    if ((atom->contentType() != DefinedAtom::typeInitializerPtr)
972
7
     && (atom->contentType() != DefinedAtom::typeTerminatorPtr))
973
7
    desc |= N_NO_DEAD_STRIP;
974
7
  }
975
205
  return desc;
976
205
}
977
978
bool Util::AtomSorter::operator()(const AtomAndIndex &left,
979
112
                                  const AtomAndIndex &right) {
980
112
  return (left.atom->name().compare(right.atom->name()) < 0);
981
112
}
982
983
llvm::Error Util::getSymbolTableRegion(const DefinedAtom* atom,
984
                                       bool &inGlobalsRegion,
985
205
                                       SymbolScope &scope) {
986
205
  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
987
205
  switch (atom->scope()) {
988
205
  case Atom::scopeTranslationUnit:
989
45
    scope = 0;
990
45
    inGlobalsRegion = false;
991
45
    return llvm::Error::success();
992
205
  case Atom::scopeLinkageUnit:
993
34
    if ((_ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) &&
994
34
        
_ctx.exportSymbolNamed(atom->name())4
) {
995
0
      return llvm::make_error<GenericError>(
996
0
                          Twine("cannot export hidden symbol ") + atom->name());
997
0
    }
998
34
    if (rMode) {
999
6
      if (_ctx.keepPrivateExterns()) {
1000
2
        // -keep_private_externs means keep in globals region as N_PEXT.
1001
2
        scope = N_PEXT | N_EXT;
1002
2
        inGlobalsRegion = true;
1003
2
        return llvm::Error::success();
1004
2
      }
1005
32
    }
1006
32
    // scopeLinkageUnit symbols are no longer global once linked.
1007
32
    scope = N_PEXT;
1008
32
    inGlobalsRegion = false;
1009
32
    return llvm::Error::success();
1010
126
  case Atom::scopeGlobal:
1011
126
    if (_ctx.exportRestrictMode()) {
1012
4
      if (_ctx.exportSymbolNamed(atom->name())) {
1013
2
        scope = N_EXT;
1014
2
        inGlobalsRegion = true;
1015
2
        return llvm::Error::success();
1016
2
      } else {
1017
2
        scope = N_PEXT;
1018
2
        inGlobalsRegion = false;
1019
2
        return llvm::Error::success();
1020
2
      }
1021
122
    } else {
1022
122
      scope = N_EXT;
1023
122
      inGlobalsRegion = true;
1024
122
      return llvm::Error::success();
1025
122
    }
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
79
                             NormalizedFile &file) {
1035
79
  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
1036
79
  // Mach-O symbol table has four regions: stabs, locals, globals, undefs.
1037
79
1038
79
  // Add all stabs.
1039
79
  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
79
1053
79
  // Add all local (non-global) symbols in address order
1054
79
  std::vector<AtomAndIndex> globals;
1055
79
  globals.reserve(512);
1056
187
  for (SectionInfo *sect : _sectionInfos) {
1057
340
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1058
340
      const DefinedAtom *atom = info.atom;
1059
340
      if (!atom->name().empty()) {
1060
205
        SymbolScope symbolScope;
1061
205
        bool inGlobalsRegion;
1062
205
        if (auto ec = getSymbolTableRegion(atom, inGlobalsRegion, symbolScope)){
1063
0
          return ec;
1064
0
        }
1065
205
        if (inGlobalsRegion) {
1066
126
          AtomAndIndex ai = { atom, sect->finalSectionIndex, symbolScope };
1067
126
          globals.push_back(ai);
1068
126
        } else {
1069
79
          Symbol sym;
1070
79
          sym.name  = atom->name();
1071
79
          sym.type  = N_SECT;
1072
79
          sym.scope = symbolScope;
1073
79
          sym.sect  = sect->finalSectionIndex;
1074
79
          sym.desc  = descBits(atom);
1075
79
          sym.value = _atomToAddress[atom];
1076
79
          _atomToSymbolIndex[atom] = file.localSymbols.size();
1077
79
          file.localSymbols.push_back(sym);
1078
79
        }
1079
205
      } else 
if (135
rMode135
&&
_archHandler.needsLocalSymbolInRelocatableFile(atom)43
){
1080
4
        // Create 'Lxxx' labels for anonymous atoms if archHandler says so.
1081
4
        static unsigned tempNum = 1;
1082
4
        char tmpName[16];
1083
4
        sprintf(tmpName, "L%04u", tempNum++);
1084
4
        StringRef tempRef(tmpName);
1085
4
        Symbol sym;
1086
4
        sym.name  = tempRef.copy(file.ownedAllocations);
1087
4
        sym.type  = N_SECT;
1088
4
        sym.scope = 0;
1089
4
        sym.sect  = sect->finalSectionIndex;
1090
4
        sym.desc  = 0;
1091
4
        sym.value = _atomToAddress[atom];
1092
4
        _atomToSymbolIndex[atom] = file.localSymbols.size();
1093
4
        file.localSymbols.push_back(sym);
1094
4
      }
1095
340
    }
1096
187
  }
1097
79
1098
79
  // Sort global symbol alphabetically, then add to symbol table.
1099
79
  std::sort(globals.begin(), globals.end(), AtomSorter());
1100
79
  const uint32_t globalStartIndex = file.localSymbols.size();
1101
126
  for (AtomAndIndex &ai : globals) {
1102
126
    Symbol sym;
1103
126
    sym.name  = ai.atom->name();
1104
126
    sym.type  = N_SECT;
1105
126
    sym.scope = ai.scope;
1106
126
    sym.sect  = ai.index;
1107
126
    sym.desc  = descBits(static_cast<const DefinedAtom*>(ai.atom));
1108
126
    sym.value = _atomToAddress[ai.atom];
1109
126
    _atomToSymbolIndex[ai.atom] = globalStartIndex + file.globalSymbols.size();
1110
126
    file.globalSymbols.push_back(sym);
1111
126
  }
1112
79
1113
79
  // Sort undefined symbol alphabetically, then add to symbol table.
1114
79
  std::vector<AtomAndIndex> undefs;
1115
79
  undefs.reserve(128);
1116
79
  for (const UndefinedAtom *atom : atomFile.undefined()) {
1117
22
    AtomAndIndex ai = { atom, 0, N_EXT };
1118
22
    undefs.push_back(ai);
1119
22
  }
1120
79
  for (const SharedLibraryAtom *atom : atomFile.sharedLibrary()) {
1121
64
    AtomAndIndex ai = { atom, 0, N_EXT };
1122
64
    undefs.push_back(ai);
1123
64
  }
1124
79
  std::sort(undefs.begin(), undefs.end(), AtomSorter());
1125
79
  const uint32_t start = file.globalSymbols.size() + file.localSymbols.size();
1126
86
  for (AtomAndIndex &ai : undefs) {
1127
86
    Symbol sym;
1128
86
    uint16_t desc = 0;
1129
86
    if (!rMode) {
1130
64
      uint8_t ordinal = 0;
1131
64
      if (!_ctx.useFlatNamespace())
1132
62
        ordinal = dylibOrdinal(dyn_cast<SharedLibraryAtom>(ai.atom));
1133
64
      llvm::MachO::SET_LIBRARY_ORDINAL(desc, ordinal);
1134
64
    }
1135
86
    sym.name  = ai.atom->name();
1136
86
    sym.type  = N_UNDF;
1137
86
    sym.scope = ai.scope;
1138
86
    sym.sect  = 0;
1139
86
    sym.desc  = desc;
1140
86
    sym.value = 0;
1141
86
    _atomToSymbolIndex[ai.atom] = file.undefinedSymbols.size() + start;
1142
86
    file.undefinedSymbols.push_back(sym);
1143
86
  }
1144
79
1145
79
  return llvm::Error::success();
1146
79
}
1147
1148
24
const Atom *Util::targetOfLazyPointer(const DefinedAtom *lpAtom) {
1149
48
  for (const Reference *ref : *lpAtom) {
1150
48
    if (_archHandler.isLazyPointer(*ref)) {
1151
24
      return ref->target();
1152
24
    }
1153
48
  }
1154
24
  
return nullptr0
;
1155
24
}
1156
1157
12
const Atom *Util::targetOfStub(const DefinedAtom *stubAtom) {
1158
12
  for (const Reference *ref : *stubAtom) {
1159
12
    if (const Atom *ta = ref->target()) {
1160
12
      if (const DefinedAtom *lpAtom = dyn_cast<DefinedAtom>(ta)) {
1161
12
        const Atom *target = targetOfLazyPointer(lpAtom);
1162
12
        if (target)
1163
12
          return target;
1164
12
      }
1165
12
    }
1166
12
  }
1167
12
  
return nullptr0
;
1168
12
}
1169
1170
79
void Util::addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file) {
1171
187
  for (SectionInfo *si : _sectionInfos) {
1172
187
    Section &normSect = file.sections[si->normalizedSectionIndex];
1173
187
    switch (si->type) {
1174
187
    case llvm::MachO::S_NON_LAZY_SYMBOL_POINTERS:
1175
23
      for (const AtomInfo &info : si->atomsAndOffsets) {
1176
23
        bool foundTarget = false;
1177
23
        for (const Reference *ref : *info.atom) {
1178
12
          const Atom *target = ref->target();
1179
12
          if (target) {
1180
12
            if (isa<const SharedLibraryAtom>(target)) {
1181
12
              uint32_t index = _atomToSymbolIndex[target];
1182
12
              normSect.indirectSymbols.push_back(index);
1183
12
              foundTarget = true;
1184
12
            } else {
1185
0
              normSect.indirectSymbols.push_back(
1186
0
                                            llvm::MachO::INDIRECT_SYMBOL_LOCAL);
1187
0
            }
1188
12
          }
1189
12
        }
1190
23
        if (!foundTarget) {
1191
11
          normSect.indirectSymbols.push_back(
1192
11
                                             llvm::MachO::INDIRECT_SYMBOL_ABS);
1193
11
        }
1194
23
      }
1195
13
      break;
1196
187
    case llvm::MachO::S_LAZY_SYMBOL_POINTERS:
1197
12
      for (const AtomInfo &info : si->atomsAndOffsets) {
1198
12
        const Atom *target = targetOfLazyPointer(info.atom);
1199
12
        if (target) {
1200
12
          uint32_t index = _atomToSymbolIndex[target];
1201
12
          normSect.indirectSymbols.push_back(index);
1202
12
        }
1203
12
      }
1204
10
      break;
1205
187
    case llvm::MachO::S_SYMBOL_STUBS:
1206
12
      for (const AtomInfo &info : si->atomsAndOffsets) {
1207
12
        const Atom *target = targetOfStub(info.atom);
1208
12
        if (target) {
1209
12
          uint32_t index = _atomToSymbolIndex[target];
1210
12
          normSect.indirectSymbols.push_back(index);
1211
12
        }
1212
12
      }
1213
10
      break;
1214
187
    default:
1215
154
      break;
1216
187
    }
1217
187
  }
1218
79
}
1219
1220
void Util::addDependentDylibs(const lld::File &atomFile,
1221
79
                              NormalizedFile &nFile) {
1222
79
  // Scan all imported symbols and build up list of dylibs they are from.
1223
79
  int ordinal = 1;
1224
79
  for (const auto *dylib : _ctx.allDylibs()) {
1225
56
    DylibPathToInfo::iterator pos = _dylibInfo.find(dylib->installName());
1226
56
    if (pos == _dylibInfo.end()) {
1227
55
      DylibInfo info;
1228
55
      bool flatNamespaceAtom = dylib == _ctx.flatNamespaceFile();
1229
55
1230
55
      // If we're in -flat_namespace mode (or this atom came from the flat
1231
55
      // namespace file under -undefined dynamic_lookup) then use the flat
1232
55
      // lookup ordinal.
1233
55
      if (flatNamespaceAtom || _ctx.useFlatNamespace())
1234
1
        info.ordinal = BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
1235
54
      else
1236
54
        info.ordinal = ordinal++;
1237
55
      info.hasWeak = false;
1238
55
      info.hasNonWeak = !info.hasWeak;
1239
55
      _dylibInfo[dylib->installName()] = info;
1240
55
1241
55
      // Unless this was a flat_namespace atom, record the source dylib.
1242
55
      if (!flatNamespaceAtom) {
1243
55
        DependentDylib depInfo;
1244
55
        depInfo.path = dylib->installName();
1245
55
        depInfo.kind = llvm::MachO::LC_LOAD_DYLIB;
1246
55
        depInfo.currentVersion = _ctx.dylibCurrentVersion(dylib->path());
1247
55
        depInfo.compatVersion = _ctx.dylibCompatVersion(dylib->path());
1248
55
        nFile.dependentDylibs.push_back(depInfo);
1249
55
      }
1250
55
    } else {
1251
1
      pos->second.hasWeak = false;
1252
1
      pos->second.hasNonWeak = !pos->second.hasWeak;
1253
1
    }
1254
56
  }
1255
79
  // Automatically weak link dylib in which all symbols are weak (canBeNull).
1256
79
  for (DependentDylib &dep : nFile.dependentDylibs) {
1257
55
    DylibInfo &info = _dylibInfo[dep.path];
1258
55
    if (info.hasWeak && 
!info.hasNonWeak0
)
1259
0
      dep.kind = llvm::MachO::LC_LOAD_WEAK_DYLIB;
1260
55
    else if (_ctx.isUpwardDylib(dep.path))
1261
0
      dep.kind = llvm::MachO::LC_LOAD_UPWARD_DYLIB;
1262
55
  }
1263
79
}
1264
1265
87
int Util::dylibOrdinal(const SharedLibraryAtom *sa) {
1266
87
  return _dylibInfo[sa->loadName()].ordinal;
1267
87
}
1268
1269
void Util::segIndexForSection(const SectionInfo *sect, uint8_t &segmentIndex,
1270
122
                                                  uint64_t &segmentStartAddr) {
1271
122
  segmentIndex = 0;
1272
243
  for (const SegmentInfo *seg : _segmentInfos) {
1273
243
    if ((seg->address <= sect->address)
1274
243
      && (seg->address+seg->size >= sect->address+sect->size)) {
1275
122
      segmentStartAddr = seg->address;
1276
122
      return;
1277
122
    }
1278
121
    ++segmentIndex;
1279
121
  }
1280
122
  
llvm_unreachable0
("section not in any segment");
1281
0
}
1282
1283
37
uint32_t Util::sectionIndexForAtom(const Atom *atom) {
1284
37
  uint64_t address = _atomToAddress[atom];
1285
66
  for (const SectionInfo *si : _sectionInfos) {
1286
66
    if ((si->address <= address) && 
(address < si->address+si->size)53
)
1287
37
      return si->finalSectionIndex;
1288
66
  }
1289
37
  
llvm_unreachable0
("atom not in any section");
1290
0
}
1291
1292
79
void Util::addSectionRelocs(const lld::File &, NormalizedFile &file) {
1293
79
  if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
1294
49
    return;
1295
30
1296
30
  // Utility function for ArchHandler to find symbol index for an atom.
1297
109
  
auto symIndexForAtom = [&] (const Atom &atom) -> uint32_t 30
{
1298
109
    auto pos = _atomToSymbolIndex.find(&atom);
1299
109
    assert(pos != _atomToSymbolIndex.end());
1300
109
    return pos->second;
1301
109
  };
1302
30
1303
30
  // Utility function for ArchHandler to find section index for an atom.
1304
37
  auto sectIndexForAtom = [&] (const Atom &atom) -> uint32_t {
1305
37
    return sectionIndexForAtom(&atom);
1306
37
  };
1307
30
1308
30
  // Utility function for ArchHandler to find address of atom in output file.
1309
91
  auto addressForAtom = [&] (const Atom &atom) -> uint64_t {
1310
91
    auto pos = _atomToAddress.find(&atom);
1311
91
    assert(pos != _atomToAddress.end());
1312
91
    return pos->second;
1313
91
  };
1314
30
1315
65
  for (SectionInfo *si : _sectionInfos) {
1316
65
    Section &normSect = file.sections[si->normalizedSectionIndex];
1317
114
    for (const AtomInfo &info : si->atomsAndOffsets) {
1318
114
      const DefinedAtom *atom = info.atom;
1319
206
      for (const Reference *ref : *atom) {
1320
206
        // Skip emitting relocs for sections which are always able to be
1321
206
        // implicitly regenerated and where the relocation targets an address
1322
206
        // which is defined.
1323
206
        if (si->relocsToDefinedCanBeImplicit && 
isa<DefinedAtom>(ref->target())29
)
1324
28
          continue;
1325
178
        _archHandler.appendSectionRelocations(*atom, info.offsetInSection, *ref,
1326
178
                                              symIndexForAtom,
1327
178
                                              sectIndexForAtom,
1328
178
                                              addressForAtom,
1329
178
                                              normSect.relocations);
1330
178
      }
1331
114
    }
1332
65
  }
1333
30
}
1334
1335
79
void Util::addFunctionStarts(const lld::File &, NormalizedFile &file) {
1336
79
  if (!_ctx.generateFunctionStartsLoadCommand())
1337
33
    return;
1338
46
  file.functionStarts.reserve(8192);
1339
46
  // Delta compress function starts, starting with the mach header symbol.
1340
46
  const uint64_t badAddress = ~0ULL;
1341
46
  uint64_t addr = badAddress;
1342
119
  for (SectionInfo *si : _sectionInfos) {
1343
220
    for (const AtomInfo &info : si->atomsAndOffsets) {
1344
220
      auto type = info.atom->contentType();
1345
220
      if (type == DefinedAtom::typeMachHeader) {
1346
46
        addr = _atomToAddress[info.atom];
1347
46
        continue;
1348
46
      }
1349
174
      if (type != DefinedAtom::typeCode)
1350
106
        continue;
1351
68
      assert(addr != badAddress && "Missing mach header symbol");
1352
68
      // Skip atoms which have 0 size.  This is so that LC_FUNCTION_STARTS
1353
68
      // can't spill in to the next section.
1354
68
      if (!info.atom->size())
1355
6
        continue;
1356
62
      uint64_t nextAddr = _atomToAddress[info.atom];
1357
62
      if (_archHandler.isThumbFunction(*info.atom))
1358
9
        nextAddr |= 1;
1359
62
      uint64_t delta = nextAddr - addr;
1360
62
      if (delta) {
1361
62
        ByteBuffer buffer;
1362
62
        buffer.append_uleb128(delta);
1363
62
        file.functionStarts.insert(file.functionStarts.end(), buffer.bytes(),
1364
62
                                   buffer.bytes() + buffer.size());
1365
62
      }
1366
62
      addr = nextAddr;
1367
62
    }
1368
119
  }
1369
46
1370
46
  // Null terminate, and pad to pointer size for this arch.
1371
46
  file.functionStarts.push_back(0);
1372
46
1373
46
  auto size = file.functionStarts.size();
1374
46
  for (unsigned i = size, e = llvm::alignTo(size, _ctx.is64Bit() ? 
839
:
47
);
1375
250
       i != e; 
++i204
)
1376
204
    file.functionStarts.push_back(0);
1377
46
}
1378
1379
79
void Util::buildDataInCodeArray(const lld::File &, NormalizedFile &file) {
1380
79
  if (!_ctx.generateDataInCodeLoadCommand())
1381
4
    return;
1382
183
  
for (SectionInfo *si : _sectionInfos)75
{
1383
333
    for (const AtomInfo &info : si->atomsAndOffsets) {
1384
333
      // Atoms that contain data-in-code have "transition" references
1385
333
      // which mark a point where the embedded data starts of ends.
1386
333
      // This needs to be converted to the mach-o format which is an array
1387
333
      // of data-in-code ranges.
1388
333
      uint32_t startOffset = 0;
1389
333
      DataRegionType mode = DataRegionType(0);
1390
407
      for (const Reference *ref : *info.atom) {
1391
407
        if (ref->kindNamespace() != Reference::KindNamespace::mach_o)
1392
2
          continue;
1393
405
        if (_archHandler.isDataInCodeTransition(ref->kindValue())) {
1394
26
          DataRegionType nextMode = (DataRegionType)ref->addend();
1395
26
          if (mode != nextMode) {
1396
13
            if (mode != 0) {
1397
9
              // Found end data range, so make range entry.
1398
9
              DataInCode entry;
1399
9
              entry.offset = si->address + info.offsetInSection + startOffset;
1400
9
              entry.length = ref->offsetInAtom() - startOffset;
1401
9
              entry.kind   = mode;
1402
9
              file.dataInCode.push_back(entry);
1403
9
            }
1404
13
          }
1405
26
          mode = nextMode;
1406
26
          startOffset = ref->offsetInAtom();
1407
26
        }
1408
405
      }
1409
333
      if (mode != 0) {
1410
1
        // Function ends with data (no end transition).
1411
1
        DataInCode entry;
1412
1
        entry.offset = si->address + info.offsetInSection + startOffset;
1413
1
        entry.length = info.atom->size() - startOffset;
1414
1
        entry.kind   = mode;
1415
1
        file.dataInCode.push_back(entry);
1416
1
      }
1417
333
    }
1418
183
  }
1419
75
}
1420
1421
void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
1422
79
                                                        NormalizedFile &nFile) {
1423
79
  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1424
30
    return;
1425
49
1426
49
  uint8_t segmentIndex;
1427
49
  uint64_t segmentStartAddr;
1428
49
  uint32_t offsetInBindInfo = 0;
1429
49
1430
122
  for (SectionInfo *sect : _sectionInfos) {
1431
122
    segIndexForSection(sect, segmentIndex, segmentStartAddr);
1432
226
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1433
226
      const DefinedAtom *atom = info.atom;
1434
226
      for (const Reference *ref : *atom) {
1435
201
        uint64_t segmentOffset = _atomToAddress[atom] + ref->offsetInAtom()
1436
201
                                - segmentStartAddr;
1437
201
        const Atom* targ = ref->target();
1438
201
        if (_archHandler.isPointer(*ref)) {
1439
32
          // A pointer to a DefinedAtom requires rebasing.
1440
32
          if (isa<DefinedAtom>(targ)) {
1441
19
            RebaseLocation rebase;
1442
19
            rebase.segIndex = segmentIndex;
1443
19
            rebase.segOffset = segmentOffset;
1444
19
            rebase.kind = llvm::MachO::REBASE_TYPE_POINTER;
1445
19
            nFile.rebasingInfo.push_back(rebase);
1446
19
          }
1447
32
          // A pointer to an SharedLibraryAtom requires binding.
1448
32
          if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1449
13
            BindLocation bind;
1450
13
            bind.segIndex = segmentIndex;
1451
13
            bind.segOffset = segmentOffset;
1452
13
            bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1453
13
            bind.canBeNull = sa->canBeNullAtRuntime();
1454
13
            bind.ordinal = dylibOrdinal(sa);
1455
13
            bind.symbolName = targ->name();
1456
13
            bind.addend = ref->addend();
1457
13
            nFile.bindingInfo.push_back(bind);
1458
13
          }
1459
32
        }
1460
169
        else if (_archHandler.isLazyPointer(*ref)) {
1461
12
          BindLocation bind;
1462
12
          if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1463
12
            bind.ordinal = dylibOrdinal(sa);
1464
12
          } else {
1465
0
            bind.ordinal = llvm::MachO::BIND_SPECIAL_DYLIB_SELF;
1466
0
          }
1467
12
          bind.segIndex = segmentIndex;
1468
12
          bind.segOffset = segmentOffset;
1469
12
          bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1470
12
          bind.canBeNull = false; //sa->canBeNullAtRuntime();
1471
12
          bind.symbolName = targ->name();
1472
12
          bind.addend = ref->addend();
1473
12
          nFile.lazyBindingInfo.push_back(bind);
1474
12
1475
12
          // Now that we know the segmentOffset and the ordinal attribute,
1476
12
          // we can fix the helper's code
1477
12
1478
12
          fixLazyReferenceImm(atom, offsetInBindInfo, nFile);
1479
12
1480
12
          // 5 bytes for opcodes + variable sizes (target name + \0 and offset
1481
12
          // encode's size)
1482
12
          offsetInBindInfo +=
1483
12
              6 + targ->name().size() + llvm::getULEB128Size(bind.segOffset);
1484
12
          if (bind.ordinal > BIND_IMMEDIATE_MASK)
1485
0
            offsetInBindInfo += llvm::getULEB128Size(bind.ordinal);
1486
12
        }
1487
201
      }
1488
226
    }
1489
122
  }
1490
49
}
1491
1492
void Util::fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
1493
12
                               NormalizedFile &file) {
1494
24
  for (const auto &ref : *atom) {
1495
24
    const DefinedAtom *da = dyn_cast<DefinedAtom>(ref->target());
1496
24
    if (da == nullptr)
1497
12
      return;
1498
12
1499
12
    const Reference *helperRef = nullptr;
1500
12
    for (const Reference *hr : *da) {
1501
12
      if (hr->kindValue() == _archHandler.lazyImmediateLocationKind()) {
1502
12
        helperRef = hr;
1503
12
        break;
1504
12
      }
1505
12
    }
1506
12
    if (helperRef == nullptr)
1507
0
      continue;
1508
12
1509
12
    // TODO: maybe get the fixed atom content from _archHandler ?
1510
69
    
for (SectionInfo *sectInfo : _sectionInfos)12
{
1511
123
      for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) {
1512
123
        if (atomInfo.atom == helperRef->target()) {
1513
12
          auto sectionContent =
1514
12
              file.sections[sectInfo->normalizedSectionIndex].content;
1515
12
          uint8_t *rawb =
1516
12
              file.ownedAllocations.Allocate<uint8_t>(sectionContent.size());
1517
12
          llvm::MutableArrayRef<uint8_t> newContent{rawb,
1518
12
                                                    sectionContent.size()};
1519
12
          std::copy(sectionContent.begin(), sectionContent.end(),
1520
12
                    newContent.begin());
1521
12
          llvm::support::ulittle32_t *loc =
1522
12
              reinterpret_cast<llvm::support::ulittle32_t *>(
1523
12
                  &newContent[atomInfo.offsetInSection +
1524
12
                              helperRef->offsetInAtom()]);
1525
12
          *loc = offset;
1526
12
          file.sections[sectInfo->normalizedSectionIndex].content = newContent;
1527
12
        }
1528
123
      }
1529
69
    }
1530
12
  }
1531
12
}
1532
1533
79
void Util::addExportInfo(const lld::File &atomFile, NormalizedFile &nFile) {
1534
79
  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1535
30
    return;
1536
49
1537
122
  
for (SectionInfo *sect : _sectionInfos)49
{
1538
226
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1539
226
      const DefinedAtom *atom = info.atom;
1540
226
      if (atom->scope() != Atom::scopeGlobal)
1541
135
        continue;
1542
91
      if (_ctx.exportRestrictMode()) {
1543
0
        if (!_ctx.exportSymbolNamed(atom->name()))
1544
0
          continue;
1545
91
      }
1546
91
      Export exprt;
1547
91
      exprt.name = atom->name();
1548
91
      exprt.offset = _atomToAddress[atom] - _ctx.baseAddress();
1549
91
      exprt.kind = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
1550
91
      if (atom->merge() == DefinedAtom::mergeAsWeak)
1551
1
        exprt.flags = EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
1552
90
      else
1553
90
        exprt.flags = 0;
1554
91
      exprt.otherOffset = 0;
1555
91
      exprt.otherName = StringRef();
1556
91
      nFile.exportInfo.push_back(exprt);
1557
91
    }
1558
122
  }
1559
49
}
1560
1561
79
uint32_t Util::fileFlags() {
1562
79
  // FIXME: these need to determined at runtime.
1563
79
  if (_ctx.outputMachOType() == MH_OBJECT) {
1564
30
    return _subsectionsViaSymbols ? 
MH_SUBSECTIONS_VIA_SYMBOLS28
:
02
;
1565
49
  } else {
1566
49
    uint32_t flags = MH_DYLDLINK;
1567
49
    if (!_ctx.useFlatNamespace())
1568
48
        flags |= MH_TWOLEVEL | MH_NOUNDEFS;
1569
49
    if ((_ctx.outputMachOType() == MH_EXECUTE) && 
_ctx.PIE()26
)
1570
14
      flags |= MH_PIE;
1571
49
    if (_hasTLVDescriptors)
1572
0
      flags |= (MH_PIE | MH_HAS_TLV_DESCRIPTORS);
1573
49
    return flags;
1574
49
  }
1575
79
}
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
79
                                           const MachOLinkingContext &context) {
1587
79
  // The util object buffers info until the normalized file can be made.
1588
79
  Util util(context);
1589
79
  util.processDefinedAtoms(atomFile);
1590
79
  util.organizeSections();
1591
79
1592
79
  std::unique_ptr<NormalizedFile> f(new NormalizedFile());
1593
79
  NormalizedFile &normFile = *f.get();
1594
79
  normFile.arch = context.arch();
1595
79
  normFile.fileType = context.outputMachOType();
1596
79
  normFile.flags = util.fileFlags();
1597
79
  normFile.stackSize = context.stackSize();
1598
79
  normFile.installName = context.installName();
1599
79
  normFile.currentVersion = context.currentVersion();
1600
79
  normFile.compatVersion = context.compatibilityVersion();
1601
79
  normFile.os = context.os();
1602
79
1603
79
  // If we are emitting an object file, then the min version is the maximum
1604
79
  // of the min's of all the source files and the cmdline.
1605
79
  if (normFile.fileType == llvm::MachO::MH_OBJECT)
1606
30
    normFile.minOSverson = std::max(context.osMinVersion(), util.minVersion());
1607
49
  else
1608
49
    normFile.minOSverson = context.osMinVersion();
1609
79
1610
79
  normFile.minOSVersionKind = util.minVersionCommandType();
1611
79
1612
79
  normFile.sdkVersion = context.sdkVersion();
1613
79
  normFile.sourceVersion = context.sourceVersion();
1614
79
1615
79
  if (context.generateVersionLoadCommand() &&
1616
79
      
context.os() != MachOLinkingContext::OS::unknown44
)
1617
44
    normFile.hasMinVersionLoadCommand = true;
1618
35
  else if (normFile.fileType == llvm::MachO::MH_OBJECT &&
1619
35
           
util.allSourceFilesHaveMinVersions()30
&&
1620
35
           
(2
(normFile.os != MachOLinkingContext::OS::unknown)2
||
1621
2
            
util.minVersionCommandType()1
)) {
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
79
  normFile.generateDataInCodeLoadCommand =
1629
79
    context.generateDataInCodeLoadCommand();
1630
79
  normFile.pageSize = context.pageSize();
1631
79
  normFile.rpaths = context.rpaths();
1632
79
  util.addDependentDylibs(atomFile, normFile);
1633
79
  util.copySegmentInfo(normFile);
1634
79
  util.copySectionInfo(normFile);
1635
79
  util.assignAddressesToSections(normFile);
1636
79
  util.buildAtomToAddressMap();
1637
79
  if (auto err = util.synthesizeDebugNotes(normFile))
1638
0
    return std::move(err);
1639
79
  util.updateSectionInfo(normFile);
1640
79
  util.copySectionContent(normFile);
1641
79
  if (auto ec = util.addSymbols(atomFile, normFile)) {
1642
0
    return std::move(ec);
1643
0
  }
1644
79
  util.addIndirectSymbols(atomFile, normFile);
1645
79
  util.addRebaseAndBindingInfo(atomFile, normFile);
1646
79
  util.addExportInfo(atomFile, normFile);
1647
79
  util.addSectionRelocs(atomFile, normFile);
1648
79
  util.addFunctionStarts(atomFile, normFile);
1649
79
  util.buildDataInCodeArray(atomFile, normFile);
1650
79
  util.copyEntryPointAddress(normFile);
1651
79
1652
79
  return std::move(f);
1653
79
}
1654
1655
} // namespace normalized
1656
} // namespace mach_o
1657
} // namespace lld