Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /* * Copyright (c) 2017-2021 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #ifndef mach_o_writer_Header_h #define mach_o_writer_Header_h #include "Header.h" #include <vector> namespace mach_o { using namespace mach_o; /*! * @class HeaderWriter * * @abstract * The HeaderWriter constructor can be used to build a mach-o file dynamically for unit tests */ struct VIS_HIDDEN HeaderWriter : public Header { HeaderWriter() = delete; // we never allocate a HeaderWriter directly, always getting one from casting a buffer // for building static HeaderWriter* make(std::span<uint8_t> buffer, uint32_t filetype, uint32_t flags, Architecture, bool addImplicitTextSegment=true); void save(char savedPath[PATH_MAX]) const; load_command* findLoadCommand(uint32_t cmd); void setHasThreadLocalVariables(); void setHasWeakDefs(); void setUsesWeakDefs(); void setAppExtensionSafe(); void setSimSupport(); void setNoReExportedDylibs(); void setNoDynamicAccess(); void addPlatformInfo(Platform, Version32 minOS, Version32 sdk, std::span<const build_tool_version> tools={}); void addUniqueUUID(uuid_t copyOfUUID=nullptr); void addNullUUID(); void updateUUID(uuid_t); void addInstallName(const char* path, Version32 compatVers, Version32 currentVersion); void addLinkedDylib(const char* path, LinkedDylibAttributes kind=LinkedDylibAttributes::regular, Version32 compatVers=Version32(1,0), Version32 currentVersion=Version32(1,0)); void setLinkedDylib(load_command* cmd, const char* path, LinkedDylibAttributes kind, Version32 compatVers, Version32 currentVersion); void addLibSystem(); void addDylibId(CString name, Version32 compatVers, Version32 currentVersion); void addDyldID(); void addDynamicLinker(); void addRPath(const char* path); void setTargetTriple(const char* triple); void addSourceVersion(Version64 srcVers); void addDyldEnvVar(const char* envVar); void addAllowableClient(const char* clientName); void addUmbrellaName(const char* umbrellaName); void addFairPlayEncrypted(uint32_t offset, uint32_t size); void addCodeSignature(uint32_t fileOffset, uint32_t fileSize); void addSegment(std::string_view segName, uint64_t vmaddr, uint64_t vmsize, uint32_t perms, uint32_t sectionCount); void setMain(uint32_t offset); void setCustomStackSize(uint64_t stackSize); void setUnixEntry(uint64_t addr, bool entryIsThumb=false, uint64_t sp=0); void setSymbolTable(uint32_t nlistOffset, uint32_t nlistCount, uint32_t stringPoolOffset, uint32_t stringPoolSize, uint32_t localsCount, uint32_t globalsCount, uint32_t undefCount, uint32_t indOffset, uint32_t indCount, bool dynSymtab, uint32_t locrelOffset, uint32_t locrelCount, uint32_t extrelOffset, uint32_t extrelCount); void setBindOpcodesInfo(uint32_t rebaseOffset, uint32_t rebaseSize, uint32_t bindsOffset, uint32_t bindsSize, uint32_t weakBindsOffset, uint32_t weakBindsSize, uint32_t lazyBindsOffset, uint32_t lazyBindsSize, uint32_t exportTrieOffset, uint32_t exportTrieSize); void setChainedFixupsInfo(uint32_t cfOffset, uint32_t cfSize); void setExportTrieInfo(uint32_t offset, uint32_t size); void setSplitSegInfo(uint32_t offset, uint32_t size); void setDataInCode(uint32_t offset, uint32_t size); void setFunctionStarts(uint32_t offset, uint32_t size); void setFunctionVariants(uint32_t offset, uint32_t size); void setFunctionVariantFixups(uint32_t offset, uint32_t size); void addLinkerOption(std::span<uint8_t> buffer, uint32_t count); void setAtomInfo(uint32_t offset, uint32_t size); void setLinkerOptimizationHints(uint32_t offset, uint32_t size); void updateRelocatableSegmentSize(uint64_t vmSize, uint32_t fileSize); void setRelocatableSectionCount(uint32_t sectionCount); void setRelocatableSectionInfo(uint32_t sectionIndex, const char* segName, const char* sectName, uint32_t flags, uint64_t address, uint64_t size, uint32_t fileOffset, uint16_t alignment, uint32_t relocsOffset, uint32_t relocsCount); void addSegment(const SegmentInfo&, std::span<const char* const> sectionNames=std::span<const char* const>{}); void updateSegment(const SegmentInfo& info); void updateSection(const SectionInfo& info); Error removeLoadCommands(uint32_t index, uint32_t endIndex); // returns nullptr if there's not enough padding space available load_command* insertLoadCommand(uint32_t atIndex, uint32_t cmdSize); struct LinkerOption { std::vector<uint8_t> buffer; uint32_t count = 0; uint32_t lcSize() const { return ((uint32_t)buffer.size() + sizeof(linker_option_command) + 7) & (-8); } static LinkerOption make(std::span<CString>); }; static uint32_t relocatableHeaderAndLoadCommandsSize(bool is64, uint32_t sectionCount, uint32_t platformsCount, std::span<const LinkerOption> linkerOptions); using Header::findLoadCommand; private: void removeLoadCommand(void (^callback)(const load_command* cmd, bool& remove, bool& stop)); load_command* firstLoadCommand(); load_command* appendLoadCommand(uint32_t cmd, uint32_t cmdSize); void appendLoadCommand(const load_command* lc); void addBuildVersion(Platform, Version32 minOS, Version32 sdk, std::span<const build_tool_version> tools); void addMinVersion(Platform, Version32 minOS, Version32 sdk); }; } // namespace mach_o #endif /* mach_o_writer_Header_h */ |