1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
   3  * Copyright (c) 2004-2009 Apple Inc. All rights reserved. 
   5  * @APPLE_LICENSE_HEADER_START@ 
   7  * This file contains Original Code and/or Modifications of Original Code 
   8  * as defined in and that are subject to the Apple Public Source License 
   9  * Version 2.0 (the 'License'). You may not use this file except in 
  10  * compliance with the License. Please obtain a copy of the License at 
  11  * http://www.opensource.apple.com/apsl/ and read it before using this 
  14  * The Original Code and all software distributed under the License are 
  15  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  16  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  17  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  18  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  19  * Please see the License for the specific language governing rights and 
  20  * limitations under the License. 
  22  * @APPLE_LICENSE_HEADER_END@ 
  29 #include <mach-o/loader.h> 
  33 #include "mach-o/dyld_gdb.h" 
  34 #include "mach-o/dyld_images.h" 
  35 #include "ImageLoader.h" 
  37 #if __IPHONE_OS_VERSION_MIN_REQUIRED 
  38         #define INITIAL_UUID_IMAGE_COUNT 4 
  40         #define INITIAL_UUID_IMAGE_COUNT 32 
  43 static std::vector
<dyld_image_info
> sImageInfos
; 
  44 static std::vector
<dyld_uuid_info
>  sImageUUIDs
; 
  46 void addImagesToAllImages(uint32_t infoCount
, const dyld_image_info info
[]) 
  48         // make initial size large enough that we probably won't need to re-alloc it 
  49         if ( sImageInfos
.size() == 0 ) 
  50                 sImageInfos
.reserve(INITIAL_IMAGE_COUNT
); 
  51         if ( sImageUUIDs
.capacity() == 0 ) 
  52                 sImageUUIDs
.reserve(4); 
  53         // set infoArray to NULL to denote it is in-use 
  54         dyld_all_image_infos
.infoArray 
= NULL
; 
  56         // append all new images 
  57         for (uint32_t i
=0; i 
< infoCount
; ++i
) 
  58                 sImageInfos
.push_back(info
[i
]); 
  59         dyld_all_image_infos
.infoArrayCount 
= sImageInfos
.size(); 
  61         // set infoArray back to base address of vector (other process can now read) 
  62         dyld_all_image_infos
.infoArray 
= &sImageInfos
[0]; 
  66 const char* notifyGDB(enum dyld_image_states state
, uint32_t infoCount
, const dyld_image_info info
[]) 
  68         // tell gdb that about the new images 
  69         dyld_all_image_infos
.notification(dyld_image_adding
, infoCount
, info
); 
  70         // <rdar://problem/7739489> record initial count of images   
  71         // so CrashReporter can note which images were dynamically loaded 
  72         if ( dyld_all_image_infos
.initialImageCount 
== 0 ) 
  73                 dyld_all_image_infos
.initialImageCount 
= infoCount
; 
  79 void addNonSharedCacheImageUUID(const dyld_uuid_info
& info
) 
  81         // set uuidArray to NULL to denote it is in-use 
  82         dyld_all_image_infos
.uuidArray 
= NULL
; 
  84         // append all new images 
  85         sImageUUIDs
.push_back(info
); 
  86         dyld_all_image_infos
.uuidArrayCount 
= sImageUUIDs
.size(); 
  88         // set uuidArray back to base address of vector (other process can now read) 
  89         dyld_all_image_infos
.uuidArray 
= &sImageUUIDs
[0]; 
  92 void removeImageFromAllImages(const struct mach_header
* loadAddress
) 
  94         dyld_image_info goingAway
; 
  96         // set infoArray to NULL to denote it is in-use 
  97         dyld_all_image_infos
.infoArray 
= NULL
; 
  99         // remove image from infoArray 
 100         for (std::vector
<dyld_image_info
>::iterator it
=sImageInfos
.begin(); it 
!= sImageInfos
.end(); it
++) { 
 101                 if ( it
->imageLoadAddress 
== loadAddress 
) { 
 103                         sImageInfos
.erase(it
); 
 107         dyld_all_image_infos
.infoArrayCount 
= sImageInfos
.size(); 
 109         // set infoArray back to base address of vector 
 110         dyld_all_image_infos
.infoArray 
= &sImageInfos
[0]; 
 113         // set uuidArrayCount to NULL to denote it is in-use 
 114         dyld_all_image_infos
.uuidArray 
= NULL
; 
 116         // remove image from infoArray 
 117         for (std::vector
<dyld_uuid_info
>::iterator it
=sImageUUIDs
.begin(); it 
!= sImageUUIDs
.end(); it
++) { 
 118                 if ( it
->imageLoadAddress 
== loadAddress 
) { 
 119                         sImageUUIDs
.erase(it
); 
 123         dyld_all_image_infos
.uuidArrayCount 
= sImageUUIDs
.size(); 
 125         // set infoArray back to base address of vector 
 126         dyld_all_image_infos
.uuidArray 
= &sImageUUIDs
[0]; 
 128         // tell gdb that about the new images 
 129         dyld_all_image_infos
.notification(dyld_image_removing
, 1, &goingAway
); 
 133 // work around for:  <rdar://problem/6530727> gdb-1109: notifier in dyld does not work if it is in thumb 
 134 extern "C" void gdb_image_notifier(enum dyld_image_mode mode
, uint32_t infoCount
, const dyld_image_info info
[]); 
 136 static void gdb_image_notifier(enum dyld_image_mode mode
, uint32_t infoCount
, const dyld_image_info info
[]) 
 139         // gdb sets a break point here to catch notifications 
 140         //dyld::log("dyld: gdb_image_notifier(%s, %d, ...)\n", mode ? "dyld_image_removing" : "dyld_image_adding", infoCount); 
 141         //for (uint32_t i=0; i < infoCount; ++i) 
 142         //      dyld::log("dyld: %d loading at %p %s\n", i, info[i].imageLoadAddress, info[i].imageFilePath); 
 143         //for (uint32_t i=0; i < dyld_all_image_infos.infoArrayCount; ++i) 
 144         //      dyld::log("dyld: %d loading at %p %s\n", i, dyld_all_image_infos.infoArray[i].imageLoadAddress, dyld_all_image_infos.infoArray[i].imageFilePath); 
 148 void setAlImageInfosHalt(const char* message
, uintptr_t flags
) 
 150         dyld_all_image_infos
.errorMessage 
= message
; 
 151         dyld_all_image_infos
.terminationFlags 
= flags
; 
 155 extern void* __dso_handle
; 
 157 #define XSTR(s) STR(s) 
 159 struct dyld_all_image_infos  dyld_all_image_infos 
__attribute__ ((section ("__DATA,__all_image_info")))  
 161                                                                 12, 0, NULL
, &gdb_image_notifier
, false, false, (const mach_header
*)&__dso_handle
, NULL
,  
 162                                                                 XSTR(DYLD_VERSION
), NULL
, 0, NULL
, 0, 0, NULL
, &dyld_all_image_infos
,  
 163                                                                 0, dyld_error_kind_none
, NULL
, NULL
, NULL
, 0 
 166 struct dyld_shared_cache_ranges dyld_shared_cache_ranges
;