00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "tconfig.h"
00035 #include "tsystem.h"
00036
00037
00038
00039 struct mach_header;
00040 extern char *getsectdatafromheader (struct mach_header *, const char *,
00041 const char *, unsigned long *);
00042 extern void _dyld_register_func_for_add_image
00043 (void (*) (struct mach_header *, unsigned long));
00044 extern void _dyld_register_func_for_remove_image
00045 (void (*) (struct mach_header *, unsigned long));
00046
00047 extern void __darwin_gcc3_preregister_frame_info (void);
00048
00049
00050 extern void _init_keymgr (void);
00051 extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key);
00052 extern void _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr);
00053
00054 extern void *__keymgr_global[];
00055 typedef struct _Sinfo_Node {
00056 unsigned int size ;
00057 unsigned short major_version ;
00058 unsigned short minor_version ;
00059 } _Tinfo_Node ;
00060
00061
00062 #define KEYMGR_API_MAJOR_GCC3 3
00063
00064 #define KEYMGR_GCC3_LIVE_IMAGE_LIST 301
00065 #define KEYMGR_GCC3_DW2_OBJ_LIST 302
00066
00067
00068 struct live_images {
00069 unsigned long this_size;
00070 struct mach_header *mh;
00071 unsigned long vm_slide;
00072 void (*destructor)(struct live_images *);
00073 struct live_images *next;
00074 unsigned int examined_p;
00075 void *fde;
00076 void *object_info;
00077 unsigned long info[2];
00078 };
00079
00080
00081
00082
00083
00084
00085 static void darwin_unwind_dyld_remove_image_hook
00086 (struct mach_header *m, unsigned long s);
00087 static void darwin_unwind_dyld_remove_image_hook
00088 (struct mach_header *m, unsigned long s);
00089 extern void __darwin_gcc3_preregister_frame_info (void);
00090
00091 static void
00092 darwin_unwind_dyld_add_image_hook (struct mach_header *mh, unsigned long slide)
00093 {
00094 struct live_images *l = (struct live_images *)calloc (1, sizeof (*l));
00095 l->mh = mh;
00096 l->vm_slide = slide;
00097 l->this_size = sizeof (*l);
00098 l->next = (struct live_images *)
00099 _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
00100 _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l);
00101 }
00102
00103 static void
00104 darwin_unwind_dyld_remove_image_hook (struct mach_header *m, unsigned long s)
00105 {
00106 struct live_images *top, **lip, *destroy = NULL;
00107
00108
00109
00110 top = (struct live_images *)
00111 _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
00112 for (lip = ⊤ *lip != NULL; lip = &(*lip)->next)
00113 {
00114 if ((*lip)->mh == m && (*lip)->vm_slide == s)
00115 {
00116 destroy = *lip;
00117 *lip = destroy->next;
00118
00119 if (destroy->this_size != sizeof (*destroy))
00120 abort ();
00121
00122 break;
00123 }
00124 }
00125 _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top);
00126
00127
00128 if (destroy != NULL)
00129 {
00130 if (destroy->destructor != NULL)
00131 (*destroy->destructor) (destroy);
00132 free (destroy);
00133 }
00134 }
00135
00136 void
00137 __darwin_gcc3_preregister_frame_info (void)
00138 {
00139 const _Tinfo_Node *info;
00140 _init_keymgr ();
00141 info = (_Tinfo_Node *)__keymgr_global[2];
00142 if (info != NULL)
00143 {
00144 if (info->major_version >= KEYMGR_API_MAJOR_GCC3)
00145 return;
00146
00147 }
00148
00149 _dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook);
00150 _dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook);
00151 }