Coverage Report

Created: 2017-09-19 22:28

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/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/Core/Error.h"
28
#include "lld/Core/LLVM.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
374
                 normalizedSectionIndex(0), finalSectionIndex(0) {
85
374
  uint16_t align = 1;
86
374
  if (
ctxt.sectionAligned(segmentName, sectionName, align)374
) {
87
3
    alignment = align;
88
3
  }
89
374
}
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
465
   normalizedSegmentIndex(0) {
106
465
}
107
108
class Util {
109
public:
110
  Util(const MachOLinkingContext &ctxt)
111
      : _ctx(ctxt), _archHandler(ctxt.archHandler()), _entryAtom(nullptr),
112
167
        _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
72
  bool allSourceFilesHaveMinVersions() const {
138
72
    return _allSourceFilesHaveMinVersions;
139
72
  }
140
141
72
  uint32_t minVersion() const {
142
72
    return _minVersion;
143
72
  }
144
145
169
  LoadCommandType minVersionCommandType() const {
146
169
    return _minVersionCommandType;
147
169
  }
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
167
Util::~Util() {
213
167
  // The SectionInfo structs are BumpPtr allocated, but atomsAndOffsets needs
214
167
  // to be deleted.
215
374
  for (SectionInfo *si : _sectionInfos) {
216
374
    // clear() destroys vector elements, but does not deallocate.
217
374
    // Instead use swap() to deallocate vector buffer.
218
374
    std::vector<AtomInfo> empty;
219
374
    si->atomsAndOffsets.swap(empty);
220
374
  }
221
167
  // The SegmentInfo structs are BumpPtr allocated, but sections needs
222
167
  // to be deleted.
223
465
  for (SegmentInfo *sgi : _segmentInfos) {
224
465
    std::vector<SectionInfo*> empty2;
225
465
    sgi->sections.swap(empty2);
226
465
  }
227
167
}
228
229
138
SectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
230
138
  StringRef segmentName;
231
138
  StringRef sectionName;
232
138
  SectionType sectionType;
233
138
  SectionAttr sectionAttrs;
234
138
  bool relocsToDefinedCanBeImplicit;
235
138
236
138
  // Use same table used by when parsing .o files.
237
138
  relocatableSectionInfoForContentType(type, segmentName, sectionName,
238
138
                                       sectionType, sectionAttrs,
239
138
                                       relocsToDefinedCanBeImplicit);
240
138
  // If we already have a SectionInfo with this name, re-use it.
241
138
  // This can happen if two ContentType map to the same mach-o section.
242
108
  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
136
  }
248
136
  // Otherwise allocate new SectionInfo object.
249
136
  auto *sect = new (_allocator)
250
136
      SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs,
251
136
                  relocsToDefinedCanBeImplicit);
252
136
  _sectionInfos.push_back(sect);
253
136
  _sectionMap[type] = sect;
254
136
  return sect;
255
136
}
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
276
    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
1
    case DefinedAtom::typeThunkTLV:
320
1
      _hasTLVDescriptors = true;
321
1
      break;
322
98
    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
375
    
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
225
    }
333
225
    // Otherwise allocate new SectionInfo object.
334
225
    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
225
  }
341
0
  
llvm_unreachable0
("content type not yet supported");
342
0
}
343
344
743
SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
345
743
  if (
atom->sectionChoice() == DefinedAtom::sectionBasedOnContent743
) {
346
724
    // Section for this atom is derived from content type.
347
724
    DefinedAtom::ContentType type = atom->contentType();
348
724
    auto pos = _sectionMap.find(type);
349
724
    if ( pos != _sectionMap.end() )
350
211
      return pos->second;
351
513
    bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
352
513
    return rMode ? 
getRelocatableSection(type)138
:
getFinalSection(type)375
;
353
0
  } 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
8
    for(SectionInfo *sect : _customSections) {
358
8
      const DefinedAtom *firstAtom = sect->atomsAndOffsets.front().atom;
359
8
      if (
firstAtom->customSectionName().equals(customName)8
) {
360
6
        return sect;
361
6
      }
362
13
    }
363
13
    // Not found, so need to create a new custom section.
364
13
    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
13
  }
