blob: b5585aafbc72e5cdd5663d5c56252a0da64f8c42 [file] [log] [blame]
Nick Kledzike34182f2013-11-06 21:36:55 +00001//===- 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
27#include "lld/Core/Error.h"
28#include "lld/Core/LLVM.h"
29
30#include "llvm/ADT/SmallString.h"
31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringRef.h"
33#include "llvm/Support/Casting.h"
34#include "llvm/Support/Debug.h"
35#include "llvm/Support/ErrorHandling.h"
36#include "llvm/Support/FileOutputBuffer.h"
37#include "llvm/Support/Host.h"
38#include "llvm/Support/MachO.h"
39#include "llvm/Support/MemoryBuffer.h"
40#include "llvm/Support/raw_ostream.h"
41#include "llvm/Support/system_error.h"
42
43#include <functional>
44#include <map>
45
46using namespace llvm::MachO;
47
48namespace lld {
49namespace mach_o {
50namespace normalized {
51
52/// Utility class for writing a mach-o binary file given an in-memory
53/// normalized file.
54class MachOFileLayout {
55public:
56 /// All layout computation is done in the constructor.
57 MachOFileLayout(const NormalizedFile &file);
58
59 /// Returns the final file size as computed in the constructor.
60 size_t size() const;
61
62 /// Writes the normalized file as a binary mach-o file to the specified
63 /// path. This does not have a stream interface because the generated
64 /// file may need the 'x' bit set.
65 error_code writeBinary(StringRef path);
66
67private:
68 uint32_t loadCommandsSize(uint32_t &count);
69 void buildFileOffsets();
70 void writeMachHeader();
71 error_code writeLoadCommands();
72 void writeSectionContent();
73 void writeRelocations();
74 void writeSymbolTable();
75 void writeRebaseInfo();
76 void writeBindingInfo();
77 void writeLazyBindingInfo();
78 void writeLinkEditContent();
79 void buildLinkEditInfo();
80 void buildRebaseInfo();
81 void buildBindInfo();
82 void buildLazyBindInfo();
83 void computeSymbolTableSizes();
84 void buildSectionRelocations();
85 void appendSymbols(const std::vector<Symbol> &symbols,
86 uint32_t &symOffset, uint32_t &strOffset);
87 uint32_t indirectSymbolIndex(const Section &sect, uint32_t &index);
88 uint32_t indirectSymbolElementSize(const Section &sect);
89
90 error_code writeSingleSegment32LoadCommand(uint8_t *&lc);
91 error_code writeSingleSegment64LoadCommand(uint8_t *&lc);
92 error_code writeSegment32LoadCommands(uint8_t *&lc);
93 error_code writeSegment64LoadCommands(uint8_t *&lc);
94
95 uint32_t pointerAlign(uint32_t value);
96 static StringRef dyldPath();
97
98 class ByteBuffer {
99 public:
100 ByteBuffer();
101 void append_byte(uint8_t);
102 void append_uleb128(uint64_t);
103 void append_sleb128(int64_t);
104 void append_string(StringRef);
105 void align(unsigned);
106 size_t size();
107 const uint8_t *bytes();
108 private:
109 std::vector<uint8_t> _bytes;
110 };
111
112 struct SegExtraInfo {
113 uint32_t fileOffset;
114 std::vector<const Section*> sections;
115 };
116 typedef std::map<const Segment*, SegExtraInfo> SegMap;
117 struct SectionExtraInfo {
118 uint32_t fileOffset;
119 };
120 typedef std::map<const Section*, SectionExtraInfo> SectionMap;
121
122 const NormalizedFile &_file;
123 error_code _ec;
124 uint8_t *_buffer;
125 const bool _is64;
126 const bool _swap;
127 const bool _bigEndianArch;
128 uint64_t _seg1addr;
129 uint32_t _startOfLoadCommands;
130 uint32_t _countOfLoadCommands;
131 uint32_t _endOfLoadCommands;
132 uint32_t _startOfRelocations;
133 uint32_t _startOfSymbols;
134 uint32_t _startOfIndirectSymbols;
135 uint32_t _startOfSymbolStrings;
136 uint32_t _endOfSymbolStrings;
137 uint32_t _symbolTableLocalsStartIndex;
138 uint32_t _symbolTableGlobalsStartIndex;
139 uint32_t _symbolTableUndefinesStartIndex;
140 uint32_t _symbolStringPoolSize;
141 uint32_t _symbolTableSize;
142 uint32_t _indirectSymbolTableCount;
143 // Used in object file creation only
144 uint32_t _startOfSectionsContent;
145 uint32_t _endOfSectionsContent;
146 // Used in final linked image only
147 uint32_t _startOfLinkEdit;
148 uint32_t _startOfRebaseInfo;
149 uint32_t _endOfRebaseInfo;
150 uint32_t _startOfBindingInfo;
151 uint32_t _endOfBindingInfo;
152 uint32_t _startOfLazyBindingInfo;
153 uint32_t _endOfLazyBindingInfo;
154 uint32_t _endOfLinkEdit;
155 uint64_t _addressOfLinkEdit;
156 SegMap _segInfo;
157 SectionMap _sectInfo;
158 ByteBuffer _rebaseInfo;
159 ByteBuffer _bindingInfo;
160 ByteBuffer _lazyBindingInfo;
161 ByteBuffer _weakBindingInfo;
162 ByteBuffer _exportInfo;
163};
164
165size_t headerAndLoadCommandsSize(const NormalizedFile &file) {
166 MachOFileLayout layout(file);
167 return layout.size();
168}
169
170StringRef MachOFileLayout::dyldPath() {
171 return "/usr/lib/dyld";
172}
173
174uint32_t MachOFileLayout::pointerAlign(uint32_t value) {
175 return llvm::RoundUpToAlignment(value, _is64 ? 8 : 4);
176}
177
178
179MachOFileLayout::ByteBuffer::ByteBuffer() {
180 _bytes.reserve(256);
181}
182
183void MachOFileLayout::ByteBuffer::append_byte(uint8_t b) {
184 _bytes.push_back(b);
185}
186
187
188void MachOFileLayout::ByteBuffer::append_uleb128(uint64_t value) {
189 uint8_t byte;
190 do {
191 byte = value & 0x7F;
192 value &= ~0x7F;
193 if ( value != 0 )
194 byte |= 0x80;
195 _bytes.push_back(byte);
196 value = value >> 7;
197 } while( byte >= 0x80 );
198}
199
200void MachOFileLayout::ByteBuffer::append_sleb128(int64_t value) {
201 bool isNeg = ( value < 0 );
202 uint8_t byte;
203 bool more;
204 do {
205 byte = value & 0x7F;
206 value = value >> 7;
207 if ( isNeg )
208 more = ( (value != -1) || ((byte & 0x40) == 0) );
209 else
210 more = ( (value != 0) || ((byte & 0x40) != 0) );
211 if ( more )
212 byte |= 0x80;
213 _bytes.push_back(byte);
214 }
215 while( more );
216}
217
218void MachOFileLayout::ByteBuffer::append_string(StringRef str) {
219 _bytes.insert(_bytes.end(), str.begin(), str.end());
220 _bytes.push_back('\0');
221}
222
223void MachOFileLayout::ByteBuffer::align(unsigned alignment) {
224 while ( (_bytes.size() % alignment) != 0 )
225 _bytes.push_back(0);
226}
227
228const uint8_t *MachOFileLayout::ByteBuffer::bytes() {
229 return &_bytes[0];
230}
231
232size_t MachOFileLayout::ByteBuffer::size() {
233 return _bytes.size();
234}
235
236
237
238
239MachOFileLayout::MachOFileLayout(const NormalizedFile &file)
240 : _file(file),
241 _is64(MachOLinkingContext::is64Bit(file.arch)),
242 _swap(!MachOLinkingContext::isHostEndian(file.arch)),
243 _bigEndianArch(MachOLinkingContext::isBigEndian(file.arch)),
244 _seg1addr(INT64_MAX) {
245 _startOfLoadCommands = _is64 ? sizeof(mach_header_64) : sizeof(mach_header);
246 const size_t segCommandBaseSize =
247 (_is64 ? sizeof(segment_command_64) : sizeof(segment_command));
248 const size_t sectsSize = (_is64 ? sizeof(section_64) : sizeof(section));
249 if (file.fileType == llvm::MachO::MH_OBJECT) {
250 // object files have just one segment load command containing all sections
251 _endOfLoadCommands = _startOfLoadCommands
252 + segCommandBaseSize
253 + file.sections.size() * sectsSize
254 + sizeof(symtab_command);
255 _countOfLoadCommands = 2;
256
257 // Accumulate size of each section.
258 _startOfSectionsContent = _endOfLoadCommands;
259 _endOfSectionsContent = _startOfSectionsContent;
260 unsigned relocCount = 0;
261 for (const Section &sect : file.sections) {
262 _sectInfo[&sect].fileOffset = _endOfSectionsContent;
263 _endOfSectionsContent += sect.content.size();
264 relocCount += sect.relocations.size();
265 }
266
267 computeSymbolTableSizes();
268
269 // Align start of relocations.
270 _startOfRelocations = pointerAlign(_endOfSectionsContent);
271 _startOfSymbols = _startOfRelocations + relocCount * 8;
272 // Add Indirect symbol table.
273 _startOfIndirectSymbols = _startOfSymbols + _symbolTableSize;
274 // Align start of symbol table and symbol strings.
275 _startOfSymbolStrings = _startOfIndirectSymbols
276 + pointerAlign(_indirectSymbolTableCount * sizeof(uint32_t));
277 _endOfSymbolStrings = _startOfSymbolStrings
278 + pointerAlign(_symbolStringPoolSize);
279 _endOfLinkEdit = _endOfSymbolStrings;
280 DEBUG_WITH_TYPE("MachOFileLayout",
281 llvm::dbgs() << "MachOFileLayout()\n"
282 << " startOfLoadCommands=" << _startOfLoadCommands << "\n"
283 << " countOfLoadCommands=" << _countOfLoadCommands << "\n"
284 << " endOfLoadCommands=" << _endOfLoadCommands << "\n"
285 << " startOfRelocations=" << _startOfRelocations << "\n"
286 << " startOfSymbols=" << _startOfSymbols << "\n"
287 << " startOfSymbolStrings=" << _startOfSymbolStrings << "\n"
288 << " endOfSymbolStrings=" << _endOfSymbolStrings << "\n"
289 << " startOfSectionsContent=" << _startOfSectionsContent << "\n"
290 << " endOfSectionsContent=" << _endOfSectionsContent << "\n");
291 } else {
292 // Final linked images have one load command per segment.
293 _endOfLoadCommands = _startOfLoadCommands
294 + loadCommandsSize(_countOfLoadCommands);
295
296 // Assign section file offsets.
297 buildFileOffsets();
298 buildLinkEditInfo();
299
300 // LINKEDIT of final linked images has in order:
301 // rebase info, binding info, lazy binding info, weak binding info,
302 // indirect symbol table, symbol table, symbol table strings.
303 _startOfRebaseInfo = _startOfLinkEdit;
304 _endOfRebaseInfo = _startOfRebaseInfo + _rebaseInfo.size();
305 _startOfBindingInfo = _endOfRebaseInfo;
306 _endOfBindingInfo = _startOfBindingInfo + _bindingInfo.size();
307 _startOfLazyBindingInfo = _endOfBindingInfo;
308 _endOfLazyBindingInfo = _startOfLazyBindingInfo + _lazyBindingInfo.size();
309
310 _startOfSymbols = _endOfLazyBindingInfo;
311 _startOfIndirectSymbols = _startOfSymbols + _symbolTableSize;
312 _startOfSymbolStrings = _startOfIndirectSymbols
313 + pointerAlign(_indirectSymbolTableCount * sizeof(uint32_t));
314 _endOfSymbolStrings = _startOfSymbolStrings
315 + pointerAlign(_symbolStringPoolSize);
316 _endOfLinkEdit = _endOfSymbolStrings;
317 DEBUG_WITH_TYPE("MachOFileLayout",
318 llvm::dbgs() << "MachOFileLayout()\n"
319 << " startOfLoadCommands=" << _startOfLoadCommands << "\n"
320 << " countOfLoadCommands=" << _countOfLoadCommands << "\n"
321 << " endOfLoadCommands=" << _endOfLoadCommands << "\n"
322 << " startOfLinkEdit=" << _startOfLinkEdit << "\n"
323 << " startOfRebaseInfo=" << _startOfRebaseInfo << "\n"
324 << " endOfRebaseInfo=" << _endOfRebaseInfo << "\n"
325 << " startOfBindingInfo=" << _startOfBindingInfo << "\n"
326 << " endOfBindingInfo=" << _endOfBindingInfo << "\n"
327 << " startOfLazyBindingInfo=" << _startOfLazyBindingInfo << "\n"
328 << " endOfLazyBindingInfo=" << _endOfLazyBindingInfo << "\n"
329 << " startOfSymbols=" << _startOfSymbols << "\n"
330 << " startOfSymbolStrings=" << _startOfSymbolStrings << "\n"
331 << " endOfSymbolStrings=" << _endOfSymbolStrings << "\n"
332 << " addressOfLinkEdit=" << _addressOfLinkEdit << "\n");
333 }
334}
335
336uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count) {
337 uint32_t size = 0;
338 count = 0;
339
340 const size_t segCommandSize =
341 (_is64 ? sizeof(segment_command_64) : sizeof(segment_command));
342 const size_t sectionSize = (_is64 ? sizeof(section_64) : sizeof(section));
343
344 // Add LC_SEGMENT for each segment.
345 size += _file.segments.size() * segCommandSize;
346 count += _file.segments.size();
347 // Add section record for each section.
348 size += _file.sections.size() * sectionSize;
349 // Add one LC_SEGMENT for implicit __LINKEDIT segment
350 size += segCommandSize;
351 ++count;
352
353 // Add LC_DYLD_INFO
354 size += sizeof(dyld_info_command);
355 ++count;
356
357 // Add LC_SYMTAB
358 size += sizeof(symtab_command);
359 ++count;
360
361 // Add LC_DYSYMTAB
362 if (_file.fileType != llvm::MachO::MH_PRELOAD) {
363 size += sizeof(dysymtab_command);
364 ++count;
365 }
366
367 // If main executable add LC_LOAD_DYLINKER and LC_MAIN
368 if (_file.fileType == llvm::MachO::MH_EXECUTE) {
369 size += pointerAlign(sizeof(dylinker_command) + dyldPath().size()+1);
370 ++count;
371 size += sizeof(entry_point_command);
372 ++count;
373 }
374
375 // Add LC_LOAD_DYLIB for each dependent dylib.
376 for (const DependentDylib &dep : _file.dependentDylibs) {
377 size += sizeof(dylib_command) + pointerAlign(dep.path.size()+1);
378 ++count;
379 }
380
381 return size;
382}
383
384static bool overlaps(const Segment &s1, const Segment &s2) {
385 if (s2.address >= s1.address+s1.size)
386 return false;
387 if (s1.address >= s2.address+s2.size)
388 return false;
389 return true;
390}
391
392static bool overlaps(const Section &s1, const Section &s2) {
393 if (s2.address >= s1.address+s1.content.size())
394 return false;
395 if (s1.address >= s2.address+s2.content.size())
396 return false;
397 return true;
398}
399
400void MachOFileLayout::buildFileOffsets() {
401 // Verify no segments overlap
402 for (const Segment &sg1 : _file.segments) {
403 for (const Segment &sg2 : _file.segments) {
404 if (&sg1 == &sg2)
405 continue;
406 if (overlaps(sg1,sg2)) {
407 _ec = llvm::make_error_code(llvm::errc::executable_format_error);
408 return;
409 }
410 }
411 }
412
413 // Verify no sections overlap
414 for (const Section &s1 : _file.sections) {
415 for (const Section &s2 : _file.sections) {
416 if (&s1 == &s2)
417 continue;
418 if (overlaps(s1,s2)) {
419 _ec = llvm::make_error_code(llvm::errc::executable_format_error);
420 return;
421 }
422 }
423 }
424
425 // Build side table of extra info about segments and sections.
426 SegExtraInfo t;
427 t.fileOffset = 0;
428 for (const Segment &sg : _file.segments) {
429 _segInfo[&sg] = t;
430 }
431 SectionExtraInfo t2;
432 t2.fileOffset = 0;
433 // Assign sections to segments.
434 for (const Section &s : _file.sections) {
435 _sectInfo[&s] = t2;
436 for (const Segment &sg : _file.segments) {
437 if ((s.address >= sg.address)
438 && (s.address+s.content.size() <= sg.address+sg.size)) {
439 if (!sg.name.equals(s.segmentName)) {
440 _ec = llvm::make_error_code(llvm::errc::executable_format_error);
441 return;
442 }
443 _segInfo[&sg].sections.push_back(&s);
444 }
445 }
446 }
447
448 // Assign file offsets.
449 uint32_t fileOffset = 0;
450 DEBUG_WITH_TYPE("MachOFileLayout",
451 llvm::dbgs() << "buildFileOffsets()\n");
452 for (const Segment &sg : _file.segments) {
453 // FIXME: 4096 should be infered from segments in normalized file.
454 _segInfo[&sg].fileOffset = llvm::RoundUpToAlignment(fileOffset, 4096);
455 if ((_seg1addr == INT64_MAX) && sg.access)
456 _seg1addr = sg.address;
457 DEBUG_WITH_TYPE("MachOFileLayout",
458 llvm::dbgs() << " segment=" << sg.name
459 << ", fileOffset=" << _segInfo[&sg].fileOffset << "\n");
460 for (const Section *s : _segInfo[&sg].sections) {
461 fileOffset = s->address - sg.address + _segInfo[&sg].fileOffset;
462 _sectInfo[s].fileOffset = fileOffset;
463 DEBUG_WITH_TYPE("MachOFileLayout",
464 llvm::dbgs() << " section=" << s->sectionName
465 << ", fileOffset=" << fileOffset << "\n");
466 }
467 _addressOfLinkEdit = sg.address + sg.size;
468 }
469 _startOfLinkEdit = llvm::RoundUpToAlignment(fileOffset, 4096);
470}
471
472
473size_t MachOFileLayout::size() const {
474 return _endOfSymbolStrings;
475}
476
477void MachOFileLayout::writeMachHeader() {
478 mach_header *mh = reinterpret_cast<mach_header*>(_buffer);
479 mh->magic = _is64 ? llvm::MachO::MH_MAGIC_64 : llvm::MachO::MH_MAGIC;
480 mh->cputype = MachOLinkingContext::cpuTypeFromArch(_file.arch);
481 mh->cpusubtype = MachOLinkingContext::cpuSubtypeFromArch(_file.arch);
482 mh->filetype = _file.fileType;
483 mh->ncmds = _countOfLoadCommands;
484 mh->sizeofcmds = _endOfLoadCommands - _startOfLoadCommands;
485 mh->flags = _file.flags;
486 if (_swap)
487 swapStruct(*mh);
488}
489
490uint32_t MachOFileLayout::indirectSymbolIndex(const Section &sect,
491 uint32_t &index) {
492 if (sect.indirectSymbols.empty())
493 return 0;
494 uint32_t result = index;
495 index += sect.indirectSymbols.size();
496 return result;
497}
498
499uint32_t MachOFileLayout::indirectSymbolElementSize(const Section &sect) {
500 if (sect.indirectSymbols.empty())
501 return 0;
502 if (sect.type != S_SYMBOL_STUBS)
503 return 0;
504 return sect.content.size() / sect.indirectSymbols.size();
505}
506
507error_code MachOFileLayout::writeSingleSegment64LoadCommand(uint8_t *&lc) {
508 segment_command_64* seg = reinterpret_cast<segment_command_64*>(lc);
509 seg->cmd = LC_SEGMENT_64;
510 seg->cmdsize = sizeof(segment_command_64)
511 + _file.sections.size() * sizeof(section_64);
512 uint8_t *next = lc + seg->cmdsize;
513 memset(seg->segname, 0, 16);
514 seg->vmaddr = 0;
515 seg->vmsize = _endOfSectionsContent - _endOfLoadCommands;
516 seg->fileoff = _endOfLoadCommands;
517 seg->filesize = seg->vmsize;
518 seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
519 seg->initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
520 seg->nsects = _file.sections.size();
521 seg->flags = 0;
522 if (_swap)
523 swapStruct(*seg);
524 section_64 *sout = reinterpret_cast<section_64*>
525 (lc+sizeof(segment_command_64));
526 uint32_t relOffset = _startOfRelocations;
527 uint32_t contentOffset = _startOfSectionsContent;
528 uint32_t indirectSymRunningIndex = 0;
529 for (const Section &sin : _file.sections) {
530 setString16(sin.sectionName, sout->sectname);
531 setString16(sin.segmentName, sout->segname);
532 sout->addr = sin.address;
533 sout->size = sin.content.size();
534 sout->offset = contentOffset;
535 sout->align = sin.alignment;
536 sout->reloff = sin.relocations.empty() ? 0 : relOffset;
537 sout->nreloc = sin.relocations.size();
538 sout->flags = sin.type | sin.attributes;
539 sout->reserved1 = indirectSymbolIndex(sin, indirectSymRunningIndex);
540 sout->reserved2 = indirectSymbolElementSize(sin);
541 relOffset += sin.relocations.size() * sizeof(any_relocation_info);
542 contentOffset += sin.content.size();
543 if (_swap)
544 swapStruct(*sout);
545 ++sout;
546 }
547 lc = next;
548 return error_code::success();
549}
550
551error_code MachOFileLayout::writeSingleSegment32LoadCommand(uint8_t *&lc) {
552 segment_command* seg = reinterpret_cast<segment_command*>(lc);
553 seg->cmd = LC_SEGMENT;
554 seg->cmdsize = sizeof(segment_command)
555 + _file.sections.size() * sizeof(section);
556 uint8_t *next = lc + seg->cmdsize;
557 memset(seg->segname, 0, 16);
558 seg->vmaddr = 0;
559 seg->vmsize = _endOfSectionsContent - _endOfLoadCommands;
560 seg->fileoff = _endOfLoadCommands;
561 seg->filesize = seg->vmsize;
562 seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
563 seg->initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
564 seg->nsects = _file.sections.size();
565 seg->flags = 0;
566 if (_swap)
567 swapStruct(*seg);
568 section *sout = reinterpret_cast<section*>(lc+sizeof(segment_command));
569 uint32_t relOffset = _startOfRelocations;
570 uint32_t contentOffset = _startOfSectionsContent;
571 uint32_t indirectSymRunningIndex = 0;
572 for (const Section &sin : _file.sections) {
573 setString16(sin.sectionName, sout->sectname);
574 setString16(sin.segmentName, sout->segname);
575 sout->addr = sin.address;
576 sout->size = sin.content.size();
577 sout->offset = contentOffset;
578 sout->align = sin.alignment;
579 sout->reloff = sin.relocations.empty() ? 0 : relOffset;
580 sout->nreloc = sin.relocations.size();
581 sout->flags = sin.type | sin.attributes;
582 sout->reserved1 = indirectSymbolIndex(sin, indirectSymRunningIndex);
583 sout->reserved2 = indirectSymbolElementSize(sin);
584 relOffset += sin.relocations.size() * sizeof(any_relocation_info);
585 contentOffset += sin.content.size();
586 if (_swap)
587 swapStruct(*sout);
588 ++sout;
589 }
590 lc = next;
591 return error_code::success();
592}
593
594
595error_code MachOFileLayout::writeSegment64LoadCommands(uint8_t *&lc) {
596 uint32_t indirectSymRunningIndex = 0;
597 for (const Segment &seg : _file.segments) {
598 // Write segment command with trailing sections.
599 SegExtraInfo &segInfo = _segInfo[&seg];
600 segment_command_64* cmd = reinterpret_cast<segment_command_64*>(lc);
601 cmd->cmd = LC_SEGMENT_64;
602 cmd->cmdsize = sizeof(segment_command_64)
603 + segInfo.sections.size() * sizeof(section_64);
604 uint8_t *next = lc + cmd->cmdsize;
605 setString16(seg.name, cmd->segname);
606 cmd->vmaddr = seg.address;
607 cmd->vmsize = seg.size;
608 cmd->fileoff = segInfo.fileOffset;
609 cmd->filesize = seg.access ? (uint64_t)seg.size : 0;
610 cmd->maxprot = seg.access;
611 cmd->initprot = seg.access;
612 cmd->nsects = segInfo.sections.size();
613 cmd->flags = 0;
614 if (_swap)
615 swapStruct(*cmd);
616 section_64 *sect = reinterpret_cast<section_64*>
617 (lc+sizeof(segment_command_64));
618 for (const Section *section : segInfo.sections) {
619 setString16(section->sectionName, sect->sectname);
620 setString16(section->segmentName, sect->segname);
621 sect->addr = section->address;
622 sect->size = section->content.size();
623 sect->offset = section->address - seg.address + segInfo.fileOffset;
624 sect->align = section->alignment;
625 sect->reloff = 0;
626 sect->nreloc = 0;
627 sect->flags = section->type | section->attributes;
628 sect->reserved1 = indirectSymbolIndex(*section, indirectSymRunningIndex);
629 sect->reserved2 = indirectSymbolElementSize(*section);
630 if (_swap)
631 swapStruct(*sect);
632 ++sect;
633 }
634 lc = reinterpret_cast<uint8_t*>(next);
635 }
636 // Add implicit __LINKEDIT segment
637 segment_command_64* cmd = reinterpret_cast<segment_command_64*>(lc);
638 cmd->cmd = LC_SEGMENT_64;
639 cmd->cmdsize = sizeof(segment_command_64);
640 uint8_t *next = lc + cmd->cmdsize;
641 setString16("__LINKEDIT", cmd->segname);
642 cmd->vmaddr = _addressOfLinkEdit;
643 cmd->vmsize = _endOfLinkEdit - _startOfLinkEdit;
644 cmd->fileoff = _startOfLinkEdit;
645 cmd->filesize = _endOfLinkEdit - _startOfLinkEdit;
646 cmd->maxprot = VM_PROT_READ;
647 cmd->initprot = VM_PROT_READ;
648 cmd->nsects = 0;
649 cmd->flags = 0;
650 if (_swap)
651 swapStruct(*cmd);
652 lc = next;
653 return error_code::success();
654}
655
656// FIXME: See if this can be combined with writeSegment64LoadCommands
657// by using templates.
658error_code MachOFileLayout::writeSegment32LoadCommands(uint8_t *&lc) {
659 uint32_t indirectSymRunningIndex = 0;
660 for (const Segment &seg : _file.segments) {
661 // Write segment command with trailing sections.
662 SegExtraInfo &segInfo = _segInfo[&seg];
663 segment_command* cmd = reinterpret_cast<segment_command*>(lc);
664 cmd->cmd = LC_SEGMENT;
665 cmd->cmdsize = sizeof(segment_command)
666 + segInfo.sections.size() * sizeof(section);
667 uint8_t *next = lc + cmd->cmdsize;
668 setString16(seg.name, cmd->segname);
669 cmd->vmaddr = seg.address;
670 cmd->vmsize = seg.size;
671 cmd->fileoff = segInfo.fileOffset;
672 cmd->filesize = seg.access ? (uint32_t)seg.size : 0;
673 cmd->maxprot = seg.access;
674 cmd->initprot = seg.access;
675 cmd->nsects = segInfo.sections.size();
676 cmd->flags = 0;
677 if (_swap)
678 swapStruct(*cmd);
679 section *sect = reinterpret_cast<section*>(lc+sizeof(segment_command));
680 for (const Section *section : segInfo.sections) {
681 setString16(section->sectionName, sect->sectname);
682 setString16(section->segmentName, sect->segname);
683 sect->addr = section->address;
684 sect->size = section->content.size();
685 sect->offset = section->address - seg.address + segInfo.fileOffset;
686 sect->align = section->alignment;
687 sect->reloff = 0;
688 sect->nreloc = 0;
689 sect->flags = section->type | section->attributes;
690 sect->reserved1 = indirectSymbolIndex(*section, indirectSymRunningIndex);
691 sect->reserved2 = indirectSymbolElementSize(*section);
692 if (_swap)
693 swapStruct(*sect);
694 ++sect;
695 }
696 lc = reinterpret_cast<uint8_t*>(next);
697 }
698 return error_code::success();
699}
700
701
702error_code MachOFileLayout::writeLoadCommands() {
703 error_code ec;
704 uint8_t *lc = &_buffer[_startOfLoadCommands];
705 if (_file.fileType == llvm::MachO::MH_OBJECT) {
706 // Object files have one unnamed segment which holds all sections.
707 if (_is64)
708 ec = writeSingleSegment64LoadCommand(lc);
709 else
710 ec = writeSingleSegment32LoadCommand(lc);
711 // Add LC_SYMTAB with symbol table info
712 symtab_command* st = reinterpret_cast<symtab_command*>(lc);
713 st->cmd = LC_SYMTAB;
714 st->cmdsize = sizeof(symtab_command);
715 st->symoff = _startOfSymbols;
716 st->nsyms = _file.localSymbols.size() + _file.globalSymbols.size()
717 + _file.undefinedSymbols.size();
718 st->stroff = _startOfSymbolStrings;
719 st->strsize = _endOfSymbolStrings - _startOfSymbolStrings;
720 if (_swap)
721 swapStruct(*st);
722 } else {
723 // Final linked images have sections under segments.
724 if (_is64)
725 ec = writeSegment64LoadCommands(lc);
726 else
727 ec = writeSegment32LoadCommands(lc);
728
729 // Add LC_DYLD_INFO_ONLY.
730 dyld_info_command* di = reinterpret_cast<dyld_info_command*>(lc);
731 di->cmd = LC_DYLD_INFO_ONLY;
732 di->cmdsize = sizeof(dyld_info_command);
733 di->rebase_off = _rebaseInfo.size() ? _startOfRebaseInfo : 0;
734 di->rebase_size = _rebaseInfo.size();
735 di->bind_off = _bindingInfo.size() ? _startOfBindingInfo : 0;
736 di->bind_size = _bindingInfo.size();
737 di->weak_bind_off = 0;
738 di->weak_bind_size = 0;
739 di->lazy_bind_off = _lazyBindingInfo.size() ? _startOfLazyBindingInfo : 0;
740 di->lazy_bind_size = _lazyBindingInfo.size();
741 di->export_off = 0;
742 di->export_size = 0;
743 if (_swap)
744 swapStruct(*di);
745 lc += sizeof(dyld_info_command);
746
747 // Add LC_SYMTAB with symbol table info.
748 symtab_command* st = reinterpret_cast<symtab_command*>(lc);
749 st->cmd = LC_SYMTAB;
750 st->cmdsize = sizeof(symtab_command);
751 st->symoff = _startOfSymbols;
752 st->nsyms = _file.localSymbols.size() + _file.globalSymbols.size()
753 + _file.undefinedSymbols.size();
754 st->stroff = _startOfSymbolStrings;
755 st->strsize = _endOfSymbolStrings - _startOfSymbolStrings;
756 if (_swap)
757 swapStruct(*st);
758 lc += sizeof(symtab_command);
759
760 // Add LC_DYSYMTAB
761 if (_file.fileType != llvm::MachO::MH_PRELOAD) {
762 dysymtab_command* dst = reinterpret_cast<dysymtab_command*>(lc);
763 dst->cmd = LC_DYSYMTAB;
764 dst->cmdsize = sizeof(dysymtab_command);
765 dst->ilocalsym = _symbolTableLocalsStartIndex;
766 dst->nlocalsym = _file.localSymbols.size();
767 dst->iextdefsym = _symbolTableGlobalsStartIndex;
768 dst->nextdefsym = _file.globalSymbols.size();
769 dst->iundefsym = _symbolTableUndefinesStartIndex;
770 dst->nundefsym = _file.undefinedSymbols.size();
771 dst->tocoff = 0;
772 dst->ntoc = 0;
773 dst->modtaboff = 0;
774 dst->nmodtab = 0;
775 dst->extrefsymoff = 0;
776 dst->nextrefsyms = 0;
777 dst->indirectsymoff = _startOfIndirectSymbols;
778 dst->nindirectsyms = _indirectSymbolTableCount;
779 dst->extreloff = 0;
780 dst->nextrel = 0;
781 dst->locreloff = 0;
782 dst->nlocrel = 0;
783 if (_swap)
784 swapStruct(*dst);
785 lc += sizeof(dysymtab_command);
786 }
787
788 // If main executable, add LC_LOAD_DYLINKER and LC_MAIN.
789 if (_file.fileType == llvm::MachO::MH_EXECUTE) {
790 // Build LC_LOAD_DYLINKER load command.
791 uint32_t size=pointerAlign(sizeof(dylinker_command)+dyldPath().size()+1);
792 dylinker_command* dl = reinterpret_cast<dylinker_command*>(lc);
793 dl->cmd = LC_LOAD_DYLINKER;
794 dl->cmdsize = size;
795 dl->name = sizeof(dylinker_command); // offset
796 if (_swap)
797 swapStruct(*dl);
798 memcpy(lc+sizeof(dylinker_command), dyldPath().data(), dyldPath().size());
799 lc[sizeof(dylinker_command)+dyldPath().size()] = '\0';
800 lc += size;
801 // Build LC_MAIN load command.
802 entry_point_command* ep = reinterpret_cast<entry_point_command*>(lc);
803 ep->cmd = LC_MAIN;
804 ep->cmdsize = sizeof(entry_point_command);
805 ep->entryoff = _file.entryAddress - _seg1addr;
806 ep->stacksize = 0;
807 if (_swap)
808 swapStruct(*ep);
809 lc += sizeof(entry_point_command);
810 }
811
812 // Add LC_LOAD_DYLIB commands
813 for (const DependentDylib &dep : _file.dependentDylibs) {
814 dylib_command* dc = reinterpret_cast<dylib_command*>(lc);
815 uint32_t size = sizeof(dylib_command) + pointerAlign(dep.path.size()+1);
816 dc->cmd = LC_LOAD_DYLIB;
817 dc->cmdsize = size;
818 dc->dylib.name = sizeof(dylib_command); // offset
819 dc->dylib.timestamp = 0; // FIXME
820 dc->dylib.current_version = 0; // FIXME
821 dc->dylib.compatibility_version = 0; // FIXME
822 if (_swap)
823 swapStruct(*dc);
824 memcpy(lc+sizeof(dylib_command), dep.path.begin(), dep.path.size());
825 lc[sizeof(dylib_command)+dep.path.size()] = '\0';
826 lc += size;
827 }
828
829 }
830 return ec;
831}
832
833
834void MachOFileLayout::writeSectionContent() {
835 for (const Section &s : _file.sections) {
836 // Copy all section content to output buffer.
837 uint32_t offset = _sectInfo[&s].fileOffset;
838 uint8_t *p = &_buffer[offset];
839 memcpy(p, &s.content[0], s.content.size());
840 p += s.content.size();
841 }
842}
843
844void MachOFileLayout::writeRelocations() {
845 uint32_t relOffset = _startOfRelocations;
846 for (Section sect : _file.sections) {
847 for (Relocation r : sect.relocations) {
848 any_relocation_info* rb = reinterpret_cast<any_relocation_info*>(
849 &_buffer[relOffset]);
850 *rb = packRelocation(r, _swap, _bigEndianArch);
851 relOffset += sizeof(any_relocation_info);
852 }
853 }
854}
855
856
857void MachOFileLayout::appendSymbols(const std::vector<Symbol> &symbols,
858 uint32_t &symOffset, uint32_t &strOffset) {
859 for (const Symbol &sym : symbols) {
860 if (_is64) {
861 nlist_64* nb = reinterpret_cast<nlist_64*>(&_buffer[symOffset]);
862 nb->n_strx = strOffset - _startOfSymbolStrings;
863 nb->n_type = sym.type | sym.scope;
864 nb->n_sect = sym.sect;
865 nb->n_desc = sym.desc;
866 nb->n_value = sym.value;
867 if (_swap)
868 swapStruct(*nb);
869 symOffset += sizeof(nlist_64);
870 } else {
871 nlist* nb = reinterpret_cast<nlist*>(&_buffer[symOffset]);
872 nb->n_strx = strOffset - _startOfSymbolStrings;
873 nb->n_type = sym.type | sym.scope;
874 nb->n_sect = sym.sect;
875 nb->n_desc = sym.desc;
876 nb->n_value = sym.value;
877 if (_swap)
878 swapStruct(*nb);
879 symOffset += sizeof(nlist);
880 }
881 memcpy(&_buffer[strOffset], sym.name.begin(), sym.name.size());
882 strOffset += sym.name.size();
883 _buffer[strOffset++] ='\0'; // Strings in table have nul terminator.
884 }
885}
886
887void MachOFileLayout::writeSymbolTable() {
888 // Write symbol table and symbol strings in parallel.
889 uint32_t symOffset = _startOfSymbols;
890 uint32_t strOffset = _startOfSymbolStrings;
891 _buffer[strOffset++] = '\0'; // Reserve n_strx offset of zero to mean no name.
892 appendSymbols(_file.localSymbols, symOffset, strOffset);
893 appendSymbols(_file.globalSymbols, symOffset, strOffset);
894 appendSymbols(_file.undefinedSymbols, symOffset, strOffset);
895 // Write indirect symbol table array.
896 uint32_t *indirects = reinterpret_cast<uint32_t*>
897 (&_buffer[_startOfIndirectSymbols]);
898 if (_file.fileType == llvm::MachO::MH_OBJECT) {
899 // Object files have sections in same order as input normalized file.
900 for (const Section &section : _file.sections) {
901 for (uint32_t index : section.indirectSymbols) {
902 if (_swap)
903 *indirects++ = SwapByteOrder(index);
904 else
905 *indirects++ = index;
906 }
907 }
908 } else {
909 // Final linked images must sort sections from normalized file.
910 for (const Segment &seg : _file.segments) {
911 SegExtraInfo &segInfo = _segInfo[&seg];
912 for (const Section *section : segInfo.sections) {
913 for (uint32_t index : section->indirectSymbols) {
914 if (_swap)
915 *indirects++ = SwapByteOrder(index);
916 else
917 *indirects++ = index;
918 }
919 }
920 }
921 }
922}
923
924void MachOFileLayout::writeRebaseInfo() {
925 memcpy(&_buffer[_startOfRebaseInfo], _rebaseInfo.bytes(), _rebaseInfo.size());
926}
927
928void MachOFileLayout::writeBindingInfo() {
929 memcpy(&_buffer[_startOfBindingInfo],
930 _bindingInfo.bytes(), _bindingInfo.size());
931}
932
933void MachOFileLayout::writeLazyBindingInfo() {
934 memcpy(&_buffer[_startOfLazyBindingInfo],
935 _lazyBindingInfo.bytes(), _lazyBindingInfo.size());
936}
937
938void MachOFileLayout::buildLinkEditInfo() {
939 buildRebaseInfo();
940 buildBindInfo();
941 buildLazyBindInfo();
942 computeSymbolTableSizes();
943}
944
945void MachOFileLayout::buildSectionRelocations() {
946
947}
948
949void MachOFileLayout::buildRebaseInfo() {
950 // TODO: compress rebasing info.
951 for (const RebaseLocation& entry : _file.rebasingInfo) {
952 _rebaseInfo.append_byte(REBASE_OPCODE_SET_TYPE_IMM | entry.kind);
953 _rebaseInfo.append_byte(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
954 | entry.segIndex);
955 _rebaseInfo.append_uleb128(entry.segOffset);
956 _rebaseInfo.append_uleb128(REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1);
957 }
958 _rebaseInfo.append_byte(REBASE_OPCODE_DONE);
959 _rebaseInfo.align(_is64 ? 8 : 4);
960}
961
962void MachOFileLayout::buildBindInfo() {
963 // TODO: compress bind info.
964 for (const BindLocation& entry : _file.bindingInfo) {
965 _bindingInfo.append_byte(BIND_OPCODE_SET_TYPE_IMM | entry.kind);
966 _bindingInfo.append_byte(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
967 | entry.segIndex);
968 _bindingInfo.append_uleb128(entry.segOffset);
969 _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | entry.ordinal);
970 _bindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
971 _bindingInfo.append_string(entry.symbolName);
972 if (entry.addend != 0) {
973 _bindingInfo.append_byte(BIND_OPCODE_SET_ADDEND_SLEB);
974 _bindingInfo.append_sleb128(entry.addend);
975 }
976 _bindingInfo.append_byte(BIND_OPCODE_DO_BIND);
977 }
978 _bindingInfo.append_byte(BIND_OPCODE_DONE);
979 _bindingInfo.align(_is64 ? 8 : 4);
980}
981
982void MachOFileLayout::buildLazyBindInfo() {
983 for (const BindLocation& entry : _file.lazyBindingInfo) {
984 _lazyBindingInfo.append_byte(BIND_OPCODE_SET_TYPE_IMM | entry.kind);
985 _lazyBindingInfo.append_byte(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
986 | entry.segIndex);
987 _lazyBindingInfo.append_uleb128(entry.segOffset);
988 _lazyBindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | entry.ordinal);
989 _lazyBindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
990 _lazyBindingInfo.append_string(entry.symbolName);
991 _lazyBindingInfo.append_byte(BIND_OPCODE_DO_BIND);
992 }
993 _lazyBindingInfo.append_byte(BIND_OPCODE_DONE);
994 _lazyBindingInfo.align(_is64 ? 8 : 4);
995}
996
997void MachOFileLayout::computeSymbolTableSizes() {
998 // MachO symbol tables have three ranges: locals, globals, and undefines
999 const size_t nlistSize = (_is64 ? sizeof(nlist_64) : sizeof(nlist));
1000 _symbolTableSize = nlistSize * (_file.localSymbols.size()
1001 + _file.globalSymbols.size()
1002 + _file.undefinedSymbols.size());
1003 _symbolStringPoolSize = 0;
1004 for (const Symbol &sym : _file.localSymbols) {
1005 _symbolStringPoolSize += (sym.name.size()+1);
1006 }
1007 for (const Symbol &sym : _file.globalSymbols) {
1008 _symbolStringPoolSize += (sym.name.size()+1);
1009 }
1010 for (const Symbol &sym : _file.undefinedSymbols) {
1011 _symbolStringPoolSize += (sym.name.size()+1);
1012 }
1013 _symbolTableLocalsStartIndex = 0;
1014 _symbolTableGlobalsStartIndex = _file.localSymbols.size();
1015 _symbolTableUndefinesStartIndex = _symbolTableGlobalsStartIndex
1016 + _file.globalSymbols.size();
1017
1018 _indirectSymbolTableCount = 0;
1019 for (const Section &sect : _file.sections) {
1020 _indirectSymbolTableCount += sect.indirectSymbols.size();
1021 }
1022}
1023
1024
1025void MachOFileLayout::writeLinkEditContent() {
1026 if (_file.fileType == llvm::MachO::MH_OBJECT) {
1027 writeRelocations();
1028 writeSymbolTable();
1029 } else {
1030 writeRebaseInfo();
1031 writeBindingInfo();
1032 writeLazyBindingInfo();
1033 // TODO: add weak binding info
1034 writeSymbolTable();
1035 }
1036}
1037
1038
1039error_code MachOFileLayout::writeBinary(StringRef path) {
1040 // Check for pending error from constructor.
1041 if (_ec)
1042 return _ec;
1043 // Create FileOutputBuffer with calculated size.
1044 OwningPtr<llvm::FileOutputBuffer> fob;
1045 unsigned flags = 0;
1046 if (_file.fileType != llvm::MachO::MH_OBJECT)
1047 flags = llvm::FileOutputBuffer::F_executable;
1048 error_code ec;
1049 ec = llvm::FileOutputBuffer::create(path, size(), fob, flags);
1050 if (ec)
1051 return ec;
1052
1053 // Write content.
1054 _buffer = fob->getBufferStart();
1055 writeMachHeader();
1056 ec = writeLoadCommands();
1057 if (ec)
1058 return ec;
1059 writeSectionContent();
1060 writeLinkEditContent();
1061 fob->commit();
1062
1063 return error_code::success();
1064}
1065
1066
1067
1068/// Takes in-memory normalized view and writes a mach-o object file.
1069error_code
1070writeBinary(const NormalizedFile &file, StringRef path) {
1071 MachOFileLayout layout(file);
1072 return layout.writeBinary(path);
1073}
1074
1075
1076} // namespace normalized
1077} // namespace mach_o
1078} // namespace lld
1079