| 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 = llvm::alignTo<8>( |
| 37 | Value: 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 = |
| 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 ; |
| 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: |
| 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 | |
| 88 | StringTableBuilder &getStringTableBuilder() { return StrTableBuilder; } |
| 89 | |
| 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 | |