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