Coverage Report

Created: 2017-09-21 03:39

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.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 For mach-o object files, this implementation converts normalized
12
/// mach-o in memory to mach-o binary on disk.
13
///
14
///                 +---------------+
15
///                 | binary mach-o |
16
///                 +---------------+
17
///                        ^
18
///                        |
19
///                        |
20
///                  +------------+
21
///                  | normalized |
22
///                  +------------+
23
24
#include "MachONormalizedFile.h"
25
#include "MachONormalizedFileBinaryUtils.h"
26
#include "lld/Core/Error.h"
27
#include "lld/Core/LLVM.h"
28
#include "llvm/ADT/SmallString.h"
29
#include "llvm/ADT/SmallVector.h"
30
#include "llvm/ADT/StringRef.h"
31
#include "llvm/ADT/ilist.h"
32
#include "llvm/ADT/ilist_node.h"
33
#include "llvm/BinaryFormat/MachO.h"
34
#include "llvm/Support/Casting.h"
35
#include "llvm/Support/Debug.h"
36
#include "llvm/Support/Errc.h"
37
#include "llvm/Support/ErrorHandling.h"
38
#include "llvm/Support/FileOutputBuffer.h"
39
#include "llvm/Support/Format.h"
40
#include "llvm/Support/Host.h"
41
#include "llvm/Support/MemoryBuffer.h"
42
#include "llvm/Support/raw_ostream.h"
43
#include <functional>
44
#include <list>
45
#include <map>
46
#include <system_error>
47
48
using namespace llvm::MachO;
49
50
namespace lld {
51
namespace mach_o {
52
namespace normalized {
53
54
struct TrieNode; // Forward declaration.
55
56
struct TrieEdge : public llvm::ilist_node<TrieEdge> {
57
276
  TrieEdge(StringRef s, TrieNode *node) : _subString(s), _child(node) {}
58
59
  StringRef          _subString;
60
  struct TrieNode   *_child;
61
};
62
63
} // namespace normalized
64
} // namespace mach_o
65
} // namespace lld
66
67
68
namespace llvm {
69
using lld::mach_o::normalized::TrieEdge;
70
template <>
71
struct ilist_alloc_traits<TrieEdge> : ilist_noalloc_traits<TrieEdge> {};
72
} // namespace llvm
73
74
75
namespace lld {
76
namespace mach_o {
77
namespace normalized {
78
79
struct TrieNode {
80
  typedef llvm::ilist<TrieEdge> TrieEdgeList;
81
82
  TrieNode(StringRef s)
83
      : _cummulativeString(s), _address(0), _flags(0), _other(0),
84
368
        _trieOffset(0), _hasExportInfo(false) {}
85
  ~TrieNode() = default;
86
87
  void addSymbol(const Export &entry, BumpPtrAllocator &allocator,
88
                 std::vector<TrieNode *> &allNodes);
89
90
  void addOrderedNodes(const Export &entry,
91
                       std::vector<TrieNode *> &allNodes);
92
  bool updateOffset(uint32_t &offset);
93
  void appendToByteBuffer(ByteBuffer &out);
94
95
private:
96
  StringRef                 _cummulativeString;
97
  TrieEdgeList              _children;
98
  uint64_t                  _address;
99
  uint64_t                  _flags;
100
  uint64_t                  _other;
101
  StringRef                 _importedName;
102
  uint32_t                  _trieOffset;
103
  bool                      _hasExportInfo;
104
  bool                      _ordered = false;
105
};
106
107
/// Utility class for writing a mach-o binary file given an in-memory
108
/// normalized file.
109
class MachOFileLayout {
110
public:
111
  /// All layout computation is done in the constructor.
112
  MachOFileLayout(const NormalizedFile &file);
113
114
  /// Returns the final file size as computed in the constructor.
115
  size_t      size() const;
116
117
  // Returns size of the mach_header and load commands.
118
  size_t      headerAndLoadCommandsSize() const;
119
120
  /// Writes the normalized file as a binary mach-o file to the specified
121
  /// path.  This does not have a stream interface because the generated
122
  /// file may need the 'x' bit set.
123
  llvm::Error writeBinary(StringRef path);
124
125
private:
126
  uint32_t    loadCommandsSize(uint32_t &count);
127
  void        buildFileOffsets();
128
  void        writeMachHeader();
129
  llvm::Error writeLoadCommands();
130
  void        writeSectionContent();
131
  void        writeRelocations();
132
  void        writeSymbolTable();
133
  void        writeRebaseInfo();
134
  void        writeBindingInfo();
135
  void        writeLazyBindingInfo();
136
  void        writeExportInfo();
137
  void        writeFunctionStartsInfo();
138
  void        writeDataInCodeInfo();
139
  void        writeLinkEditContent();
140
  void        buildLinkEditInfo();
141
  void        buildRebaseInfo();
142
  void        buildBindInfo();
143
  void        buildLazyBindInfo();
144
  void        buildExportTrie();
145
  void        computeFunctionStartsSize();
146
  void        computeDataInCodeSize();
147
  void        computeSymbolTableSizes();
148
  void        buildSectionRelocations();
149
  void        appendSymbols(const std::vector<Symbol> &symbols,
150
                                      uint32_t &symOffset, uint32_t &strOffset);
151
  uint32_t    indirectSymbolIndex(const Section &sect, uint32_t &index);
152
  uint32_t    indirectSymbolElementSize(const Section &sect);
153
154
  // For use as template parameter to load command methods.
155
  struct MachO64Trait {
156
    typedef llvm::MachO::segment_command_64 command;
157
    typedef llvm::MachO::section_64         section;
158
    enum { LC = llvm::MachO::LC_SEGMENT_64 };
159
  };
160
161
  // For use as template parameter to load command methods.
162
  struct MachO32Trait {
163
    typedef llvm::MachO::segment_command   command;
164
    typedef llvm::MachO::section           section;
165
    enum { LC = llvm::MachO::LC_SEGMENT };
166
  };
167
168
  template <typename T>
169
  llvm::Error writeSingleSegmentLoadCommand(uint8_t *&lc);
170
  template <typename T> llvm::Error writeSegmentLoadCommands(uint8_t *&lc);
171
172
  uint32_t pointerAlign(uint32_t value);
173
  static StringRef dyldPath();
174
175
  struct SegExtraInfo {
176
    uint32_t                    fileOffset;
177
    uint32_t                    fileSize;
178
    std::vector<const Section*> sections;
179
  };
180
  typedef std::map<const Segment*, SegExtraInfo> SegMap;
181
  struct SectionExtraInfo {
182
    uint32_t                    fileOffset;
183
  };
184
  typedef std::map<const Section*, SectionExtraInfo> SectionMap;
185
186
  const NormalizedFile &_file;
187
  std::error_code _ec;
188
  uint8_t              *_buffer;
189
  const bool            _is64;
190
  const bool            _swap;
191
  const bool            _bigEndianArch;
192
  uint64_t              _seg1addr;
193
  uint32_t              _startOfLoadCommands;
194
  uint32_t              _countOfLoadCommands;
195
  uint32_t              _endOfLoadCommands;
196
  uint32_t              _startOfRelocations;
197
  uint32_t              _startOfFunctionStarts;
198
  uint32_t              _startOfDataInCode;
199
  uint32_t              _startOfSymbols;
200
  uint32_t              _startOfIndirectSymbols;
201
  uint32_t              _startOfSymbolStrings;
202
  uint32_t              _endOfSymbolStrings;
203
  uint32_t              _symbolTableLocalsStartIndex;
204
  uint32_t              _symbolTableGlobalsStartIndex;
205
  uint32_t              _symbolTableUndefinesStartIndex;
206
  uint32_t              _symbolStringPoolSize;
207
  uint32_t              _symbolTableSize;
208
  uint32_t              _functionStartsSize;
209
  uint32_t              _dataInCodeSize;
210
  uint32_t              _indirectSymbolTableCount;
211
  // Used in object file creation only
212
  uint32_t              _startOfSectionsContent;
213
  uint32_t              _endOfSectionsContent;
214
  // Used in final linked image only
215
  uint32_t              _startOfLinkEdit;
216
  uint32_t              _startOfRebaseInfo;
217
  uint32_t              _endOfRebaseInfo;
218
  uint32_t              _startOfBindingInfo;
219
  uint32_t              _endOfBindingInfo;
220
  uint32_t              _startOfLazyBindingInfo;
221
  uint32_t              _endOfLazyBindingInfo;
222
  uint32_t              _startOfExportTrie;
223
  uint32_t              _endOfExportTrie;
224
  uint32_t              _endOfLinkEdit;
225
  uint64_t              _addressOfLinkEdit;
226
  SegMap                _segInfo;
227
  SectionMap            _sectInfo;
228
  ByteBuffer            _rebaseInfo;
229
  ByteBuffer            _bindingInfo;
230
  ByteBuffer            _lazyBindingInfo;
231
  ByteBuffer            _weakBindingInfo;
232
  ByteBuffer            _exportTrie;
233
};
234
235
167
size_t headerAndLoadCommandsSize(const NormalizedFile &file) {
236
167
  MachOFileLayout layout(file);
237
167
  return layout.headerAndLoadCommandsSize();
238
167
}
239
240
306
StringRef MachOFileLayout::dyldPath() {
241
306
  return "/usr/lib/dyld";
242
306
}
243
244
1.41k
uint32_t MachOFileLayout::pointerAlign(uint32_t value) {
245
1.41k
  return llvm::alignTo(value, _is64 ? 
81.19k
:
4226
);
246
1.41k
}
247
248
249
167
size_t MachOFileLayout::headerAndLoadCommandsSize() const {
250
167
  return _endOfLoadCommands;
251
167
}
252
253
MachOFileLayout::MachOFileLayout(const NormalizedFile &file)
254
    : _file(file),
255
      _is64(MachOLinkingContext::is64Bit(file.arch)),
256
      _swap(!MachOLinkingContext::isHostEndian(file.arch)),
257
      _bigEndianArch(MachOLinkingContext::isBigEndian(file.arch)),
258
338
      _seg1addr(INT64_MAX) {
259
338
  _startOfLoadCommands = _is64 ? 
sizeof(mach_header_64)276
:
sizeof(mach_header)62
;
260
338
  const size_t segCommandBaseSize =
261
338
          (_is64 ? 
sizeof(segment_command_64)276
:
sizeof(segment_command)62
);
262
338
  const size_t sectsSize = (_is64 ? 
sizeof(section_64)276
:
sizeof(section)62
);
263
338
  if (
file.fileType == llvm::MachO::MH_OBJECT338
) {
264
148
    // object files have just one segment load command containing all sections
265
148
    _endOfLoadCommands = _startOfLoadCommands
266
148
                               + segCommandBaseSize
267
148
                               + file.sections.size() * sectsSize
268
148
                               + sizeof(symtab_command);
269
148
    _countOfLoadCommands = 2;
270
148
    if (
file.hasMinVersionLoadCommand148
) {
271
4
      _endOfLoadCommands += sizeof(version_min_command);
272
4
      _countOfLoadCommands++;
273
4
    }
274
148
    if (
!_file.functionStarts.empty()148
) {
275
0
      _endOfLoadCommands += sizeof(linkedit_data_command);
276
0
      _countOfLoadCommands++;
277
0
    }
278
148
    if (
_file.generateDataInCodeLoadCommand148
) {
279
141
      _endOfLoadCommands += sizeof(linkedit_data_command);
280
141
      _countOfLoadCommands++;
281
141
    }
282
148
    // Assign file offsets to each section.
283
148
    _startOfSectionsContent = _endOfLoadCommands;
284
148
    unsigned relocCount = 0;
285
148
    uint64_t offset = _startOfSectionsContent;
286
294
    for (const Section &sect : file.sections) {
287
294
      if (isZeroFillSection(sect.type))
288
4
        _sectInfo[&sect].fileOffset = 0;
289
290
      else {
290
290
        offset = llvm::alignTo(offset, sect.alignment);
291
290
        _sectInfo[&sect].fileOffset = offset;
292
290
        offset += sect.content.size();
293
290
      }
294
294
      relocCount += sect.relocations.size();
295
294
    }
296
148
    _endOfSectionsContent = offset;
297
148
298
148
    computeSymbolTableSizes();
299
148
    computeFunctionStartsSize();
300
148
    computeDataInCodeSize();
301
148
302
148
    // Align start of relocations.
303
148
    _startOfRelocations = pointerAlign(_endOfSectionsContent);
304
148
    _startOfFunctionStarts = _startOfRelocations + relocCount * 8;
305
148
    _startOfDataInCode = _startOfFunctionStarts + _functionStartsSize;
306
148
    _startOfSymbols = _startOfDataInCode + _dataInCodeSize;
307
148
    // Add Indirect symbol table.
308
148
    _startOfIndirectSymbols = _startOfSymbols + _symbolTableSize;
309
148
    // Align start of symbol table and symbol strings.
310
148
    _startOfSymbolStrings = _startOfIndirectSymbols
311
148
                  + pointerAlign(_indirectSymbolTableCount * sizeof(uint32_t));
312
148
    _endOfSymbolStrings = _startOfSymbolStrings
313
148
                          + pointerAlign(_symbolStringPoolSize);
314
148
    _endOfLinkEdit = _endOfSymbolStrings;
315
148
    DEBUG_WITH_TYPE("MachOFileLayout",
316
148
                  llvm::dbgs() << "MachOFileLayout()\n"
317
148
      << "  startOfLoadCommands=" << _startOfLoadCommands << "\n"
318
148
      << "  countOfLoadCommands=" << _countOfLoadCommands << "\n"
319
148
      << "  endOfLoadCommands=" << _endOfLoadCommands << "\n"
320
148
      << "  startOfRelocations=" << _startOfRelocations << "\n"
321
148
      << "  startOfSymbols=" << _startOfSymbols << "\n"
322
148
      << "  startOfSymbolStrings=" << _startOfSymbolStrings << "\n"
323
148
      << "  endOfSymbolStrings=" << _endOfSymbolStrings << "\n"
324
148
      << "  startOfSectionsContent=" << _startOfSectionsContent << "\n"
325
148
      << "  endOfSectionsContent=" << _endOfSectionsContent << "\n");
326
338
  } else {
327
190
    // Final linked images have one load command per segment.
328
190
    _endOfLoadCommands = _startOfLoadCommands
329
190
                          + loadCommandsSize(_countOfLoadCommands);
330
190
331
190
    // Assign section file offsets.
332
190
    buildFileOffsets();
333
190
    buildLinkEditInfo();
334
190
335
190
    // LINKEDIT of final linked images has in order:
336
190
    // rebase info, binding info, lazy binding info, weak binding info,
337
190
    // data-in-code, symbol table, indirect symbol table, symbol table strings.
338
190
    _startOfRebaseInfo = _startOfLinkEdit;
339
190
    _endOfRebaseInfo = _startOfRebaseInfo + _rebaseInfo.size();
340
190
    _startOfBindingInfo = _endOfRebaseInfo;
341
190
    _endOfBindingInfo = _startOfBindingInfo + _bindingInfo.size();
342
190
    _startOfLazyBindingInfo = _endOfBindingInfo;
343
190
    _endOfLazyBindingInfo = _startOfLazyBindingInfo + _lazyBindingInfo.size();
344
190
    _startOfExportTrie = _endOfLazyBindingInfo;
345
190
    _endOfExportTrie = _startOfExportTrie + _exportTrie.size();
346
190
    _startOfFunctionStarts = _endOfExportTrie;
347
190
    _startOfDataInCode = _startOfFunctionStarts + _functionStartsSize;
348
190
    _startOfSymbols = _startOfDataInCode + _dataInCodeSize;
349
190
    _startOfIndirectSymbols = _startOfSymbols + _symbolTableSize;
350
190
    _startOfSymbolStrings = _startOfIndirectSymbols
351
190
                  + pointerAlign(_indirectSymbolTableCount * sizeof(uint32_t));
352
190
    _endOfSymbolStrings = _startOfSymbolStrings
353
190
                          + pointerAlign(_symbolStringPoolSize);
354
190
    _endOfLinkEdit = _endOfSymbolStrings;
355
190
    DEBUG_WITH_TYPE("MachOFileLayout",
356
190
                  llvm::dbgs() << "MachOFileLayout()\n"
357
190
      << "  startOfLoadCommands=" << _startOfLoadCommands << "\n"
358
190
      << "  countOfLoadCommands=" << _countOfLoadCommands << "\n"
359
190
      << "  endOfLoadCommands=" << _endOfLoadCommands << "\n"
360
190
      << "  startOfLinkEdit=" << _startOfLinkEdit << "\n"
361
190
      << "  startOfRebaseInfo=" << _startOfRebaseInfo << "\n"
362
190
      << "  endOfRebaseInfo=" << _endOfRebaseInfo << "\n"
363
190
      << "  startOfBindingInfo=" << _startOfBindingInfo << "\n"
364
190
      << "  endOfBindingInfo=" << _endOfBindingInfo << "\n"
365
190
      << "  startOfLazyBindingInfo=" << _startOfLazyBindingInfo << "\n"
366
190
      << "  endOfLazyBindingInfo=" << _endOfLazyBindingInfo << "\n"
367
190
      << "  startOfExportTrie=" << _startOfExportTrie << "\n"
368
190
      << "  endOfExportTrie=" << _endOfExportTrie << "\n"
369
190
      << "  startOfFunctionStarts=" << _startOfFunctionStarts << "\n"
370
190
      << "  startOfDataInCode=" << _startOfDataInCode << "\n"
371
190
      << "  startOfSymbols=" << _startOfSymbols << "\n"
372
190
      << "  startOfSymbolStrings=" << _startOfSymbolStrings << "\n"
373
190
      << "  endOfSymbolStrings=" << _endOfSymbolStrings << "\n"
374
190
      << "  addressOfLinkEdit=" << _addressOfLinkEdit << "\n");
375
190
  }
376
338
}
377
378
190
uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count) {
379
190
  uint32_t size = 0;
380
190
  count = 0;
381
190
382
190
  const size_t segCommandSize =
383
190
          (_is64 ? 
sizeof(segment_command_64)170
:
sizeof(segment_command)20
);
384
190
  const size_t sectionSize = (_is64 ? 
sizeof(section_64)170
:
sizeof(section)20
);
385
190
386
190
  // Add LC_SEGMENT for each segment.
387
190
  size += _file.segments.size() * segCommandSize;
388
190
  count += _file.segments.size();
389
190
  // Add section record for each section.
390
190
  size += _file.sections.size() * sectionSize;
391
190
392
190
  // If creating a dylib, add LC_ID_DYLIB.
393
190
  if (
_file.fileType == llvm::MachO::MH_DYLIB190
) {
394
82
    size += sizeof(dylib_command) + pointerAlign(_file.installName.size() + 1);
395
82
    ++count;
396
82
  }
397
190
398
190
  // Add LC_DYLD_INFO
399
190
  size += sizeof(dyld_info_command);
400
190
  ++count;
401
190
402
190
  // Add LC_SYMTAB
403
190
  size += sizeof(symtab_command);
404
190
  ++count;
405
190
406
190
  // Add LC_DYSYMTAB
407
190
  if (
_file.fileType != llvm::MachO::MH_PRELOAD190
) {
408
190
    size += sizeof(dysymtab_command);
409
190
    ++count;
410
190
  }
411
190
412
190
  // If main executable add LC_LOAD_DYLINKER
413
190
  if (
_file.fileType == llvm::MachO::MH_EXECUTE190
) {
414
102
    size += pointerAlign(sizeof(dylinker_command) + dyldPath().size()+1);
415
102
    ++count;
416
102
  }
417
190
418
190
  // Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_WATCHOS,
419
190
  // LC_VERSION_MIN_TVOS
420
190
  if (
_file.hasMinVersionLoadCommand190
) {
421
172
    size += sizeof(version_min_command);
422
172
    ++count;
423
172
  }
424
190
425
190
  // Add LC_SOURCE_VERSION
426
190
  size += sizeof(source_version_command);
427
190
  ++count;
428
190
429
190
  // If main executable add LC_MAIN
430
190
  if (
_file.fileType == llvm::MachO::MH_EXECUTE190
) {
431
102
    size += sizeof(entry_point_command);
432
102
    ++count;
433
102
  }
434
190
435
190
  // Add LC_LOAD_DYLIB for each dependent dylib.
436
210
  for (const DependentDylib &dep : _file.dependentDylibs) {
437
210
    size += sizeof(dylib_command) + pointerAlign(dep.path.size()+1);
438
210
    ++count;
439
210
  }
440
190
441
190
  // Add LC_RPATH
442
2
  for (const StringRef &path : _file.rpaths) {
443
2
    size += pointerAlign(sizeof(rpath_command) + path.size() + 1);
444
2
    ++count;
445
2
  }
446
190
447
190
  // Add LC_FUNCTION_STARTS if needed
448
190
  if (
!_file.functionStarts.empty()190
) {
449
86
    size += sizeof(linkedit_data_command);
450
86
    ++count;
451
86
  }
452
190
453
190
  // Add LC_DATA_IN_CODE if requested.  Note, we do encode zero length entries.
454
190
  // FIXME: Zero length entries is only to match ld64.  Should we change this?
455
190
  if (
_file.generateDataInCodeLoadCommand190
) {
456
172
    size += sizeof(linkedit_data_command);
457
172
    ++count;
458
172
  }
459
190
460
190
  return size;
461
190
}
462
463
1.19k
static bool overlaps(const Segment &s1, const Segment &s2) {
464
1.19k
  if (s2.address >= s1.address+s1.size)
465
894
    return false;
466
298
  
if (298
s1.address >= s2.address+s2.size298
)
467
298
    return false;
468
0
  return true;
469
0
}
470
471
1.60k
static bool overlaps(const Section &s1, const Section &s2) {
472
1.60k
  if (s2.address >= s1.address+s1.content.size())
473
1.20k
    return false;
474
401
  
if (401
s1.address >= s2.address+s2.content.size()401
)
475
401
    return false;
476
0
  return true;
477
0
}
478
479
190
void MachOFileLayout::buildFileOffsets() {
480
190
  // Verify no segments overlap
481
560
  for (const Segment &sg1 : _file.segments) {
482
1.75k
    for (const Segment &sg2 : _file.segments) {
483
1.75k
      if (&sg1 == &sg2)
484
560
        continue;
485
1.19k
      
if (1.19k
overlaps(sg1,sg2)1.19k
) {
486
0
        _ec = make_error_code(llvm::errc::executable_format_error);
487
0
        return;
488
0
      }
489
190
    }
490
560
  }
491
190
492
190
  // Verify no sections overlap
493
190
  
for (const Section &s1 : _file.sections) 190
{
494
2.06k
    for (const Section &s2 : _file.sections) {
495
2.06k
      if (&s1 == &s2)
496
458
        continue;
497
1.60k
      
if (1.60k
overlaps(s1,s2)1.60k
) {
498
0
        _ec = make_error_code(llvm::errc::executable_format_error);
499
0
        return;
500
0
      }
501
190
    }
502
458
  }
503
190
504
190
  // Build side table of extra info about segments and sections.
505
190
  SegExtraInfo t;
506
190
  t.fileOffset = 0;
507
560
  for (const Segment &sg : _file.segments) {
508
560
    _segInfo[&sg] = t;
509
560
  }
510
190
  SectionExtraInfo t2;
511
190
  t2.fileOffset = 0;
512
190
  // Assign sections to segments.
513
458
  for (const Section &s : _file.sections) {
514
458
    _sectInfo[&s] = t2;
515
458
    bool foundSegment = false;
516
904
    for (const Segment &sg : _file.segments) {
517
904
      if (
sg.name.equals(s.segmentName)904
) {
518
458
        if ((s.address >= sg.address)
519
458
                        && 
(s.address+s.content.size() <= sg.address+sg.size)458
) {
520
458
          _segInfo[&sg].sections.push_back(&s);
521
458
          foundSegment = true;
522
458
          break;
523
458
        }
524
458
      }
525
904
    }
526
458
    if (
!foundSegment458
) {
527
0
      _ec = make_error_code(llvm::errc::executable_format_error);
528
0
      return;
529
0
    }
530
190
  }
531
190
532
190
  // Assign file offsets.
533
190
  uint32_t fileOffset = 0;
534
190
  DEBUG_WITH_TYPE("MachOFileLayout",
535
190
                  llvm::dbgs() << "buildFileOffsets()\n");
536
560
  for (const Segment &sg : _file.segments) {
537
560
    _segInfo[&sg].fileOffset = fileOffset;
538
560
    if (
(_seg1addr == INT64_MAX) && 560
sg.init_access292
)
539
190
      _seg1addr = sg.address;
540
560
    DEBUG_WITH_TYPE("MachOFileLayout",
541
560
                  llvm::dbgs() << "  segment=" << sg.name
542
560
                  << ", fileOffset=" << _segInfo[&sg].fileOffset << "\n");
543
560
544
560
    uint32_t segFileSize = 0;
545
560
    // A segment that is not zero-fill must use a least one page of disk space.
546
560
    if (sg.init_access)
547
458
      segFileSize = _file.pageSize;
548
458
    for (const Section *s : _segInfo[&sg].sections) {
549
458
      uint32_t sectOffset = s->address - sg.address;
550
458
      uint32_t sectFileSize =
551
458
        isZeroFillSection(s->type) ? 
06
:
s->content.size()452
;
552
458
      segFileSize = std::max(segFileSize, sectOffset + sectFileSize);
553
458
554
458
      _sectInfo[s].fileOffset = _segInfo[&sg].fileOffset + sectOffset;
555
458
      DEBUG_WITH_TYPE("MachOFileLayout",
556
458
                  llvm::dbgs() << "    section=" << s->sectionName
557
458
                  << ", fileOffset=" << fileOffset << "\n");
558
458
    }
559
560
560
560
    // round up all segments to page aligned, except __LINKEDIT
561
560
    if (
!sg.name.equals("__LINKEDIT")560
) {
562
370
      _segInfo[&sg].fileSize = llvm::alignTo(segFileSize, _file.pageSize);
563
370
      fileOffset = llvm::alignTo(fileOffset + segFileSize, _file.pageSize);
564
370
    }
565
560
    _addressOfLinkEdit = sg.address + sg.size;
566
560
  }
567
190
  _startOfLinkEdit = fileOffset;
568
190
}
569
570
171
size_t MachOFileLayout::size() const {
571
171
  return _endOfSymbolStrings;
572
171
}
573
574
171
void MachOFileLayout::writeMachHeader() {
575
171
  auto cpusubtype = MachOLinkingContext::cpuSubtypeFromArch(_file.arch);
576
171
  // dynamic x86 executables on newer OS version should also set the
577
171
  // CPU_SUBTYPE_LIB64 mask in the CPU subtype.
578
171
  // FIXME: Check that this is a dynamic executable, not a static one.
579
171
  if (_file.fileType == llvm::MachO::MH_EXECUTE &&
580
51
      cpusubtype == CPU_SUBTYPE_X86_64_ALL &&
581
171
      
_file.os == MachOLinkingContext::OS::macOSX45
) {
582
45
    uint32_t version;
583
45
    bool failed = MachOLinkingContext::parsePackedVersion("10.5", version);
584
45
    if (
!failed && 45
_file.minOSverson >= version45
)
585
44
      cpusubtype |= CPU_SUBTYPE_LIB64;
586
45
  }
587
171
588
171
  mach_header *mh = reinterpret_cast<mach_header*>(_buffer);
589
171
  mh->magic = _is64 ? 
llvm::MachO::MH_MAGIC_64138
:
llvm::MachO::MH_MAGIC33
;
590
171
  mh->cputype =  MachOLinkingContext::cpuTypeFromArch(_file.arch);
591
171
  mh->cpusubtype = cpusubtype;
592
171
  mh->filetype = _file.fileType;
593
171
  mh->ncmds = _countOfLoadCommands;
594
171
  mh->sizeofcmds = _endOfLoadCommands - _startOfLoadCommands;
595
171
  mh->flags = _file.flags;
596
171
  if (_swap)
597
2
    swapStruct(*mh);
598
171
}
599
600
uint32_t MachOFileLayout::indirectSymbolIndex(const Section &sect,
601
378
                                                   uint32_t &index) {
602
378
  if (sect.indirectSymbols.empty())
603
321
    return 0;
604
57
  uint32_t result = index;
605
57
  index += sect.indirectSymbols.size();
606
57
  return result;
607
57
}
608
609
378
uint32_t MachOFileLayout::indirectSymbolElementSize(const Section &sect) {
610
378
  if (sect.indirectSymbols.empty())
611
321
    return 0;
612
57
  
if (57
sect.type != S_SYMBOL_STUBS57
)
613
40
    return 0;
614
17
  return sect.content.size() / sect.indirectSymbols.size();
615
17
}
616
617
template <typename T>
618
76
llvm::Error MachOFileLayout::writeSingleSegmentLoadCommand(uint8_t *&lc) {
619
76
  typename T::command* seg = reinterpret_cast<typename T::command*>(lc);
620
76
  seg->cmd = T::LC;
621
76
  seg->cmdsize = sizeof(typename T::command)
622
76
                          + _file.sections.size() * sizeof(typename T::section);
623
76
  uint8_t *next = lc + seg->cmdsize;
624
76
  memset(seg->segname, 0, 16);
625
76
  seg->vmaddr = 0;
626
76
  seg->vmsize = _file.sections.back().address
627
76
              + _file.sections.back().content.size();
628
76
  seg->fileoff = _endOfLoadCommands;
629
76
  seg->filesize = _sectInfo[&_file.sections.back()].fileOffset +
630
76
                  _file.sections.back().content.size() -
631
76
                  _sectInfo[&_file.sections.front()].fileOffset;
632
76
  seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
633
76
  seg->initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
634
76
  seg->nsects = _file.sections.size();
635
76
  seg->flags = 0;
636
76
  if (_swap)
637
2
    swapStruct(*seg);
638
76
  typename T::section *sout = reinterpret_cast<typename T::section*>
639
76
                                              (lc+sizeof(typename T::command));
640
76
  uint32_t relOffset = _startOfRelocations;
641
76
  uint32_t indirectSymRunningIndex = 0;
642
149
  for (const Section &sin : _file.sections) {
643
149
    setString16(sin.sectionName, sout->sectname);
644
149
    setString16(sin.segmentName, sout->segname);
645
149
    sout->addr = sin.address;
646
149
    sout->size = sin.content.size();
647
149
    sout->offset = _sectInfo[&sin].fileOffset;
648
149
    sout->align = llvm::Log2_32(sin.alignment);
649
149
    sout->reloff = sin.relocations.empty() ? 
094
:
relOffset55
;
650
149
    sout->nreloc = sin.relocations.size();
651
149
    sout->flags = sin.type | sin.attributes;
652
149
    sout->reserved1 = indirectSymbolIndex(sin, indirectSymRunningIndex);
653
149
    sout->reserved2 = indirectSymbolElementSize(sin);
654
149
    relOffset += sin.relocations.size() * sizeof(any_relocation_info);
655
149
    if (_swap)
656
3
      swapStruct(*sout);
657
149
    ++sout;
658
149
  }
659
76
  lc = next;
660
76
  return llvm::Error::success();
661
76
}
llvm::Error lld::mach_o::normalized::MachOFileLayout::writeSingleSegmentLoadCommand<lld::mach_o::normalized::MachOFileLayout::MachO64Trait>(unsigned char*&)
Line
Count
Source
618
53
llvm::Error MachOFileLayout::writeSingleSegmentLoadCommand(uint8_t *&lc) {
619
53
  typename T::command* seg = reinterpret_cast<typename T::command*>(lc);
620
53
  seg->cmd = T::LC;
621
53
  seg->cmdsize = sizeof(typename T::command)
622
53
                          + _file.sections.size() * sizeof(typename T::section);
623
53
  uint8_t *next = lc + seg->cmdsize;
624
53
  memset(seg->segname, 0, 16);
625
53
  seg->vmaddr = 0;
626
53
  seg->vmsize = _file.sections.back().address
627
53
              + _file.sections.back().content.size();
628
53
  seg->fileoff = _endOfLoadCommands;
629
53
  seg->filesize = _sectInfo[&_file.sections.back()].fileOffset +
630
53
                  _file.sections.back().content.size() -
631
53
                  _sectInfo[&_file.sections.front()].fileOffset;
632
53
  seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
633
53
  seg->initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
634
53
  seg->nsects = _file.sections.size();
635
53
  seg->flags = 0;
636
53
  if (_swap)
637
0
    swapStruct(*seg);
638
53
  typename T::section *sout = reinterpret_cast<typename T::section*>
639
53
                                              (lc+sizeof(typename T::command));
640
53
  uint32_t relOffset = _startOfRelocations;
641
53
  uint32_t indirectSymRunningIndex = 0;
642
111
  for (const Section &sin : _file.sections) {
643
111
    setString16(sin.sectionName, sout->sectname);
644
111
    setString16(sin.segmentName, sout->segname);
645
111
    sout->addr = sin.address;
646
111
    sout->size = sin.content.size();
647
111
    sout->offset = _sectInfo[&sin].fileOffset;
648
111
    sout->align = llvm::Log2_32(sin.alignment);
649
111
    sout->reloff = sin.relocations.empty() ? 
077
:
relOffset34
;
650
111
    sout->nreloc = sin.relocations.size();
651
111
    sout->flags = sin.type | sin.attributes;
652
111
    sout->reserved1 = indirectSymbolIndex(sin, indirectSymRunningIndex);
653
111
    sout->reserved2 = indirectSymbolElementSize(sin);
654
111
    relOffset += sin.relocations.size() * sizeof(any_relocation_info);
655
111
    if (_swap)
656
0
      swapStruct(*sout);
657
111
    ++sout;
658
111
  }
659
53
  lc = next;
660
53
  return llvm::Error::success();
661
53
}
llvm::Error lld::mach_o::normalized::MachOFileLayout::writeSingleSegmentLoadCommand<lld::mach_o::normalized::MachOFileLayout::MachO32Trait>(unsigned char*&)
Line
Count
Source
618
23
llvm::Error MachOFileLayout::writeSingleSegmentLoadCommand(uint8_t *&lc) {
619
23
  typename T::command* seg = reinterpret_cast<typename T::command*>(lc);
620
23
  seg->cmd = T::LC;
621
23
  seg->cmdsize = sizeof(typename T::command)
622
23
                          + _file.sections.size() * sizeof(typename T::section);
623
23
  uint8_t *next = lc + seg->cmdsize;
624
23
  memset(seg->segname, 0, 16);
625
23
  seg->vmaddr = 0;
626
23
  seg->vmsize = _file.sections.back().address
627
23
              + _file.sections.back().content.size();
628
23
  seg->fileoff = _endOfLoadCommands;
629
23
  seg->filesize = _sectInfo[&_file.sections.back()].fileOffset +
630
23
                  _file.sections.back().content.size() -
631
23
                  _sectInfo[&_file.sections.front()].fileOffset;
632
23
  seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
633
23
  seg->initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
634
23
  seg->nsects = _file.sections.size();
635
23
  seg->flags = 0;
636
23
  if (_swap)
637
2
    swapStruct(*seg);
638
23
  typename T::section *sout = reinterpret_cast<typename T::section*>
639
23
                                              (lc+sizeof(typename T::command));
640
23
  uint32_t relOffset = _startOfRelocations;
641
23
  uint32_t indirectSymRunningIndex = 0;
642
38
  for (const Section &sin : _file.sections) {
643
38
    setString16(sin.sectionName, sout->sectname);
644
38
    setString16(sin.segmentName, sout->segname);
645
38
    sout->addr = sin.address;
646
38
    sout->size = sin.content.size();
647
38
    sout->offset = _sectInfo[&sin].fileOffset;
648
38
    sout->align = llvm::Log2_32(sin.alignment);
649
38
    sout->reloff = sin.relocations.empty() ? 
017
:
relOffset21
;
650
38
    sout->nreloc = sin.relocations.size();
651
38
    sout->flags = sin.type | sin.attributes;
652
38
    sout->reserved1 = indirectSymbolIndex(sin, indirectSymRunningIndex);
653
38
    sout->reserved2 = indirectSymbolElementSize(sin);
654
38
    relOffset += sin.relocations.size() * sizeof(any_relocation_info);
655
38
    if (_swap)
656
3
      swapStruct(*sout);
657
38
    ++sout;
658
38
  }
659
23
  lc = next;
660
23
  return llvm::Error::success();
661
23
}
662
663
template <typename T>
664
95
llvm::Error MachOFileLayout::writeSegmentLoadCommands(uint8_t *&lc) {
665
95
  uint32_t indirectSymRunningIndex = 0;
666
280
  for (const Segment &seg : _file.segments) {
667
280
    // Link edit has no sections and a custom range of address, so handle it
668
280
    // specially.
669
280
    SegExtraInfo &segInfo = _segInfo[&seg];
670
280
    if (
seg.name.equals("__LINKEDIT")280
) {
671
95
      size_t linkeditSize = _endOfLinkEdit - _startOfLinkEdit;
672
95
      typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
673
95
      cmd->cmd = T::LC;
674
95
      cmd->cmdsize = sizeof(typename T::command);
675
95
      uint8_t *next = lc + cmd->cmdsize;
676
95
      setString16("__LINKEDIT", cmd->segname);
677
95
      cmd->vmaddr   = _addressOfLinkEdit;
678
95
      cmd->vmsize   = llvm::alignTo(linkeditSize, _file.pageSize);
679
95
      cmd->fileoff  = _startOfLinkEdit;
680
95
      cmd->filesize = linkeditSize;
681
95
      cmd->initprot = seg.init_access;
682
95
      cmd->maxprot  = seg.max_access;
683
95
      cmd->nsects   = 0;
684
95
      cmd->flags    = 0;
685
95
      if (_swap)
686
0
        swapStruct(*cmd);
687
95
      lc = next;
688
95
      continue;
689
95
    }
690
185
    // Write segment command with trailing sections.
691
185
    typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
692
185
    cmd->cmd = T::LC;
693
185
    cmd->cmdsize = sizeof(typename T::command)
694
185
                        + segInfo.sections.size() * sizeof(typename T::section);
695
185
    uint8_t *next = lc + cmd->cmdsize;
696
185
    setString16(seg.name, cmd->segname);
697
185
    cmd->vmaddr   = seg.address;
698
185
    cmd->vmsize   = seg.size;
699
185
    cmd->fileoff  = segInfo.fileOffset;
700
185
    cmd->filesize = segInfo.fileSize;
701
185
    cmd->initprot = seg.init_access;
702
185
    cmd->maxprot  = seg.max_access;
703
185
    cmd->nsects   = segInfo.sections.size();
704
185
    cmd->flags    = 0;
705
185
    if (_swap)
706
0
      swapStruct(*cmd);
707
185
    typename T::section *sect = reinterpret_cast<typename T::section*>
708
185
                                               (lc+sizeof(typename T::command));
709
229
    for (const Section *section : segInfo.sections) {
710
229
      setString16(section->sectionName, sect->sectname);
711
229
      setString16(section->segmentName, sect->segname);
712
229
      sect->addr      = section->address;
713
229
      sect->size      = section->content.size();
714
229
      if (isZeroFillSection(section->type))
715
3
        sect->offset  = 0;
716
229
      else
717
226
        sect->offset  = section->address - seg.address + segInfo.fileOffset;
718
229
      sect->align     = llvm::Log2_32(section->alignment);
719
229
      sect->reloff    = 0;
720
229
      sect->nreloc    = 0;
721
229
      sect->flags     = section->type | section->attributes;
722
229
      sect->reserved1 = indirectSymbolIndex(*section, indirectSymRunningIndex);
723
229
      sect->reserved2 = indirectSymbolElementSize(*section);
724
229
      if (_swap)
725
0
        swapStruct(*sect);
726
229
      ++sect;
727
229
    }
728
280
    lc = reinterpret_cast<uint8_t*>(next);
729
280
  }
730
95
  return llvm::Error::success();
731
95
}
llvm::Error lld::mach_o::normalized::MachOFileLayout::writeSegmentLoadCommands<lld::mach_o::normalized::MachOFileLayout::MachO64Trait>(unsigned char*&)
Line
Count
Source
664
85
llvm::Error MachOFileLayout::writeSegmentLoadCommands(uint8_t *&lc) {
665
85
  uint32_t indirectSymRunningIndex = 0;
666
248
  for (const Segment &seg : _file.segments) {
667
248
    // Link edit has no sections and a custom range of address, so handle it
668
248
    // specially.
669
248
    SegExtraInfo &segInfo = _segInfo[&seg];
670
248
    if (
seg.name.equals("__LINKEDIT")248
) {
671
85
      size_t linkeditSize = _endOfLinkEdit - _startOfLinkEdit;
672
85
      typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
673
85
      cmd->cmd = T::LC;
674
85
      cmd->cmdsize = sizeof(typename T::command);
675
85
      uint8_t *next = lc + cmd->cmdsize;
676
85
      setString16("__LINKEDIT", cmd->segname);
677
85
      cmd->vmaddr   = _addressOfLinkEdit;
678
85
      cmd->vmsize   = llvm::alignTo(linkeditSize, _file.pageSize);
679
85
      cmd->fileoff  = _startOfLinkEdit;
680
85
      cmd->filesize = linkeditSize;
681
85
      cmd->initprot = seg.init_access;
682
85
      cmd->maxprot  = seg.max_access;
683
85
      cmd->nsects   = 0;
684
85
      cmd->flags    = 0;
685
85
      if (_swap)
686
0
        swapStruct(*cmd);
687
85
      lc = next;
688
85
      continue;
689
85
    }
690
163
    // Write segment command with trailing sections.
691
163
    typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
692
163
    cmd->cmd = T::LC;
693
163
    cmd->cmdsize = sizeof(typename T::command)
694
163
                        + segInfo.sections.size() * sizeof(typename T::section);
695
163
    uint8_t *next = lc + cmd->cmdsize;
696
163
    setString16(seg.name, cmd->segname);
697
163
    cmd->vmaddr   = seg.address;
698
163
    cmd->vmsize   = seg.size;
699
163
    cmd->fileoff  = segInfo.fileOffset;
700
163
    cmd->filesize = segInfo.fileSize;
701
163
    cmd->initprot = seg.init_access;
702
163
    cmd->maxprot  = seg.max_access;
703
163
    cmd->nsects   = segInfo.sections.size();
704
163
    cmd->flags    = 0;
705
163
    if (_swap)
706
0
      swapStruct(*cmd);
707
163
    typename T::section *sect = reinterpret_cast<typename T::section*>
708
163
                                               (lc+sizeof(typename T::command));
709
193
    for (const Section *section : segInfo.sections) {
710
193
      setString16(section->sectionName, sect->sectname);
711
193
      setString16(section->segmentName, sect->segname);
712
193
      sect->addr      = section->address;
713
193
      sect->size      = section->content.size();
714
193
      if (isZeroFillSection(section->type))
715
3
        sect->offset  = 0;
716
193
      else
717
190
        sect->offset  = section->address - seg.address + segInfo.fileOffset;
718
193
      sect->align     = llvm::Log2_32(section->alignment);
719
193
      sect->reloff    = 0;
720
193
      sect->nreloc    = 0;
721
193
      sect->flags     = section->type | section->attributes;
722
193
      sect->reserved1 = indirectSymbolIndex(*section, indirectSymRunningIndex);
723
193
      sect->reserved2 = indirectSymbolElementSize(*section);
724
193
      if (_swap)
725
0
        swapStruct(*sect);
726
193
      ++sect;
727
193
    }
728
248
    lc = reinterpret_cast<uint8_t*>(next);
729
248
  }
730
85
  return llvm::Error::success();
731
85
}
llvm::Error lld::mach_o::normalized::MachOFileLayout::writeSegmentLoadCommands<lld::mach_o::normalized::MachOFileLayout::MachO32Trait>(unsigned char*&)
Line
Count
Source
664
10
llvm::Error MachOFileLayout::writeSegmentLoadCommands(uint8_t *&lc) {
665
10
  uint32_t indirectSymRunningIndex = 0;
666
32
  for (const Segment &seg : _file.segments) {
667
32
    // Link edit has no sections and a custom range of address, so handle it
668
32
    // specially.
669
32
    SegExtraInfo &segInfo = _segInfo[&seg];
670
32
    if (
seg.name.equals("__LINKEDIT")32
) {
671
10
      size_t linkeditSize = _endOfLinkEdit - _startOfLinkEdit;
672
10
      typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
673
10
      cmd->cmd = T::LC;
674
10
      cmd->cmdsize = sizeof(typename T::command);
675
10
      uint8_t *next = lc + cmd->cmdsize;
676
10
      setString16("__LINKEDIT", cmd->segname);
677
10
      cmd->vmaddr   = _addressOfLinkEdit;
678
10
      cmd->vmsize   = llvm::alignTo(linkeditSize, _file.pageSize);
679
10
      cmd->fileoff  = _startOfLinkEdit;
680
10
      cmd->filesize = linkeditSize;
681
10
      cmd->initprot = seg.init_access;
682
10
      cmd->maxprot  = seg.max_access;
683
10
      cmd->nsects   = 0;
684
10
      cmd->flags    = 0;
685
10
      if (_swap)
686
0
        swapStruct(*cmd);
687
10
      lc = next;
688
10
      continue;
689
10
    }
690
22
    // Write segment command with trailing sections.
691
22
    typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
692
22
    cmd->cmd = T::LC;
693
22
    cmd->cmdsize = sizeof(typename T::command)
694
22
                        + segInfo.sections.size() * sizeof(typename T::section);
695
22
    uint8_t *next = lc + cmd->cmdsize;
696
22
    setString16(seg.name, cmd->segname);
697
22
    cmd->vmaddr   = seg.address;
698
22
    cmd->vmsize   = seg.size;
699
22
    cmd->fileoff  = segInfo.fileOffset;
700
22
    cmd->filesize = segInfo.fileSize;
701
22
    cmd->initprot = seg.init_access;
702
22
    cmd->maxprot  = seg.max_access;
703
22
    cmd->nsects   = segInfo.sections.size();
704
22
    cmd->flags    = 0;
705
22
    if (_swap)
706
0
      swapStruct(*cmd);
707
22
    typename T::section *sect = reinterpret_cast<typename T::section*>
708
22
                                               (lc+sizeof(typename T::command));
709
36
    for (const Section *section : segInfo.sections) {
710
36
      setString16(section->sectionName, sect->sectname);
711
36
      setString16(section->segmentName, sect->segname);
712
36
      sect->addr      = section->address;
713
36
      sect->size      = section->content.size();
714
36
      if (isZeroFillSection(section->type))
715
0
        sect->offset  = 0;
716
36
      else
717
36
        sect->offset  = section->address - seg.address + segInfo.fileOffset;
718
36
      sect->align     = llvm::Log2_32(section->alignment);
719
36
      sect->reloff    = 0;
720
36
      sect->nreloc    = 0;
721
36
      sect->flags     = section->type | section->attributes;
722
36
      sect->reserved1 = indirectSymbolIndex(*section, indirectSymRunningIndex);
723
36
      sect->reserved2 = indirectSymbolElementSize(*section);
724
36
      if (_swap)
725
0
        swapStruct(*sect);
726
36
      ++sect;
727
36
    }
728
32
    lc = reinterpret_cast<uint8_t*>(next);
729
32
  }
730
10
  return llvm::Error::success();
731
10
}
732
733
static void writeVersionMinLoadCommand(const NormalizedFile &_file,
734
                                       bool _swap,
735
171
                                       uint8_t *&lc) {
736
171
  if (!_file.hasMinVersionLoadCommand)
737
83
    return;
738
88
  version_min_command *vm = reinterpret_cast<version_min_command*>(lc);
739
88
  switch (_file.os) {
740
1
    case MachOLinkingContext::OS::unknown:
741
1
      vm->cmd     = _file.minOSVersionKind;
742
1
      vm->cmdsize = sizeof(version_min_command);
743
1
      vm->version = _file.minOSverson;
744
1
      vm->sdk     = 0;
745
1
      break;
746
76
    case MachOLinkingContext::OS::macOSX:
747
76
      vm->cmd     = LC_VERSION_MIN_MACOSX;
748
76
      vm->cmdsize = sizeof(version_min_command);
749
76
      vm->version = _file.minOSverson;
750
76
      vm->sdk     = _file.sdkVersion;
751
76
      break;
752
11
    case MachOLinkingContext::OS::iOS:
753
11
    case MachOLinkingContext::OS::iOS_simulator:
754
11
      vm->cmd     = LC_VERSION_MIN_IPHONEOS;
755
11
      vm->cmdsize = sizeof(version_min_command);
756
11
      vm->version = _file.minOSverson;
757
11
      vm->sdk     = _file.sdkVersion;
758
11
      break;
759
88
  }
760
88
  
if (88
_swap88
)
761
0
    swapStruct(*vm);
762
171
  lc += sizeof(version_min_command);
763
171
}
764
765
171
llvm::Error MachOFileLayout::writeLoadCommands() {
766
171
  uint8_t *lc = &_buffer[_startOfLoadCommands];
767
171
  if (
_file.fileType == llvm::MachO::MH_OBJECT171
) {
768
76
    // Object files have one unnamed segment which holds all sections.
769
76
    if (
_is6476
) {
770
53
     if (auto ec = writeSingleSegmentLoadCommand<MachO64Trait>(lc))
771
0
       return ec;
772
23
    } else {
773
23
      if (auto ec = writeSingleSegmentLoadCommand<MachO32Trait>(lc))
774
0
        return ec;
775
76
    }
776
76
    // Add LC_SYMTAB with symbol table info
777
76
    symtab_command* st = reinterpret_cast<symtab_command*>(lc);
778
76
    st->cmd     = LC_SYMTAB;
779
76
    st->cmdsize = sizeof(symtab_command);
780
76
    st->symoff  = _startOfSymbols;
781
76
    st->nsyms   = _file.stabsSymbols.size() + _file.localSymbols.size() +
782
76
                  _file.globalSymbols.size() + _file.undefinedSymbols.size();
783
76
    st->stroff  = _startOfSymbolStrings;
784
76
    st->strsize = _endOfSymbolStrings - _startOfSymbolStrings;
785
76
    if (_swap)
786
2
      swapStruct(*st);
787
76
    lc += sizeof(symtab_command);
788
76
789
76
    // Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS,
790
76
    // LC_VERSION_MIN_WATCHOS, LC_VERSION_MIN_TVOS
791
76
    writeVersionMinLoadCommand(_file, _swap, lc);
792
76
793
76
    // Add LC_FUNCTION_STARTS if needed.
794
76
    if (
_functionStartsSize != 076
) {
795
0
      linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
796
0
      dl->cmd      = LC_FUNCTION_STARTS;
797
0
      dl->cmdsize  = sizeof(linkedit_data_command);
798
0
      dl->dataoff  = _startOfFunctionStarts;
799
0
      dl->datasize = _functionStartsSize;
800
0
      if (_swap)
801
0
        swapStruct(*dl);
802
0
      lc += sizeof(linkedit_data_command);
803
0
    }
804
76
805
76
    // Add LC_DATA_IN_CODE if requested.
806
76
    if (
_file.generateDataInCodeLoadCommand76
) {
807
70
      linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
808
70
      dl->cmd      = LC_DATA_IN_CODE;
809
70
      dl->cmdsize  = sizeof(linkedit_data_command);
810
70
      dl->dataoff  = _startOfDataInCode;
811
70
      dl->datasize = _dataInCodeSize;
812
70
      if (_swap)
813
0
        swapStruct(*dl);
814
70
      lc += sizeof(linkedit_data_command);
815
70
    }
816
171
  } else {
817
95
    // Final linked images have sections under segments.
818
95
    if (
_is6495
) {
819
85
      if (auto ec = writeSegmentLoadCommands<MachO64Trait>(lc))
820
0
        return ec;
821
10
    } else {
822
10
      if (auto ec = writeSegmentLoadCommands<MachO32Trait>(lc))
823
0
        return ec;
824
95
    }
825
95
826
95
    // Add LC_ID_DYLIB command for dynamic libraries.
827
95
    
if (95
_file.fileType == llvm::MachO::MH_DYLIB95
) {
828
41
      dylib_command *dc = reinterpret_cast<dylib_command*>(lc);
829
41
      StringRef path = _file.installName;
830
41
      uint32_t size = sizeof(dylib_command) + pointerAlign(path.size() + 1);
831
41
      dc->cmd                         = LC_ID_DYLIB;
832
41
      dc->cmdsize                     = size;
833
41
      dc->dylib.name                  = sizeof(dylib_command); // offset
834
41
      // needs to be some constant value different than the one in LC_LOAD_DYLIB
835
41
      dc->dylib.timestamp             = 1;
836
41
      dc->dylib.current_version       = _file.currentVersion;
837
41
      dc->dylib.compatibility_version = _file.compatVersion;
838
41
      if (_swap)
839
0
        swapStruct(*dc);
840
41
      memcpy(lc + sizeof(dylib_command), path.begin(), path.size());
841
41
      lc[sizeof(dylib_command) + path.size()] = '\0';
842
41
      lc += size;
843
41
    }
844
95
845
95
    // Add LC_DYLD_INFO_ONLY.
846
95
    dyld_info_command* di = reinterpret_cast<dyld_info_command*>(lc);
847
95
    di->cmd            = LC_DYLD_INFO_ONLY;
848
95
    di->cmdsize        = sizeof(dyld_info_command);
849
95
    di->rebase_off     = _rebaseInfo.size() ? 
_startOfRebaseInfo95
:
00
;
850
95
    di->rebase_size    = _rebaseInfo.size();
851
95
    di->bind_off       = _bindingInfo.size() ? 
_startOfBindingInfo95
:
00
;
852
95
    di->bind_size      = _bindingInfo.size();
853
95
    di->weak_bind_off  = 0;
854
95
    di->weak_bind_size = 0;
855
95
    di->lazy_bind_off  = _lazyBindingInfo.size() ? 
_startOfLazyBindingInfo17
:
078
;
856
95
    di->lazy_bind_size = _lazyBindingInfo.size();
857
95
    di->export_off     = _exportTrie.size() ? 
_startOfExportTrie92
:
03
;
858
95
    di->export_size    = _exportTrie.size();
859
95
    if (_swap)
860
0
      swapStruct(*di);
861
95
    lc += sizeof(dyld_info_command);
862
95
863
95
    // Add LC_SYMTAB with symbol table info.
864
95
    symtab_command* st = reinterpret_cast<symtab_command*>(lc);
865
95
    st->cmd     = LC_SYMTAB;
866
95
    st->cmdsize = sizeof(symtab_command);
867
95
    st->symoff  = _startOfSymbols;
868
95
    st->nsyms   = _file.stabsSymbols.size() + _file.localSymbols.size() +
869
95
                  _file.globalSymbols.size() + _file.undefinedSymbols.size();
870
95
    st->stroff  = _startOfSymbolStrings;
871
95
    st->strsize = _endOfSymbolStrings - _startOfSymbolStrings;
872
95
    if (_swap)
873
0
      swapStruct(*st);
874
95
    lc += sizeof(symtab_command);
875
95
876
95
    // Add LC_DYSYMTAB
877
95
    if (
_file.fileType != llvm::MachO::MH_PRELOAD95
) {
878
95
      dysymtab_command* dst = reinterpret_cast<dysymtab_command*>(lc);
879
95
      dst->cmd            = LC_DYSYMTAB;
880
95
      dst->cmdsize        = sizeof(dysymtab_command);
881
95
      dst->ilocalsym      = _symbolTableLocalsStartIndex;
882
95
      dst->nlocalsym      = _file.stabsSymbols.size() +
883
95
                            _file.localSymbols.size();
884
95
      dst->iextdefsym     = _symbolTableGlobalsStartIndex;
885
95
      dst->nextdefsym     = _file.globalSymbols.size();
886
95
      dst->iundefsym      = _symbolTableUndefinesStartIndex;
887
95
      dst->nundefsym      = _file.undefinedSymbols.size();
888
95
      dst->tocoff         = 0;
889
95
      dst->ntoc           = 0;
890
95
      dst->modtaboff      = 0;
891
95
      dst->nmodtab        = 0;
892
95
      dst->extrefsymoff   = 0;
893
95
      dst->nextrefsyms    = 0;
894
95
      dst->indirectsymoff = _startOfIndirectSymbols;
895
95
      dst->nindirectsyms  = _indirectSymbolTableCount;
896
95
      dst->extreloff      = 0;
897
95
      dst->nextrel        = 0;
898
95
      dst->locreloff      = 0;
899
95
      dst->nlocrel        = 0;
900
95
      if (_swap)
901
0
        swapStruct(*dst);
902
95
      lc += sizeof(dysymtab_command);
903
95
    }
904
95
905
95
    // If main executable, add LC_LOAD_DYLINKER
906
95
    if (
_file.fileType == llvm::MachO::MH_EXECUTE95
) {
907
51
      // Build LC_LOAD_DYLINKER load command.
908
51
      uint32_t size=pointerAlign(sizeof(dylinker_command)+dyldPath().size()+1);
909
51
      dylinker_command* dl = reinterpret_cast<dylinker_command*>(lc);
910
51
      dl->cmd              = LC_LOAD_DYLINKER;
911
51
      dl->cmdsize          = size;
912
51
      dl->name             = sizeof(dylinker_command); // offset
913
51
      if (_swap)
914
0
        swapStruct(*dl);
915
51
      memcpy(lc+sizeof(dylinker_command), dyldPath().data(), dyldPath().size());
916
51
      lc[sizeof(dylinker_command)+dyldPath().size()] = '\0';
917
51
      lc += size;
918
51
    }
919
95
920
95
    // Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_WATCHOS,
921
95
    // LC_VERSION_MIN_TVOS
922
95
    writeVersionMinLoadCommand(_file, _swap, lc);
923
95
924
95
    // Add LC_SOURCE_VERSION
925
95
    {
926
95
      // Note, using a temporary here to appease UB as we may not be aligned
927
95
      // enough for a struct containing a uint64_t when emitting a 32-bit binary
928
95
      source_version_command sv;
929
95
      sv.cmd       = LC_SOURCE_VERSION;
930
95
      sv.cmdsize   = sizeof(source_version_command);
931
95
      sv.version   = _file.sourceVersion;
932
95
      if (_swap)
933
0
        swapStruct(sv);
934
95
      memcpy(lc, &sv, sizeof(source_version_command));
935
95
      lc += sizeof(source_version_command);
936
95
    }
937
95
938
95
    // If main executable, add LC_MAIN.
939
95
    if (
_file.fileType == llvm::MachO::MH_EXECUTE95
) {
940
51
      // Build LC_MAIN load command.
941
51
      // Note, using a temporary here to appease UB as we may not be aligned
942
51
      // enough for a struct containing a uint64_t when emitting a 32-bit binary
943
51
      entry_point_command ep;
944
51
      ep.cmd       = LC_MAIN;
945
51
      ep.cmdsize   = sizeof(entry_point_command);
946
51
      ep.entryoff  = _file.entryAddress - _seg1addr;
947
51
      ep.stacksize = _file.stackSize;
948
51
      if (_swap)
949
0
        swapStruct(ep);
950
51
      memcpy(lc, &ep, sizeof(entry_point_command));
951
51
      lc += sizeof(entry_point_command);
952
51
    }
953
95
954
95
    // Add LC_LOAD_DYLIB commands
955
105
    for (const DependentDylib &dep : _file.dependentDylibs) {
956
105
      dylib_command* dc = reinterpret_cast<dylib_command*>(lc);
957
105
      uint32_t size = sizeof(dylib_command) + pointerAlign(dep.path.size()+1);
958
105
      dc->cmd                         = dep.kind;
959
105
      dc->cmdsize                     = size;
960
105
      dc->dylib.name                  = sizeof(dylib_command); // offset
961
105
      // needs to be some constant value different than the one in LC_ID_DYLIB
962
105
      dc->dylib.timestamp             = 2;
963
105
      dc->dylib.current_version       = dep.currentVersion;
964
105
      dc->dylib.compatibility_version = dep.compatVersion;
965
105
      if (_swap)
966
0
        swapStruct(*dc);
967
105
      memcpy(lc+sizeof(dylib_command), dep.path.begin(), dep.path.size());
968
105
      lc[sizeof(dylib_command)+dep.path.size()] = '\0';
969
105
      lc += size;
970
105
    }
971
95
972
95
    // Add LC_RPATH
973
1
    for (const StringRef &path : _file.rpaths) {
974
1
      rpath_command *rpc = reinterpret_cast<rpath_command *>(lc);
975
1
      uint32_t size = pointerAlign(sizeof(rpath_command) + path.size() + 1);
976
1
      rpc->cmd                         = LC_RPATH;
977
1
      rpc->cmdsize                     = size;
978
1
      rpc->path                        = sizeof(rpath_command); // offset
979
1
      if (_swap)
980
0
        swapStruct(*rpc);
981
1
      memcpy(lc+sizeof(rpath_command), path.begin(), path.size());
982
1
      lc[sizeof(rpath_command)+path.size()] = '\0';
983
1
      lc += size;
984
1
    }
985
95
986
95
    // Add LC_FUNCTION_STARTS if needed.
987
95
    if (
_functionStartsSize != 095
) {
988
86
      linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
989
86
      dl->cmd      = LC_FUNCTION_STARTS;
990
86
      dl->cmdsize  = sizeof(linkedit_data_command);
991
86
      dl->dataoff  = _startOfFunctionStarts;
992
86
      dl->datasize = _functionStartsSize;
993
86
      if (_swap)
994
0
        swapStruct(*dl);
995
86
      lc += sizeof(linkedit_data_command);
996
86
    }
997
95
998
95
    // Add LC_DATA_IN_CODE if requested.
999
95
    if (
_file.generateDataInCodeLoadCommand95
) {
1000
86
      linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
1001
86
      dl->cmd      = LC_DATA_IN_CODE;
1002
86
      dl->cmdsize  = sizeof(linkedit_data_command);
1003
86
      dl->dataoff  = _startOfDataInCode;
1004
86
      dl->datasize = _dataInCodeSize;
1005
86
      if (_swap)
1006
0
        swapStruct(*dl);
1007
86
      lc += sizeof(linkedit_data_command);
1008
86
    }
1009
95
  }
1010
171
  return llvm::Error::success();
1011
171
}
1012
1013
171
void MachOFileLayout::writeSectionContent() {
1014
378
  for (const Section &s : _file.sections) {
1015
378
    // Copy all section content to output buffer.
1016
378
    if (isZeroFillSection(s.type))
1017
5
      continue;
1018
373
    
if (373
s.content.empty()373
)
1019
9
      continue;
1020
364
    uint32_t offset = _sectInfo[&s].fileOffset;
1021
364
    uint8_t *p = &_buffer[offset];
1022
364
    memcpy(p, &s.content[0], s.content.size());
1023
364
    p += s.content.size();
1024
364
  }
1025
171
}
1026
1027
76
void MachOFileLayout::writeRelocations() {
1028
76
  uint32_t relOffset = _startOfRelocations;
1029
149
  for (Section sect : _file.sections) {
1030
494
    for (Relocation r : sect.relocations) {
1031
494
      any_relocation_info* rb = reinterpret_cast<any_relocation_info*>(
1032
494
                                                           &_buffer[relOffset]);
1033
494
      *rb = packRelocation(r, _swap, _bigEndianArch);
1034
494
      relOffset += sizeof(any_relocation_info);
1035
494
    }
1036
149
  }
1037
76
}
1038
1039
void MachOFileLayout::appendSymbols(const std::vector<Symbol> &symbols,
1040
684
                                   uint32_t &symOffset, uint32_t &strOffset) {
1041
676
  for (const Symbol &sym : symbols) {
1042
676
    if (
_is64676
) {
1043
553
      nlist_64* nb = reinterpret_cast<nlist_64*>(&_buffer[symOffset]);
1044
553
      nb->n_strx = strOffset - _startOfSymbolStrings;
1045
553
      nb->n_type = sym.type | sym.scope;
1046
553
      nb->n_sect = sym.sect;
1047
553
      nb->n_desc = sym.desc;
1048
553
      nb->n_value = sym.value;
1049
553
      if (_swap)
1050
0
        swapStruct(*nb);
1051
553
      symOffset += sizeof(nlist_64);
1052
676
    } else {
1053
123
      nlist* nb = reinterpret_cast<nlist*>(&_buffer[symOffset]);
1054
123
      nb->n_strx = strOffset - _startOfSymbolStrings;
1055
123
      nb->n_type = sym.type | sym.scope;
1056
123
      nb->n_sect = sym.sect;
1057
123
      nb->n_desc = sym.desc;
1058
123
      nb->n_value = sym.value;
1059
123
      if (_swap)
1060
5
        swapStruct(*nb);
1061
123
      symOffset += sizeof(nlist);
1062
123
    }
1063
676
    memcpy(&_buffer[strOffset], sym.name.begin(), sym.name.size());
1064
676
    strOffset += sym.name.size();
1065
676
    _buffer[strOffset++] ='\0'; // Strings in table have nul terminator.
1066
676
  }
1067
684
}
1068
1069
171
void MachOFileLayout::writeFunctionStartsInfo() {
1070
171
  if (!_functionStartsSize)
1071
85
    return;
1072
86
  memcpy(&_buffer[_startOfFunctionStarts], _file.functionStarts.data(),
1073
86
         _functionStartsSize);
1074
86
}
1075
1076
171
void MachOFileLayout::writeDataInCodeInfo() {
1077
171
  uint32_t offset = _startOfDataInCode;
1078
28
  for (const DataInCode &entry : _file.dataInCode) {
1079
28
    data_in_code_entry *dst = reinterpret_cast<data_in_code_entry*>(
1080
28
                                                             &_buffer[offset]);
1081
28
    dst->offset = entry.offset;
1082
28
    dst->length = entry.length;
1083
28
    dst->kind   = entry.kind;
1084
28
    if (_swap)
1085
0
      swapStruct(*dst);
1086
28
    offset += sizeof(data_in_code_entry);
1087
28
  }
1088
171
}
1089
1090
171
void MachOFileLayout::writeSymbolTable() {
1091
171
  // Write symbol table and symbol strings in parallel.
1092
171
  uint32_t symOffset = _startOfSymbols;
1093
171
  uint32_t strOffset = _startOfSymbolStrings;
1094
171
  // Reserve n_strx offset of zero to mean no name.
1095
171
  _buffer[strOffset++] = ' ';
1096
171
  _buffer[strOffset++] = '\0';
1097
171
  appendSymbols(_file.stabsSymbols, symOffset, strOffset);
1098
171
  appendSymbols(_file.localSymbols, symOffset, strOffset);
1099
171
  appendSymbols(_file.globalSymbols, symOffset, strOffset);
1100
171
  appendSymbols(_file.undefinedSymbols, symOffset, strOffset);
1101
171
  // Write indirect symbol table array.
1102
171
  uint32_t *indirects = reinterpret_cast<uint32_t*>
1103
171
                                            (&_buffer[_startOfIndirectSymbols]);
1104
171
  if (
_file.fileType == llvm::MachO::MH_OBJECT171
) {
1105
76
    // Object files have sections in same order as input normalized file.
1106
149
    for (const Section &section : _file.sections) {
1107
0
      for (uint32_t index : section.indirectSymbols) {
1108
0
        if (_swap)
1109
0
          *indirects++ = llvm::sys::getSwappedBytes(index);
1110
0
        else
1111
0
          *indirects++ = index;
1112
0
      }
1113
149
    }
1114
171
  } else {
1115
95
    // Final linked images must sort sections from normalized file.
1116
280
    for (const Segment &seg : _file.segments) {
1117
280
      SegExtraInfo &segInfo = _segInfo[&seg];
1118
229
      for (const Section *section : segInfo.sections) {
1119
97
        for (uint32_t index : section->indirectSymbols) {
1120
97
          if (_swap)
1121
0
            *indirects++ = llvm::sys::getSwappedBytes(index);
1122
97
          else
1123
97
            *indirects++ = index;
1124
97
        }
1125
229
      }
1126
280
    }
1127
95
  }
1128
171
}
1129
1130
95
void MachOFileLayout::writeRebaseInfo() {
1131
95
  memcpy(&_buffer[_startOfRebaseInfo], _rebaseInfo.bytes(), _rebaseInfo.size());
1132
95
}
1133
1134
95
void MachOFileLayout::writeBindingInfo() {
1135
95
  memcpy(&_buffer[_startOfBindingInfo],
1136
95
                                    _bindingInfo.bytes(), _bindingInfo.size());
1137
95
}
1138
1139
95
void MachOFileLayout::writeLazyBindingInfo() {
1140
95
  memcpy(&_buffer[_startOfLazyBindingInfo],
1141
95
                            _lazyBindingInfo.bytes(), _lazyBindingInfo.size());
1142
95
}
1143
1144
95
void MachOFileLayout::writeExportInfo() {
1145
95
  memcpy(&_buffer[_startOfExportTrie], _exportTrie.bytes(), _exportTrie.size());
1146
95
}
1147
1148
190
void MachOFileLayout::buildLinkEditInfo() {
1149
190
  buildRebaseInfo();
1150
190
  buildBindInfo();
1151
190
  buildLazyBindInfo();
1152
190
  buildExportTrie();
1153
190
  computeSymbolTableSizes();
1154
190
  computeFunctionStartsSize();
1155
190
  computeDataInCodeSize();
1156
190
}
1157
1158
0
void MachOFileLayout::buildSectionRelocations() {
1159
0
1160
0
}
1161
1162
190
void MachOFileLayout::buildRebaseInfo() {
1163
190
  // TODO: compress rebasing info.
1164
39
  for (const RebaseLocation& entry : _file.rebasingInfo) {
1165
39
    _rebaseInfo.append_byte(REBASE_OPCODE_SET_TYPE_IMM | entry.kind);
1166
39
    _rebaseInfo.append_byte(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
1167
39
                            | entry.segIndex);
1168
39
    _rebaseInfo.append_uleb128(entry.segOffset);
1169
39
    _rebaseInfo.append_uleb128(REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1);
1170
39
  }
1171
190
  _rebaseInfo.append_byte(REBASE_OPCODE_DONE);
1172
190
  _rebaseInfo.align(_is64 ? 
8170
:
420
);
1173
190
}
1174
1175
190
void MachOFileLayout::buildBindInfo() {
1176
190
  // TODO: compress bind info.
1177
190
  uint64_t lastAddend = 0;
1178
190
  int lastOrdinal = 0x80000000;
1179
190
  StringRef lastSymbolName;
1180
190
  BindType lastType = (BindType)0;
1181
190
  Hex32 lastSegOffset = ~0U;
1182
190
  uint8_t lastSegIndex = (uint8_t)~0U;
1183
32
  for (const BindLocation& entry : _file.bindingInfo) {
1184
32
    if (
entry.ordinal != lastOrdinal32
) {
1185
20
      if (entry.ordinal <= 0)
1186
3
        _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
1187
3
                                 (entry.ordinal & BIND_IMMEDIATE_MASK));
1188
17
      else 
if (17
entry.ordinal <= BIND_IMMEDIATE_MASK17
)
1189
17
        _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
1190
17
                                 entry.ordinal);
1191
0
      else {
1192
0
        _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB);
1193
0
        _bindingInfo.append_uleb128(entry.ordinal);
1194
0
      }
1195
20
      lastOrdinal = entry.ordinal;
1196
20
    }
1197
32
1198
32
    if (
lastSymbolName != entry.symbolName32
) {
1199
32
      _bindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
1200
32
      _bindingInfo.append_string(entry.symbolName);
1201
32
      lastSymbolName = entry.symbolName;
1202
32
    }
1203
32
1204
32
    if (
lastType != entry.kind32
) {
1205
19
      _bindingInfo.append_byte(BIND_OPCODE_SET_TYPE_IMM | entry.kind);
1206
19
      lastType = entry.kind;
1207
19
    }
1208
32
1209
32
    if (
lastSegIndex != entry.segIndex || 32
lastSegOffset != entry.segOffset13
) {
1210
32
      _bindingInfo.append_byte(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
1211
32
                               | entry.segIndex);
1212
32
      _bindingInfo.append_uleb128(entry.segOffset);
1213
32
      lastSegIndex = entry.segIndex;
1214
32
      lastSegOffset = entry.segOffset;
1215
32
    }
1216
32
    if (
entry.addend != lastAddend32
) {
1217
0
      _bindingInfo.append_byte(BIND_OPCODE_SET_ADDEND_SLEB);
1218
0
      _bindingInfo.append_sleb128(entry.addend);
1219
0
      lastAddend = entry.addend;
1220
0
    }
1221
32
    _bindingInfo.append_byte(BIND_OPCODE_DO_BIND);
1222
32
  }
