1 //===- MachOLayoutBuilder.h -------------------------------------*- C++ -*-===//
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 #ifndef LLVM_LIB_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H
10 #define LLVM_LIB_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H
11 
12 #include "MachOObject.h"
13 #include "llvm/ObjCopy/MachO/MachOObjcopy.h"
14 
15 namespace llvm {
16 namespace objcopy {
17 namespace macho {
18 
19 /// When MachO binaries include a LC_CODE_SIGNATURE load command,
20 /// the __LINKEDIT data segment will include a section corresponding
21 /// to the LC_CODE_SIGNATURE load command. This section serves as a signature
22 /// for the binary. Included in the CodeSignature section is a header followed
23 /// by a hash of the binary. If present, the CodeSignature section is the
24 /// last component of the binary.
25 struct CodeSignatureInfo {
26   // NOTE: These values are to be kept in sync with those in
27   // LLD's CodeSignatureSection class.
28 
29   static constexpr uint32_t Align = 16;
30   static constexpr uint8_t BlockSizeShift = 12;
31   // The binary is read in blocks of the following size.
32   static constexpr size_t BlockSize = (1 << BlockSizeShift); // 4 KiB
33   // For each block, a SHA256 hash (256 bits, 32 bytes) is written to
34   // the CodeSignature section.
35   static constexpr size_t HashSize = 256 / 8;
36   static constexpr size_t BlobHeadersSize = llvm::alignTo<8>(
37       sizeof(llvm::MachO::CS_SuperBlob) + sizeof(llvm::MachO::CS_BlobIndex));
38   // The size of the entire header depends upon the filename the binary is being
39   // written to, but the rest of the header is fixed in size.
40   static constexpr uint32_t FixedHeadersSize =
41       BlobHeadersSize + sizeof(llvm::MachO::CS_CodeDirectory);
42 
43   // The offset relative to the start of the binary where
44   // the CodeSignature section should begin.
45   uint32_t StartOffset;
46   // The size of the entire header, output file name size included.
47   uint32_t AllHeadersSize;
48   // The number of blocks required to hash the binary.
49   uint32_t BlockCount;
50   StringRef OutputFileName;
51   // The size of the entire CodeSignature section, including both the header and
52   // hashes.
53   uint32_t Size;
54 };
55 
56 class MachOLayoutBuilder {
57   Object &O;
58   bool Is64Bit;
59   StringRef OutputFileName;
60   uint64_t PageSize;
61   CodeSignatureInfo CodeSignature;
62 
63   // Points to the __LINKEDIT segment if it exists.
64   MachO::macho_load_command *LinkEditLoadCommand = nullptr;
65   StringTableBuilder StrTableBuilder;
66 
67   uint32_t computeSizeOfCmds() const;
68   void constructStringTable();
69   void updateSymbolIndexes();
70   void updateDySymTab(MachO::macho_load_command &MLC);
71   uint64_t layoutSegments();
72   uint64_t layoutRelocations(uint64_t Offset);
73   Error layoutTail(uint64_t Offset);
74 
75   static StringTableBuilder::Kind getStringTableBuilderKind(const Object &O,
76                                                             bool Is64Bit);
77 
78 public:
MachOLayoutBuilder(Object & O,bool Is64Bit,StringRef OutputFileName,uint64_t PageSize)79   MachOLayoutBuilder(Object &O, bool Is64Bit, StringRef OutputFileName,
80                      uint64_t PageSize)
81       : O(O), Is64Bit(Is64Bit), OutputFileName(OutputFileName),
82         PageSize(PageSize),
83         StrTableBuilder(getStringTableBuilderKind(O, Is64Bit)) {}
84 
85   // Recomputes and updates fields in the given object such as file offsets.
86   Error layout();
87 
getStringTableBuilder()88   StringTableBuilder &getStringTableBuilder() { return StrTableBuilder; }
89 
getCodeSignature()90   const CodeSignatureInfo &getCodeSignature() const { return CodeSignature; }
91 };
92 
93 } // end namespace macho
94 } // end namespace objcopy
95 } // end namespace llvm
96 
97 #endif // LLVM_LIB_OBJCOPY_MACHO_MACHOLAYOUTBUILDER_H
98