Loading...
common/MachOFile.h dyld-1340 /dev/null
--- dyld/dyld-1340/common/MachOFile.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (c) 2017 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 MachOFile_h
-#define MachOFile_h
-
-#include <mach-o/loader.h>
-#include <mach-o/fat.h>
-#include <uuid/uuid.h>
-
-#include <array>
-#include <optional>
-#include <string_view>
-
-#include "Defines.h"
-#include "GradedArchitectures.h"
-#include "Header.h"
-#include "UUID.h"
-#include "Diagnostics.h"
-#include "MachOLayout.h"
-#include "Platform.h"
-#include "SupportedArchs.h"
-#include <mach-o/fixup-chains.h>
-#include <mach-o/loader.h>
-
-// needed until dyld builds with a newer SDK
-#ifndef CPU_SUBTYPE_ARM64E
-  #define CPU_SUBTYPE_ARM64E 2
-#endif
-#ifndef CPU_TYPE_ARM64_32
-  #define CPU_TYPE_ARM64_32 0x0200000C
-#endif
-#ifndef CPU_SUBTYPE_ARM64_32_V8
-  #define CPU_SUBTYPE_ARM64_32_V8 1
-#endif
-#ifndef BIND_OPCODE_THREADED
-    #define BIND_OPCODE_THREADED    0xD0
-#endif
-#ifndef BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB
-    #define BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB    0x00
-#endif
-#ifndef BIND_SUBOPCODE_THREADED_APPLY
-    #define BIND_SUBOPCODE_THREADED_APPLY                               0x01
-#endif
-#ifndef BIND_SPECIAL_DYLIB_WEAK_LOOKUP
-  #define BIND_SPECIAL_DYLIB_WEAK_LOOKUP                (-3)
-#endif
-#ifndef EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
-  #define EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE             0x02
-#endif
-#ifndef SG_READ_ONLY
-  #define SG_READ_ONLY            0x10
-#endif
-
-#ifndef LC_DYLD_EXPORTS_TRIE
-  #define LC_DYLD_EXPORTS_TRIE    0x80000033
-#endif
-#ifndef LC_DYLD_CHAINED_FIXUPS
-  #define LC_DYLD_CHAINED_FIXUPS  0x80000034
-#endif
-
-#ifndef S_INIT_FUNC_OFFSETS
-  #define S_INIT_FUNC_OFFSETS       0x16
-#endif
-
-#ifndef MH_FILESET
-    #define MH_FILESET              0xc     /* set of mach-o's */
-#endif
-
-namespace objc_visitor {
-struct Visitor;
-}
-
-namespace dyld3 {
-
-using lsl::UUID;
-
-// replacements for posix that handle EINTR
-int	stat(const char* path, struct stat* buf) VIS_HIDDEN;
-int	open(const char* path, int flag, int other) VIS_HIDDEN;
-int fstatat(int fd, const char *path, struct stat *buf, int flag) VIS_HIDDEN;
-
-
-/// Returns true if (addLHS + addRHS) > b, or if the add overflowed
-template<typename T>
-VIS_HIDDEN inline bool greaterThanAddOrOverflow(uint32_t addLHS, uint32_t addRHS, T b) {
-    return (addLHS > b) || (addRHS > (b-addLHS));
-}
-
-/// Returns true if (addLHS + addRHS) > b, or if the add overflowed
-template<typename T>
-VIS_HIDDEN inline bool greaterThanAddOrOverflow(uint64_t addLHS, uint64_t addRHS, T b) {
-    return (addLHS > b) || (addRHS > (b-addLHS));
-}
-
-
-// A file read/mapped into memory
-struct VIS_HIDDEN FatFile : fat_header
-{
-    static const FatFile*  isFatFile(const void* fileContent);
-    void                   forEachSlice(Diagnostics& diag, uint64_t fileLen, void (^callback)(uint32_t sliceCpuType, uint32_t sliceCpuSubType, const void* sliceStart, uint64_t sliceSize, bool& stop)) const;
-    const char*            archNames(char strBuf[256], uint64_t fileLen) const;
-private:
-    bool                   isValidSlice(Diagnostics& diag, uint64_t fileLen, uint32_t sliceIndex,
-                                        uint32_t sliceCpuType, uint32_t sliceCpuSubType, uint64_t sliceOffset, uint64_t sliceLen) const;
-    void                   forEachSlice(Diagnostics& diag, uint64_t fileLen, bool validate,
-                                        void (^callback)(uint32_t sliceCpuType, uint32_t sliceCpuSubType, const void* sliceStart, uint64_t sliceSize, bool& stop)) const;
-};
-
-
-// A mach-o file read/mapped into memory
-// Only info from mach_header or load commands is accessible (no LINKEDIT info)
-struct VIS_HIDDEN MachOFile : mach_header
-{
-    typedef mach_o::ChainedFixupPointerOnDisk ChainedFixupPointerOnDisk;
-
-    static uint64_t         read_uleb128(Diagnostics& diag, const uint8_t*& p, const uint8_t* end);
-    static int64_t          read_sleb128(Diagnostics& diag, const uint8_t*& p, const uint8_t* end);
-    static const MachOFile* compatibleSlice(Diagnostics& diag, uint64_t& sliceOffsetOut, uint64_t& sliceLenOut, const void* content, size_t size, const char* path, mach_o::Platform platform, bool isOSBinary, const mach_o::GradedArchitectures&, bool internalInstall=false);
-    static const MachOFile* isMachO(const void* content);
-
-    bool            hasMachOMagic() const;
-    bool            isMachO(Diagnostics& diag, uint64_t fileSize) const;
-    bool            isDyldManaged() const;
-    bool            isDylib() const;
-    bool            isBundle() const;
-    bool            isMainExecutable() const;
-    bool            isDynamicExecutable() const;
-    bool            isStaticExecutable() const;
-    bool            isKextBundle() const;
-    bool            isFileSet() const;
-    bool            isPreload() const;
-    bool            isDyld() const;
-    bool            isPIE() const;
-    bool            isArch(const char* archName) const;
-    const char*     archName() const;
-    bool            is64() const;
-    uint32_t        maskedCpuSubtype() const;
-    size_t          machHeaderSize() const;
-    uint32_t        pointerSize() const;
-    bool            uses16KPages() const;
-    bool            inDyldCache() const;
-    bool            hasWeakDefs() const;
-    bool            usesWeakDefs() const;
-    void            forEachDependentDylib(void (^callback)(const char* loadPath, bool isWeak, bool isReExport, bool isUpward, uint32_t compatVersion, uint32_t curVersion, bool& stop)) const;
-#if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS || BUILDING_UNIT_TESTS || BUILDING_DYLD_SYMBOLS_CACHE
-    bool            addendsExceedPatchTableLimit(Diagnostics& diag, mach_o::Fixups fixups) const;
-    bool            canBePlacedInDyldCache(const char* path, bool checkObjC, void (^failureReason)(const char* format, ...)) const;
-    bool            canHavePrebuiltExecutableLoader(mach_o::Platform platform, const std::string_view& path,
-                                                    void (^failureReason)(const char*)) const;
-#endif
-
-#if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
-    // Note this is only for binaries in file layout, so can only be used by the cache builder
-    objc_visitor::Visitor makeObjCVisitor(Diagnostics& diag) const;
-#endif
-
-#if BUILDING_APP_CACHE_UTIL
-    bool            canBePlacedInKernelCollection(const char* path, void (^failureReason)(const char*)) const;
-#endif
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
-    bool            usesClassicRelocationsInKernelCollection() const;
-#endif
-    bool            hasChainedFixups() const;
-    bool            hasChainedFixupsLoadCommand() const;
-    bool            hasOpcodeFixups() const;
-    void            removeLoadCommand(Diagnostics& diag, void (^callback)(const load_command* cmd, bool& remove, bool& stop));
-    bool            hasSection(const char* segName, const char* sectName) const;
-    bool            inCodeSection(uint32_t runtimeOffset) const;
-    uint32_t        dependentDylibCount(bool* allDepsAreNormal = nullptr) const;
-    uint32_t        getFixupsLoadCommandFileOffset() const;
-    bool            hasInitializer(Diagnostics& diag) const;
-    void            forEachInitializerPointerSection(Diagnostics& diag, void (^callback)(uint32_t sectionOffset, uint32_t sectionSize, bool& stop)) const;
-    bool            hasObjC() const;
-    bool            hasConstObjCSection() const;
-    uint64_t        mappedSize() const;
-    void            forEachDOFSection(Diagnostics& diag, void (^callback)(uint32_t offset)) const;
-    enum class Malformed { linkeditOrder, linkeditAlignment, linkeditPermissions, dyldInfoAndlocalRelocs, segmentOrder,
-                            textPermissions, executableData, writableData, codeSigAlignment, sectionsAddrRangeWithinSegment,
-                            noLinkedDylibs, loaderPathsAreReal, mainExecInDyldCache, noUUID, zerofillSwiftMetadata, sdkOnOrAfter2021, sdkOnOrAfter2022 };
-    bool            enforceFormat(Malformed) const;
-
-    bool            validSegments(Diagnostics& diag, const char* path, size_t fileLen) const;
-
-    // used at runtime to validate loaded image matches closure
-    void            forEachCDHashOfCodeSignature(const void* codeSigStart, size_t codeSignLen,
-                                                 void (^callback)(const uint8_t cdHash[20])) const;
-
-    static void     forEachTreatAsWeakDef(void (^handler)(const char* symbolName));
-
-    // used by closure builder to find the offset and size of the trie.
-    bool            hasExportTrie(uint32_t& runtimeOffset, uint32_t& size) const;
-
-    uint32_t                        entryAddrRegisterIndexForThreadCmd() const;
-    bool                            use64BitEntryRegs() const;
-    uint64_t                        entryAddrFromThreadCmd(const thread_command* cmd) const;
-
-    // used by DyldSharedCache to find closure
-    static const uint8_t*   trieWalk(Diagnostics& diag, const uint8_t* start, const uint8_t* end, const char* symbol);
-
-#if !SUPPORT_VM_LAYOUT || BUILDING_UNIT_TESTS || BUILDING_DYLD_SYMBOLS_CACHE
-    // Get the layout information for this MachOFile.  Requires that the file is in file layout, not VM layout.
-    // If you have a MachOLoaded/MachOAnalyzer, do not use this method
-    bool                    getLinkeditLayout(Diagnostics& diag, mach_o::LinkeditLayout& layout) const;
-    void                    withFileLayout(Diagnostics &diag, void (^callback)(const mach_o::Layout& layout)) const;
-#endif
-
-    void            forEachLoadCommand(Diagnostics& diag, void (^callback)(const load_command* cmd, bool& stop)) const;
-
-    struct PointerMetaData
-    {
-                    PointerMetaData();
-                    PointerMetaData(const ChainedFixupPointerOnDisk* fixupLoc, uint16_t pointer_format);
-
-        bool        operator==(const PointerMetaData& other) const;
-
-        uint32_t    diversity         : 16,
-                    high8             :  8,
-                    authenticated     :  1,
-                    key               :  2,
-                    usesAddrDiversity :  1,
-                    padding           :  4 = 0;
-    };
-
-    static uint16_t chainedPointerFormat(const dyld_chained_fixups_header* chainHeader);
-    static void     withChainStarts(Diagnostics& diag, const dyld_chained_fixups_header* chainHeader, void (^callback)(const dyld_chained_starts_in_image*));
-
-    static void     forEachFixupChainSegment(Diagnostics& diag, const dyld_chained_starts_in_image* starts,
-                                             void (^handler)(const dyld_chained_starts_in_segment* segInfo, uint32_t segIndex, bool& stop));
-    static void     forEachFixupInSegmentChains(Diagnostics& diag, const dyld_chained_starts_in_segment* segInfo,
-                                                bool notifyNonPointers, uint8_t* segmentContent,
-                                                void (^handler)(ChainedFixupPointerOnDisk* fixupLocation, bool& stop));
-    static bool     walkChain(Diagnostics& diag, ChainedFixupPointerOnDisk* start, uint16_t pointer_format,
-                              bool notifyNonPointers, uint32_t max_valid_pointer,
-                              void (^handler)(ChainedFixupPointerOnDisk* fixupLocation, bool& stop));
-    static void     forEachChainedFixupTarget(Diagnostics& diag, const dyld_chained_fixups_header* chainHeader, const linkedit_data_command* chainedFixups,
-                                              void (^callback)(int libOrdinal, const char* symbolName, uint64_t addend, bool weakImport, bool& stop));
-
-protected:
-    bool            hasMachOBigEndianMagic() const;
-    bool            hasLoadCommand(uint32_t) const;
-
-    void    analyzeSegmentsLayout(uint64_t& vmSpace, bool& hasZeroFill) const;
-
-    // This calls the callback for all code directories required for a given platform/binary combination.
-    // On watchOS main executables this is all cd hashes.
-    // On watchOS dylibs this is only the single cd hash we need (by rank defined by dyld, not the kernel).
-    // On all other platforms this always returns a single best cd hash (ranked to match the kernel).
-    // Note the callback parameter is really a CS_CodeDirectory.
-    void    forEachCodeDirectoryBlob(const void* codeSigStart, size_t codeSignLen, void (^callback)(const void* cd)) const;
-    void    forEachSection(void (^callback)(const mach_o::Header::SectionInfo&, bool& stop)) const;
-    void    forEachSection(void (^callback)(const mach_o::Header::SegmentInfo&, const mach_o::Header::SectionInfo&, bool& stop)) const;
-};
-
-
-} // namespace dyld3
-
-#endif /* MachOFile_h */