375
743
}
376
377
648
void Util::appendAtom(SectionInfo *sect, const DefinedAtom *atom) {
378
648
  // Figure out offset for atom in this section given alignment constraints.
379
648
  uint64_t offset = sect->size;
380
648
  DefinedAtom::Alignment atomAlign = atom->alignment();
381
648
  uint64_t align = atomAlign.value;
382
648
  uint64_t requiredModulus = atomAlign.modulus;
383
648
  uint64_t currentModulus = (offset % align);
384
648
  if ( 
currentModulus != requiredModulus648
) {
385
9
    if ( requiredModulus > currentModulus )
386
0
      offset += requiredModulus-currentModulus;
387
9
    else
388
9
      offset += align+requiredModulus-currentModulus;
389
9
  }
390
648
  // Record max alignment of any atom in this section.
391
648
  if (align > sect->alignment)
392
205
    sect->alignment = atomAlign.value;
393
648
  // Assign atom to this section with this offset.
394
648
  AtomInfo ai = {atom, offset};
395
648
  sect->atomsAndOffsets.push_back(ai);
396
648
  // Update section size to include this atom.
397
648
  sect->size = offset + atom->size();
398
648
}
399
400
167
void Util::processDefinedAtoms(const lld::File &atomFile) {
401
838
  for (const DefinedAtom *atom : atomFile.defined()) {
402
838
    processAtomAttributes(atom);
403
838
    assignAtomToSection(atom);
404
838
  }
405
167
}
406
407
838
void Util::processAtomAttributes(const DefinedAtom *atom) {
408
838
  if (auto *
machoFile838
= 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
596
    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 585
v585
= machoFile->minVersionLoadCommandKind())
425
9
        _minVersionCommandType = v;
426
596
  }
427
838
}
428
429
838
void Util::assignAtomToSection(const DefinedAtom *atom) {
430
838
  if (
atom->contentType() == DefinedAtom::typeMachHeader838
) {
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
838
  } else 
if (743
atom->contentType() == DefinedAtom::typeDSOHandle743
)
436
95
    _machHeaderAliasAtoms.push_back(atom);
437
743
  else
438
648
    appendAtom(sectionForAtom(atom), atom);
439
838
}
440
441
687
SegmentInfo *Util::segmentForName(StringRef segName) {
442
900
  for (SegmentInfo *si : _segmentInfos) {
443
900
    if ( si->name.equals(segName) )
444
222
      return si;
445
465
  }
446
465
  auto *info = new (_allocator) SegmentInfo(segName);
447
465
448
465
  // Set the initial segment protection.
449
465
  if (segName.equals("__TEXT"))
450
159
    info->init_access = VM_PROT_READ | VM_PROT_EXECUTE;
451
306
  else 
if (306
segName.equals("__PAGEZERO")306
)
452
51
    info->init_access = 0;
453
255
  else 
if (255
segName.equals("__LINKEDIT")255
)
454
167
    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
465
460
465
  // Set max segment protection
461
465
  // Note, its overkill to use a switch statement here, but makes it so much
462
465
  // easier to use switch coverage to catch new cases.
463
465
  switch (_ctx.os()) {
464
430
    case lld::MachOLinkingContext::OS::unknown:
465
430
    case lld::MachOLinkingContext::OS::macOSX:
466
430
    case lld::MachOLinkingContext::OS::iOS_simulator:
467
430
      if (
segName.equals("__PAGEZERO")430
) {
468
45
        info->max_access = 0;
469
45
        break;
470
45
      }
471
385
      // All others default to all
472
385
      info->max_access = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
473
385
      break;
474
35
    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
465
  }
479
465
  _segmentInfos.push_back(info);
480
465
  return info;
481
465
}
482
483
712
unsigned Util::SegmentSorter::weight(const SegmentInfo *seg) {
484
712
 return llvm::StringSwitch<unsigned>(seg->name)
485
712
    .Case("__PAGEZERO",  1)
486
712
    .Case("__TEXT",      2)
487
712
    .Case("__DATA",      3)
488
712
    .Default(100);
489
712
}
490
491
bool Util::SegmentSorter::operator()(const SegmentInfo *left,
492
356
                                  const SegmentInfo *right) {
493
356
  return (weight(left) < weight(right));
494
356
}
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
167
void Util::organizeSections() {
514
167
  // NOTE!: Keep this in sync with assignAddressesToSections.
515
167
  switch (_ctx.outputMachOType()) {
516
51
    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
72
    default:
527
72
      break;
528
167
  }
529
167
  segmentForName("__LINKEDIT");
530
167
531
167
  // Group sections into segments.
532
374
  for (SectionInfo *si : _sectionInfos) {
533
374
    SegmentInfo *seg = segmentForName(si->segmentName);
534
374
    seg->sections.push_back(si);
535
374
  }
536
167
  // Sort segments.
537
167
  std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
538
167
539
167
  // Sort sections within segments.
540
465
  for (SegmentInfo *seg : _segmentInfos) {
541
465
    if (
seg->name.equals("__TEXT")465
) {
542
159
      std::sort(seg->sections.begin(), seg->sections.end(),
543
159
                TextSectionSorter());
544
159
    }
545
465
  }
546
167
547
167
  // Record final section indexes.
548
167
  uint32_t segmentIndex = 0;
549
167
  uint32_t sectionIndex = 1;
550
465
  for (SegmentInfo *seg : _segmentInfos) {
551
465
    seg->normalizedSegmentIndex = segmentIndex++;
552
465
    for (SectionInfo *sect : seg->sections)
553
374
      sect->finalSectionIndex = sectionIndex++;
554
465
  }
555
167
}
556
557
255
void Util::layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr) {
558
255
  seg->address = addr;
559
127
  for (SectionInfo *sect : seg->sections) {
560
127
    sect->address = llvm::alignTo(addr, sect->alignment);
561
127
    addr = sect->address + sect->size;
562
127
  }
563
255
  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
564
255
}
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
159
                                                               uint64_t &addr) {
569
159
  seg->address = addr;
570
159
  // Walks sections starting at end to calculate padding for start.
571
159
  int64_t taddr = 0;
572
406
  for (auto it = seg->sections.rbegin(); 
it != seg->sections.rend()406
;
++it247
) {
573
247
    SectionInfo *sect = *it;
574
247
    taddr -= sect->size;
575
247
    taddr = taddr & (0 - sect->alignment);
576
247
  }
577
159
  int64_t padding = taddr - hlcSize;
578
319
  while (padding < 0)
579
160
    padding += _ctx.pageSize();
580
159
  // Start assigning section address starting at padded offset.
581
159
  addr += (padding + hlcSize);
582
247
  for (SectionInfo *sect : seg->sections) {
583
247
    sect->address = llvm::alignTo(addr, sect->alignment);
584
247
    addr = sect->address + sect->size;
585
247
  }
586
159
  seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
587
159
}
588
589
167
void Util::assignAddressesToSections(const NormalizedFile &file) {
590
167
  // NOTE!: Keep this in sync with organizeSections.
591
167
  size_t hlcSize = headerAndLoadCommandsSize(file);
592
167
  uint64_t address = 0;
593
465
  for (SegmentInfo *seg : _segmentInfos) {
594
465
    if (
seg->name.equals("__PAGEZERO")465
) {
595
51
      seg->size = _ctx.pageZeroSize();
596
51
      address += seg->size;
597
51
    }
598
414
    else 
if (414
seg->name.equals("__TEXT")414
) {
599
159
      // _ctx.baseAddress()  == 0 implies it was either unspecified or
600
159
      // pageZeroSize is also 0. In either case resetting address is safe.
601
159
      address = _ctx.baseAddress() ? 
_ctx.baseAddress()51
:
address108
;
602
159
      layoutSectionsInTextSegment(hlcSize, seg, address);
603
159
    } else
604
255
      layoutSectionsInSegment(seg, address);
605
465
606
465
    address = llvm::alignTo(address, _ctx.pageSize());
607
465
  }
608
167
  DEBUG_WITH_TYPE("WriterMachO-norm",
609
167
    llvm::dbgs() << "assignAddressesToSections()\n";
610
167
    for (SegmentInfo *sgi : _segmentInfos) {
611
167
      llvm::dbgs()  << "   address=" << llvm::format("0x%08llX", sgi->address)
612
167
                    << ", size="  << llvm::format("0x%08llX", sgi->size)
613
167
                    << ", segment-name='" << sgi->name
614
167
                    << "'\n";
615
167
      for (SectionInfo *si : sgi->sections) {
616
167
        llvm::dbgs()<< "      addr="  << llvm::format("0x%08llX", si->address)
617
167
                    << ", size="  << llvm::format("0x%08llX", si->size)
618
167
                    << ", section-name='" << si->sectionName
619
167
                    << "\n";
620
167
      }
621
167
    }
622
167
  );
623
167
}
624
625
167
void Util::copySegmentInfo(NormalizedFile &file) {
626
465
  for (SegmentInfo *sgi : _segmentInfos) {
627
465
    Segment seg;
628
465
    seg.name    = sgi->name;
629
465
    seg.address = sgi->address;
630
465
    seg.size    = sgi->size;
631
465
    seg.init_access  = sgi->init_access;
632
465
    seg.max_access  = sgi->max_access;
633
465
    file.segments.push_back(seg);
634
465
  }
635
167
}
636
637
374
void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
638
374
   // Add new empty section to end of file.sections.
