From 2f7e082381e64bbcdd06cf8f06eb84a9c8ad67de Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Thu, 2 Jul 2026 21:52:24 +0100 Subject: [PATCH] libc: Add missing macOS mach-o headers --- .../include/any-darwin-any/mach-o/arm/reloc.h | 67 ++++ .../any-darwin-any/mach-o/dyld_images.h | 224 ++++++++++++ .../any-darwin-any/mach-o/fixup-chains.h | 334 ++++++++++++++++++ .../include/any-darwin-any/mach-o/ldsyms.h | 133 +++++++ lib/libc/include/any-darwin-any/mach-o/swap.h | 284 +++++++++++++++ .../include/any-darwin-any/mach-o/utils.h | 242 +++++++++++++ tools/macos-headers.c | 34 +- 7 files changed, 1305 insertions(+), 13 deletions(-) create mode 100644 lib/libc/include/any-darwin-any/mach-o/arm/reloc.h create mode 100644 lib/libc/include/any-darwin-any/mach-o/dyld_images.h create mode 100644 lib/libc/include/any-darwin-any/mach-o/fixup-chains.h create mode 100644 lib/libc/include/any-darwin-any/mach-o/ldsyms.h create mode 100644 lib/libc/include/any-darwin-any/mach-o/swap.h create mode 100644 lib/libc/include/any-darwin-any/mach-o/utils.h diff --git a/lib/libc/include/any-darwin-any/mach-o/arm/reloc.h b/lib/libc/include/any-darwin-any/mach-o/arm/reloc.h new file mode 100644 index 0000000000000000000000000000000000000000..d8102863352eccceb0a159c0c6bd4616174c265d --- /dev/null +++ b/lib/libc/include/any-darwin-any/mach-o/arm/reloc.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1999 Apple Computer, 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 _MACHO_ARM_RELOC_H_ +#define _MACHO_ARM_RELOC_H_ + +/* + * Relocation types used in the arm implementation. Relocation entries for + * things other than instructions use the same generic relocation as discribed + * in and their r_type is ARM_RELOC_VANILLA, one of the + * *_SECTDIFF or the *_PB_LA_PTR types. The rest of the relocation types are + * for instructions. Since they are for instructions the r_address field + * indicates the 32 bit instruction that the relocation is to be preformed on. + */ + +enum reloc_type_arm +{ + ARM_RELOC_VANILLA, /* generic relocation as discribed above */ + ARM_RELOC_PAIR, /* the second relocation entry of a pair */ + ARM_RELOC_SECTDIFF, /* a PAIR follows with subtract symbol value */ + ARM_RELOC_LOCAL_SECTDIFF, /* like ARM_RELOC_SECTDIFF, but the symbol + referenced was local. */ + ARM_RELOC_PB_LA_PTR,/* prebound lazy pointer */ + ARM_RELOC_BR24, /* 24 bit branch displacement (to a word address) */ + ARM_THUMB_RELOC_BR22, /* 22 bit branch displacement (to a half-word + address) */ + ARM_THUMB_32BIT_BRANCH, /* obsolete - a thumb 32-bit branch instruction + possibly needing page-spanning branch workaround */ + + /* + * For these two r_type relocations they always have a pair following them + * and the r_length bits are used differently. The encoding of the + * r_length is as follows: + * low bit of r_length: + * 0 - :lower16: for movw instructions + * 1 - :upper16: for movt instructions + * high bit of r_length: + * 0 - arm instructions + * 1 - thumb instructions + * the other half of the relocated expression is in the following pair + * relocation entry in the the low 16 bits of r_address field. + */ + ARM_RELOC_HALF, + ARM_RELOC_HALF_SECTDIFF +}; + +#endif /* #ifndef _MACHO_ARM_RELOC_H_ */ diff --git a/lib/libc/include/any-darwin-any/mach-o/dyld_images.h b/lib/libc/include/any-darwin-any/mach-o/dyld_images.h new file mode 100644 index 0000000000000000000000000000000000000000..0e2b7356e5dec3ce9b8afd8e2789a02a2e3b0123 --- /dev/null +++ b/lib/libc/include/any-darwin-any/mach-o/dyld_images.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2006-2010 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 _DYLD_IMAGES_ +#define _DYLD_IMAGES_ + +#include +#include +#include + +#ifndef __OPEN_SOURCE__ +#if !0 +#include +#include +#endif +#endif + +#if defined(__cplusplus) && (BUILDING_LIBDYLD || BUILDING_DYLD) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + + +/* + * Beginning in Mac OS X 10.4, this is how gdb discovers which mach-o images are loaded in a process. + * + * gdb looks for the symbol "_dyld_all_image_infos" in dyld. It contains the fields below. + * + * For a snashot of what images are currently loaded, the infoArray fields contain a pointer + * to an array of all images. If infoArray is NULL, it means it is being modified, come back later. + * + * To be notified of changes, gdb sets a break point on the address pointed to by the notificationn + * field. The function it points to is called by dyld with an array of information about what images + * have been added (dyld_image_adding) or are about to be removed (dyld_image_removing). + * + * The notification is called after infoArray is updated. This means that if gdb attaches to a process + * and infoArray is NULL, gdb can set a break point on notification and let the proccess continue to + * run until the break point. Then gdb can inspect the full infoArray. + * + * The dyldVersion field always points to a C string that contains the dyld version. For instance, + * in dyld-127.3, dyldVersion would contain a pointer to "127.3". + * + * The errorMessage and terminationFlags fields are normally zero. If dyld terminates a process + * (for instance because a required dylib or symbol is missing), then the errorMessage field will + * be set to point to a C string message buffer containing the reason dyld terminate the process. + * The low bit of the terminationFlags will be set if dyld terminated the process before any user + * code ran, in which case there is no need for the crash log to contain the backtrace. + * + * When dyld terminates a process because some required dylib or symbol cannot be bound, in + * addition to the errorMessage field, it now sets the errorKind field and the corresponding + * fields: errorClientOfDylibPath, errorTargetDylibPath, errorSymbol. + * + */ + +enum dyld_image_mode { dyld_image_adding=0, dyld_image_removing=1, dyld_image_info_change=2, dyld_image_dyld_moved=3 }; + +struct dyld_image_info { + const struct mach_header* imageLoadAddress; /* base address image is mapped into */ + const char* imageFilePath; /* path dyld used to load the image */ + uintptr_t imageFileModDate; /* time_t of image file */ + /* if stat().st_mtime of imageFilePath does not match imageFileModDate, */ + /* then file has been modified since dyld loaded it */ +}; + +struct dyld_uuid_info { + const struct mach_header* imageLoadAddress; /* base address image is mapped into */ + uuid_t imageUUID; /* UUID of image */ +}; + +#define DYLD_AOT_IMAGE_KEY_SIZE 32 +struct dyld_aot_image_info { + const struct mach_header* x86LoadAddress; + const struct mach_header* aotLoadAddress; + uint64_t aotImageSize; + uint8_t aotImageKey[DYLD_AOT_IMAGE_KEY_SIZE]; // uniquely identifying SHA-256 key for this aot +}; + +struct dyld_aot_shared_cache_info { + const uintptr_t cacheBaseAddress; + uuid_t cacheUUID; +}; + +typedef void (*dyld_image_notifier)(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]); + +/* for use in dyld_all_image_infos.errorKind field */ +enum { dyld_error_kind_none=0, + dyld_error_kind_dylib_missing=1, + dyld_error_kind_dylib_wrong_arch=2, + dyld_error_kind_dylib_version=3, + dyld_error_kind_symbol_missing=4 + }; + +/* internal limit */ +#define DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT 8 + +// Must be aligned to support atomic updates +// Note sim cannot assume alignment until all host dylds are new enough +#if TARGET_OS_SIMULATOR +struct dyld_all_image_infos +#else +struct __attribute__((aligned(16))) dyld_all_image_infos +#endif +{ + uint32_t version; /* 1 in Mac OS X 10.4 and 10.5 */ + uint32_t infoArrayCount; +#if defined(__cplusplus) && (BUILDING_LIBDYLD || BUILDING_DYLD) + std::atomic infoArray; +#else + const struct dyld_image_info* infoArray; +#endif + dyld_image_notifier notification; + bool processDetachedFromSharedRegion; + /* the following fields are only in version 2 (Mac OS X 10.6, iPhoneOS 2.0) and later */ + bool libSystemInitialized; + const struct mach_header* dyldImageLoadAddress; + /* the following field is only in version 3 (Mac OS X 10.6, iPhoneOS 3.0) and later */ + void* jitInfo; + /* the following fields are only in version 5 (Mac OS X 10.6, iPhoneOS 3.0) and later */ + const char* dyldVersion; + const char* errorMessage; + uintptr_t terminationFlags; + /* the following field is only in version 6 (Mac OS X 10.6, iPhoneOS 3.1) and later */ + void* coreSymbolicationShmPage; + /* the following field is only in version 7 (Mac OS X 10.6, iPhoneOS 3.1) and later */ + uintptr_t systemOrderFlag; + /* the following field is only in version 8 (Mac OS X 10.7, iPhoneOS 3.1) and later */ + uintptr_t uuidArrayCount; + const struct dyld_uuid_info* uuidArray; /* only images not in dyld shared cache */ + /* the following field is only in version 9 (Mac OS X 10.7, iOS 4.0) and later */ + struct dyld_all_image_infos* dyldAllImageInfosAddress; + /* the following field is only in version 10 (Mac OS X 10.7, iOS 4.2) and later */ + uintptr_t initialImageCount; + /* the following field is only in version 11 (Mac OS X 10.7, iOS 4.2) and later */ + uintptr_t errorKind; + const char* errorClientOfDylibPath; + const char* errorTargetDylibPath; + const char* errorSymbol; + /* the following field is only in version 12 (Mac OS X 10.7, iOS 4.3) and later */ + uintptr_t sharedCacheSlide; + /* the following field is only in version 13 (Mac OS X 10.9, iOS 7.0) and later */ + uint8_t sharedCacheUUID[16]; + /* the following field is only in version 15 (macOS 10.12, iOS 10.0) and later */ + uintptr_t sharedCacheBaseAddress; +#if defined(__cplusplus) && (BUILDING_LIBDYLD || BUILDING_DYLD) + // We want this to be atomic in libdyld so that we can see updates when we map it shared + std::atomic infoArrayChangeTimestamp; +#else + uint64_t infoArrayChangeTimestamp; +#endif + const char* dyldPath; + + mach_port_t notifyPorts[DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT]; + +#if __LP64__ + uintptr_t reserved[11-(DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT/2)]; +#else + uintptr_t reserved[9-DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT]; +#endif + // The following fields were added in version 18 (previously they were reserved padding fields) + uint64_t sharedCacheFSID; + uint64_t sharedCacheFSObjID; + /* the following field is only in version 16 (macOS 10.13, iOS 11.0) and later */ + uintptr_t compact_dyld_image_info_addr; + size_t compact_dyld_image_info_size; + uint32_t platform; // FIXME: really a dyld_platform_t, but those aren't exposed here. + + /* the following field is only in version 17 (macOS 10.16) and later */ + uint32_t aotInfoCount; + const struct dyld_aot_image_info* aotInfoArray; + uint64_t aotInfoArrayChangeTimestamp; + uintptr_t aotSharedCacheBaseAddress; + uint8_t aotSharedCacheUUID[16]; +}; + +/* + * Beginning in Mac OS X 10.5, this is how gdb discovers where the shared cache is in a process. + * Images that are in the shared cache have their segments rearranged, so when using imageFilePath + * to load the file from disk, you have to know to adjust addresses based on how their segment + * was rearranged. + * + * gdb looks for the symbol "_dyld_shared_region_ranges" in dyld. + * + * It contains information the count of shared regions used by the process. The count is + * the number of start/length pairs. + */ +struct dyld_shared_cache_ranges { + uintptr_t sharedRegionsCount; /* how many ranges follow */ + struct { + uintptr_t start; + uintptr_t length; + } ranges[4]; /* max regions */ +}; +extern struct dyld_shared_cache_ranges dyld_shared_cache_ranges __attribute__((visibility("hidden"))); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _DYLD_IMAGES_ */ diff --git a/lib/libc/include/any-darwin-any/mach-o/fixup-chains.h b/lib/libc/include/any-darwin-any/mach-o/fixup-chains.h new file mode 100644 index 0000000000000000000000000000000000000000..d5e1b3bdf8e4e2dcec2359313a8f3146efbd64b0 --- /dev/null +++ b/lib/libc/include/any-darwin-any/mach-o/fixup-chains.h @@ -0,0 +1,334 @@ +/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- + * + * Copyright (c) 2018 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_FIXUP_CHAINS__ +#define __MACH_O_FIXUP_CHAINS__ 7 + + +#include + + +//#define LC_DYLD_EXPORTS_TRIE 0x80000033 // used with linkedit_data_command +//#define LC_DYLD_CHAINED_FIXUPS 0x80000034 // used with linkedit_data_command, payload is dyld_chained_fixups_header + + +// header of the LC_DYLD_CHAINED_FIXUPS payload +struct dyld_chained_fixups_header +{ + uint32_t fixups_version; // 0 + uint32_t starts_offset; // offset of dyld_chained_starts_in_image in chain_data + uint32_t imports_offset; // offset of imports table in chain_data + uint32_t symbols_offset; // offset of symbol strings in chain_data + uint32_t imports_count; // number of imported symbol names + uint32_t imports_format; // DYLD_CHAINED_IMPORT* + uint32_t symbols_format; // 0 => uncompressed, 1 => zlib compressed +}; + +// This struct is embedded in LC_DYLD_CHAINED_FIXUPS payload +struct dyld_chained_starts_in_image +{ + uint32_t seg_count; + uint32_t seg_info_offset[1]; // each entry is offset into this struct for that segment + // followed by pool of dyld_chain_starts_in_segment data +}; + +// This struct is embedded in dyld_chain_starts_in_image +// and passed down to the kernel for page-in linking +struct dyld_chained_starts_in_segment +{ + uint32_t size; // size of this (amount kernel needs to copy) + uint16_t page_size; // 0x1000 or 0x4000 + uint16_t pointer_format; // DYLD_CHAINED_PTR_* + uint64_t segment_offset; // offset in memory to start of segment + uint32_t max_valid_pointer; // for 32-bit OS, any value beyond this is not a pointer + uint16_t page_count; // how many pages are in array + uint16_t page_start[1]; // each entry is offset in each page of first element in chain + // or DYLD_CHAINED_PTR_START_NONE if no fixups on page + // uint16_t chain_starts[1]; // some 32-bit formats may require multiple starts per page. + // for those, if high bit is set in page_starts[], then it + // is index into chain_starts[] which is a list of starts + // the last of which has the high bit set +}; + +enum { + DYLD_CHAINED_PTR_START_NONE = 0xFFFF, // used in page_start[] to denote a page with no fixups + DYLD_CHAINED_PTR_START_MULTI = 0x8000, // used in page_start[] to denote a page which has multiple starts + DYLD_CHAINED_PTR_START_LAST = 0x8000, // used in chain_starts[] to denote last start in list for page +}; + +// these values are set in the reserved1 field of the __chain_starts section +enum { + DYLD_CHAINED_STARTS_USE_FILE_OFFSET = 0x1, // denotes chain starts linked with -fixup_chains_section + DYLD_CHAINED_STARTS_USE_VM_OFFSET = 0x2, // denotes chain starts linked with -fixup_chains_section_vm +}; + +// This struct is embedded in __TEXT,__chain_starts section in firmware +struct dyld_chained_starts_offsets +{ + uint32_t pointer_format; // DYLD_CHAINED_PTR_32_FIRMWARE or DYLD_CHAINED_PTR_ARM64E_KERNEL + uint32_t starts_count; // number of starts in array + uint32_t chain_starts[1]; // array chain start offsets +}; + + +// values for dyld_chained_starts_in_segment.pointer_format +enum { + DYLD_CHAINED_PTR_ARM64E = 1, // stride 8, unauth target is vmaddr + DYLD_CHAINED_PTR_64 = 2, // target is vmaddr + DYLD_CHAINED_PTR_32 = 3, // target is vmaddr + DYLD_CHAINED_PTR_32_CACHE = 4, + DYLD_CHAINED_PTR_32_FIRMWARE = 5, + DYLD_CHAINED_PTR_64_OFFSET = 6, // target is vm offset + DYLD_CHAINED_PTR_ARM64E_OFFSET = 7, // old name + DYLD_CHAINED_PTR_ARM64E_KERNEL = 7, // stride 4, unauth target is vm offset + DYLD_CHAINED_PTR_64_KERNEL_CACHE = 8, + DYLD_CHAINED_PTR_ARM64E_USERLAND = 9, // stride 8, unauth target is vm offset + DYLD_CHAINED_PTR_ARM64E_FIRMWARE = 10, // stride 4, unauth target is vmaddr + DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE = 11, // stride 1, x86_64 kernel caches + DYLD_CHAINED_PTR_ARM64E_USERLAND24 = 12, // stride 8, unauth target is vm offset, 24-bit bind + DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE = 13, // stride 8, regular/auth targets both vm offsets. Only A keys supported + DYLD_CHAINED_PTR_ARM64E_SEGMENTED = 14, // stride 4, rebase offsets use segIndex and segOffset +}; + + +// DYLD_CHAINED_PTR_ARM64E +struct dyld_chained_ptr_arm64e_rebase +{ + uint64_t target : 43, + high8 : 8, + next : 11, // 4 or 8-byte stide + bind : 1, // == 0 + auth : 1; // == 0 +}; + +// DYLD_CHAINED_PTR_ARM64E +struct dyld_chained_ptr_arm64e_bind +{ + uint64_t ordinal : 16, + zero : 16, + addend : 19, // +/-256K + next : 11, // 4 or 8-byte stide + bind : 1, // == 1 + auth : 1; // == 0 +}; + +// DYLD_CHAINED_PTR_ARM64E +struct dyld_chained_ptr_arm64e_auth_rebase +{ + uint64_t target : 32, // runtimeOffset + diversity : 16, + addrDiv : 1, + key : 2, + next : 11, // 4 or 8-byte stide + bind : 1, // == 0 + auth : 1; // == 1 +}; + +// DYLD_CHAINED_PTR_ARM64E +struct dyld_chained_ptr_arm64e_auth_bind +{ + uint64_t ordinal : 16, + zero : 16, + diversity : 16, + addrDiv : 1, + key : 2, + next : 11, // 4 or 8-byte stide + bind : 1, // == 1 + auth : 1; // == 1 +}; + +// DYLD_CHAINED_PTR_64/DYLD_CHAINED_PTR_64_OFFSET +struct dyld_chained_ptr_64_rebase +{ + uint64_t target : 36, // 64GB max image size (DYLD_CHAINED_PTR_64 => vmAddr, DYLD_CHAINED_PTR_64_OFFSET => runtimeOffset) + high8 : 8, // top 8 bits set to this (DYLD_CHAINED_PTR_64 => after slide added, DYLD_CHAINED_PTR_64_OFFSET => before slide added) + reserved : 7, // all zeros + next : 12, // 4-byte stride + bind : 1; // == 0 +}; + + +// DYLD_CHAINED_PTR_ARM64E_USERLAND24 +struct dyld_chained_ptr_arm64e_bind24 +{ + uint64_t ordinal : 24, + zero : 8, + addend : 19, // +/-256K + next : 11, // 8-byte stide + bind : 1, // == 1 + auth : 1; // == 0 +}; + +// DYLD_CHAINED_PTR_ARM64E_USERLAND24 +struct dyld_chained_ptr_arm64e_auth_bind24 +{ + uint64_t ordinal : 24, + zero : 8, + diversity : 16, + addrDiv : 1, + key : 2, + next : 11, // 8-byte stide + bind : 1, // == 1 + auth : 1; // == 1 +}; + +// DYLD_CHAINED_PTR_ARM64E_SEGMENTED +struct dyld_chained_ptr_arm64e_segmented_rebase +{ + uint32_t targetSegOffset : 28, // offset in segment + targetSegIndex : 4; // index into segment address table + uint32_t padding : 19, + next : 12, // 4-byte stide + auth : 1; // == 0 +}; + +// DYLD_CHAINED_PTR_ARM64E_SEGMENTED +struct dyld_chained_ptr_arm64e_auth_segmented_rebase +{ + uint32_t targetSegOffset : 28, // offset in segment + targetSegIndex : 4; // index into segment address table + uint32_t diversity : 16, + addrDiv : 1, + key : 2, + next : 12, // 4-byte stide + auth : 1; // == 1 +}; + +// DYLD_CHAINED_PTR_64 +struct dyld_chained_ptr_64_bind +{ + uint64_t ordinal : 24, + addend : 8, // 0 thru 255 + reserved : 19, // all zeros + next : 12, // 4-byte stride + bind : 1; // == 1 +}; + +// DYLD_CHAINED_PTR_64_KERNEL_CACHE, DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE +struct dyld_chained_ptr_64_kernel_cache_rebase +{ + uint64_t target : 30, // basePointers[cacheLevel] + target + cacheLevel : 2, // what level of cache to bind to (indexes a mach_header array) + diversity : 16, + addrDiv : 1, + key : 2, + next : 12, // 1 or 4-byte stide + isAuth : 1; // 0 -> not authenticated. 1 -> authenticated +}; + +// DYLD_CHAINED_PTR_32 +// Note: for DYLD_CHAINED_PTR_32 some non-pointer values are co-opted into the chain +// as out of range rebases. If an entry in the chain is > max_valid_pointer, then it +// is not a pointer. To restore the value, subtract off the bias, which is +// (64MB+max_valid_pointer)/2. +struct dyld_chained_ptr_32_rebase +{ + uint32_t target : 26, // vmaddr, 64MB max image size + next : 5, // 4-byte stride + bind : 1; // == 0 +}; + +// DYLD_CHAINED_PTR_32 +struct dyld_chained_ptr_32_bind +{ + uint32_t ordinal : 20, + addend : 6, // 0 thru 63 + next : 5, // 4-byte stride + bind : 1; // == 1 +}; + +// DYLD_CHAINED_PTR_32_CACHE +struct dyld_chained_ptr_32_cache_rebase +{ + uint32_t target : 30, // 1GB max dyld cache TEXT and DATA + next : 2; // 4-byte stride +}; + + +// DYLD_CHAINED_PTR_32_FIRMWARE +struct dyld_chained_ptr_32_firmware_rebase +{ + uint32_t target : 26, // 64MB max firmware TEXT and DATA + next : 6; // 4-byte stride +}; + +// DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE +struct dyld_chained_ptr_arm64e_shared_cache_rebase +{ + uint64_t runtimeOffset : 34, // offset from the start of the shared cache + high8 : 8, + unused : 10, + next : 11, // 8-byte stide + auth : 1; // == 0 +}; + +// DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE +struct dyld_chained_ptr_arm64e_shared_cache_auth_rebase +{ + uint64_t runtimeOffset : 34, // offset from the start of the shared cache + diversity : 16, + addrDiv : 1, + keyIsData : 1, // implicitly always the 'A' key. 0 -> IA. 1 -> DA + next : 11, // 8-byte stide + auth : 1; // == 1 +}; + + + +// values for dyld_chained_fixups_header.imports_format +enum { + DYLD_CHAINED_IMPORT = 1, + DYLD_CHAINED_IMPORT_ADDEND = 2, + DYLD_CHAINED_IMPORT_ADDEND64 = 3, +}; + +// DYLD_CHAINED_IMPORT +struct dyld_chained_import +{ + uint32_t lib_ordinal : 8, // -15 .. 240 (0xF1 .. 0xF0) + weak_import : 1, + name_offset : 23; +}; + +// DYLD_CHAINED_IMPORT_ADDEND +struct dyld_chained_import_addend +{ + uint32_t lib_ordinal : 8, // -15 .. 240 (0xF1 .. 0xF0) + weak_import : 1, + name_offset : 23; + int32_t addend; +}; + +// DYLD_CHAINED_IMPORT_ADDEND64 +struct dyld_chained_import_addend64 +{ + uint64_t lib_ordinal : 16, // -15 .. 65520 (0xFFF1 .. 0xFFF0) + weak_import : 1, + reserved : 15, + name_offset : 32; + uint64_t addend; +}; + +#endif // __MACH_O_FIXUP_CHAINS__ + diff --git a/lib/libc/include/any-darwin-any/mach-o/ldsyms.h b/lib/libc/include/any-darwin-any/mach-o/ldsyms.h new file mode 100644 index 0000000000000000000000000000000000000000..3f28b1b19db74d489302d1086704a95de63a0871 --- /dev/null +++ b/lib/libc/include/any-darwin-any/mach-o/ldsyms.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1999 Apple Computer, 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 _MACHO_LDSYMS_H_ +#define _MACHO_LDSYMS_H_ + +#include + +/* + * This file describes the link editor defined symbols. The semantics of a + * link editor symbol is that it is defined by the link editor only if it is + * referenced and it is an error for the user to define them (see the man page + * ld(1)). The standard UNIX link editor symbols: __end, __etext and __edata + * are not not supported by the Apple Mach-O link editor. These symbols are + * really not meaningful in a Mach-O object file and the link editor symbols + * that are supported (described here) replace them. In the case of the + * standard UNIX link editor symbols the program can use the symbol + * __mh_execute_header and walk the load commands of it's program to determine + * the ending (or beginning) of any section or segment in the program. Note + * that the compiler prepends an underbar to all external symbol names coded + * in a high level language. Thus in 'C' names are coded without an underbar + * and symbol names in the symbol table have an underbar. There are two cpp + * macros for each link editor defined name in this file. The macro with a + * leading underbar is the symbol name and the one without is the name as + * coded in 'C'. + */ + +/* + * The value of the link editor defined symbol _MH_EXECUTE_SYM is the address + * of the mach header in a Mach-O executable file type. It does not appear in + * any file type other than a MH_EXECUTE file type. The type of the symbol is + * absolute as the header is not part of any section. + */ +#define _MH_EXECUTE_SYM "__mh_execute_header" +#define MH_EXECUTE_SYM "_mh_execute_header" +extern const struct +#ifdef __LP64__ +mach_header_64 +#else +mach_header +#endif +_mh_execute_header; + +/* + * The value of the link editor defined symbol _MH_BUNDLE_SYM is the address + * of the mach header in a Mach-O bundle file type. It does not appear in + * any file type other than a MH_BUNDLE file type. The type of the symbol is + * an N_SECT symbol even thought the header is not part of any section. This + * symbol is private to the code in the bundle it is a part of. + */ +#define _MH_BUNDLE_SYM "__mh_bundle_header" +#define MH_BUNDLE_SYM "_mh_bundle_header" +extern const struct +#ifdef __LP64__ +mach_header_64 +#else +mach_header +#endif +_mh_bundle_header; + +/* + * The value of the link editor defined symbol _MH_DYLIB_SYM is the address + * of the mach header in a Mach-O dylib file type. It does not appear in + * any file type other than a MH_DYLIB file type. The type of the symbol is + * an N_SECT symbol even thought the header is not part of any section. This + * symbol is private to the code in the library it is a part of. + */ +#define _MH_DYLIB_SYM "__mh_dylib_header" +#define MH_DYLIB_SYM "_mh_dylib_header" +extern const struct +#ifdef __LP64__ +mach_header_64 +#else +mach_header +#endif +_mh_dylib_header; + +/* + * The value of the link editor defined symbol _MH_DYLINKER_SYM is the address + * of the mach header in a Mach-O dylinker file type. It does not appear in + * any file type other than a MH_DYLINKER file type. The type of the symbol is + * an N_SECT symbol even thought the header is not part of any section. This + * symbol is private to the code in the dynamic linker it is a part of. + */ +#define _MH_DYLINKER_SYM "__mh_dylinker_header" +#define MH_DYLINKER_SYM "_mh_dylinker_header" +extern const struct +#ifdef __LP64__ +mach_header_64 +#else +mach_header +#endif +_mh_dylinker_header; + +/* + * For the MH_PRELOAD file type the headers are not loaded as part of any + * segment so the link editor defines symbols defined for the beginning + * and ending of each segment and each section in each segment. The names for + * the symbols for a segment's beginning and end will have the form: + * __SEGNAME__begin and __SEGNAME__end where __SEGNAME is the name of the + * segment. The names for the symbols for a section's beginning and end will + * have the form: __SEGNAME__sectname__begin and __SEGNAME__sectname__end + * where __sectname is the name of the section and __SEGNAME is the segment it + * is in. + * + * The above symbols' types are those of the section they are referring to. + * This is true even for symbols who's values are end's of a section and + * that value is next address after that section and not really in that + * section. This results in these symbols having types referring to sections + * who's values are not in that section. + */ + +#endif /* _MACHO_LDSYMS_H_ */ diff --git a/lib/libc/include/any-darwin-any/mach-o/swap.h b/lib/libc/include/any-darwin-any/mach-o/swap.h new file mode 100644 index 0000000000000000000000000000000000000000..15a0732d6f528508bf67d45b7c2838898598a42e --- /dev/null +++ b/lib/libc/include/any-darwin-any/mach-o/swap.h @@ -0,0 +1,284 @@ +/* + * Copyright (c) 1999 Apple Computer, 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_SWAP_H_ +#define _MACH_O_SWAP_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __CCTOOLS_DEPRECATED + #define __CCTOOLS_DEPRECATED __API_DEPRECATED("No longer supported", macos(10.0, 13.0), ios(1.0, 16.0), watchos(1.0, 8.0), tvos(1.0, 16.0)) + #define __CCTOOLS_DEPRECATED_MSG(_msg) __API_DEPRECATED_WITH_REPLACEMENT(_msg, macos(10.0, 13.0), ios(1.0, 16.0), watchos(1.0, 8.0), tvos(1.0, 16.0)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern void swap_fat_header( + struct fat_header *fat_header, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED_MSG("use macho_for_each_slice()"); + +extern void swap_fat_arch( + struct fat_arch *fat_archs, + uint32_t nfat_arch, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED_MSG("use macho_for_each_slice()"); + +extern void swap_fat_arch_64( + struct fat_arch_64 *fat_archs64, + uint32_t nfat_arch, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED_MSG("use macho_for_each_slice()"); + +extern void swap_mach_header( + struct mach_header *mh, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_mach_header_64( + struct mach_header_64 *mh, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_load_command( + struct load_command *lc, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_segment_command( + struct segment_command *sg, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_segment_command_64( + struct segment_command_64 *sg, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_section( + struct section *s, + uint32_t nsects, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_section_64( + struct section_64 *s, + uint32_t nsects, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_symtab_command( + struct symtab_command *st, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_dysymtab_command( + struct dysymtab_command *dyst, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_symseg_command( + struct symseg_command *ss, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_fvmlib_command( + struct fvmlib_command *fl, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_dylib_command( + struct dylib_command *dl, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_sub_framework_command( + struct sub_framework_command *sub, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_sub_umbrella_command( + struct sub_umbrella_command *usub, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_sub_library_command( + struct sub_library_command *lsub, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_sub_client_command( + struct sub_client_command *csub, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_prebound_dylib_command( + struct prebound_dylib_command *pbdylib, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_dylinker_command( + struct dylinker_command *dyld, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_fvmfile_command( + struct fvmfile_command *ff, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_thread_command( + struct thread_command *ut, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_ident_command( + struct ident_command *ident, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_routines_command( + struct routines_command *r_cmd, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_routines_command_64( + struct routines_command_64 *r_cmd, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_twolevel_hints_command( + struct twolevel_hints_command *hints_cmd, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_prebind_cksum_command( + struct prebind_cksum_command *cksum_cmd, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_uuid_command( + struct uuid_command *uuid_cmd, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_linkedit_data_command( + struct linkedit_data_command *ld, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_version_min_command( + struct version_min_command *ver_cmd, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; +extern void swap_rpath_command( + struct rpath_command *rpath_cmd, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_encryption_command( + struct encryption_info_command *ec, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_encryption_command_64( + struct encryption_info_command_64 *ec, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_linker_option_command( + struct linker_option_command *lo, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_dyld_info_command( + struct dyld_info_command *ed, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_entry_point_command( + struct entry_point_command *ep, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_source_version_command( + struct source_version_command *sv, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_note_command( + struct note_command *nc, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_build_version_command( + struct build_version_command *bv, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_build_tool_version( + struct build_tool_version *bt, + uint32_t ntools, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_prebind_cksum_command( + struct prebind_cksum_command *cksum_cmd, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_uuid_command( + struct uuid_command *uuid_cmd, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_twolevel_hint( + struct twolevel_hint *hints, + uint32_t nhints, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_fileset_entry_command( + struct fileset_entry_command *lc, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_nlist( + struct nlist *symbols, + uint32_t nsymbols, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_nlist_64( + struct nlist_64 *symbols, + uint32_t nsymbols, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_ranlib( + struct ranlib *ranlibs, + uint32_t nranlibs, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_ranlib_64( + struct ranlib_64 *ranlibs, + uint64_t nranlibs, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_relocation_info( + struct relocation_info *relocs, + uint32_t nrelocs, + enum NXByteOrder target_byte_order) __CCTOOLS_DEPRECATED; + +extern void swap_indirect_symbols( + uint32_t *indirect_symbols, + uint32_t nindirect_symbols, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_dylib_reference( + struct dylib_reference *refs, + uint32_t nrefs, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_dylib_module( + struct dylib_module *mods, + uint32_t nmods, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_dylib_module_64( + struct dylib_module_64 *mods, + uint32_t nmods, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +extern void swap_dylib_table_of_contents( + struct dylib_table_of_contents *tocs, + uint32_t ntocs, + enum NXByteOrder target_byte_sex) __CCTOOLS_DEPRECATED; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _MACH_O_SWAP_H_ */ diff --git a/lib/libc/include/any-darwin-any/mach-o/utils.h b/lib/libc/include/any-darwin-any/mach-o/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..5e30bd8a278dab892be83ccc14a398637cac5ccd --- /dev/null +++ b/lib/libc/include/any-darwin-any/mach-o/utils.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 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_UTILS_H_ +#define _MACH_O_UTILS_H_ + +#include +#include +#include + +#include +#include + +#include + + +#if __cplusplus +extern "C" { +#endif + +/*! + * @function macho_cpu_type_for_arch_name + * + * @abstract + * Converts an architecture name into a cpu type/subtype pair. + * + * @param archName + * An architecture name (e.g "arm64e" or "x86_64"). + * + * @param type + * A pointer to where to store the cpu type of the given name. + * + * @param subtype + * A pointer to where to store the cpu subtype of the given name. + * + * @return + * If the archName is known, returns true and fills in the type/subtype. + * If the archName is unknown, returns false. + */ +extern bool macho_cpu_type_for_arch_name(const char* _Nonnull archName, cpu_type_t* _Nonnull type, cpu_subtype_t* _Nonnull subtype) +__API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(8.0)); + + +/*! + * @function macho_arch_name_for_cpu_type + * + * @abstract + * Converts a cpu type/subtype pair into the architecture name. + * + * @param type + * The cpu type from (e.g CPU_TYPE_ARM64) + * + * @param subtype + * The cpu subtype from (e.g CPU_SUBTYPE_ARM64E) + * + * @return + * Returns a static c-string which is the name for the cpu type/subtype (e.g. "arm64e"). + * If the cpu type/subtype is unknown, NULL will be returned. + * The string returned is static and does not need to be deallocated. + */ +extern const char* _Nullable macho_arch_name_for_cpu_type(cpu_type_t type, cpu_subtype_t subtype) +__API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(8.0)); + + +/*! + * @function macho_arch_name_for_mach_header + * + * @abstract + * Returns the architecture name from the cpu type/subtype in a mach_header. + * This is a convenience wrapper around macho_arch_name_for_cpu_type(). + * + * @param mh + * A pointer to the header of a mach-o file. + * If NULL is passed, the architecture name of the main executable will be returned. + * + * @return + * Returns a static c-string which is the name for architecture of the mach-o file (e.g. "arm64e"). + * If the architecture is unknown, NULL will be returned. + * The string returned is static and does not need to be deallocated. + */ +extern const char* _Nullable macho_arch_name_for_mach_header(const struct mach_header* _Nullable mh) +__API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(8.0)); + +#ifdef __BLOCKS__ + #if __has_attribute(noescape) + #define __MACHO_NOESCAPE __attribute__((__noescape__)) + #else + #define __MACHO_NOESCAPE + #endif + +/*! + * @function macho_for_each_slice + * + * @abstract + * Temporarily maps a mach-o or universal file and iterates the slices. + * If the file is mach-o, the block is called once with the mach-o file mapped. + * If the file is universal (aka fat), the block is called once per slice in the order in the header. + * If the path does not exist or does, but is not a mach-o file, the block is never called. + * + * @param path + * The path to the file to inspect. + * + * @param callback + * A block to call once per slice. + * Can be NULL. In which case the return value tells you if the file is mach-o or fat. + * The slice pointer is only valid during the block invocation. + * To stop iterating the slices, set *stop to true. + * + * @return + * Returns zero on success, otherwise it returns an errno value. + * Common returned errors: + * ENOENT - path does not exist + * EACCES - path exists put caller does not have permission to access it + * EFTYPE - path exists but it is not a mach-o or fat file + * EBADMACHO - path is a mach-o file, but it is malformed + */ +extern int macho_for_each_slice(const char* _Nonnull path, void (^ _Nullable callback)(const struct mach_header* _Nonnull slice, uint64_t sliceFileOffset, size_t size, bool* _Nonnull stop) __MACHO_NOESCAPE) +__API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(8.0)); + + +/*! + * @function macho_for_each_slice_in_fd + * + * @abstract + * Temporarily maps a mach-o or universal file and iterates the slices. + * If the fd is to a mach-o, the block is called once with the mach-o file mapped. + * If the fd is to a universal (aka fat), the block is called once per slice in the order in the header. + * If the fd is closed or not mmap()able, the block is never called. + * + * @param fd + * An open file descriptor to a mmap()able file. + * + * @param callback + * A block to call once per slice. + * Can be NULL. In which case the return value tells you if the file is mach-o or fat. + * The slice pointer is only valid during the block invocation. + * To stop iterating the slices, set *stop to true. + * + * @return + * Returns zero on success, otherwise it returns an errno value. + * Common returned errors: + * EFTYPE - fd content is not a mach-o or fat file + * EBADMACHO - fd content is a mach-o file, but it is malformed + */ +extern int macho_for_each_slice_in_fd(int fd, void (^ _Nullable callback)(const struct mach_header* _Nonnull slice, uint64_t sliceFileOffset, size_t size, bool* _Nonnull stop)__MACHO_NOESCAPE) +__API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(8.0)); + + +/*! + * @function macho_best_slice + * + * @abstract + * Examines a mach-o or universal file to find the slice that would be loaded. That is, for dylib/bundles, which + * slice dyld would load. For main executables, which slice the kernel would use. + * In simulator processes, only other simulator main executables will be considered loadable. + * If the file is mach-o and is the right arch and platform to load, the block is called once with the mach-o file mapped. + * If the file is universal (aka fat) file, the best slice is found and the block is called once with the mapped slice. + * If the file is universal (aka fat) file, but none of the slices are loadable, the callback is not called, and EBADARCH is returned. + * If the path does not exist or does but is not a mach-o or universal file, the block is never called, and an error is returned. + * + * @param path + * The path to the file to inspect. + * + * @param callback + * A block to call once with the best slice. + * Can be NULL. In which case the return value tells you if there was a loadable slice + * The slice pointer is only valid during the block invocation. + * + * @return + * Returns zero on success (meaning there is a best slice), otherwise it returns an errno value. + * Common returned errors: + * ENOENT - path does not exist + * EACCES - path exists put caller does not have permission to access it + * EFTYPE - path exists but it is not a mach-o or fat file + * EBADARCH - path exists and is mach-o or fat, but none of the slices are loadable + * EBADMACHO - path is a mach-o file, but it is malformed + */ +extern int macho_best_slice(const char* _Nonnull path, void (^ _Nullable bestSlice)(const struct mach_header* _Nonnull slice, uint64_t sliceFileOffset, size_t sliceSize)__MACHO_NOESCAPE) +__API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(8.0)); + + +/*! + * @function macho_best_slice_in_fd + * + * @abstract + * Examines a mach-o or universal file to find the slice that would be loaded. That is, for dylib/bundles, which + * slice dyld would load. For main executables, which slice the kernel would use. + * In simulator processes, only other simulator main executables will be considered loadable. + * If the fd is to a mach-o and is the right arch and platform to load, the block is call once with the mach-o file mapped. + * If the fd is to a universal (aka fat) file, the best slice is found and the block is called once with the mapped slice. + * If the fd is closed or not mmap()able, the block is never called. + * + * @param fd + * An open file descriptor to a mmap()able file. + * + * @param callback + * A block to call once with the best slice. + * Can be NULL. In which case the return value tells you if there was a loadable slice + * The slice pointer is only valid during the block invocation. + * + * @return + * Returns zero on success (meaning there is a best slice), otherwise it returns an errno value. + * Common returned errors: + * EFTYPE - fd content is not a mach-o or fat file + * EBADMACHO - fd content is a mach-o file, but it is malformed + * EBADARCH - fd content is a mach-o or fat, but none of the slices are loadable + */ +extern int macho_best_slice_in_fd(int fd, void (^ _Nullable bestSlice)(const struct mach_header* _Nonnull slice, uint64_t sliceFileOffset, size_t sliceSize)__MACHO_NOESCAPE) +__API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(8.0)); + +#endif // __BLOCKS__ + + + + + +#if __cplusplus +} +#endif + + +#endif // _MACH_O_UTILS_H_ + diff --git a/tools/macos-headers.c b/tools/macos-headers.c index d7a9fc1be9aae7d9e6fe15b88b13017922ab110a..b739f8f2dfe7ef23fe73757c79192d3a8f3efd27 100644 --- a/tools/macos-headers.c +++ b/tools/macos-headers.c @@ -114,6 +114,9 @@ #include #include /* #include - not found on macos catalina */ +#define _XOPEN_SOURCE +#include +#undef _XOPEN_SOURCE #include #include #include @@ -138,20 +141,31 @@ #include #include -// Depended on by libcxx -#include -#include -#include +// Mach-O headers +#include +#include #include +#include #include +#include +#include +#include +#include #include +#include #include -#include #include -#include -#include +#include +#include + +#include #include #include + +// Depended on by libcxx +#include +#include +#include #include // Depended on by LLVM @@ -197,16 +211,10 @@ #include #include -// Depended on by bdwgc -#include - // Provided by macOS LibC #include #include -#define _XOPEN_SOURCE -#include - int main(int argc, char **argv) { return 0; } -- 2.54.0