Coverage Report

Created: 2019-05-19 14:56

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