639
374
  Section temp;
640
374
  file.sections.push_back(std::move(temp));
641
374
  Section* normSect = &file.sections.back();
642
374
  // Copy fields to normalized section.
643
374
  normSect->segmentName   = si->segmentName;
644
374
  normSect->sectionName   = si->sectionName;
645
374
  normSect->type          = si->type;
646
374
  normSect->attributes    = si->attributes;
647
374
  normSect->address       = si->address;
648
374
  normSect->alignment     = si->alignment;
649
374
  // Record where normalized section is.
650
374
  si->normalizedSectionIndex = file.sections.size()-1;
651
374
}
652
653
167
void Util::copySectionContent(NormalizedFile &file) {
654
167
  const bool r = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
655
167
656
167
  // 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
167
663
4
  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 (15
atomInfo.atom == &atom15
)
667
4
          return sectInfo->address;
668
0
    
llvm_unreachable0
("atom not assigned to section");
669
0
  };
670
167
671
374
  for (SectionInfo *si : _sectionInfos) {
672
374
    Section *normSect = &file.sections[si->normalizedSectionIndex];
673
374
    if (
isZeroFillSection(si->type)374
) {
674
5
      const uint8_t *empty = nullptr;
675
5
      normSect->content = llvm::makeArrayRef(empty, si->size);
676
5
      continue;
677
5
    }
678
369
    // Copy content from atoms to content buffer for section.
679
369
    llvm::MutableArrayRef<uint8_t> sectionContent;
680
369
    if (
si->size369
) {
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
733
    for (AtomInfo &ai : si->atomsAndOffsets) {
686
733
      if (
!ai.atom->size()733
) {
687
113
        assert(ai.atom->begin() == ai.atom->end() &&
688
113
               "Cannot have references without content");
689
113
        continue;
690
113
      }
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
374
  }
698
167
}
699
700
167
void Util::copySectionInfo(NormalizedFile &file) {
701
167
  file.sections.reserve(_sectionInfos.size());
702
167
  // Write sections grouped by segment.
703
465
  for (SegmentInfo *sgi : _segmentInfos) {
704
374
    for (SectionInfo *si : sgi->sections) {
705
374
      appendSection(si, file);
706
374
    }
707
465
  }
708
167
}
709
710
167
void Util::updateSectionInfo(NormalizedFile &file) {
711
167
  file.sections.reserve(_sectionInfos.size());
712
167
  // sections grouped by segment.
713
465
  for (SegmentInfo *sgi : _segmentInfos) {
714
465
    Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
715
465
    normSeg->address = sgi->address;
716
465
    normSeg->size = sgi->size;
717
374
    for (SectionInfo *si : sgi->sections) {
718
374
      Section *normSect = &file.sections[si->normalizedSectionIndex];
719
374
      normSect->address = si->address;
720
374
    }
721
465
  }
722
167
}
723
724
166
void Util::copyEntryPointAddress(NormalizedFile &nFile) {
725
166
  if (
!_entryAtom166
) {
726
119
    nFile.entryAddress = 0;
727
119
    return;
728
119
  }
729
47
730
47
  
if (47
_ctx.outputTypeHasEntry()47
) {
731
47
    if (_archHandler.isThumbFunction(*_entryAtom))
732
1
      nFile.entryAddress = (_atomToAddress[_entryAtom] | 1);
733
47
    else
734
46
      nFile.entryAddress = _atomToAddress[_entryAtom];
735
47
  }
736
166
}
737
738
167
void Util::buildAtomToAddressMap() {
739
167
  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
740
167
                   << "assign atom addresses:\n");
741
167
  const bool lookForEntry = _ctx.outputTypeHasEntry();
742
374
  for (SectionInfo *sect : _sectionInfos) {
743
743
    for (const AtomInfo &info : sect->atomsAndOffsets) {
744
743
      _atomToAddress[info.atom] = sect->address + info.offsetInSection;
745
743
      if (
lookForEntry && 743
(info.atom->contentType() == DefinedAtom::typeCode)293
&&
746
77
          (info.atom->size() != 0) &&
747
743
          
info.atom->name() == _ctx.entrySymbolName()74
) {
748
47
        _entryAtom = info.atom;
749
47
      }
750
743
      DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
751
743
                      << "   address="
752
743
                      << llvm::format("0x%016X", _atomToAddress[info.atom])
753
743
                      << llvm::format("    0x%09lX", info.atom)
754
743
                      << ", file=#"
755
743
                      << info.atom->file().ordinal()
756
743
                      << ", atom=#"
757
743
                      << info.atom->ordinal()
758
743
                      << ", name="
759
743
                      << info.atom->name()
760
743
                      << ", type="
761
743
                      << info.atom->contentType()
762
743
                      << "\n");
763
743
    }
764
374
  }