1223
190
  _bindingInfo.append_byte(BIND_OPCODE_DONE);
1224
190
  _bindingInfo.align(_is64 ? 
8170
:
420
);
1225
190
}
1226
1227
190
void MachOFileLayout::buildLazyBindInfo() {
1228
23
  for (const BindLocation& entry : _file.lazyBindingInfo) {
1229
23
    _lazyBindingInfo.append_byte(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
1230
23
                            | entry.segIndex);
1231
23
    _lazyBindingInfo.append_uleb128(entry.segOffset);
1232
23
    if (entry.ordinal <= 0)
1233
2
      _lazyBindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
1234
2
                                   (entry.ordinal & BIND_IMMEDIATE_MASK));
1235
21
    else 
if (21
entry.ordinal <= BIND_IMMEDIATE_MASK21
)
1236
21
      _lazyBindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
1237
21
                                   entry.ordinal);
1238
0
    else {
1239
0
      _lazyBindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB);
1240
0
      _lazyBindingInfo.append_uleb128(entry.ordinal);
1241
0
    }
1242
23
    // FIXME: We need to | the opcode here with flags.
1243
23
    _lazyBindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
1244
23
    _lazyBindingInfo.append_string(entry.symbolName);
1245
23
    _lazyBindingInfo.append_byte(BIND_OPCODE_DO_BIND);
