this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Disable Lintian; The warnings/errors are not applicable to Darling

+1 -1889
-3
debian/darling-dkms.lintian-overrides
··· 1 - package-contains-vcs-control-file usr/src/darling-mach-0.1/lkm/.gitignore 2 - executable-not-elf-or-script usr/src/darling-mach-0.1/lkm* 3 - extended-description-is-empty
-6
debian/source/lintian-overrides
··· 1 - darling source: configure-generated-file-in-source * 2 - darling source: autotools-pkg-config-macro-not-cross-compilation-safe * 3 - darling source: source-contains-prebuilt-windows-binary * 4 - darling source: maintainer-script-lacks-debhelper-token debian/* 5 - darling source: debhelper-but-no-misc-depends darling-dkms 6 - darling source: package-needs-versioned-debhelper-build-depends 10
-1642
src/dyld/src/dyld2.cpp.rej
··· 1 - --- src/dyld.cpp 2 - +++ src/dyld2.cpp 3 - @@ -60,79 +62,78 @@ 4 - #include <System/machine/cpu_capabilities.h> 5 - #include <System/sys/reason.h> 6 - #include <kern/kcdata.h> 7 - +#include <sys/attr.h> 8 - +#include <sys/fsgetpath.h> 9 - + 10 - +#if TARGET_OS_SIMULATOR 11 - + enum { 12 - + AMFI_DYLD_INPUT_PROC_IN_SIMULATOR = (1 << 0), 13 - + }; 14 - + enum amfi_dyld_policy_output_flag_set { 15 - + AMFI_DYLD_OUTPUT_ALLOW_AT_PATH = (1 << 0), 16 - + AMFI_DYLD_OUTPUT_ALLOW_PATH_VARS = (1 << 1), 17 - + AMFI_DYLD_OUTPUT_ALLOW_CUSTOM_SHARED_CACHE = (1 << 2), 18 - + AMFI_DYLD_OUTPUT_ALLOW_FALLBACK_PATHS = (1 << 3), 19 - + AMFI_DYLD_OUTPUT_ALLOW_PRINT_VARS = (1 << 4), 20 - + AMFI_DYLD_OUTPUT_ALLOW_FAILED_LIBRARY_INSERTION = (1 << 5), 21 - + }; 22 - + extern "C" int amfi_check_dyld_policy_self(uint64_t input_flags, uint64_t* output_flags); 23 - +#else 24 - + #include <libamfi.h> 25 - +#endif 26 - #include <sandbox.h> 27 - #include <sandbox/private.h> 28 - - 29 - -#include <array> 30 - - 31 - -#ifndef CPU_SUBTYPE_ARM_V5TEJ 32 - - #define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t) 7) 33 - -#endif 34 - -#ifndef CPU_SUBTYPE_ARM_XSCALE 35 - - #define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t) 8) 36 - -#endif 37 - -#ifndef CPU_SUBTYPE_ARM_V7 38 - - #define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t) 9) 39 - -#endif 40 - -#ifndef CPU_SUBTYPE_ARM_V7F 41 - - #define CPU_SUBTYPE_ARM_V7F ((cpu_subtype_t) 10) 42 - -#endif 43 - -#ifndef CPU_SUBTYPE_ARM_V7S 44 - - #define CPU_SUBTYPE_ARM_V7S ((cpu_subtype_t) 11) 45 - -#endif 46 - -#ifndef CPU_SUBTYPE_ARM_V7K 47 - - #define CPU_SUBTYPE_ARM_V7K ((cpu_subtype_t) 12) 48 - -#endif 49 - -#ifndef LC_DYLD_ENVIRONMENT 50 - - #define LC_DYLD_ENVIRONMENT 0x27 51 - +#if __has_feature(ptrauth_calls) 52 - + #include <ptrauth.h> 53 - #endif 54 - 55 - -#ifndef CPU_SUBTYPE_X86_64_H 56 - - #define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t) 8) 57 - -#endif 58 - - 59 - -#ifndef VM_PROT_SLIDE 60 - - #define VM_PROT_SLIDE 0x20 61 - -#endif 62 - +extern "C" int __fork(); 63 - 64 - -#include <vector> 65 - +#include <array> 66 - #include <algorithm> 67 - +#include <vector> 68 - 69 - -#include "mach-o/dyld_gdb.h" 70 - 71 - -#include "dyld.h" 72 - +#include "dyld2.h" 73 - #include "ImageLoader.h" 74 - #include "ImageLoaderMachO.h" 75 - #include "dyldLibSystemInterface.h" 76 - -#if DYLD_SHARED_CACHE_SUPPORT 77 - #include "dyld_cache_format.h" 78 - -#endif 79 - #include "dyld_process_info_internal.h" 80 - -#include <coreSymbolicationDyldSupport.h> 81 - -#if TARGET_IPHONE_SIMULATOR 82 - - extern "C" void xcoresymbolication_load_notifier(void *connection, uint64_t load_timestamp, const char *image_path, const struct mach_header *mach_header); 83 - - extern "C" void xcoresymbolication_unload_notifier(void *connection, uint64_t unload_timestamp, const char *image_path, const struct mach_header *mach_header); 84 - - #define coresymbolication_load_notifier(c, t, p, h) xcoresymbolication_load_notifier(c, t, p, h) 85 - - #define coresymbolication_unload_notifier(c, t, p, h) xcoresymbolication_unload_notifier(c, t, p, h) 86 - -#endif 87 - 88 - #if SUPPORT_ACCELERATE_TABLES 89 - #include "ImageLoaderMegaDylib.h" 90 - #endif 91 - 92 - -#if TARGET_IPHONE_SIMULATOR 93 - +#if TARGET_OS_SIMULATOR 94 - extern "C" void* gSyscallHelpers; 95 - #else 96 - #include "dyldSyscallInterface.h" 97 - #endif 98 - 99 - +#include "Closure.h" 100 - +#include "libdyldEntryVector.h" 101 - +#include "MachOLoaded.h" 102 - +#include "Loading.h" 103 - +#include "DyldSharedCache.h" 104 - +#include "SharedCacheRuntime.h" 105 - +#include "StringUtils.h" 106 - +#include "Tracing.h" 107 - +#include "ClosureBuilder.h" 108 - +#include "ClosureFileSystemPhysical.h" 109 - +#include "FileUtils.h" 110 - +#include "BootArgs.h" 111 - + 112 - +#ifndef MH_HAS_OBJC 113 - + #define MH_HAS_OBJC 0x40000000 114 - +#endif 115 - 116 - // not libc header for send() syscall interface 117 - extern "C" ssize_t __sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); 118 - 119 - 120 - // ARM and x86_64 are the only architecture that use cpu-sub-types 121 - -#define CPU_SUBTYPES_SUPPORTED ((__arm__ || __x86_64__) && !TARGET_IPHONE_SIMULATOR) 122 - +#define CPU_SUBTYPES_SUPPORTED ((__arm__ || __arm64__ || __x86_64__) && !TARGET_OS_SIMULATOR) 123 - 124 - #if __LP64__ 125 - #define LC_SEGMENT_COMMAND LC_SEGMENT_64 126 - @@ -784,125 +818,124 @@ static void notifySingleFromCache(dyld_image_states state, const mach_header* mh 127 - } 128 - } 129 - if ( (state == dyld_image_state_dependents_initialized) && (sNotifyObjCInit != NULL) && (mh->flags & MH_HAS_OBJC) ) { 130 - + dyld3::ScopedTimer timer(DBG_DYLD_TIMING_OBJC_INIT, (uint64_t)mh, 0, 0); 131 - (*sNotifyObjCInit)(path, mh); 132 - } 133 - } 134 - #endif 135 - 136 - -static mach_port_t sNotifyReplyPorts[DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT]; 137 - - 138 - - 139 - -static void notifyMonitoringDyld(bool unloading, unsigned portSlot, unsigned imageCount, const dyld_image_info infos[]) 140 - -{ 141 - - unsigned entriesSize = imageCount*sizeof(dyld_process_info_image_entry); 142 - - unsigned pathsSize = 0; 143 - - for (unsigned j=0; j < imageCount; ++j) { 144 - - pathsSize += (strlen(infos[j].imageFilePath) + 1); 145 - +#if !TARGET_OS_SIMULATOR 146 - +static void sendMessage(unsigned portSlot, mach_msg_id_t msgId, mach_msg_size_t sendSize, mach_msg_header_t* buffer, mach_msg_size_t bufferSize) { 147 - + // Allocate a port to listen on in this monitoring task 148 - + mach_port_t sendPort = dyld::gProcessInfo->notifyPorts[portSlot]; 149 - + if (sendPort == MACH_PORT_NULL) { 150 - + return; 151 - } 152 - - unsigned totalSize = (sizeof(dyld_process_info_notify_header) + entriesSize + pathsSize + 127) & -128; // align 153 - - if ( totalSize > DYLD_PROCESS_INFO_NOTIFY_MAX_BUFFER_SIZE ) { 154 - - // Putting all image paths into one message would make buffer too big. 155 - - // Instead split into two messages. Recurse as needed until paths fit in buffer. 156 - - unsigned imageHalfCount = imageCount/2; 157 - - notifyMonitoringDyld(unloading, portSlot, imageHalfCount, infos); 158 - - notifyMonitoringDyld(unloading, portSlot, imageCount - imageHalfCount, &infos[imageHalfCount]); 159 - + mach_port_t replyPort = MACH_PORT_NULL; 160 - + mach_port_options_t options = { .flags = MPO_CONTEXT_AS_GUARD | MPO_STRICT, 161 - + .mpl = { 1 }}; 162 - + kern_return_t kr = mach_port_construct(mach_task_self(), &options, (mach_port_context_t)&replyPort, &replyPort); 163 - + if (kr != KERN_SUCCESS) { 164 - return; 165 - } 166 - - uint8_t buffer[totalSize]; 167 - - dyld_process_info_notify_header* header = (dyld_process_info_notify_header*)buffer; 168 - - header->version = 1; 169 - - header->imageCount = imageCount; 170 - - header->imagesOffset = sizeof(dyld_process_info_notify_header); 171 - - header->stringsOffset = sizeof(dyld_process_info_notify_header) + entriesSize; 172 - - header->timestamp = mach_absolute_time(); 173 - - dyld_process_info_image_entry* entries = (dyld_process_info_image_entry*)&buffer[header->imagesOffset]; 174 - - char* const pathPoolStart = (char*)&buffer[header->stringsOffset]; 175 - - char* pathPool = pathPoolStart; 176 - - for (unsigned j=0; j < imageCount; ++j) { 177 - - strcpy(pathPool, infos[j].imageFilePath); 178 - - uint32_t len = (uint32_t)strlen(pathPool); 179 - - bzero(entries->uuid, 16); 180 - - const ImageLoader* image = findImageByMachHeader(infos[j].imageLoadAddress); 181 - - if ( image != NULL ) { 182 - - image->getUUID(entries->uuid); 183 - - } 184 - -#if SUPPORT_ACCELERATE_TABLES 185 - - else if ( sAllCacheImagesProxy != NULL ) { 186 - - const mach_header* mh; 187 - - const char* path; 188 - - unsigned index; 189 - - if ( sAllCacheImagesProxy->addressInCache(infos[j].imageLoadAddress, &mh, &path, &index) ) { 190 - - sAllCacheImagesProxy->getDylibUUID(index, entries->uuid); 191 - - } 192 - + // Assemble a message 193 - + mach_msg_header_t* h = buffer; 194 - + h->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,MACH_MSG_TYPE_MAKE_SEND_ONCE); 195 - + h->msgh_id = msgId; 196 - + h->msgh_local_port = replyPort; 197 - + h->msgh_remote_port = sendPort; 198 - + h->msgh_reserved = 0; 199 - + h->msgh_size = sendSize; 200 - + kr = mach_msg(h, MACH_SEND_MSG | MACH_RCV_MSG, h->msgh_size, bufferSize, replyPort, 0, MACH_PORT_NULL); 201 - + mach_msg_destroy(h); 202 - + if ( kr == MACH_SEND_INVALID_DEST ) { 203 - + if (OSAtomicCompareAndSwap32(sendPort, 0, (volatile int32_t*)&dyld::gProcessInfo->notifyPorts[portSlot])) { 204 - + mach_port_deallocate(mach_task_self(), sendPort); 205 - + } 206 - + } 207 - + mach_port_destruct(mach_task_self(), replyPort, 0, (mach_port_context_t)&replyPort); 208 - +} 209 - + 210 - +static void notifyMonitoringDyld(bool unloading, unsigned imageCount, const struct mach_header* loadAddresses[], 211 - + const char* imagePaths[]) 212 - +{ 213 - + dyld3::ScopedTimer(DBG_DYLD_REMOTE_IMAGE_NOTIFIER, 0, 0, 0); 214 - + for (int slot=0; slot < DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT; ++slot) { 215 - + if ( dyld::gProcessInfo->notifyPorts[slot] == 0) continue; 216 - + unsigned entriesSize = imageCount*sizeof(dyld_process_info_image_entry); 217 - + unsigned pathsSize = 0; 218 - + for (unsigned j=0; j < imageCount; ++j) { 219 - + pathsSize += (strlen(imagePaths[j]) + 1); 220 - + } 221 - + unsigned totalSize = (sizeof(dyld_process_info_notify_header) + entriesSize + pathsSize + 127) & -128; // align 222 - + if ( totalSize > DYLD_PROCESS_INFO_NOTIFY_MAX_BUFFER_SIZE ) { 223 - + // Putting all image paths into one message would make buffer too big. 224 - + // Instead split into two messages. Recurse as needed until paths fit in buffer. 225 - + unsigned imageHalfCount = imageCount/2; 226 - + notifyMonitoringDyld(unloading, imageHalfCount, loadAddresses, imagePaths); 227 - + notifyMonitoringDyld(unloading, imageCount - imageHalfCount, &loadAddresses[imageHalfCount], &imagePaths[imageHalfCount]); 228 - + return; 229 - } 230 - -#endif 231 - - entries->loadAddress = (uint64_t)infos[j].imageLoadAddress; 232 - - entries->pathStringOffset = (uint32_t)(pathPool - pathPoolStart); 233 - - entries->pathLength = len; 234 - - pathPool += (len +1); 235 - - ++entries; 236 - - } 237 - - 238 - - if ( sNotifyReplyPorts[portSlot] == 0 ) { 239 - - if ( !mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &sNotifyReplyPorts[portSlot]) ) 240 - - mach_port_insert_right(mach_task_self(), sNotifyReplyPorts[portSlot], sNotifyReplyPorts[portSlot], MACH_MSG_TYPE_MAKE_SEND); 241 - - //dyld::log("allocated reply port %d\n", sNotifyReplyPorts[portSlot]); 242 - - } 243 - - //dyld::log("found port to send to\n"); 244 - - mach_msg_header_t* h = (mach_msg_header_t*)buffer; 245 - - h->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,MACH_MSG_TYPE_MAKE_SEND); // MACH_MSG_TYPE_MAKE_SEND_ONCE 246 - - h->msgh_id = unloading ? DYLD_PROCESS_INFO_NOTIFY_UNLOAD_ID : DYLD_PROCESS_INFO_NOTIFY_LOAD_ID; 247 - - h->msgh_local_port = sNotifyReplyPorts[portSlot]; 248 - - h->msgh_remote_port = dyld::gProcessInfo->notifyPorts[portSlot]; 249 - - h->msgh_reserved = 0; 250 - - h->msgh_size = (mach_msg_size_t)sizeof(buffer); 251 - - //dyld::log("sending to port[%d]=%d, size=%d, reply port=%d, id=0x%X\n", portSlot, dyld::gProcessInfo->notifyPorts[portSlot], h->msgh_size, sNotifyReplyPorts[portSlot], h->msgh_id); 252 - - kern_return_t sendResult = mach_msg(h, MACH_SEND_MSG | MACH_RCV_MSG | MACH_SEND_TIMEOUT, h->msgh_size, h->msgh_size, sNotifyReplyPorts[portSlot], 100, MACH_PORT_NULL); 253 - - //dyld::log("send result = 0x%X, msg_id=%d, msg_size=%d\n", sendResult, h->msgh_id, h->msgh_size); 254 - - if ( sendResult == MACH_SEND_INVALID_DEST ) { 255 - - // sender is not responding, detatch 256 - - //dyld::log("process requesting notification gone. deallocation send port %d and receive port %d\n", dyld::gProcessInfo->notifyPorts[portSlot], sNotifyReplyPorts[portSlot]); 257 - - mach_port_deallocate(mach_task_self(), dyld::gProcessInfo->notifyPorts[portSlot]); 258 - - mach_port_deallocate(mach_task_self(), sNotifyReplyPorts[portSlot]); 259 - - dyld::gProcessInfo->notifyPorts[portSlot] = 0; 260 - - sNotifyReplyPorts[portSlot] = 0; 261 - - } 262 - -} 263 - - 264 - -#define MAX_KERNEL_IMAGES_PER_CALL (100) 265 - - 266 - -static void flushKernelNotifications(bool loading, bool force, std::array<dyld_kernel_image_info_t,MAX_KERNEL_IMAGES_PER_CALL>& kernelInfos, uint32_t &kernelInfoCount) { 267 - - if ((force && kernelInfoCount != 0) || kernelInfoCount == MAX_KERNEL_IMAGES_PER_CALL) { 268 - - if (loading) { 269 - - task_register_dyld_image_infos(mach_task_self(), kernelInfos.data(), kernelInfoCount); 270 - + uint8_t buffer[totalSize + MAX_TRAILER_SIZE]; 271 - + dyld_process_info_notify_header* header = (dyld_process_info_notify_header*)buffer; 272 - + header->version = 1; 273 - + header->imageCount = imageCount; 274 - + header->imagesOffset = sizeof(dyld_process_info_notify_header); 275 - + header->stringsOffset = sizeof(dyld_process_info_notify_header) + entriesSize; 276 - + header->timestamp = dyld::gProcessInfo->infoArrayChangeTimestamp; 277 - + dyld_process_info_image_entry* entries = (dyld_process_info_image_entry*)&buffer[header->imagesOffset]; 278 - + char* const pathPoolStart = (char*)&buffer[header->stringsOffset]; 279 - + char* pathPool = pathPoolStart; 280 - + for (unsigned j=0; j < imageCount; ++j) { 281 - + strcpy(pathPool, imagePaths[j]); 282 - + uint32_t len = (uint32_t)strlen(pathPool); 283 - + bzero(entries->uuid, 16); 284 - + dyld3::MachOFile* mf = (dyld3::MachOFile*)loadAddresses[j]; 285 - + mf->getUuid(entries->uuid); 286 - + entries->loadAddress = (uint64_t)loadAddresses[j]; 287 - + entries->pathStringOffset = (uint32_t)(pathPool - pathPoolStart); 288 - + entries->pathLength = len; 289 - + pathPool += (len +1); 290 - + ++entries; 291 - + } 292 - + if (unloading) { 293 - + sendMessage(slot, DYLD_PROCESS_INFO_NOTIFY_UNLOAD_ID, totalSize, (mach_msg_header_t*)buffer, totalSize+MAX_TRAILER_SIZE); 294 - } else { 295 - - task_unregister_dyld_image_infos(mach_task_self(), kernelInfos.data(), kernelInfoCount); 296 - + sendMessage(slot, DYLD_PROCESS_INFO_NOTIFY_LOAD_ID, totalSize, (mach_msg_header_t*)buffer, totalSize+MAX_TRAILER_SIZE); 297 - } 298 - - kernelInfoCount = 0; 299 - } 300 - } 301 - 302 - -static 303 - -void queueKernelNotification(const ImageLoader& image, bool loading, std::array<dyld_kernel_image_info_t,MAX_KERNEL_IMAGES_PER_CALL>& kernelInfos, uint32_t &kernelInfoCount) { 304 - - if ( !image.inSharedCache() ) { 305 - - ino_t inode = image.getInode(); 306 - - image.getUUID(kernelInfos[kernelInfoCount].uuid); 307 - - memcpy(&kernelInfos[kernelInfoCount].fsobjid, &inode, 8); 308 - - kernelInfos[kernelInfoCount].load_addr = (uint64_t)image.machHeader(); 309 - - // FIXME we should also be grabbing the device ID, but that is not necessary yet, 310 - - // and requires threading it through the ImageLoader 311 - - kernelInfos[kernelInfoCount].fsid.val[0] = 0; 312 - - kernelInfos[kernelInfoCount].fsid.val[1] = 0; 313 - - kernelInfoCount++; 314 - +static void notifyMonitoringDyldMain() 315 - +{ 316 - + dyld3::ScopedTimer(DBG_DYLD_REMOTE_IMAGE_NOTIFIER, 0, 0, 0); 317 - + for (int slot=0; slot < DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT; ++slot) { 318 - + if ( dyld::gProcessInfo->notifyPorts[slot] == 0) continue; 319 - + uint8_t buffer[sizeof(mach_msg_header_t) + MAX_TRAILER_SIZE]; 320 - + sendMessage(slot, DYLD_PROCESS_INFO_NOTIFY_MAIN_ID, sizeof(mach_msg_header_t), (mach_msg_header_t*)buffer, sizeof(mach_msg_header_t) + MAX_TRAILER_SIZE); 321 - } 322 - - flushKernelNotifications(loading, false, kernelInfos, kernelInfoCount); 323 - } 324 - +#else 325 - +extern void notifyMonitoringDyldMain() VIS_HIDDEN; 326 - +extern void notifyMonitoringDyld(bool unloading, unsigned imageCount, const struct mach_header* loadAddresses[], 327 - + const char* imagePaths[]) VIS_HIDDEN; 328 - +#endif 329 - 330 - void notifyKernel(const ImageLoader& image, bool loading) { 331 - - std::array<dyld_kernel_image_info_t,MAX_KERNEL_IMAGES_PER_CALL> kernelInfos; 332 - - uint32_t kernelInfoCount = 0; 333 - - queueKernelNotification(image, loading, kernelInfos, kernelInfoCount); 334 - - flushKernelNotifications(loading, true, kernelInfos, kernelInfoCount); 335 - + uint32_t baseCode = loading ? DBG_DYLD_UUID_MAP_A : DBG_DYLD_UUID_UNMAP_A; 336 - + uuid_t uuid; 337 - + image.getUUID(uuid); 338 - + if ( image.inSharedCache() ) { 339 - + dyld3::kdebug_trace_dyld_image(baseCode, image.getInstallPath(), (const uuid_t *)&uuid, {0}, {{ 0, 0 }}, image.machHeader()); 340 - + } else { 341 - + fsid_t fsid = {{0, 0}}; 342 - + fsobj_id_t fsobj = {0}; 343 - + ino_t inode = image.getInode(); 344 - + fsobj.fid_objno = (uint32_t)inode; 345 - + fsobj.fid_generation = (uint32_t)(inode>>32); 346 - + fsid.val[0] = image.getDevice(); 347 - + dyld3::kdebug_trace_dyld_image(baseCode, image.getPath(), (const uuid_t *)&uuid, fsobj, fsid, image.machHeader()); 348 - + } 349 - } 350 - 351 - static void notifySingle(dyld_image_states state, const ImageLoader* image, ImageLoader::InitializerTimingList* timingInfo) 352 - @@ -949,32 +983,10 @@ static void notifySingle(dyld_image_states state, const ImageLoader* image, Imag 353 - // mach message csdlc about dynamically unloaded images 354 - if ( image->addFuncNotified() && (state == dyld_image_state_terminated) ) { 355 - notifyKernel(*image, false); 356 - - 357 - - uint64_t loadTimestamp = mach_absolute_time(); 358 - - if ( sEnv.DYLD_PRINT_CS_NOTIFICATIONS ) { 359 - - dyld::log("dyld: coresymbolication_unload_notifier(%p, 0x%016llX, %p, %s)\n", 360 - - dyld::gProcessInfo->coreSymbolicationShmPage, loadTimestamp, image->machHeader(), image->getPath()); 361 - - } 362 - - if ( dyld::gProcessInfo->coreSymbolicationShmPage != NULL) { 363 - - coresymbolication_unload_notifier(dyld::gProcessInfo->coreSymbolicationShmPage, loadTimestamp, image->getPath(), image->machHeader()); 364 - - } 365 - - for (int slot=0; slot < DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT; ++slot) { 366 - - if ( dyld::gProcessInfo->notifyPorts[slot] != 0 ) { 367 - - dyld_image_info info; 368 - - info.imageLoadAddress = image->machHeader(); 369 - - info.imageFilePath = image->getPath(); 370 - - info.imageFileModDate = 0; 371 - - notifyMonitoringDyld(true, slot, 1, &info); 372 - - } 373 - - else if ( sNotifyReplyPorts[slot] != 0 ) { 374 - - // monitoring process detached from this process, so release reply port 375 - - //dyld::log("deallocated reply port %d\n", sNotifyReplyPorts[slot]); 376 - - mach_port_deallocate(mach_task_self(), sNotifyReplyPorts[slot]); 377 - - sNotifyReplyPorts[slot] = 0; 378 - - } 379 - - } 380 - + const struct mach_header* loadAddress[] = { image->machHeader() }; 381 - + const char* loadPath[] = { image->getPath() }; 382 - + notifyMonitoringDyld(true, 1, loadAddress, loadPath); 383 - } 384 - - 385 - } 386 - 387 - 388 - @@ -1186,32 +1237,80 @@ static void notifyBatchPartial(dyld_image_states state, bool orLater, dyld_image 389 - if ( dontLoadReason != NULL ) 390 - throw dontLoadReason; 391 - if ( !preflightOnly && (state == dyld_image_state_dependents_mapped) ) { 392 - - if ( (dyld::gProcessInfo->coreSymbolicationShmPage != NULL) || sEnv.DYLD_PRINT_CS_NOTIFICATIONS ) { 393 - - // mach message csdlc about loaded images 394 - - uint64_t loadTimestamp = mach_absolute_time(); 395 - - for (unsigned j=0; j < imageCount; ++j) { 396 - - if ( sEnv.DYLD_PRINT_CS_NOTIFICATIONS ) { 397 - - dyld::log("dyld: coresymbolication_load_notifier(%p, 0x%016llX, %p, %s)\n", 398 - - dyld::gProcessInfo->coreSymbolicationShmPage, loadTimestamp, infos[j].imageLoadAddress, infos[j].imageFilePath); 399 - - } 400 - - coresymbolication_load_notifier(dyld::gProcessInfo->coreSymbolicationShmPage, loadTimestamp, infos[j].imageFilePath, infos[j].imageLoadAddress); 401 - - } 402 - - } 403 - - for (int slot=0; slot < DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT; ++slot) { 404 - - if ( dyld::gProcessInfo->notifyPorts[slot] ) 405 - - notifyMonitoringDyld(false, slot, imageCount, infos); 406 - + const struct mach_header* loadAddresses[imageCount]; 407 - + const char* loadPaths[imageCount]; 408 - + for(uint32_t i = 0; i<imageCount; ++i) { 409 - + loadAddresses[i] = infos[i].imageLoadAddress; 410 - + loadPaths[i] = infos[i].imageFilePath; 411 - } 412 - + notifyMonitoringDyld(false, imageCount, loadAddresses, loadPaths); 413 - } 414 - } 415 - } 416 - 417 - - 418 - - 419 - static void notifyBatch(dyld_image_states state, bool preflightOnly) 420 - { 421 - notifyBatchPartial(state, false, NULL, preflightOnly, false); 422 - } 423 - 424 - +#if __MAC_OS_X_VERSION_MIN_REQUIRED 425 - +static 426 - +void coresymbolication_load_notifier(void* connection, uint64_t timestamp, const char* path, const struct mach_header* mh) 427 - +{ 428 - + const struct mach_header* loadAddress[] = { mh }; 429 - + const char* loadPath[] = { path }; 430 - + notifyMonitoringDyld(false, 1, loadAddress, loadPath); 431 - +} 432 - + 433 - +static 434 - +void coresymbolication_unload_notifier(void* connection, uint64_t timestamp, const char* path, const struct mach_header* mh) 435 - +{ 436 - + const struct mach_header* loadAddress = { mh }; 437 - + const char* loadPath = { path }; 438 - + notifyMonitoringDyld(true, 1, &loadAddress, &loadPath); 439 - +} 440 - + 441 - +static 442 - +kern_return_t legacy_task_register_dyld_image_infos(task_t task, dyld_kernel_image_info_array_t dyld_images, 443 - + mach_msg_type_number_t dyld_imagesCnt) 444 - +{ 445 - + return KERN_SUCCESS; 446 - +} 447 - + 448 - +static 449 - +kern_return_t legacy_task_unregister_dyld_image_infos(task_t task, dyld_kernel_image_info_array_t dyld_images, 450 - + mach_msg_type_number_t dyld_imagesCnt) 451 - +{ 452 - + return KERN_SUCCESS; 453 - +} 454 - + 455 - +static 456 - +kern_return_t legacy_task_get_dyld_image_infos(task_inspect_t task, dyld_kernel_image_info_array_t *dyld_images, 457 - + mach_msg_type_number_t *dyld_imagesCnt) 458 - +{ 459 - + return KERN_SUCCESS; 460 - +} 461 - + 462 - +static 463 - +kern_return_t legacy_task_register_dyld_shared_cache_image_info(task_t task, dyld_kernel_image_info_t dyld_cache_image, 464 - + boolean_t no_cache, boolean_t private_cache) 465 - +{ 466 - + return KERN_SUCCESS; 467 - +} 468 - + 469 - +static 470 - +kern_return_t legacy_task_register_dyld_set_dyld_state(task_t task, uint8_t dyld_state) 471 - +{ 472 - + return KERN_SUCCESS; 473 - +} 474 - + 475 - +static 476 - +kern_return_t legacy_task_register_dyld_get_process_state(task_t task, dyld_kernel_process_info_t *dyld_process_state) 477 - +{ 478 - + return KERN_SUCCESS; 479 - +} 480 - +#endif 481 - + 482 - // In order for register_func_for_add_image() callbacks to to be called bottom up, 483 - // we need to maintain a list of root images. The main executable is usally the 484 - // first root. Any images dynamically added are also roots (unless already loaded). 485 - @@ -1267,7 +1366,7 @@ static void setRunInitialzersOldWay() 486 - 487 - static bool sandboxBlocked(const char* path, const char* kind) 488 - { 489 - -#if TARGET_IPHONE_SIMULATOR 490 - +#if TARGET_OS_SIMULATOR 491 - // sandbox calls not yet supported in simulator runtime 492 - return false; 493 - #else 494 - @@ -2664,10 +2873,10 @@ const int kX86_64_RowCount = 2; 495 - static const cpu_subtype_t kX86_64[kX86_64_RowCount][5] = { 496 - 497 - // x86_64h can run: x86_64h, x86_64h(lib), x86_64(lib), and x86_64 498 - - { CPU_SUBTYPE_X86_64_H, CPU_SUBTYPE_LIB64|CPU_SUBTYPE_X86_64_H, CPU_SUBTYPE_LIB64|CPU_SUBTYPE_X86_64_ALL, CPU_SUBTYPE_X86_64_ALL, CPU_SUBTYPE_END_OF_LIST }, 499 - + { CPU_SUBTYPE_X86_64_H, (cpu_subtype_t)(CPU_SUBTYPE_LIB64|CPU_SUBTYPE_X86_64_H), (cpu_subtype_t)(CPU_SUBTYPE_LIB64|CPU_SUBTYPE_X86_64_ALL), CPU_SUBTYPE_X86_64_ALL, CPU_SUBTYPE_END_OF_LIST }, 500 - 501 - // x86_64 can run: x86_64(lib) and x86_64 502 - - { CPU_SUBTYPE_X86_64_ALL, CPU_SUBTYPE_LIB64|CPU_SUBTYPE_X86_64_ALL, CPU_SUBTYPE_END_OF_LIST }, 503 - + { CPU_SUBTYPE_X86_64_ALL, (cpu_subtype_t)(CPU_SUBTYPE_LIB64|CPU_SUBTYPE_X86_64_ALL), CPU_SUBTYPE_END_OF_LIST }, 504 - 505 - }; 506 - #endif 507 - @@ -3923,775 +4227,181 @@ ImageLoader* load(const char* path, const LoadContext& context, unsigned& cacheI 508 - 509 - 510 - 511 - -#if DYLD_SHARED_CACHE_SUPPORT 512 - 513 - 514 - +static void mapSharedCache() 515 - +{ 516 - + dyld3::SharedCacheOptions opts; 517 - + opts.cacheDirOverride = sSharedCacheOverrideDir; 518 - + opts.forcePrivate = (gLinkContext.sharedRegionMode == ImageLoader::kUsePrivateSharedRegion); 519 - + 520 - 521 - -#if __i386__ 522 - - #define ARCH_NAME "i386" 523 - - #define ARCH_CACHE_MAGIC "dyld_v1 i386" 524 - -#elif __x86_64__ 525 - - #define ARCH_NAME "x86_64" 526 - - #define ARCH_CACHE_MAGIC "dyld_v1 x86_64" 527 - - #define ARCH_NAME_H "x86_64h" 528 - - #define ARCH_CACHE_MAGIC_H "dyld_v1 x86_64h" 529 - -#elif __ARM_ARCH_5TEJ__ 530 - - #define ARCH_NAME "armv5" 531 - - #define ARCH_CACHE_MAGIC "dyld_v1 armv5" 532 - -#elif __ARM_ARCH_6K__ 533 - - #define ARCH_NAME "armv6" 534 - - #define ARCH_CACHE_MAGIC "dyld_v1 armv6" 535 - -#elif __ARM_ARCH_7F__ 536 - - #define ARCH_NAME "armv7f" 537 - - #define ARCH_CACHE_MAGIC "dyld_v1 armv7f" 538 - -#elif __ARM_ARCH_7K__ 539 - - #define ARCH_NAME "armv7k" 540 - - #define ARCH_CACHE_MAGIC "dyld_v1 armv7k" 541 - -#elif __ARM_ARCH_7A__ 542 - - #define ARCH_NAME "armv7" 543 - - #define ARCH_CACHE_MAGIC "dyld_v1 armv7" 544 - -#elif __ARM_ARCH_7S__ 545 - - #define ARCH_NAME "armv7s" 546 - - #define ARCH_CACHE_MAGIC "dyld_v1 armv7s" 547 - -#elif __arm64__ 548 - - #define ARCH_NAME "arm64" 549 - - #define ARCH_CACHE_MAGIC "dyld_v1 arm64" 550 - +#if __x86_64__ && !TARGET_OS_SIMULATOR 551 - + opts.useHaswell = sHaswell; 552 - +#else 553 - + opts.useHaswell = false; 554 - #endif 555 - + opts.verbose = gLinkContext.verboseMapping; 556 - + loadDyldCache(opts, &sSharedCacheLoadInfo); 557 - 558 - + // update global state 559 - + if ( sSharedCacheLoadInfo.loadAddress != nullptr ) { 560 - + gLinkContext.dyldCache = sSharedCacheLoadInfo.loadAddress; 561 - + dyld::gProcessInfo->processDetachedFromSharedRegion = opts.forcePrivate; 562 - + dyld::gProcessInfo->sharedCacheSlide = sSharedCacheLoadInfo.slide; 563 - + dyld::gProcessInfo->sharedCacheBaseAddress = (unsigned long)sSharedCacheLoadInfo.loadAddress; 564 - + sSharedCacheLoadInfo.loadAddress->getUUID(dyld::gProcessInfo->sharedCacheUUID); 565 - + dyld3::kdebug_trace_dyld_image(DBG_DYLD_UUID_SHARED_CACHE_A, sSharedCacheLoadInfo.path, (const uuid_t *)&dyld::gProcessInfo->sharedCacheUUID[0], {0,0}, {{ 0, 0 }}, (const mach_header *)sSharedCacheLoadInfo.loadAddress); 566 - + } 567 - 568 - -static int __attribute__((noinline)) _shared_region_check_np(uint64_t* start_address) 569 - -{ 570 - - if ( gLinkContext.sharedRegionMode == ImageLoader::kUseSharedRegion ) 571 - - return syscall(294, start_address); 572 - - return -1; 573 - +//#if __IPHONE_OS_VERSION_MIN_REQUIRED && !TARGET_OS_SIMULATOR 574 - +// RAM disk booting does not have shared cache yet 575 - +// Don't make lack of a shared cache fatal in that case 576 - +// if ( sSharedCacheLoadInfo.loadAddress == nullptr ) { 577 - +// if ( sSharedCacheLoadInfo.errorMessage != nullptr ) 578 - +// halt(sSharedCacheLoadInfo.errorMessage); 579 - +// else 580 - +// halt("error loading dyld shared cache"); 581 - +// } 582 - +//#endif 583 - } 584 - 585 - 586 - -static void rebaseChain(uint8_t* pageContent, uint16_t startOffset, uintptr_t slideAmount, const dyld_cache_slide_info2* slideInfo) 587 - -{ 588 - - const uintptr_t deltaMask = (uintptr_t)(slideInfo->delta_mask); 589 - - const uintptr_t valueMask = ~deltaMask; 590 - - const uintptr_t valueAdd = (uintptr_t)(slideInfo->value_add); 591 - - const unsigned deltaShift = __builtin_ctzll(deltaMask) - 2; 592 - 593 - - uint32_t pageOffset = startOffset; 594 - - uint32_t delta = 1; 595 - - while ( delta != 0 ) { 596 - - uint8_t* loc = pageContent + pageOffset; 597 - - uintptr_t rawValue = *((uintptr_t*)loc); 598 - - delta = (uint32_t)((rawValue & deltaMask) >> deltaShift); 599 - - uintptr_t value = (rawValue & valueMask); 600 - - if ( value != 0 ) { 601 - - value += valueAdd; 602 - - value += slideAmount; 603 - - } 604 - - *((uintptr_t*)loc) = value; 605 - - //dyld::log(" pageOffset=0x%03X, loc=%p, org value=0x%08llX, new value=0x%08llX, delta=0x%X\n", pageOffset, loc, (uint64_t)rawValue, (uint64_t)value, delta); 606 - - pageOffset += delta; 607 - - } 608 - +// create when NSLinkModule is called for a second time on a bundle 609 - +ImageLoader* cloneImage(ImageLoader* image) 610 - +{ 611 - + // open file (automagically closed when this function exits) 612 - + FileOpener file(image->getPath()); 613 - + 614 - + struct stat stat_buf; 615 - + if ( fstat(file.getFileDescriptor(), &stat_buf) == -1) 616 - + throw "stat error"; 617 - + 618 - + dyld::LoadContext context; 619 - + context.useSearchPaths = false; 620 - + context.useFallbackPaths = false; 621 - + context.useLdLibraryPath = false; 622 - + context.implicitRPath = false; 623 - + context.matchByInstallName = false; 624 - + context.dontLoad = false; 625 - + context.mustBeBundle = true; 626 - + context.mustBeDylib = false; 627 - + context.canBePIE = false; 628 - + context.origin = NULL; 629 - + context.rpath = NULL; 630 - + return loadPhase6(file.getFileDescriptor(), stat_buf, image->getPath(), context); 631 - } 632 - 633 - 634 - -static void loadAndCheckCodeSignature(int fd, uint32_t count, const shared_file_mapping_np mappings[], 635 - - off_t codeSignatureOffset, size_t codeSignatureSize, 636 - - const void *firstPages, size_t firstPagesSize) 637 - +ImageLoader* loadFromMemory(const uint8_t* mem, uint64_t len, const char* moduleName) 638 - { 639 - - // register code signature blob for whole dyld cache 640 - - fsignatures_t siginfo; 641 - - siginfo.fs_file_start = 0; // cache always starts at beginning of file 642 - - siginfo.fs_blob_start = (void*)codeSignatureOffset; 643 - - siginfo.fs_blob_size = codeSignatureSize; 644 - + // if fat wrapper, find usable sub-file 645 - + const fat_header* memStartAsFat = (fat_header*)mem; 646 - + uint64_t fileOffset = 0; 647 - + uint64_t fileLength = len; 648 - + if ( memStartAsFat->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) { 649 - + if ( fatFindBest(memStartAsFat, &fileOffset, &fileLength) ) { 650 - + mem = &mem[fileOffset]; 651 - + len = fileLength; 652 - + } 653 - + else { 654 - + throw "no matching architecture in universal wrapper"; 655 - + } 656 - + } 657 - 658 - - int result = fcntl(fd, F_ADDFILESIGS_RETURN, &siginfo); 659 - - // <rdar://problem/12891874> don't warn in chrooted case because mapping syscall is about to fail too 660 - - if ( result == -1 ) { 661 - -#if __IPHONE_OS_VERSION_MIN_REQUIRED 662 - - throwf("code signature registration for shared cache failed with errno=%d\n", errno); 663 - -#else 664 - - if ( gLinkContext.verboseMapping ) 665 - - dyld::log("dyld: code signature registration for shared cache failed with errno=%d\n", errno); 666 - -#endif 667 - + // try each loader 668 - + if ( isCompatibleMachO(mem, moduleName) ) { 669 - + ImageLoader* image = ImageLoaderMachO::instantiateFromMemory(moduleName, (macho_header*)mem, len, gLinkContext); 670 - + // don't add bundles to global list, they can be loaded but not linked. When linked it will be added to list 671 - + if ( ! image->isBundle() ) 672 - + addImage(image); 673 - + return image; 674 - } 675 - - uint64_t codeSignedLength = siginfo.fs_file_start; 676 - - for (uint32_t i = 0; i < count; ++i) { 677 - - if ( (mappings[i].sfm_size > codeSignedLength) || (mappings[i].sfm_file_offset > (codeSignedLength - mappings[i].sfm_size)) ) 678 - - throw "dyld shared cache mapping not covered by code signature"; 679 - + 680 - + // try other file formats here... 681 - + 682 - + // throw error about what was found 683 - + switch (*(uint32_t*)mem) { 684 - + case MH_MAGIC: 685 - + case MH_CIGAM: 686 - + case MH_MAGIC_64: 687 - + case MH_CIGAM_64: 688 - + throw "mach-o, but wrong architecture"; 689 - + default: 690 - + throwf("unknown file type, first eight bytes: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", 691 - + mem[0], mem[1], mem[2], mem[3], mem[4], mem[5], mem[6],mem[7]); 692 - } 693 - - 694 - - void *fdata = xmmap(NULL, firstPagesSize, PROT_READ|PROT_EXEC, MAP_PRIVATE, fd, 0); 695 - - if ( fdata == MAP_FAILED ) 696 - - throwf("mmap() errno=%d validating first page of shared cache", errno); 697 - - if ( memcmp(fdata, firstPages, firstPagesSize) != 0 ) 698 - - throwf("mmap() page compare failed for shared cache"); 699 - - munmap(fdata, firstPagesSize); 700 - } 701 - 702 - -static int __attribute__((noinline)) _shared_region_map_and_slide_np(int fd, uint32_t count, const shared_file_mapping_np mappings[], 703 - - long slide, void* slideInfo, unsigned long slideInfoSize) 704 - -{ 705 - - if ( gLinkContext.sharedRegionMode == ImageLoader::kUseSharedRegion ) { 706 - - return syscall(438, fd, count, mappings, slide, slideInfo, slideInfoSize); 707 - - } 708 - 709 - - // remove the shared region sub-map 710 - - vm_deallocate(mach_task_self(), (vm_address_t)SHARED_REGION_BASE, SHARED_REGION_SIZE); 711 - +void registerAddCallback(ImageCallback func) 712 - +{ 713 - + // now add to list to get notified when any more images are added 714 - + sAddImageCallbacks.push_back(func); 715 - 716 - - // notify gdb or other lurkers that this process is no longer using the shared region 717 - - dyld::gProcessInfo->processDetachedFromSharedRegion = true; 718 - - 719 - - // map cache just for this process with mmap() 720 - - const shared_file_mapping_np* const start = mappings; 721 - - const shared_file_mapping_np* const end = &mappings[count]; 722 - - for (const shared_file_mapping_np* p = start; p < end; ++p ) { 723 - - void* mmapAddress = (void*)(uintptr_t)(p->sfm_address); 724 - - size_t size = p->sfm_size; 725 - - //dyld::log("dyld: mapping address %p with size 0x%08lX\n", mmapAddress, size); 726 - - int protection = 0; 727 - - if ( p->sfm_init_prot & VM_PROT_EXECUTE ) 728 - - protection |= PROT_EXEC; 729 - - if ( p->sfm_init_prot & VM_PROT_READ ) 730 - - protection |= PROT_READ; 731 - - if ( p->sfm_init_prot & VM_PROT_WRITE ) 732 - - protection |= PROT_WRITE; 733 - - off_t offset = p->sfm_file_offset; 734 - - if ( mmap(mmapAddress, size, protection, MAP_FIXED | MAP_PRIVATE, fd, offset) != mmapAddress ) { 735 - - // failed to map some chunk of this shared cache file 736 - - // clear shared region 737 - - vm_deallocate(mach_task_self(), (vm_address_t)SHARED_REGION_BASE, SHARED_REGION_SIZE); 738 - - // go back to not using shared region at all 739 - - gLinkContext.sharedRegionMode = ImageLoader::kDontUseSharedRegion; 740 - - if ( gLinkContext.verboseMapping ) { 741 - - dyld::log("dyld: shared cached region cannot be mapped at address %p with size 0x%08lX\n", 742 - - mmapAddress, size); 743 - - } 744 - - // return failure 745 - - return -1; 746 - - } 747 - - } 748 - - 749 - - // update all __DATA pages with slide info 750 - - const dyld_cache_slide_info* slideInfoHeader = (dyld_cache_slide_info*)slideInfo; 751 - - if ( slideInfoHeader->version == 2 ) { 752 - - const dyld_cache_slide_info2* slideHeader = (dyld_cache_slide_info2*)slideInfo; 753 - - const uint32_t page_size = slideHeader->page_size; 754 - - const uint16_t* page_starts = (uint16_t*)((long)(slideInfo) + slideHeader->page_starts_offset); 755 - - const uint16_t* page_extras = (uint16_t*)((long)(slideInfo) + slideHeader->page_extras_offset); 756 - - const uintptr_t dataPagesStart = mappings[1].sfm_address; 757 - - for (int i=0; i < slideHeader->page_starts_count; ++i) { 758 - - uint8_t* page = (uint8_t*)(long)(dataPagesStart + (page_size*i)); 759 - - uint16_t pageEntry = page_starts[i]; 760 - - //dyld::log("page[%d]: page_starts[i]=0x%04X\n", i, pageEntry); 761 - - if ( pageEntry == DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE ) 762 - - continue; 763 - - if ( pageEntry & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA ) { 764 - - uint16_t chainIndex = (pageEntry & 0x3FFF); 765 - - bool done = false; 766 - - while ( !done ) { 767 - - uint16_t info = page_extras[chainIndex]; 768 - - uint16_t pageStartOffset = (info & 0x3FFF)*4; 769 - - //dyld::log(" chain[%d] pageOffset=0x%03X\n", chainIndex, pageStartOffset); 770 - - rebaseChain(page, pageStartOffset, slide, slideHeader); 771 - - done = (info & DYLD_CACHE_SLIDE_PAGE_ATTR_END); 772 - - ++chainIndex; 773 - - } 774 - - } 775 - - else { 776 - - uint32_t pageOffset = pageEntry * 4; 777 - - //dyld::log(" start pageOffset=0x%03X\n", pageOffset); 778 - - rebaseChain(page, pageOffset, slide, slideHeader); 779 - - } 780 - + // call callback with all existing images 781 - + for (std::vector<ImageLoader*>::iterator it=sAllImages.begin(); it != sAllImages.end(); it++) { 782 - + ImageLoader* image = *it; 783 - + if ( image->getState() >= dyld_image_state_bound && image->getState() < dyld_image_state_terminated ) { 784 - + dyld3::ScopedTimer timer(DBG_DYLD_TIMING_FUNC_FOR_ADD_IMAGE, (uint64_t)image->machHeader(), (uint64_t)(*func), 0); 785 - + (*func)(image->machHeader(), image->getSlide()); 786 - } 787 - } 788 - - else if ( slide != 0 ) { 789 - - const uintptr_t dataPagesStart = mappings[1].sfm_address; 790 - - const uint16_t* toc = (uint16_t*)((long)(slideInfoHeader) + slideInfoHeader->toc_offset); 791 - - const uint8_t* entries = (uint8_t*)((long)(slideInfoHeader) + slideInfoHeader->entries_offset); 792 - - for(uint32_t i=0; i < slideInfoHeader->toc_count; ++i) { 793 - - const uint8_t* entry = &entries[toc[i]*slideInfoHeader->entries_size]; 794 - - const uint8_t* page = (uint8_t*)(long)(dataPagesStart + (4096*i)); 795 - - //dyld::log("page=%p toc[%d]=%d entries=%p\n", page, i, toc[i], entry); 796 - - for(int j=0; j < 128; ++j) { 797 - - uint8_t b = entry[j]; 798 - - //dyld::log(" entry[%d] = 0x%02X\n", j, b); 799 - - if ( b != 0 ) { 800 - - for(int k=0; k < 8; ++k) { 801 - - if ( b & (1<<k) ) { 802 - - uintptr_t* p = (uintptr_t*)(page + j*8*4 + k*4); 803 - - uintptr_t value = *p; 804 - - //dyld::log(" *%p was 0x%lX will be 0x%lX\n", p, value, value+sSharedCacheSlide); 805 - - *p = value + slide; 806 - - } 807 - - } 808 - - } 809 - - } 810 - +#if SUPPORT_ACCELERATE_TABLES 811 - + if ( sAllCacheImagesProxy != NULL ) { 812 - + dyld_image_info infos[allImagesCount()+1]; 813 - + unsigned cacheCount = sAllCacheImagesProxy->appendImagesToNotify(dyld_image_state_bound, true, infos); 814 - + for (unsigned i=0; i < cacheCount; ++i) { 815 - + dyld3::ScopedTimer timer(DBG_DYLD_TIMING_FUNC_FOR_ADD_IMAGE, (uint64_t)infos[i].imageLoadAddress, (uint64_t)(*func), 0); 816 - + (*func)(infos[i].imageLoadAddress, sSharedCacheLoadInfo.slide); 817 - } 818 - } 819 - - 820 - - // succesfully mapped shared cache for just this process 821 - - gLinkContext.sharedRegionMode = ImageLoader::kUsePrivateSharedRegion; 822 - - 823 - - return 0; 824 - -} 825 - - 826 - - 827 - -const void* imMemorySharedCacheHeader() 828 - -{ 829 - - return sSharedCache; 830 - -} 831 - - 832 - -const char* getStandardSharedCacheFilePath() 833 - -{ 834 - -#if __IPHONE_OS_VERSION_MIN_REQUIRED 835 - - return IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME; 836 - -#else 837 - - #if __x86_64__ 838 - - if ( sHaswell ) { 839 - - const char* path2 = MACOSX_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME_H; 840 - - struct stat statBuf; 841 - - if ( my_stat(path2, &statBuf) == 0 ) 842 - - return path2; 843 - - } 844 - - #endif 845 - - return MACOSX_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME; 846 - #endif 847 - } 848 - 849 - -int openSharedCacheFile() 850 - +void registerLoadCallback(LoadImageCallback func) 851 - { 852 - - char path[MAXPATHLEN]; 853 - - strlcpy(path, sSharedCacheDir, MAXPATHLEN); 854 - - strlcat(path, "/", MAXPATHLEN); 855 - -#if __x86_64__ 856 - - if ( sHaswell ) { 857 - - strlcat(path, DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME_H, MAXPATHLEN); 858 - - int fd = my_open(path, O_RDONLY, 0); 859 - - if ( fd != -1 ) { 860 - - if ( gLinkContext.verboseMapping ) 861 - - dyld::log("dyld: Mapping%s shared cache from %s\n", (gLinkContext.sharedRegionMode == ImageLoader::kUsePrivateSharedRegion) ? " private": "", path); 862 - - return fd; 863 - - } 864 - - strlcpy(path, sSharedCacheDir, MAXPATHLEN); 865 - - } 866 - -#endif 867 - - strlcat(path, DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME, MAXPATHLEN); 868 - -#if __IPHONE_OS_VERSION_MIN_REQUIRED 869 - - struct stat enableStatBuf; 870 - - struct stat devCacheStatBuf; 871 - - struct stat prodCacheStatBuf; 872 - - if ( ((my_stat(IPHONE_DYLD_SHARED_CACHE_DIR "enable-dylibs-to-override-cache", &enableStatBuf) == 0) 873 - - && (enableStatBuf.st_size < ENABLE_DYLIBS_TO_OVERRIDE_CACHE_SIZE) 874 - - && (my_stat(IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME DYLD_SHARED_CACHE_DEVELOPMENT_EXT, &devCacheStatBuf) == 0)) 875 - - || (my_stat(IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME, &prodCacheStatBuf) != 0)) 876 - - strlcat(path, DYLD_SHARED_CACHE_DEVELOPMENT_EXT, MAXPATHLEN); 877 - -#endif 878 - - if ( gLinkContext.verboseMapping ) 879 - - dyld::log("dyld: Mapping%s shared cache from %s\n", (gLinkContext.sharedRegionMode == ImageLoader::kUsePrivateSharedRegion) ? " private": "", path); 880 - - return my_open(path, O_RDONLY, 0); 881 - -} 882 - - 883 - + // now add to list to get notified when any more images are added 884 - + sAddLoadImageCallbacks.push_back(func); 885 - 886 - -static void getCacheBounds(uint32_t mappingsCount, const shared_file_mapping_np mappings[], uint64_t& lowAddress, uint64_t& highAddress) 887 - -{ 888 - - lowAddress = 0; 889 - - highAddress = 0; 890 - - for(uint32_t i=0; i < mappingsCount; ++i) { 891 - - if ( lowAddress == 0 ) { 892 - - lowAddress = mappings[i].sfm_address; 893 - - highAddress = mappings[i].sfm_address + mappings[i].sfm_size; 894 - - } 895 - - else { 896 - - if ( mappings[i].sfm_address < lowAddress ) 897 - - lowAddress = mappings[i].sfm_address; 898 - - if ( (mappings[i].sfm_address + mappings[i].sfm_size) > highAddress ) 899 - - highAddress = mappings[i].sfm_address + mappings[i].sfm_size; 900 - + // call callback with all existing images 901 - + for (ImageLoader* image : sAllImages) { 902 - + if ( image->getState() >= dyld_image_state_bound && image->getState() < dyld_image_state_terminated ) { 903 - + dyld3::ScopedTimer timer(DBG_DYLD_TIMING_FUNC_FOR_ADD_IMAGE, (uint64_t)image->machHeader(), (uint64_t)(*func), 0); 904 - + (*func)(image->machHeader(), image->getPath(), !image->neverUnload()); 905 - } 906 - } 907 - -} 908 - - 909 - -static long pickCacheSlide(uint32_t mappingsCount, shared_file_mapping_np mappings[]) 910 - -{ 911 - -#if __x86_64__ 912 - - // x86_64 has a two memory regions: 913 - - // 256MB at 0x00007FFF70000000 914 - - // 1024MB at 0x00007FFF80000000 915 - - // Some old shared caches have r/w region after rx region, so all regions slide within 1GB range 916 - - // Newer shared caches have r/w region based at 0x7FFF70000000 and r/o regions at 0x7FFF80000000, so each part has max slide 917 - - if ( (mappingsCount >= 3) && (mappings[1].sfm_init_prot == (VM_PROT_READ|VM_PROT_WRITE)) && (mappings[1].sfm_address == 0x00007FFF70000000) ) { 918 - - const uint64_t rwSize = mappings[1].sfm_size; 919 - - const uint64_t rwSlop = 0x10000000ULL - rwSize; 920 - - const uint64_t roSize = (mappings[2].sfm_address + mappings[2].sfm_size) - mappings[0].sfm_address; 921 - - const uint64_t roSlop = 0x40000000ULL - roSize; 922 - - const uint64_t space = (rwSlop < roSlop) ? rwSlop : roSlop; 923 - - 924 - - // choose new random slide 925 - - long slide = (arc4random() % space) & (-4096); 926 - - //dyld::log("rwSlop=0x%0llX, roSlop=0x%0llX\n", rwSlop, roSlop); 927 - - //dyld::log("space=0x%0llX, slide=0x%0lX\n", space, slide); 928 - - 929 - - // update mappings 930 - - for(uint32_t i=0; i < mappingsCount; ++i) { 931 - - mappings[i].sfm_address += slide; 932 - +#if SUPPORT_ACCELERATE_TABLES 933 - + if ( sAllCacheImagesProxy != NULL ) { 934 - + dyld_image_info infos[allImagesCount()+1]; 935 - + unsigned cacheCount = sAllCacheImagesProxy->appendImagesToNotify(dyld_image_state_bound, true, infos); 936 - + for (unsigned i=0; i < cacheCount; ++i) { 937 - + dyld3::ScopedTimer timer(DBG_DYLD_TIMING_FUNC_FOR_ADD_IMAGE, (uint64_t)infos[i].imageLoadAddress, (uint64_t)(*func), 0); 938 - + (*func)(infos[i].imageLoadAddress, infos[i].imageFilePath, false); 939 - } 940 - - 941 - - return slide; 942 - } 943 - - // else fall through to handle old style cache 944 - #endif 945 - - // get bounds of cache 946 - - uint64_t lowAddress; 947 - - uint64_t highAddress; 948 - - getCacheBounds(mappingsCount, mappings, lowAddress, highAddress); 949 - - 950 - - // find slop space 951 - - const uint64_t space = (SHARED_REGION_BASE + SHARED_REGION_SIZE) - highAddress; 952 - - 953 - - // choose new random slide 954 - -#if __arm__ 955 - - // <rdar://problem/20848977> change shared cache slide for 32-bit arm to always be 16k aligned 956 - - long slide = ((arc4random() % space) & (-16384)); 957 - -#else 958 - - long slide = dyld_page_trunc(arc4random() % space); 959 - -#endif 960 - - //dyld::log("slideSpace=0x%0llX\n", space); 961 - - //dyld::log("slide=0x%0lX\n", slide); 962 - - 963 - - // update mappings 964 - - for(uint32_t i=0; i < mappingsCount; ++i) { 965 - - mappings[i].sfm_address += slide; 966 - - } 967 - - 968 - - return slide; 969 - } 970 - 971 - -static void mapSharedCache() 972 - +void registerBulkLoadCallback(LoadImageBulkCallback func) 973 - { 974 - - uint64_t cacheBaseAddress = 0; 975 - - // quick check if a cache is already mapped into shared region 976 - - if ( _shared_region_check_np(&cacheBaseAddress) == 0 ) { 977 - - sSharedCache = (dyld_cache_header*)cacheBaseAddress; 978 - - // if we don't understand the currently mapped shared cache, then ignore 979 - -#if __x86_64__ 980 - - const char* magic = (sHaswell ? ARCH_CACHE_MAGIC_H : ARCH_CACHE_MAGIC); 981 - -#else 982 - - const char* magic = ARCH_CACHE_MAGIC; 983 - -#endif 984 - - if ( strcmp(sSharedCache->magic, magic) != 0 ) { 985 - - sSharedCache = NULL; 986 - - if ( gLinkContext.verboseMapping ) { 987 - - dyld::log("dyld: existing shared cached in memory is not compatible\n"); 988 - - return; 989 - - } 990 - - } 991 - - // check if cache file is slidable 992 - - const dyld_cache_header* header = sSharedCache; 993 - - if ( (header->mappingOffset >= 0x48) && (header->slideInfoSize != 0) ) { 994 - - // solve for slide by comparing loaded address to address of first region 995 - - const uint8_t* loadedAddress = (uint8_t*)sSharedCache; 996 - - const dyld_cache_mapping_info* const mappings = (dyld_cache_mapping_info*)(loadedAddress+header->mappingOffset); 997 - - const uint8_t* preferedLoadAddress = (uint8_t*)(long)(mappings[0].address); 998 - - sSharedCacheSlide = loadedAddress - preferedLoadAddress; 999 - - dyld::gProcessInfo->sharedCacheSlide = sSharedCacheSlide; 1000 - - dyld::gProcessInfo->sharedCacheBaseAddress = cacheBaseAddress; 1001 - - //dyld::log("sSharedCacheSlide=0x%08lX, loadedAddress=%p, preferedLoadAddress=%p\n", sSharedCacheSlide, loadedAddress, preferedLoadAddress); 1002 - - } 1003 - - // if cache has a uuid, copy it 1004 - - if ( header->mappingOffset >= 0x68 ) { 1005 - - memcpy(dyld::gProcessInfo->sharedCacheUUID, header->uuid, 16); 1006 - - } 1007 - - // verbose logging 1008 - - if ( gLinkContext.verboseMapping ) { 1009 - - dyld::log("dyld: re-using existing %s shared cache mapping\n", (header->cacheType == kDyldSharedCacheTypeDevelopment ? "development" : "production")); 1010 - - } 1011 - - if (header->mappingOffset >= 0x68) { 1012 - - dyld_kernel_image_info_t kernelCacheInfo; 1013 - - memcpy(&kernelCacheInfo.uuid[0], &sSharedCache->uuid[0], sizeof(uuid_t)); 1014 - - kernelCacheInfo.load_addr = (uint64_t)sSharedCache; 1015 - - kernelCacheInfo.fsobjid.fid_objno = 0; 1016 - - kernelCacheInfo.fsobjid.fid_generation = 0; 1017 - - kernelCacheInfo.fsid.val[0] = 0; 1018 - - kernelCacheInfo.fsid.val[0] = 0; 1019 - - task_register_dyld_shared_cache_image_info(mach_task_self(), kernelCacheInfo, false, false); 1020 - - } 1021 - - } 1022 - - else { 1023 - -#if __i386__ || __x86_64__ 1024 - - // <rdar://problem/5925940> Safe Boot should disable dyld shared cache 1025 - - // if we are in safe-boot mode and the cache was not made during this boot cycle, 1026 - - // delete the cache file 1027 - - uint32_t safeBootValue = 0; 1028 - - size_t safeBootValueSize = sizeof(safeBootValue); 1029 - - if ( (sysctlbyname("kern.safeboot", &safeBootValue, &safeBootValueSize, NULL, 0) == 0) && (safeBootValue != 0) ) { 1030 - - // user booted machine in safe-boot mode 1031 - - struct stat dyldCacheStatInfo; 1032 - - // Don't use custom DYLD_SHARED_CACHE_DIR if provided, use standard path 1033 - - if ( my_stat(MACOSX_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME, &dyldCacheStatInfo) == 0 ) { 1034 - - struct timeval bootTimeValue; 1035 - - size_t bootTimeValueSize = sizeof(bootTimeValue); 1036 - - if ( (sysctlbyname("kern.boottime", &bootTimeValue, &bootTimeValueSize, NULL, 0) == 0) && (bootTimeValue.tv_sec != 0) ) { 1037 - - // if the cache file was created before this boot, then throw it away and let it rebuild itself 1038 - - if ( dyldCacheStatInfo.st_mtime < bootTimeValue.tv_sec ) { 1039 - - ::unlink(MACOSX_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME); 1040 - - gLinkContext.sharedRegionMode = ImageLoader::kDontUseSharedRegion; 1041 - - return; 1042 - - } 1043 - - } 1044 - - } 1045 - - } 1046 - -#endif 1047 - - // map in shared cache to shared region 1048 - - int fd = openSharedCacheFile(); 1049 - - if ( fd != -1 ) { 1050 - - uint8_t firstPages[8192]; 1051 - - if ( ::read(fd, firstPages, 8192) == 8192 ) { 1052 - - dyld_cache_header* header = (dyld_cache_header*)firstPages; 1053 - - #if __x86_64__ 1054 - - const char* magic = (sHaswell ? ARCH_CACHE_MAGIC_H : ARCH_CACHE_MAGIC); 1055 - - #else 1056 - - const char* magic = ARCH_CACHE_MAGIC; 1057 - - #endif 1058 - - if ( strcmp(header->magic, magic) == 0 ) { 1059 - - const dyld_cache_mapping_info* const fileMappingsStart = (dyld_cache_mapping_info*)&firstPages[header->mappingOffset]; 1060 - - const dyld_cache_mapping_info* const fileMappingsEnd = &fileMappingsStart[header->mappingCount]; 1061 - - #if __IPHONE_OS_VERSION_MIN_REQUIRED 1062 - - if ( (header->mappingCount != 3) 1063 - - || (header->mappingOffset > 256) 1064 - - || (fileMappingsStart[0].fileOffset != 0) 1065 - - || (fileMappingsStart[0].address != SHARED_REGION_BASE) 1066 - - || ((fileMappingsStart[0].address + fileMappingsStart[0].size) > fileMappingsStart[1].address) 1067 - - || ((fileMappingsStart[1].address + fileMappingsStart[1].size) > fileMappingsStart[2].address) 1068 - - || ((fileMappingsStart[0].fileOffset + fileMappingsStart[0].size) != fileMappingsStart[1].fileOffset) 1069 - - || ((fileMappingsStart[1].fileOffset + fileMappingsStart[1].size) != fileMappingsStart[2].fileOffset) ) 1070 - - throw "dyld shared cache file is invalid"; 1071 - - #endif 1072 - - shared_file_mapping_np mappings[header->mappingCount]; 1073 - - unsigned int mappingCount = header->mappingCount; 1074 - - int readWriteMappingIndex = -1; 1075 - - int readOnlyMappingIndex = -1; 1076 - - // validate that the cache file has not been truncated 1077 - - bool goodCache = false; 1078 - - struct stat stat_buf; 1079 - - if ( fstat(fd, &stat_buf) == 0 ) { 1080 - - goodCache = true; 1081 - - int i=0; 1082 - - for (const dyld_cache_mapping_info* p = fileMappingsStart; p < fileMappingsEnd; ++p, ++i) { 1083 - - mappings[i].sfm_address = p->address; 1084 - - mappings[i].sfm_size = p->size; 1085 - - mappings[i].sfm_file_offset = p->fileOffset; 1086 - - mappings[i].sfm_max_prot = p->maxProt; 1087 - - mappings[i].sfm_init_prot = p->initProt; 1088 - - // rdar://problem/5694507 old update_dyld_shared_cache tool could make a cache file 1089 - - // that is not page aligned, but otherwise ok. 1090 - - if ( p->fileOffset+p->size > (uint64_t)(stat_buf.st_size+4095 & (-4096)) ) { 1091 - - dyld::log("dyld: shared cached file is corrupt: %s" DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME "\n", sSharedCacheDir); 1092 - - goodCache = false; 1093 - - } 1094 - - if ( (mappings[i].sfm_init_prot & (VM_PROT_READ|VM_PROT_WRITE)) == (VM_PROT_READ|VM_PROT_WRITE) ) { 1095 - - readWriteMappingIndex = i; 1096 - - } 1097 - - if ( mappings[i].sfm_init_prot == VM_PROT_READ ) { 1098 - - readOnlyMappingIndex = i; 1099 - - } 1100 - - } 1101 - - // if shared cache is code signed, add a mapping for the code signature 1102 - - uint64_t signatureSize = header->codeSignatureSize; 1103 - - // zero size in header means signature runs to end-of-file 1104 - - if ( signatureSize == 0 ) 1105 - - signatureSize = stat_buf.st_size - header->codeSignatureOffset; 1106 - - if ( signatureSize != 0 ) { 1107 - -#if __arm__ || __arm64__ 1108 - - size_t alignedSignatureSize = (signatureSize+16383) & (-16384); 1109 - -#else 1110 - - size_t alignedSignatureSize = (signatureSize+4095) & (-4096); 1111 - -#endif 1112 - - // <rdar://problem/23188073> validate code signature covers entire shared cache 1113 - - loadAndCheckCodeSignature(fd, mappingCount, mappings, header->codeSignatureOffset, alignedSignatureSize, firstPages, sizeof(firstPages)); 1114 - - } 1115 - -#if __IPHONE_OS_VERSION_MIN_REQUIRED 1116 - - else { 1117 - - throw "dyld shared cache file not code signed"; 1118 - - } 1119 - -#endif 1120 - - } 1121 - -#if __MAC_OS_X_VERSION_MIN_REQUIRED 1122 - - // sanity check that /usr/lib/libSystem.B.dylib stat() info matches cache 1123 - - if ( header->imagesCount * sizeof(dyld_cache_image_info) + header->imagesOffset < 8192 ) { 1124 - - bool foundLibSystem = false; 1125 - - if ( my_stat("/usr/lib/libSystem.B.dylib", &stat_buf) == 0 ) { 1126 - - const dyld_cache_image_info* images = (dyld_cache_image_info*)&firstPages[header->imagesOffset]; 1127 - - const dyld_cache_image_info* const imagesEnd = &images[header->imagesCount]; 1128 - - for (const dyld_cache_image_info* p = images; p < imagesEnd; ++p) { 1129 - - if ( ((time_t)p->modTime == stat_buf.st_mtime) && ((ino_t)p->inode == stat_buf.st_ino) ) { 1130 - - foundLibSystem = true; 1131 - - break; 1132 - - } 1133 - - } 1134 - - } 1135 - - if ( !sSharedCacheIgnoreInodeAndTimeStamp && !foundLibSystem ) { 1136 - - dyld::log("dyld: shared cached file was built against a different libSystem.dylib, ignoring cache.\n" 1137 - - "to update dyld shared cache run: 'sudo update_dyld_shared_cache' then reboot.\n"); 1138 - - goodCache = false; 1139 - - } 1140 - - } 1141 - -#endif 1142 - -#if __IPHONE_OS_VERSION_MIN_REQUIRED 1143 - - { 1144 - - uint64_t lowAddress; 1145 - - uint64_t highAddress; 1146 - - getCacheBounds(mappingCount, mappings, lowAddress, highAddress); 1147 - - if ( (highAddress-lowAddress) > SHARED_REGION_SIZE ) 1148 - - throw "dyld shared cache is too big to fit in shared region"; 1149 - - } 1150 - -#endif 1151 - - 1152 - - if ( goodCache && (readWriteMappingIndex == -1) ) { 1153 - - dyld::log("dyld: shared cached file is missing read/write mapping: %s" DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME "\n", sSharedCacheDir); 1154 - - goodCache = false; 1155 - - } 1156 - - if ( goodCache && (readOnlyMappingIndex == -1) ) { 1157 - - dyld::log("dyld: shared cached file is missing read-only mapping: %s" DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME "\n", sSharedCacheDir); 1158 - - goodCache = false; 1159 - - } 1160 - - if ( goodCache ) { 1161 - - long cacheSlide = 0; 1162 - - void* slideInfo = (void*)(long)(mappings[readOnlyMappingIndex].sfm_address + (header->slideInfoOffset - mappings[readOnlyMappingIndex].sfm_file_offset));; 1163 - - uint64_t slideInfoSize = header->slideInfoSize; 1164 - - // check if shared cache contains slid info 1165 - - if ( slideInfoSize != 0 ) { 1166 - - // <rdar://problem/8611968> don't slide shared cache if ASLR disabled (main executable didn't slide) 1167 - - if ( sMainExecutable->isPositionIndependentExecutable() && (sMainExecutable->getSlide() == 0) ) { 1168 - - cacheSlide = 0; 1169 - - } 1170 - - else { 1171 - - // generate random slide amount 1172 - - cacheSlide = pickCacheSlide(mappingCount, mappings); 1173 - - } 1174 - - 1175 - - slideInfo = (void*)((uint8_t*)slideInfo + cacheSlide); 1176 - - // add VM_PROT_SLIDE bit to __DATA area of cache 1177 - - mappings[readWriteMappingIndex].sfm_max_prot |= VM_PROT_SLIDE; 1178 - - mappings[readWriteMappingIndex].sfm_init_prot |= VM_PROT_SLIDE; 1179 - - } 1180 - - if ( gLinkContext.verboseMapping ) { 1181 - - dyld::log("dyld: calling _shared_region_map_and_slide_np() with regions:\n"); 1182 - - for (int i=0; i < mappingCount; ++i) { 1183 - - dyld::log(" address=0x%08llX, size=0x%08llX, fileOffset=0x%08llX\n", mappings[i].sfm_address, mappings[i].sfm_size, mappings[i].sfm_file_offset); 1184 - - } 1185 - - } 1186 - - 1187 - - if (_shared_region_map_and_slide_np(fd, mappingCount, mappings, cacheSlide, slideInfo, slideInfoSize) == 0) { 1188 - - // successfully mapped cache into shared region 1189 - - sSharedCache = (dyld_cache_header*)mappings[0].sfm_address; 1190 - - sSharedCacheSlide = cacheSlide; 1191 - - dyld::gProcessInfo->sharedCacheSlide = cacheSlide; 1192 - - dyld::gProcessInfo->sharedCacheBaseAddress = mappings[0].sfm_address; 1193 - - //dyld::log("sSharedCache=%p sSharedCacheSlide=0x%08lX\n", sSharedCache, sSharedCacheSlide); 1194 - - // if cache has a uuid, copy it 1195 - - if ( header->mappingOffset >= 0x68 ) { 1196 - - const bool privateSharedCache = gLinkContext.sharedRegionMode == ImageLoader::kUsePrivateSharedRegion; 1197 - - memcpy(dyld::gProcessInfo->sharedCacheUUID, header->uuid, 16); 1198 - - dyld_kernel_image_info_t kernelCacheInfo; 1199 - - memcpy(&kernelCacheInfo.uuid[0], &sSharedCache->uuid[0], sizeof(uuid_t)); 1200 - - kernelCacheInfo.load_addr = (uint64_t)sSharedCache; 1201 - - kernelCacheInfo.fsobjid.fid_objno = 0; 1202 - - kernelCacheInfo.fsobjid.fid_generation = 0; 1203 - - kernelCacheInfo.fsid.val[0] = 0; 1204 - - kernelCacheInfo.fsid.val[0] = 0; 1205 - - if (privateSharedCache) { 1206 - - kernelCacheInfo.fsobjid = *(fsobj_id_t*)(&stat_buf.st_ino); 1207 - - struct statfs statfs_buf; 1208 - - if ( fstatfs(fd, &statfs_buf) == 0 ) { 1209 - - kernelCacheInfo.fsid = statfs_buf.f_fsid; 1210 - - } 1211 - - } 1212 - - task_register_dyld_shared_cache_image_info(mach_task_self(), kernelCacheInfo, false, privateSharedCache); 1213 - - } 1214 - - } 1215 - - else { 1216 - -#if __IPHONE_OS_VERSION_MIN_REQUIRED 1217 - - throwf("dyld shared cache could not be mapped. errno=%d, slide=0x%08lX, slideInfo=%p, slideInfoSize=0x%08llX, mappingCount=%u, " 1218 - - "address/size/off/init/max [0]=0x%0llX/0x%0llX/0x%0llX/0x%02X/0x%02X, [1]=0x%0llX/0x%0llX/0x%0llX/0x%02X/0x%02X, [2]=0x%0llX/0x%0llX/0x%0llX/0x%02X/0x%02X", 1219 - - errno, cacheSlide, slideInfo, slideInfoSize, mappingCount, 1220 - - mappings[0].sfm_address, mappings[0].sfm_size, mappings[0].sfm_file_offset, mappings[0].sfm_init_prot, mappings[0].sfm_max_prot, 1221 - - mappings[1].sfm_address, mappings[1].sfm_size, mappings[1].sfm_file_offset, mappings[1].sfm_init_prot, mappings[1].sfm_max_prot, 1222 - - mappings[2].sfm_address, mappings[2].sfm_size, mappings[2].sfm_file_offset, mappings[2].sfm_init_prot, mappings[2].sfm_max_prot); 1223 - -#endif 1224 - - if ( gLinkContext.verboseMapping ) 1225 - - dyld::log("dyld: shared cached file could not be mapped\n"); 1226 - - } 1227 - - } 1228 - - } 1229 - - else { 1230 - - if ( gLinkContext.verboseMapping ) 1231 - - dyld::log("dyld: shared cached file is invalid\n"); 1232 - - } 1233 - - } 1234 - - else { 1235 - - if ( gLinkContext.verboseMapping ) 1236 - - dyld::log("dyld: shared cached file cannot be read\n"); 1237 - - } 1238 - - close(fd); 1239 - - } 1240 - - else { 1241 - - if ( gLinkContext.verboseMapping ) 1242 - - dyld::log("dyld: shared cached file cannot be opened\n"); 1243 - - } 1244 - - } 1245 - - 1246 - - // remember if dyld loaded at same address as when cache built 1247 - - if ( sSharedCache != NULL ) { 1248 - - gLinkContext.dyldLoadedAtSameAddressNeededBySharedCache = ((uintptr_t)(sSharedCache->dyldBaseAddress) == (uintptr_t)&_mh_dylinker_header); 1249 - - } 1250 - - 1251 - - // tell gdb where the shared cache is 1252 - - if ( sSharedCache != NULL ) { 1253 - - const dyld_cache_mapping_info* const start = (dyld_cache_mapping_info*)((uint8_t*)sSharedCache + sSharedCache->mappingOffset); 1254 - - dyld_shared_cache_ranges.sharedRegionsCount = sSharedCache->mappingCount; 1255 - - // only room to tell gdb about first four regions 1256 - - if ( dyld_shared_cache_ranges.sharedRegionsCount > 4 ) 1257 - - dyld_shared_cache_ranges.sharedRegionsCount = 4; 1258 - - const dyld_cache_mapping_info* const end = &start[dyld_shared_cache_ranges.sharedRegionsCount]; 1259 - - int index = 0; 1260 - - for (const dyld_cache_mapping_info* p = start; p < end; ++p, ++index ) { 1261 - - dyld_shared_cache_ranges.ranges[index].start = p->address+sSharedCacheSlide; 1262 - - dyld_shared_cache_ranges.ranges[index].length = p->size; 1263 - - if ( gLinkContext.verboseMapping ) { 1264 - - dyld::log(" 0x%08llX->0x%08llX %s%s%s init=%x, max=%x\n", 1265 - - p->address+sSharedCacheSlide, p->address+sSharedCacheSlide+p->size-1, 1266 - - ((p->initProt & VM_PROT_READ) ? "read " : ""), 1267 - - ((p->initProt & VM_PROT_WRITE) ? "write " : ""), 1268 - - ((p->initProt & VM_PROT_EXECUTE) ? "execute " : ""), p->initProt, p->maxProt); 1269 - - } 1270 - - #if __i386__ 1271 - - // If a non-writable and executable region is found in the R/W shared region, then this is __IMPORT segments 1272 - - // This is an old cache. Make writable. dyld no longer supports turn W on and off as it binds 1273 - - if ( (p->initProt == (VM_PROT_READ|VM_PROT_EXECUTE)) && ((p->address & 0xF0000000) == 0xA0000000) ) { 1274 - - if ( p->size != 0 ) { 1275 - - vm_prot_t prot = VM_PROT_EXECUTE | PROT_READ | VM_PROT_WRITE; 1276 - - vm_protect(mach_task_self(), p->address, p->size, false, prot); 1277 - - if ( gLinkContext.verboseMapping ) { 1278 - - dyld::log("%18s at 0x%08llX->0x%08llX altered permissions to %c%c%c\n", "", p->address, 1279 - - p->address+p->size-1, 1280 - - (prot & PROT_READ) ? 'r' : '.', (prot & PROT_WRITE) ? 'w' : '.', (prot & PROT_EXEC) ? 'x' : '.' ); 1281 - - } 1282 - - } 1283 - - } 1284 - - #endif 1285 - - } 1286 - - if ( gLinkContext.verboseMapping ) { 1287 - - // list the code blob 1288 - - dyld_cache_header* header = (dyld_cache_header*)sSharedCache; 1289 - - uint64_t signatureSize = header->codeSignatureSize; 1290 - - // zero size in header means signature runs to end-of-file 1291 - - if ( signatureSize == 0 ) { 1292 - - struct stat stat_buf; 1293 - - // FIXME: need size of cache file actually used 1294 - - if ( my_stat(IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME, &stat_buf) == 0 ) 1295 - - signatureSize = stat_buf.st_size - header->codeSignatureOffset; 1296 - - } 1297 - - if ( signatureSize != 0 ) { 1298 - - const dyld_cache_mapping_info* const last = &start[dyld_shared_cache_ranges.sharedRegionsCount-1]; 1299 - - uint64_t codeBlobStart = last->address + last->size; 1300 - - dyld::log(" 0x%08llX->0x%08llX (code signature)\n", codeBlobStart, codeBlobStart+signatureSize); 1301 - - } 1302 - - } 1303 - - #if SUPPORT_ACCELERATE_TABLES 1304 - - if ( !dylibsCanOverrideCache() && !sDisableAcceleratorTables && (sSharedCache->mappingOffset > 0x80) && (sSharedCache->accelerateInfoAddr != 0) ) { 1305 - - sAllCacheImagesProxy = ImageLoaderMegaDylib::makeImageLoaderMegaDylib(sSharedCache, sSharedCacheSlide, gLinkContext); 1306 - - } 1307 - - #endif 1308 - - } 1309 - -} 1310 - -#endif // #if DYLD_SHARED_CACHE_SUPPORT 1311 - - 1312 - - 1313 - - 1314 - -// create when NSLinkModule is called for a second time on a bundle 1315 - -ImageLoader* cloneImage(ImageLoader* image) 1316 - -{ 1317 - - // open file (automagically closed when this function exits) 1318 - - FileOpener file(image->getPath()); 1319 - - 1320 - - struct stat stat_buf; 1321 - - if ( fstat(file.getFileDescriptor(), &stat_buf) == -1) 1322 - - throw "stat error"; 1323 - - 1324 - - dyld::LoadContext context; 1325 - - context.useSearchPaths = false; 1326 - - context.useFallbackPaths = false; 1327 - - context.useLdLibraryPath = false; 1328 - - context.implicitRPath = false; 1329 - - context.matchByInstallName = false; 1330 - - context.dontLoad = false; 1331 - - context.mustBeBundle = true; 1332 - - context.mustBeDylib = false; 1333 - - context.canBePIE = false; 1334 - - context.origin = NULL; 1335 - - context.rpath = NULL; 1336 - - return loadPhase6(file.getFileDescriptor(), stat_buf, image->getPath(), context); 1337 - -} 1338 - - 1339 - - 1340 - -ImageLoader* loadFromMemory(const uint8_t* mem, uint64_t len, const char* moduleName) 1341 - -{ 1342 - - // if fat wrapper, find usable sub-file 1343 - - const fat_header* memStartAsFat = (fat_header*)mem; 1344 - - uint64_t fileOffset = 0; 1345 - - uint64_t fileLength = len; 1346 - - if ( memStartAsFat->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) { 1347 - - if ( fatFindBest(memStartAsFat, &fileOffset, &fileLength) ) { 1348 - - mem = &mem[fileOffset]; 1349 - - len = fileLength; 1350 - - } 1351 - - else { 1352 - - throw "no matching architecture in universal wrapper"; 1353 - + // call callback with all existing images 1354 - + unsigned count = dyld::gProcessInfo->infoArrayCount; 1355 - + const dyld_image_info* infoArray = dyld::gProcessInfo->infoArray; 1356 - + if ( infoArray != NULL ) { 1357 - + const mach_header* mhs[count]; 1358 - + const char* paths[count]; 1359 - + for (unsigned i=0; i < count; ++i) { 1360 - + mhs[i] = infoArray[i].imageLoadAddress; 1361 - + paths[i] = infoArray[i].imageFilePath; 1362 - } 1363 - + dyld3::ScopedTimer timer(DBG_DYLD_TIMING_FUNC_FOR_ADD_IMAGE, (uint64_t)mhs[0], (uint64_t)func, 0); 1364 - + func(count, mhs, paths); 1365 - } 1366 - 1367 - - // try each loader 1368 - - if ( isCompatibleMachO(mem, moduleName) ) { 1369 - - ImageLoader* image = ImageLoaderMachO::instantiateFromMemory(moduleName, (macho_header*)mem, len, gLinkContext); 1370 - - // don't add bundles to global list, they can be loaded but not linked. When linked it will be added to list 1371 - - if ( ! image->isBundle() ) 1372 - - addImage(image); 1373 - - return image; 1374 - - } 1375 - - 1376 - - // try other file formats here... 1377 - - 1378 - - // throw error about what was found 1379 - - switch (*(uint32_t*)mem) { 1380 - - case MH_MAGIC: 1381 - - case MH_CIGAM: 1382 - - case MH_MAGIC_64: 1383 - - case MH_CIGAM_64: 1384 - - throw "mach-o, but wrong architecture"; 1385 - - default: 1386 - - throwf("unknown file type, first eight bytes: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", 1387 - - mem[0], mem[1], mem[2], mem[3], mem[4], mem[5], mem[6],mem[7]); 1388 - - } 1389 - -} 1390 - - 1391 - - 1392 - -void registerAddCallback(ImageCallback func) 1393 - -{ 1394 - // now add to list to get notified when any more images are added 1395 - - sAddImageCallbacks.push_back(func); 1396 - - 1397 - - // call callback with all existing images 1398 - - for (std::vector<ImageLoader*>::iterator it=sAllImages.begin(); it != sAllImages.end(); it++) { 1399 - - ImageLoader* image = *it; 1400 - - if ( image->getState() >= dyld_image_state_bound && image->getState() < dyld_image_state_terminated ) 1401 - - (*func)(image->machHeader(), image->getSlide()); 1402 - - } 1403 - -#if SUPPORT_ACCELERATE_TABLES 1404 - - if ( sAllCacheImagesProxy != NULL ) { 1405 - - dyld_image_info infos[allImagesCount()+1]; 1406 - - unsigned cacheCount = sAllCacheImagesProxy->appendImagesToNotify(dyld_image_state_bound, true, infos); 1407 - - for (unsigned i=0; i < cacheCount; ++i) { 1408 - - (*func)(infos[i].imageLoadAddress, sSharedCacheSlide); 1409 - - } 1410 - - } 1411 - -#endif 1412 - + sAddBulkLoadImageCallbacks.push_back(func); 1413 - } 1414 - 1415 - void registerRemoveCallback(ImageCallback func) 1416 - @@ -5626,75 +5386,81 @@ static void loadInsertedDylib(const char* path) 1417 - } 1418 - 1419 - 1420 - -// 1421 - -// Sets: 1422 - -// sEnvMode 1423 - -// gLinkContext.requireCodeSignature 1424 - -// gLinkContext.processIsRestricted // Mac OS X only 1425 - -// gLinkContext.processUsingLibraryValidation // Mac OS X only 1426 - -// 1427 - -static void configureProcessRestrictions(const macho_header* mainExecutableMH) 1428 - +static void configureProcessRestrictions(const macho_header* mainExecutableMH, const char* envp[]) 1429 - { 1430 - - uint32_t flags; 1431 - -#if TARGET_IPHONE_SIMULATOR 1432 - - sEnvMode = envAll; 1433 - - gLinkContext.requireCodeSignature = true; 1434 - + uint64_t amfiInputFlags = 0; 1435 - +#if TARGET_OS_SIMULATOR 1436 - + amfiInputFlags |= AMFI_DYLD_INPUT_PROC_IN_SIMULATOR; 1437 - +#elif __MAC_OS_X_VERSION_MIN_REQUIRED 1438 - + if ( hasRestrictedSegment(mainExecutableMH) ) 1439 - + amfiInputFlags |= AMFI_DYLD_INPUT_PROC_HAS_RESTRICT_SEG; 1440 - #elif __IPHONE_OS_VERSION_MIN_REQUIRED 1441 - - sEnvMode = envNone; 1442 - - gLinkContext.requireCodeSignature = true; 1443 - - if ( csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1 ) { 1444 - - if ( flags & CS_ENFORCEMENT ) { 1445 - - if ( flags & CS_GET_TASK_ALLOW ) { 1446 - - // Xcode built app for Debug allowed to use DYLD_* variables 1447 - - sEnvMode = envAll; 1448 - + if ( isFairPlayEncrypted(mainExecutableMH) ) 1449 - + amfiInputFlags |= AMFI_DYLD_INPUT_PROC_IS_ENCRYPTED; 1450 - +#endif 1451 - + uint64_t amfiOutputFlags = 0; 1452 - + const char* amfiFake = nullptr; 1453 - + if ( dyld3::internalInstall() && dyld3::BootArgs::enableDyldTestMode() ) { 1454 - + amfiFake = _simple_getenv(envp, "DYLD_AMFI_FAKE"); 1455 - + } 1456 - + if ( amfiFake != nullptr ) { 1457 - + amfiOutputFlags = hexToUInt64(amfiFake, nullptr); 1458 - + } 1459 - + if ( (amfiFake != nullptr) || (amfi_check_dyld_policy_self(amfiInputFlags, &amfiOutputFlags) == 0) ) { 1460 - + gLinkContext.allowAtPaths = (amfiOutputFlags & AMFI_DYLD_OUTPUT_ALLOW_AT_PATH); 1461 - + gLinkContext.allowEnvVarsPrint = (amfiOutputFlags & AMFI_DYLD_OUTPUT_ALLOW_PRINT_VARS); 1462 - + gLinkContext.allowEnvVarsPath = (amfiOutputFlags & AMFI_DYLD_OUTPUT_ALLOW_PATH_VARS); 1463 - + gLinkContext.allowEnvVarsSharedCache = (amfiOutputFlags & AMFI_DYLD_OUTPUT_ALLOW_CUSTOM_SHARED_CACHE); 1464 - + gLinkContext.allowClassicFallbackPaths = (amfiOutputFlags & AMFI_DYLD_OUTPUT_ALLOW_FALLBACK_PATHS); 1465 - + gLinkContext.allowInsertFailures = (amfiOutputFlags & AMFI_DYLD_OUTPUT_ALLOW_FAILED_LIBRARY_INSERTION); 1466 - + } 1467 - + else { 1468 - +#if __MAC_OS_X_VERSION_MIN_REQUIRED 1469 - + // support chrooting from old kernel 1470 - + bool isRestricted = false; 1471 - + bool libraryValidation = false; 1472 - + // any processes with setuid or setgid bit set or with __RESTRICT segment is restricted 1473 - + if ( issetugid() || hasRestrictedSegment(mainExecutableMH) ) { 1474 - + isRestricted = true; 1475 - + } 1476 - + bool usingSIP = (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0); 1477 - + uint32_t flags; 1478 - + if ( csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1 ) { 1479 - + // On OS X CS_RESTRICT means the program was signed with entitlements 1480 - + if ( ((flags & CS_RESTRICT) == CS_RESTRICT) && usingSIP ) { 1481 - + isRestricted = true; 1482 - } 1483 - - else { 1484 - - // Development kernel can use DYLD_PRINT_* variables on any FairPlay encrypted app 1485 - - uint32_t secureValue = 0; 1486 - - size_t secureValueSize = sizeof(secureValue); 1487 - - if ( (sysctlbyname("kern.secure_kernel", &secureValue, &secureValueSize, NULL, 0) == 0) && (secureValue == 0) && isFairPlayEncrypted(mainExecutableMH) ) { 1488 - - sEnvMode = envPrintOnly; 1489 - - } 1490 - + // Library Validation loosens searching but requires everything to be code signed 1491 - + if ( flags & CS_REQUIRE_LV ) { 1492 - + isRestricted = false; 1493 - + libraryValidation = true; 1494 - } 1495 - } 1496 - - else { 1497 - - // Development kernel can run unsigned code 1498 - - sEnvMode = envAll; 1499 - - gLinkContext.requireCodeSignature = false; 1500 - - } 1501 - - } 1502 - - if ( issetugid() ) { 1503 - - sEnvMode = envNone; 1504 - - } 1505 - -#elif __MAC_OS_X_VERSION_MIN_REQUIRED 1506 - - sEnvMode = envAll; 1507 - - gLinkContext.requireCodeSignature = false; 1508 - - gLinkContext.processIsRestricted = false; 1509 - - gLinkContext.processUsingLibraryValidation = false; 1510 - - // any processes with setuid or setgid bit set or with __RESTRICT segment is restricted 1511 - - if ( issetugid() || hasRestrictedSegment(mainExecutableMH) ) { 1512 - - gLinkContext.processIsRestricted = true; 1513 - - } 1514 - - if ( csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1 ) { 1515 - - // On OS X CS_RESTRICT means the program was signed with entitlements 1516 - - if ( ((flags & CS_RESTRICT) == CS_RESTRICT) && (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0) ) { 1517 - - gLinkContext.processIsRestricted = true; 1518 - - } 1519 - - // Library Validation loosens searching but requires everything to be code signed 1520 - - if ( flags & CS_REQUIRE_LV ) { 1521 - - gLinkContext.processIsRestricted = false; 1522 - - //gLinkContext.requireCodeSignature = true; 1523 - - gLinkContext.processUsingLibraryValidation = true; 1524 - - } 1525 - - } 1526 - + gLinkContext.allowAtPaths = !isRestricted; 1527 - + gLinkContext.allowEnvVarsPrint = !isRestricted; 1528 - + gLinkContext.allowEnvVarsPath = !isRestricted; 1529 - + gLinkContext.allowEnvVarsSharedCache = !libraryValidation || !usingSIP; 1530 - + gLinkContext.allowClassicFallbackPaths = !isRestricted; 1531 - + gLinkContext.allowInsertFailures = false; 1532 - +#else 1533 - + halt("amfi_check_dyld_policy_self() failed\n"); 1534 - #endif 1535 - + } 1536 - } 1537 - 1538 - +// called by _dyld_register_driverkit_main() 1539 - +void setMainEntry(void (*main)()) 1540 - +{ 1541 - + if ( sEntryOveride == nullptr ) 1542 - + sEntryOveride = main; 1543 - + else 1544 - + halt("_dyld_register_driverkit_main() may only be called once"); 1545 - +} 1546 - 1547 - bool processIsRestricted() 1548 - { 1549 - #if __MAC_OS_X_VERSION_MIN_REQUIRED 1550 - - return gLinkContext.processIsRestricted; 1551 - + return !gLinkContext.allowEnvVarsPath; 1552 - #else 1553 - return false; 1554 - #endif 1555 - @@ -5742,14 +5516,11 @@ void notifyKernelAboutDyld() 1556 - case LC_UUID: { 1557 - // Add dyld to the kernel image info 1558 - uuid_command* uc = (uuid_command*)cmd; 1559 - - dyld_kernel_image_info_t kernelInfo; 1560 - - memcpy(kernelInfo.uuid, uc->uuid, 16); 1561 - - kernelInfo.load_addr = (uint64_t)mh; 1562 - - kernelInfo.fsobjid.fid_objno = 0; 1563 - - kernelInfo.fsobjid.fid_generation = 0; 1564 - - kernelInfo.fsid.val[0] = 0; 1565 - - kernelInfo.fsid.val[1] = 0; 1566 - - task_register_dyld_image_infos(mach_task_self(), &kernelInfo, 1); 1567 - + char path[MAXPATHLEN]; 1568 - + if (fsgetpath(path, MAXPATHLEN, &fsid, fsobj_id_scalar) < 0) { 1569 - + path[0] = 0; 1570 - + } 1571 - + dyld3::kdebug_trace_dyld_image(DBG_DYLD_UUID_MAP_A, path, (const uuid_t *)&uc->uuid[0], fsobj_id, fsid, (const mach_header *)mh); 1572 - return; 1573 - } 1574 - } 1575 - @@ -5812,12 +5583,28 @@ static SyscallHelpers sSysCalls = { 1576 - // Added in version 6 1577 - &abort_with_payload, 1578 - // Added in version 7 1579 - - &task_register_dyld_image_infos, 1580 - - &task_unregister_dyld_image_infos, 1581 - - &task_get_dyld_image_infos, 1582 - - &task_register_dyld_shared_cache_image_info, 1583 - - &task_register_dyld_set_dyld_state, 1584 - - &task_register_dyld_get_process_state 1585 - + &legacy_task_register_dyld_image_infos, 1586 - + &legacy_task_unregister_dyld_image_infos, 1587 - + &legacy_task_get_dyld_image_infos, 1588 - + &legacy_task_register_dyld_shared_cache_image_info, 1589 - + &legacy_task_register_dyld_set_dyld_state, 1590 - + &legacy_task_register_dyld_get_process_state, 1591 - + // Added in version 8 1592 - + &task_info, 1593 - + &thread_info, 1594 - + &kdebug_is_enabled, 1595 - + &kdebug_trace, 1596 - + // Added in version 9 1597 - + &kdebug_trace_string, 1598 - + // Added in version 10 1599 - + &amfi_check_dyld_policy_self, 1600 - + // Added in version 11 1601 - + &notifyMonitoringDyldMain, 1602 - + &notifyMonitoringDyld, 1603 - + // Add in version 12 1604 - + &mach_msg_destroy, 1605 - + &mach_port_construct, 1606 - + &mach_port_destruct 1607 - }; 1608 - 1609 - __attribute__((noinline)) 1610 - @@ -7100,32 +7806,6 @@ reloadAllImages: 1611 - #endif 1612 - 1613 - 1614 - - #if __MAC_OS_X_VERSION_MIN_REQUIRED 1615 - - // <rdar://problem/22805519> be less strict about old mach-o binaries 1616 - - uint32_t mainSDK = sMainExecutable->sdkVersion(); 1617 - - gLinkContext.strictMachORequired = (mainSDK >= DYLD_MACOSX_VERSION_10_12) || gLinkContext.processUsingLibraryValidation; 1618 - - #else 1619 - - // simulators, iOS, tvOS, and watchOS are always strict 1620 - - gLinkContext.strictMachORequired = true; 1621 - - #endif 1622 - - 1623 - - // load shared cache 1624 - - checkSharedRegionDisable(); 1625 - - #if DYLD_SHARED_CACHE_SUPPORT 1626 - - if ( gLinkContext.sharedRegionMode != ImageLoader::kDontUseSharedRegion ) { 1627 - - mapSharedCache(); 1628 - - } else { 1629 - - dyld_kernel_image_info_t kernelCacheInfo; 1630 - - bzero(&kernelCacheInfo.uuid[0], sizeof(uuid_t)); 1631 - - kernelCacheInfo.load_addr = 0; 1632 - - kernelCacheInfo.fsobjid.fid_objno = 0; 1633 - - kernelCacheInfo.fsobjid.fid_generation = 0; 1634 - - kernelCacheInfo.fsid.val[0] = 0; 1635 - - kernelCacheInfo.fsid.val[0] = 0; 1636 - - task_register_dyld_shared_cache_image_info(mach_task_self(), kernelCacheInfo, true, false); 1637 - - } 1638 - - #endif 1639 - - 1640 - #if SUPPORT_ACCELERATE_TABLES 1641 - sAllImages.reserve((sAllCacheImagesProxy != NULL) ? 16 : INITIAL_IMAGE_COUNT); 1642 - #else
-197
src/dyld/src/dyldInitialization.cpp.rej
··· 1 - --- src/dyldInitialization.cpp 2 - +++ src/dyldInitialization.cpp 3 - @@ -81,116 +57,48 @@ static void runDyldInitializers(const struct macho_header* mh, intptr_t slide, i 4 - 5 - 6 - // 7 - -// The kernel may have slid a Position Independent Executable 8 - +// On disk, all pointers in dyld's DATA segment are chained together. 9 - +// They need to be fixed up to be real pointers to run. 10 - // 11 - -static uintptr_t slideOfMainExecutable(const struct macho_header* mh) 12 - +static void rebaseDyld(const dyld3::MachOLoaded* dyldMH) 13 - { 14 - - const uint32_t cmd_count = mh->ncmds; 15 - - const struct load_command* const cmds = (struct load_command*)(((char*)mh)+sizeof(macho_header)); 16 - - const struct load_command* cmd = cmds; 17 - - for (uint32_t i = 0; i < cmd_count; ++i) { 18 - - if ( cmd->cmd == LC_SEGMENT_COMMAND ) { 19 - - const struct macho_segment_command* segCmd = (struct macho_segment_command*)cmd; 20 - - if ( (segCmd->fileoff == 0) && (segCmd->filesize != 0)) { 21 - - return (uintptr_t)mh - segCmd->vmaddr; 22 - - } 23 - - } 24 - - cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize); 25 - - } 26 - - return 0; 27 - + // walk all fixups chains and rebase dyld 28 - + const dyld3::MachOAnalyzer* ma = (dyld3::MachOAnalyzer*)dyldMH; 29 - + assert(ma->hasChainedFixups()); 30 - + uintptr_t slide = (long)ma; // all fixup chain based images have a base address of zero, so slide == load address 31 - + __block Diagnostics diag; 32 - + ma->withChainStarts(diag, 0, ^(const dyld_chained_starts_in_image* starts) { 33 - + ma->fixupAllChainedFixups(diag, starts, slide, dyld3::Array<const void*>(), nullptr); 34 - + }); 35 - + diag.assertNoError(); 36 - + 37 - + // now that rebasing done, initialize mach/syscall layer 38 - + mach_init(); 39 - + 40 - + // <rdar://47805386> mark __DATA_CONST segment in dyld as read-only (once fixups are done) 41 - + ma->forEachSegment(^(const dyld3::MachOFile::SegmentInfo& info, bool& stop) { 42 - + if ( info.readOnlyData ) { 43 - + ::mprotect(((uint8_t*)(dyldMH))+info.vmAddr, (size_t)info.vmSize, VM_PROT_READ); 44 - + } 45 - + }); 46 - } 47 - 48 - 49 - -// 50 - -// If the kernel does not load dyld at its preferred address, we need to apply 51 - -// fixups to various initialized parts of the __DATA segment 52 - -// 53 - -static void rebaseDyld(const struct macho_header* mh, intptr_t slide) 54 - -{ 55 - - // rebase non-lazy pointers (which all point internal to dyld, since dyld uses no shared libraries) 56 - - // and get interesting pointers into dyld 57 - - const uint32_t cmd_count = mh->ncmds; 58 - - const struct load_command* const cmds = (struct load_command*)(((char*)mh)+sizeof(macho_header)); 59 - - const struct load_command* cmd = cmds; 60 - - const struct macho_segment_command* linkEditSeg = NULL; 61 - -#if __x86_64__ 62 - - const struct macho_segment_command* firstWritableSeg = NULL; 63 - -#endif 64 - - const struct dysymtab_command* dynamicSymbolTable = NULL; 65 - - for (uint32_t i = 0; i < cmd_count; ++i) { 66 - - switch (cmd->cmd) { 67 - - case LC_SEGMENT_COMMAND: 68 - - { 69 - - const struct macho_segment_command* seg = (struct macho_segment_command*)cmd; 70 - - if ( strcmp(seg->segname, "__LINKEDIT") == 0 ) 71 - - linkEditSeg = seg; 72 - - const struct macho_section* const sectionsStart = (struct macho_section*)((char*)seg + sizeof(struct macho_segment_command)); 73 - - const struct macho_section* const sectionsEnd = &sectionsStart[seg->nsects]; 74 - - for (const struct macho_section* sect=sectionsStart; sect < sectionsEnd; ++sect) { 75 - - const uint8_t type = sect->flags & SECTION_TYPE; 76 - - if ( type == S_NON_LAZY_SYMBOL_POINTERS ) { 77 - - // rebase non-lazy pointers (which all point internal to dyld, since dyld uses no shared libraries) 78 - - const uint32_t pointerCount = (uint32_t)(sect->size / sizeof(uintptr_t)); 79 - - uintptr_t* const symbolPointers = (uintptr_t*)(sect->addr + slide); 80 - - for (uint32_t j=0; j < pointerCount; ++j) { 81 - - symbolPointers[j] += slide; 82 - - } 83 - - } 84 - - } 85 - -#if __x86_64__ 86 - - if ( (firstWritableSeg == NULL) && (seg->initprot & VM_PROT_WRITE) ) 87 - - firstWritableSeg = seg; 88 - -#endif 89 - - } 90 - - break; 91 - - case LC_DYSYMTAB: 92 - - dynamicSymbolTable = (struct dysymtab_command *)cmd; 93 - - break; 94 - - } 95 - - cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize); 96 - - } 97 - - 98 - - // use reloc's to rebase all random data pointers 99 - -#if __x86_64__ 100 - - const uintptr_t relocBase = firstWritableSeg->vmaddr + slide; 101 - -#else 102 - - const uintptr_t relocBase = (uintptr_t)mh; 103 - -#endif 104 - - const relocation_info* const relocsStart = (struct relocation_info*)(linkEditSeg->vmaddr + slide + dynamicSymbolTable->locreloff - linkEditSeg->fileoff); 105 - - const relocation_info* const relocsEnd = &relocsStart[dynamicSymbolTable->nlocrel]; 106 - - for (const relocation_info* reloc=relocsStart; reloc < relocsEnd; ++reloc) { 107 - - if ( reloc->r_length != RELOC_SIZE ) 108 - - throw "relocation in dyld has wrong size"; 109 - - 110 - - if ( reloc->r_type != POINTER_RELOC ) 111 - - throw "relocation in dyld has wrong type"; 112 - - 113 - - // update pointer by amount dyld slid 114 - - *((uintptr_t*)(reloc->r_address + relocBase)) += slide; 115 - - } 116 - -} 117 - - 118 - - 119 - -extern "C" void mach_init(); 120 - -extern "C" void __guard_setup(const char* apple[]); 121 - - 122 - 123 - // 124 - // This is code to bootstrap dyld. This work in normally done for a program by dyld and crt. 125 - // In dyld we have to do this manually. 126 - // 127 - -uintptr_t start(const struct macho_header* appsMachHeader, int argc, const char* argv[], 128 - - intptr_t slide, const struct macho_header* dyldsMachHeader, 129 - - uintptr_t* startGlue) 130 - +uintptr_t start(const dyld3::MachOLoaded* appsMachHeader, int argc, const char* argv[], 131 - + const dyld3::MachOLoaded* dyldsMachHeader, uintptr_t* startGlue) 132 - { 133 - + 134 - + // Emit kdebug tracepoint to indicate dyld bootstrap has started <rdar://46878536> 135 - + dyld3::kdebug_trace_dyld_marker(DBG_DYLD_TIMING_BOOTSTRAP_START, 0, 0, 0, 0); 136 - + 137 - // if kernel had to slide dyld, we need to fix up load sensitive locations 138 - // we have to do this before using any global variables 139 - - if ( slide != 0 ) { 140 - - rebaseDyld(dyldsMachHeader, slide); 141 - - } 142 - - 143 - - // allow dyld to use mach messaging 144 - - mach_init(); 145 - + rebaseDyld(dyldsMachHeader); 146 - 147 - // kernel sets up env pointer to be just past end of agv array 148 - const char** envp = &argv[argc+1]; 149 - @@ -205,37 +113,31 @@ uintptr_t start(const struct macho_header* appsMachHeader, int argc, const char* 150 - 151 - #if DYLD_INITIALIZER_SUPPORT 152 - // run all C++ initializers inside dyld 153 - - runDyldInitializers(dyldsMachHeader, slide, argc, argv, envp, apple); 154 - + runDyldInitializers(argc, argv, envp, apple); 155 - #endif 156 - 157 - // now that we are done bootstrapping dyld, call dyld's main 158 - - uintptr_t appsSlide = slideOfMainExecutable(appsMachHeader); 159 - - return dyld::_main(appsMachHeader, appsSlide, argc, argv, envp, apple, startGlue); 160 - + uintptr_t appsSlide = appsMachHeader->getSlide(); 161 - + return dyld::_main((macho_header*)appsMachHeader, appsSlide, argc, argv, envp, apple, startGlue); 162 - } 163 - 164 - 165 - -#if TARGET_IPHONE_SIMULATOR 166 - +#if TARGET_OS_SIMULATOR 167 - 168 - extern "C" uintptr_t start_sim(int argc, const char* argv[], const char* envp[], const char* apple[], 169 - - const macho_header* mainExecutableMH, const macho_header* dyldMH, uintptr_t dyldSlide, 170 - + const dyld3::MachOLoaded* mainExecutableMH, const dyld3::MachOLoaded* dyldMH, uintptr_t dyldSlide, 171 - const dyld::SyscallHelpers*, uintptr_t* startGlue); 172 - 173 - - 174 - + 175 - uintptr_t start_sim(int argc, const char* argv[], const char* envp[], const char* apple[], 176 - - const macho_header* mainExecutableMH, const macho_header* dyldMH, uintptr_t dyldSlide, 177 - + const dyld3::MachOLoaded* mainExecutableMH, const dyld3::MachOLoaded* dyldSimMH, uintptr_t dyldSlide, 178 - const dyld::SyscallHelpers* sc, uintptr_t* startGlue) 179 - { 180 - - // if simulator dyld loaded slid, it needs to rebase itself 181 - - // we have to do this before using any global variables 182 - - if ( dyldSlide != 0 ) { 183 - - rebaseDyld(dyldMH, dyldSlide); 184 - - } 185 - + // save table of syscall pointers 186 - + gSyscallHelpers = sc; 187 - 188 - - // save table of syscall pointers 189 - - gSyscallHelpers = sc; 190 - - 191 - - // allow dyld to use mach messaging 192 - - mach_init(); 193 - + // dyld_sim uses chained rebases, so it always need to be fixed up 194 - + rebaseDyld(dyldSimMH); 195 - 196 - // set up random value for stack canary 197 - __guard_setup(apple);
-40
src/dyld/src/dyld_process_info.cpp.rej
··· 1 - --- src/dyld_process_info.cpp 2 - +++ src/dyld_process_info.cpp 3 - @@ -238,28 +408,32 @@ private: 4 - uint64_t size; 5 - }; 6 - 7 - - dyld_process_info_base(unsigned imageCount, size_t totalSize); 8 - + dyld_process_info_base(dyld_platform_t platform, unsigned imageCount, size_t totalSize); 9 - void* operator new (size_t, void* buf) { return buf; } 10 - 11 - static bool inCache(uint64_t addr) { return (addr > SHARED_REGION_BASE) && (addr < SHARED_REGION_BASE+SHARED_REGION_SIZE); } 12 - - kern_return_t addImage(task_t task, bool sameCacheAsThisProcess, uint64_t imageAddress, uint64_t imagePath, const char* imagePathLocal); 13 - + bool addImage(task_t task, bool sameCacheAsThisProcess, uint64_t imageAddress, uint64_t imagePath, const char* imagePathLocal); 14 - + 15 - kern_return_t addDyldImage(task_t task, uint64_t dyldAddress, uint64_t dyldPathAddress, const char* localPath); 16 - 17 - bool invalid() { return ((char*)_stringRevBumpPtr < (char*)_curSegment); } 18 - - const char* copyPath(task_t task, uint64_t pathAddr, kern_return_t* kr); 19 - - const char* addString(const char*); 20 - + const char* copyPath(task_t task, uint64_t pathAddr); 21 - + const char* addString(const char*, size_t); 22 - const char* copySegmentName(const char*); 23 - 24 - void addInfoFromLoadCommands(const mach_header* mh, uint64_t addressInTask, size_t size); 25 - + kern_return_t addInfoFromRemoteLoadCommands(task_t task, uint64_t remoteMH); 26 - 27 - void inspectLocalImageLoadCommands(uint64_t imageAddress, void* func); 28 - kern_return_t inspectRemoteImageLoadCommands(task_t task, uint64_t imageAddress, void* func); 29 - 30 - - mutable uint32_t _retainCount; 31 - + mutable std::atomic<uint32_t> _retainCount; 32 - const uint32_t _cacheInfoOffset; 33 - const uint32_t _stateInfoOffset; 34 - const uint32_t _imageInfosOffset; 35 - const uint32_t _segmentInfosOffset; 36 - + size_t _freeSpace; 37 - + dyld_platform_t _platform; 38 - ImageInfo* const _firstImage; 39 - ImageInfo* _curImage; 40 - SegmentInfo* const _firstSegment;
+1 -1
tools/debian/make-deb
··· 17 17 ARG='-b' 18 18 fi 19 19 20 - debuild -us -uc ${ARG} 20 + debuild -us -uc --no-lintian ${ARG}