765
167
  DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
766
167
                  << "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
167
}
794
795
167
llvm::Error Util::synthesizeDebugNotes(NormalizedFile &file) {
796
167
797
167
  // Bail out early if we don't need to generate a debug map.
798
167
  if (_ctx.debugInfoMode() == MachOLinkingContext::DebugInfoMode::noDebugMap)
799
0
    return llvm::Error::success();
800
167
801
167
  std::vector<const DefinedAtom*> atomsNeedingDebugNotes;
802
167
  std::set<const mach_o::MachOFile*> filesWithStabs;
803
167
  bool objFileHasDwarf = false;
804
167
  const File *objFile = nullptr;
805
167
806
374
  for (SectionInfo *sect : _sectionInfos) {
807
743
    for (const AtomInfo &info : sect->atomsAndOffsets) {
808
743
      if (const DefinedAtom *
atom743
= dyn_cast<DefinedAtom>(info.atom)) {
809
743
810
743
        // FIXME: No stabs/debug-notes for symbols that wouldn't be in the
811
743
        //        symbol table.
812
743
        // FIXME: No stabs/debug-notes for kernel dtrace probes.
813
743
814
743
        if (atom->contentType() == DefinedAtom::typeCFI ||
815
708
            atom->contentType() == DefinedAtom::typeCString)
816
62
          continue;
817
681
818
681
        // Whenever we encounter a new file, update the 'objfileHasDwarf' flag.
819
681
        
if (681
&info.atom->file() != objFile681
) {
820
681
          objFileHasDwarf = false;
821
681
          if (const mach_o::MachOFile *atomFile =
822
540
              dyn_cast<mach_o::MachOFile>(&info.atom->file())) {
823
540
            if (
atomFile->debugInfo()540
) {
824
1
              if (isa<mach_o::DwarfDebugInfo>(atomFile->debugInfo()))
825
1
                objFileHasDwarf = true;
826
0
              else 
if (0
isa<mach_o::StabsDebugInfo>(atomFile->debugInfo())0
)
827
0
                filesWithStabs.insert(atomFile);
828
1
            }
829
540
          }
830
681
        }
831
681
832
681
        // If this atom is from a file that needs dwarf, add it to the list.
833
681
        if (objFileHasDwarf)
834
1
          atomsNeedingDebugNotes.push_back(info.atom);
835
743
      }
836
743
    }
837
374
  }
838
167
839
167
  // Sort atoms needing debug notes by file ordinal, then atom ordinal.
840
167
  std::sort(atomsNeedingDebugNotes.begin(), atomsNeedingDebugNotes.end(),
841
0
            [](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
167
847
167
  // FIXME: Handle <rdar://problem/17689030>: Add -add_ast_path option to \
848
167
  //        linker which add N_AST stab entry to output
849
167
  // See OutputFile::synthesizeDebugNotes in ObjectFile.cpp in ld64.
850
167
851
167
  StringRef oldFileName = "";
852
167
  StringRef oldDirPath = "";
853
167
  bool wroteStartSO = false;
854
167
  std::unordered_set<std::string> seenFiles;
855
1
  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 || 1
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() != '/'1
) {
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 (1
llvm::sys::fs::exists(stat)1
)
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 (1
atom->contentType() == DefinedAtom::typeCode1
) {
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
167
930
167
  // Emit ending SO if necessary.
931
167
  
if (167
wroteStartSO167
)
932
1
    _stabs.push_back(mach_o::Stab(nullptr, N_SO, 1, 0, 0, ""));
933
167
934
167
  // Copy any stabs from .o file.
935
0
  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
167
944
167
  return llvm::Error::success();
945
167
}
946
947
461
uint16_t Util::descBits(const DefinedAtom* atom) {
948
461
  uint16_t desc = 0;
949
461
  switch (atom->merge()) {
950
453
  case lld::DefinedAtom::mergeNo:
951
453
  case lld::DefinedAtom::mergeAsTentative:
952
453
    break;
953
8
  case lld::DefinedAtom::mergeAsWeak:
954
8
  case lld::DefinedAtom::mergeAsWeakAndAddressUsed:
955
8
    desc |= N_WEAK_DEF;
956
8
    break;
957
0
  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
461
  }
963
461
  
if (461
atom->contentType() == lld::DefinedAtom::typeResolver461
)
964
2
    desc |= N_SYMBOL_RESOLVER;
965
461
  if (atom->contentType() == lld::DefinedAtom::typeMachHeader)
966
95
    desc |= REFERENCED_DYNAMICALLY;
967
461
  if (_archHandler.isThumbFunction(*atom))
968
22
    desc |= N_ARM_THUMB_DEF;
969
461
  if (atom->deadStrip() == DefinedAtom::deadStripNever &&
970
461
      
_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
461
  return desc;
976
461
}
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
462
                                       SymbolScope &scope) {
986
462
  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
987
462
  switch (atom->scope()) {
988
97
  case Atom::scopeTranslationUnit:
989
97
    scope = 0;
990
97
    inGlobalsRegion = false;
991
97
    return llvm::Error::success();
992
69
  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 (68
rMode68
) {
999
17
      if (
_ctx.keepPrivateExterns()17
) {
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()296
) {
1012
21
      if (
_ctx.exportSymbolNamed(atom->name())21
) {
1013
12
        scope = N_EXT;
1014
12
        inGlobalsRegion = true;
1015
12
        return llvm::Error::success();
1016
0
      } 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_unreachable0
("atom->scope() unknown enum value");
1029
0
}
1030
1031
1032
1033
llvm::Error Util::addSymbols(const lld::File &atomFile,
1034
167
                             NormalizedFile &file) {
1035
167
  bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
1036
167
  // Mach-O symbol table has four regions: stabs, locals, globals, undefs.
1037
167
1038
167
  // Add all stabs.
1039
8
  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
8
    else
1048
6
      sym.value = stab.value;
1049
8
    sym.name = stab.str;
1050
8
    file.stabsSymbols.push_back(sym);
1051
8
  }
1052
167
1053
167
  // Add all local (non-global) symbols in address order
1054
167
  std::vector<AtomAndIndex> globals;
1055
167
  globals.reserve(512);
1056
374
  for (SectionInfo *sect : _sectionInfos) {
1057
742
    for (const AtomInfo &info : sect->atomsAndOffsets) {
1058
742
      const DefinedAtom *atom = info.atom;
1059
742
      if (
!atom->name().empty()742
) {
1060
462
        SymbolScope symbolScope;
1061
462
        bool inGlobalsRegion;
1062
462
        if (auto 
ec462
= getSymbolTableRegion(atom, inGlobalsRegion, symbolScope)){
1063
1
          return ec;
1064
1
        }
1065
461
        
if (461
inGlobalsRegion461
) {
1066
291
          AtomAndIndex ai = { atom, sect->finalSectionIndex, symbolScope };
1067
291
          globals.push_back(ai);
1068
461
        } else {
1069
170
          Symbol sym;
1070
170
          sym.name  = atom->name();
1071
170
          sym.type  = N_SECT;
1072
170
          sym.scope = symbolScope;
1073
170
          sym.sect  = sect->finalSectionIndex;
1074
170
          sym.desc  = descBits(atom);
1075
170
          sym.value = _atomToAddress[atom];
1076
170
          _atomToSymbolIndex[atom] = file.localSymbols.size();
1077
170
          file.localSymbols.push_back(sym);
1078
170
        }
1079
742
      } else 
if (280
rMode && 280
_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
742
    }
1096
374
  }
1097
167
1098
167
  // Sort global symbol alphabetically, then add to symbol table.
1099
166
  std::sort(globals.begin(), globals.end(), AtomSorter());
1100
166
  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
166
1113
166
  // Sort undefined symbol alphabetically, then add to symbol table.
1114
166
  std::vector<AtomAndIndex> undefs;
1115
166
  undefs.reserve(128);
1116
44
  for (const UndefinedAtom *atom : atomFile.undefined()) {
1117
44
    AtomAndIndex ai = { atom, 0, N_EXT };
1118
44
    undefs.push_back(ai);
1119
44
  }
1120
138
  for (const SharedLibraryAtom *atom : atomFile.sharedLibrary()) {
1121
138
    AtomAndIndex ai = { atom, 0, N_EXT };
1122
138
    undefs.push_back(ai);
1123
138
  }
1124
166
  std::sort(undefs.begin(), undefs.end(), AtomSorter());
1125
166
  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 (
!rMode182
) {
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
166
1145
166
  return llvm::Error::success();
1146
167
}
1147
1148
46
const Atom *Util::targetOfLazyPointer(const DefinedAtom *lpAtom) {
1149
92
  for (const Reference *ref : *lpAtom) {
1150
92
    if (
_archHandler.isLazyPointer(*ref)92
) {
1151
46
      return ref->target();
1152
46
    }
1153
0
  }
1154
0
  return nullptr;
1155
0
}
1156
1157
23
const Atom *Util::targetOfStub(const DefinedAtom *stubAtom) {
1158
23
  for (const Reference *ref : *stubAtom) {
1159
23
    if (const Atom *
ta23
= ref->target()) {
1160
23
      if (const DefinedAtom *
lpAtom23
= dyn_cast<DefinedAtom>(ta)) {
1161
23
        const Atom *target = targetOfLazyPointer(lpAtom);
1162
23
        if (target)
1163
23
          return target;
1164
0
      }
1165
23
    }
1166
23
  }
1167
0
  return nullptr;
1168
0
}
1169
1170
166
void Util::addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file) {
1171
372
  for (SectionInfo *si : _sectionInfos) {
1172
372
    Section &normSect = file.sections[si->normalizedSectionIndex];
1173
372
    switch (si->type) {
1174
23
    case llvm::MachO::S_NON_LAZY_SYMBOL_POINTERS:
1175
50
      for (const AtomInfo &info : si->atomsAndOffsets) {
1176
50
        bool foundTarget = false;
1177
32
        for (const Reference *ref : *info.atom) {
1178
32
          const Atom *target = ref->target();
1179
32
          if (
target32
) {
1180
32
            if (
isa<const SharedLibraryAtom>(target)32
) {
1181
31
              uint32_t index = _atomToSymbolIndex[target];
1182
31
              normSect.indirectSymbols.push_back(index);
1183
31
              foundTarget = true;
1184
32
            } else {
1185
1
              normSect.indirectSymbols.push_back(
1186
1
                                            llvm::MachO::INDIRECT_SYMBOL_LOCAL);
1187
1
            }
1188
32
          }
1189
32
        }
1190
50
        if (
!foundTarget50
) {
1191
19
          normSect.indirectSymbols.push_back(
1192
19
                                             llvm::MachO::INDIRECT_SYMBOL_ABS);
1193
19
        }
1194
50
      }
1195
23
      break;
1196
17
    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 (
target23
) {
1200
23
          uint32_t index = _atomToSymbolIndex[target];
1201
23
          normSect.indirectSymbols.push_back(index);
1202
23
        }
1203
23
      }
1204
17
      break;
1205
17
    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 (
target23
) {
1209
23
          uint32_t index = _atomToSymbolIndex[target];
1210
23
          normSect.indirectSymbols.push_back(index);
1211
23
        }
1212
23
      }
1213
17
      break;
1214
315
    default:
1215
315
      break;
1216
166
    }
1217
166
  }
1218
166
}
1219
1220
void Util::addDependentDylibs(const lld::File &atomFile,
1221
167
                              NormalizedFile &nFile) {
1222
167
  // Scan all imported symbols and build up list of dylibs they are from.
1223
167
  int ordinal = 1;
1224
111
  for (const auto *dylib : _ctx.allDylibs()) {
1225
111
    DylibPathToInfo::iterator pos = _dylibInfo.find(dylib->installName());
1226
111
    if (
pos == _dylibInfo.end()111
) {
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 || 110
_ctx.useFlatNamespace()110
)
1234
1
        info.ordinal = BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
1235
110
      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 (
!flatNamespaceAtom110
) {
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
111
    } else {
1251
1
      pos->second.hasWeak = false;
1252
1
      pos->second.hasNonWeak = !pos->second.hasWeak;
1253
1
    }
1254
111
  }
1255
167
  // Automatically weak link dylib in which all symbols are weak (canBeNull).
1256
110
  for (DependentDylib &dep : nFile.dependentDylibs) {
1257
110
    DylibInfo &info = _dylibInfo[dep.path];
1258
110
    if (
info.hasWeak && 110
!info.hasNonWeak0
)
1259
0
      dep.kind = llvm::MachO::LC_LOAD_WEAK_DYLIB;
1260
110
    else 
if (110
_ctx.isUpwardDylib(dep.path)110
)
1261
1
      dep.kind = llvm::MachO::LC_LOAD_UPWARD_DYLIB;
1262
110
  }
1263
167
}
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)452
) {
1275
229
      segmentStartAddr = seg->address;
1276
229
      return;
1277
229
    }
1278
223
    ++segmentIndex;
1279
223
  }
1280
0
  
llvm_unreachable0
("section not in any segment");
1281
0
}
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) && 132
(address < si->address+si->size)93
)
1287
77
      return si->finalSectionIndex;