1246
23
    _lazyBindingInfo.append_byte(BIND_OPCODE_DONE);
1247
23
  }
1248
190
  _lazyBindingInfo.align(_is64 ? 
8170
:
420
);
1249
190
}
1250
1251
void TrieNode::addSymbol(const Export& entry,
1252
                         BumpPtrAllocator &allocator,
1253
306
                         std::vector<TrieNode*> &allNodes) {
1254
306
  StringRef partialStr = entry.name.drop_front(_cummulativeString.size());
1255
249
  for (TrieEdge &edge : _children) {
1256
249
    StringRef edgeStr = edge._subString;
1257
249
    if (
partialStr.startswith(edgeStr)249
) {
1258
30
      // Already have matching edge, go down that path.
1259
30
      edge._child->addSymbol(entry, allocator, allNodes);
1260
30
      return;
1261
30
    }
1262
219
    // See if string has commmon prefix with existing edge.
1263
2.34k
    
for (int n=edgeStr.size()-1; 219
n > 02.34k
;
--n2.12k
) {
1264
2.20k
      if (
partialStr.substr(0, n).equals(edgeStr.substr(0, n))2.20k
) {
1265
80
        // Splice in new node:  was A -> C,  now A -> B -> C
1266
80
        StringRef bNodeStr = edge._child->_cummulativeString;
1267
80
        bNodeStr = bNodeStr.drop_back(edgeStr.size()-n).copy(allocator);
1268
80
        auto *bNode = new (allocator) TrieNode(bNodeStr);
1269
80
        allNodes.push_back(bNode);
1270
80
        TrieNode* cNode = edge._child;
1271
80
        StringRef abEdgeStr = edgeStr.substr(0,n).copy(allocator);
1272
80
        StringRef bcEdgeStr = edgeStr.substr(n).copy(allocator);
1273
80
        DEBUG_WITH_TYPE("trie-builder", llvm::dbgs()
1274
80
                        << "splice in TrieNode('" << bNodeStr
1275
80
                        << "') between edge '"
1276
80
                        << abEdgeStr << "' and edge='"
1277
80
                        << bcEdgeStr<< "'\n");
1278
80
        TrieEdge& abEdge = edge;
1279
80
        abEdge._subString = abEdgeStr;
1280
80
        abEdge._child = bNode;
1281
80
        auto *bcEdge = new (allocator) TrieEdge(bcEdgeStr, cNode);
1282
80
        bNode->_children.insert(bNode->_children.end(), bcEdge);
1283
80
        bNode->addSymbol(entry, allocator, allNodes);
1284
80
        return;
1285
80
      }
1286
2.20k
    }
1287
249
  }
1288
196
  
if (196
entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT196
) {
1289
0
    assert(entry.otherOffset != 0);
1290
0
  }
1291
196
  if (
entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER196
) {
1292
0
    assert(entry.otherOffset != 0);
1293
0
  }
1294
196
  // No commonality with any existing child, make a new edge.
1295
196
  auto *newNode = new (allocator) TrieNode(entry.name.copy(allocator));
1296
196
  auto *newEdge = new (allocator) TrieEdge(partialStr, newNode);
1297
196
  _children.insert(_children.end(), newEdge);
1298
196
  DEBUG_WITH_TYPE("trie-builder", llvm::dbgs()
1299
196
                   << "new TrieNode('" << entry.name << "') with edge '"
1300
196
                   << partialStr << "' from node='"
1301
196
                   << _cummulativeString << "'\n");
1302
196
  newNode->_address = entry.offset;
1303
196
  newNode->_flags = entry.flags | entry.kind;
1304
196
  newNode->_other = entry.otherOffset;
1305
196
  if (
(entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) && 196
!entry.otherName.empty()0
)
1306
0
    newNode->_importedName = entry.otherName.copy(allocator);
1307
306
  newNode->_hasExportInfo = true;
1308
306
  allNodes.push_back(newNode);
1309
306
}
1310
1311
void TrieNode::addOrderedNodes(const Export& entry,
1312
590
                               std::vector<TrieNode*> &orderedNodes) {
1313
590
  if (
!_ordered590
) {
1314
368
    orderedNodes.push_back(this);
1315
368
    _ordered = true;
1316
368
  }
1317
590
1318
590
  StringRef partialStr = entry.name.drop_front(_cummulativeString.size());
1319
533
  for (TrieEdge &edge : _children) {
1320
533
    StringRef edgeStr = edge._subString;
1321
533
    if (
partialStr.startswith(edgeStr)533
) {
1322
394
      // Already have matching edge, go down that path.
1323
394
      edge._child->addOrderedNodes(entry, orderedNodes);
1324
394
      return;
1325
394
    }
1326
196
  }
1327
590
}
1328
1329
747
bool TrieNode::updateOffset(uint32_t& offset) {
1330
747
  uint32_t nodeSize = 1; // Length when no export info
1331
747
  if (
_hasExportInfo747
) {
1332
398
    if (
_flags & EXPORT_SYMBOL_FLAGS_REEXPORT398
) {
1333
0
      nodeSize = llvm::getULEB128Size(_flags);
1334
0
      nodeSize += llvm::getULEB128Size(_other); // Other contains ordinal.
1335
0
      nodeSize += _importedName.size();
1336
0
      ++nodeSize; // Trailing zero in imported name.
1337
398
    } else {
1338
398
      nodeSize = llvm::getULEB128Size(_flags) + llvm::getULEB128Size(_address);
1339
398
      if (_flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1340
0
        nodeSize += llvm::getULEB128Size(_other);
1341
398
    }
1342
398
    // Overall node size so far is uleb128 of export info + actual export info.
1343
398
    nodeSize += llvm::getULEB128Size(nodeSize);
1344
398
  }
1345
747
  // Compute size of all child edges.
1346
747
  ++nodeSize; // Byte for number of chidren.
1347
562
  for (TrieEdge &edge : _children) {
1348
562
    nodeSize += edge._subString.size() + 1 // String length.
1349
562
              + llvm::getULEB128Size(edge._child->_trieOffset); // Offset len.
1350
562
  }
1351
747
  // On input, 'offset' is new prefered location for this node.
1352
747
  bool result = (_trieOffset != offset);
1353
747
  // Store new location in node object for use by parents.
1354
747
  _trieOffset = offset;
1355
747
  // Update offset for next iteration.
1356
747
  offset += nodeSize;
1357
747
  // Return true if _trieOffset was changed.
1358
747
  return result;
1359
747
}
1360
1361
368
void TrieNode::appendToByteBuffer(ByteBuffer &out) {
1362
368
  if (
_hasExportInfo368
) {
1363
196
    if (
_flags & EXPORT_SYMBOL_FLAGS_REEXPORT196
) {
1364
0
      if (
!_importedName.empty()0
) {
1365
0
        // nodes with re-export info: size, flags, ordinal, import-name
1366
0
        uint32_t nodeSize = llvm::getULEB128Size(_flags)
1367
0
                          + llvm::getULEB128Size(_other)
1368
0
                          + _importedName.size() + 1;
1369
0
        assert(nodeSize < 256);
1370
0
        out.append_byte(nodeSize);
1371
0
        out.append_uleb128(_flags);
1372
0
        out.append_uleb128(_other);
1373
0
        out.append_string(_importedName);
1374
0
      } else {
1375
0
        // nodes without re-export info: size, flags, ordinal, empty-string
1376
0
        uint32_t nodeSize = llvm::getULEB128Size(_flags)
1377
0
                          + llvm::getULEB128Size(_other) + 1;
1378
0
        assert(nodeSize < 256);
1379
0
        out.append_byte(nodeSize);
1380
0
        out.append_uleb128(_flags);
1381
0
        out.append_uleb128(_other);
1382
0
        out.append_byte(0);
1383
0
      }
1384
196
    } else 
if ( 196
_flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER196
) {
1385
0
      // Nodes with export info: size, flags, address, other
1386
0
      uint32_t nodeSize = llvm::getULEB128Size(_flags)
1387
0
                        + llvm::getULEB128Size(_address)
1388
0
                        + llvm::getULEB128Size(_other);
1389
0
      assert(nodeSize < 256);
1390
0
      out.append_byte(nodeSize);
1391
0
      out.append_uleb128(_flags);
1392
0
      out.append_uleb128(_address);
1393
0
      out.append_uleb128(_other);
1394
196
    } else {
1395
196
      // Nodes with export info: size, flags, address
1396
196
      uint32_t nodeSize = llvm::getULEB128Size(_flags)
1397
196
                        + llvm::getULEB128Size(_address);
1398
196
      assert(nodeSize < 256);
1399
196
      out.append_byte(nodeSize);
1400
196
      out.append_uleb128(_flags);
1401
196
      out.append_uleb128(_address);
1402
196
    }
1403
368
  } else {
1404
172
    // Node with no export info.
1405
172
    uint32_t nodeSize = 0;
1406
172
    out.append_byte(nodeSize);
1407
172
  }
1408
368
  // Add number of children.
1409
368
  assert(_children.size() < 256);
1410
368
  out.append_byte(_children.size());
1411
368
  // Append each child edge substring and node offset.
1412
276
  for (TrieEdge &edge : _children) {
1413
276
    out.append_string(edge._subString);
1414
276
    out.append_uleb128(edge._child->_trieOffset);
1415
276
  }
1416
368
}
1417
1418
190
void MachOFileLayout::buildExportTrie() {
1419
190
  if (_file.exportInfo.empty())
1420
98
    return;
1421
92
1422
92
  // For all temporary strings and objects used building trie.
1423
92
  BumpPtrAllocator allocator;
1424
92
1425
92
  // Build trie of all exported symbols.
1426
92
  auto *rootNode = new (allocator) TrieNode(StringRef());
1427
92
  std::vector<TrieNode*> allNodes;
1428
92
  allNodes.reserve(_file.exportInfo.size()*2);
1429
92
  allNodes.push_back(rootNode);
1430
196
  for (const Export& entry : _file.exportInfo) {
1431
196
    rootNode->addSymbol(entry, allocator, allNodes);
1432
196
  }
1433
92
1434
92
  std::vector<TrieNode*> orderedNodes;
1435
92
  orderedNodes.reserve(allNodes.size());
1436
92
1437
92
  for (const Export& entry : _file.exportInfo)
1438
196
    rootNode->addOrderedNodes(entry, orderedNodes);
1439
92
1440
92
  // Assign each node in the vector an offset in the trie stream, iterating
1441
92
  // until all uleb128 sizes have stabilized.
1442
92
  bool more;
1443
185
  do {
1444
185
    uint32_t offset = 0;
1445
185
    more = false;
1446
747
    for (TrieNode* node : orderedNodes) {
1447
747
      if (node->updateOffset(offset))
1448
280
        more = true;
1449
747
    }
1450
185
  } while (more);
1451
92
1452
92
  // Serialize trie to ByteBuffer.
1453
368
  for (TrieNode* node : orderedNodes) {
1454
368
    node->appendToByteBuffer(_exportTrie);
1455
368
  }
1456
92
  _exportTrie.align(_is64 ? 
884
:
48
);
1457
190
}
1458
1459
338
void MachOFileLayout::computeSymbolTableSizes() {
1460
338
  // MachO symbol tables have three ranges: locals, globals, and undefines
1461
338
  const size_t nlistSize = (_is64 ? 
sizeof(nlist_64)276
:
sizeof(nlist)62
);
1462
338
  _symbolTableSize = nlistSize * (_file.stabsSymbols.size()
1463
338
                                + _file.localSymbols.size()
1464
338
                                + _file.globalSymbols.size()
1465
338
                                + _file.undefinedSymbols.size());
1466
338
  // Always reserve 1-byte for the empty string and 1-byte for its terminator.
1467
338
  _symbolStringPoolSize = 2;
1468
8
  for (const Symbol &sym : _file.stabsSymbols) {
1469
8
    _symbolStringPoolSize += (sym.name.size()+1);
1470
8
  }
1471
183
  for (const Symbol &sym : _file.localSymbols) {
1472
183
    _symbolStringPoolSize += (sym.name.size()+1);
1473
183
  }
1474
296
  for (const Symbol &sym : _file.globalSymbols) {
1475
296
    _symbolStringPoolSize += (sym.name.size()+1);
1476
296
  }
1477
189
  for (const Symbol &sym : _file.undefinedSymbols) {
1478
189
    _symbolStringPoolSize += (sym.name.size()+1);
1479
189
  }
1480
338
  _symbolTableLocalsStartIndex = 0;
1481
338
  _symbolTableGlobalsStartIndex = _file.stabsSymbols.size() +
1482
338
                                  _file.localSymbols.size();
1483
338
  _symbolTableUndefinesStartIndex = _symbolTableGlobalsStartIndex
1484
338
                                    + _file.globalSymbols.size();
1485
338
1486
338
  _indirectSymbolTableCount = 0;
1487
752
  for (const Section &sect : _file.sections) {
1488
752
    _indirectSymbolTableCount += sect.indirectSymbols.size();
1489
752
  }
1490
338
}
1491
1492
338
void MachOFileLayout::computeFunctionStartsSize() {
1493
338
  _functionStartsSize = _file.functionStarts.size();
1494
338
}
1495
1496
338
void MachOFileLayout::computeDataInCodeSize() {
1497
338
  _dataInCodeSize = _file.dataInCode.size() * sizeof(data_in_code_entry);
1498
338
}
1499
1500
171
void MachOFileLayout::writeLinkEditContent() {
1501
171
  if (
_file.fileType == llvm::MachO::MH_OBJECT171
) {
1502
76
    writeRelocations();
1503
76
    writeFunctionStartsInfo();
1504
76
    writeDataInCodeInfo();
1505
76
    writeSymbolTable();
1506
171
  } else {
1507
95
    writeRebaseInfo();
1508
95
    writeBindingInfo();
1509
95
    writeLazyBindingInfo();
1510
95
    // TODO: add weak binding info
1511
95
    writeExportInfo();
1512
95
    writeFunctionStartsInfo();
1513
95
    writeDataInCodeInfo();
1514
95
    writeSymbolTable();
1515
95
  }
1516
171
}
1517
1518
171
llvm::Error MachOFileLayout::writeBinary(StringRef path) {
1519
171
  // Check for pending error from constructor.
1520
171
  if (_ec)
1521
0
    return llvm::errorCodeToError(_ec);
1522
171
  // Create FileOutputBuffer with calculated size.
1523
171
  unsigned flags = 0;
1524
171
  if (_file.fileType != llvm::MachO::MH_OBJECT)
1525
95
    flags = llvm::FileOutputBuffer::F_executable;
1526
171
  ErrorOr<std::unique_ptr<llvm::FileOutputBuffer>> fobOrErr =
1527
171
      llvm::FileOutputBuffer::create(path, size(), flags);
1528
171
  if (std::error_code ec = fobOrErr.getError())
1529
0
    return llvm::errorCodeToError(ec);
1530
171
  std::unique_ptr<llvm::FileOutputBuffer> &fob = *fobOrErr;
1531
171
  // Write content.
1532
171
  _buffer = fob->getBufferStart();
1533
171
  writeMachHeader();
1534
171
  if (auto ec = writeLoadCommands())
1535
0
    return ec;
1536
171
  writeSectionContent();
1537
171
  writeLinkEditContent();
1538
171
  fob->commit();
1539
171
1540
171
  return llvm::Error::success();
1541
171
}
1542
1543
/// Takes in-memory normalized view and writes a mach-o object file.
1544
171
llvm::Error writeBinary(const NormalizedFile &file, StringRef path) {
1545
171
  MachOFileLayout layout(file);
1546
171
  return layout.writeBinary(path);
1547
171
}
1548
1549
} // namespace normalized
1550
} // namespace mach_o
1551
} // namespace lld