1288
0
  }
1289
0
  
llvm_unreachable0
("atom not in any section");
1290
0
}
1291
1292
166
void Util::addSectionRelocs(const lld::File &, NormalizedFile &file) {
1293
166
  if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
1294
95
    return;
1295
71
1296
71
  // Utility function for ArchHandler to find symbol index for an atom.
1297
71
  
auto symIndexForAtom = [&] (const Atom &atom) -> uint32_t 71
{
1298
207
    auto pos = _atomToSymbolIndex.find(&atom);
1299
207
    assert(pos != _atomToSymbolIndex.end());
1300
207
    return pos->second;
1301
207
  };
1302
71
1303
71
  // 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
71
1308
71
  // 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
71
1315
143
  for (SectionInfo *si : _sectionInfos) {
1316
143
    Section &normSect = file.sections[si->normalizedSectionIndex];
1317
284
    for (const AtomInfo &info : si->atomsAndOffsets) {
1318
284
      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 && 416
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
284
    }
1332
143
  }
1333
166
}
1334
1335
166
void Util::addFunctionStarts(const lld::File &, NormalizedFile &file) {
1336
166
  if (!_ctx.generateFunctionStartsLoadCommand())
1337
80
    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::typeMachHeader437
) {
1346
86
        addr = _atomToAddress[info.atom];
1347
86
        continue;
1348
86
      }
1349
351
      
if (351
type != DefinedAtom::typeCode351
)
1350
213
        continue;
1351
351
      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 (
delta128
) {
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
437
      addr = nextAddr;
1367
437
    }
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 != e459
;
++i373
)
1376
373
    file.functionStarts.push_back(0);
1377
166
}
1378
1379
166
void Util::buildDataInCodeArray(const lld::File &, NormalizedFile &file) {
1380
166
  if (!_ctx.generateDataInCodeLoadCommand())
1381
10
    return;
1382
156
  
for (SectionInfo *si : _sectionInfos) 156
{
1383
720
    for (const AtomInfo &info : si->atomsAndOffsets) {
1384
720
      // Atoms that contain data-in-code have "transition" references
1385
720
      // which mark a point where the embedded data starts of ends.
1386
720
      // This needs to be converted to the mach-o format which is an array
1387
720
      // of data-in-code ranges.
1388
720
      uint32_t startOffset = 0;
1389
720
      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 (831
_archHandler.isDataInCodeTransition(ref->kindValue())831
) {
1394
58
          DataRegionType nextMode = (DataRegionType)ref->addend();
1395
58
          if (
mode != nextMode58
) {
1396
36
            if (
mode != 036
) {
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
835
      }
1409
720
      if (
mode != 0720
) {
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
720
    }
1418
362
  }
1419
166
}
1420
1421
void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
1422
166
                                                        NormalizedFile &nFile) {
1423
166
  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1424
71
    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
419
      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)419
) {
1439
71
          // A pointer to a DefinedAtom requires rebasing.
1440
71
          if (
isa<DefinedAtom>(targ)71
) {
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 *
sa71
= 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 (348
_archHandler.isLazyPointer(*ref)348
) {
1461
23
          BindLocation bind;
1462
23
          if (const SharedLibraryAtom *
sa23
= 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
348
        }
1487
419
      }
1488
455
    }
1489
229
  }
1490
166
}
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()23
) {
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
23
    
for (SectionInfo *sectInfo : _sectionInfos) 23
{
1511
312
      for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) {
1512
312
        if (
atomInfo.atom == helperRef->target()312
) {
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
46
  }
1531
23
}
1532
1533
166
void Util::addExportInfo(const lld::File &atomFile, NormalizedFile &nFile) {
1534
166
  if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1535
71
    return;
1536
95
1537
95
  
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 (202
_ctx.exportRestrictMode()202
) {
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
196
      else
1553
195
        exprt.flags = 0;
1554
455
      exprt.otherOffset = 0;
1555
455
      exprt.otherName = StringRef();
1556
455
      nFile.exportInfo.push_back(exprt);
1557
455
    }
1558
229
  }
1559
166
}
1560
1561
167
uint32_t Util::fileFlags() {
1562
167
  // FIXME: these need to determined at runtime.
1563
167
  if (
_ctx.outputMachOType() == MH_OBJECT167
) {
1564
72
    return _subsectionsViaSymbols ? 
MH_SUBSECTIONS_VIA_SYMBOLS64
:
08
;
1565
0
  } 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) && 95
_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
0
}
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
167
                                           const MachOLinkingContext &context) {
1587
167
  // The util object buffers info until the normalized file can be made.
1588
167
  Util util(context);
1589
167
  util.processDefinedAtoms(atomFile);
1590
167
  util.organizeSections();
1591
167
1592
167
  std::unique_ptr<NormalizedFile> f(new NormalizedFile());
1593
167
  NormalizedFile &normFile = *f.get();
1594
167
  normFile.arch = context.arch();
1595
167
  normFile.fileType = context.outputMachOType();
1596
167
  normFile.flags = util.fileFlags();
1597
167
  normFile.stackSize = context.stackSize();
1598
167
  normFile.installName = context.installName();
1599
167
  normFile.currentVersion = context.currentVersion();
1600
167
  normFile.compatVersion = context.compatibilityVersion();
1601
167
  normFile.os = context.os();
1602
167
1603
167
  // If we are emitting an object file, then the min version is the maximum
1604
167
  // of the min's of all the source files and the cmdline.
1605
167
  if (normFile.fileType == llvm::MachO::MH_OBJECT)
1606
72
    normFile.minOSverson = std::max(context.osMinVersion(), util.minVersion());
1607
167
  else
1608
95
    normFile.minOSverson = context.osMinVersion();
1609
167
1610
167
  normFile.minOSVersionKind = util.minVersionCommandType();
1611
167
1612
167
  normFile.sdkVersion = context.sdkVersion();
1613
167
  normFile.sourceVersion = context.sourceVersion();
1614
167
1615
167
  if (context.generateVersionLoadCommand() &&
1616
86
      context.os() != MachOLinkingContext::OS::unknown)
1617
86
    normFile.hasMinVersionLoadCommand = true;
1618
81
  else 
if (81
normFile.fileType == llvm::MachO::MH_OBJECT &&
1619
72
           util.allSourceFilesHaveMinVersions() &&
1620
3
           ((normFile.os != MachOLinkingContext::OS::unknown) ||
1621
81
            
util.minVersionCommandType()2
)) {
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
167
  normFile.generateDataInCodeLoadCommand =
1629
167
    context.generateDataInCodeLoadCommand();
1630
167
  normFile.pageSize = context.pageSize();
1631
167
  normFile.rpaths = context.rpaths();
1632
167
  util.addDependentDylibs(atomFile, normFile);
1633
167
  util.copySegmentInfo(normFile);
1634
167
  util.copySectionInfo(normFile);
1635
167
  util.assignAddressesToSections(normFile);
1636
167
  util.buildAtomToAddressMap();
1637
167
  if (auto err = util.synthesizeDebugNotes(normFile))
1638
0
    return std::move(err);
1639
167
  util.updateSectionInfo(normFile);
1640
167
  util.copySectionContent(normFile);
1641
167
  if (auto 
ec167
= util.addSymbols(atomFile, normFile)) {
1642
1
    return std::move(ec);
1643
1
  }
1644
166
  util.addIndirectSymbols(atomFile, normFile);
1645
166
  util.addRebaseAndBindingInfo(atomFile, normFile);
1646
166
  util.addExportInfo(atomFile, normFile);
1647
166
  util.addSectionRelocs(atomFile, normFile);
1648
166
  util.addFunctionStarts(atomFile, normFile);
1649
166
  util.buildDataInCodeArray(atomFile, normFile);
1650
166
  util.copyEntryPointAddress(normFile);
1651
166
1652
166
  return std::move(f);
1653
166
}
1654
1655
} // namespace normalized
1656
} // namespace mach_o
1657
} // namespace lld