#import <stdlib.h>
#import <stdio.h>
#import <string.h>
#import <unistd.h>
#import <mach/mach.h>
extern void fork_mach_init(void);
#import "stuff/openstep_mach.h"
#import <mach/mig_errors.h>
#import <mach/message.h>
#import <mach-o/loader.h>
#import <mach-o/dyld_debug.h>
#import <mach-o/dyld_gdb.h>
#import "inline_strcmp.h"
#import "dyld_debug_defs.h"
#import "lock.h"
#import "debug.h"
#import "images.h"
#import "symbols.h"
#import "reloc.h"
#import "errors.h"
#import "allocate.h"
#import "register_funcs.h"
#import "mod_init_funcs.h"
#import "dyld_init.h"
#import "_dyld_event.h"
#ifndef __MACH30__
static const unsigned long send_timeout = 240000;
#endif
static const unsigned long rcv_timeout = 240000;
enum bool dyld_debug_trace = FALSE;
struct inbound_message_request {
#ifdef __MACH30__
mach_msg_header_t head;
union{
struct{
mach_msg_body_t msgh_body;
mach_msg_port_descriptor_t subscriber;
NDR_record_t NDR;
boolean_t inconsistent_data_ok;
} subscribe_to_events_request;
struct{
mach_msg_body_t msgh_body;
mach_msg_ool_descriptor_t name;
NDR_record_t NDR;
boolean_t inconsistent_data_ok;
mach_msg_type_number_t nameCnt;
} defining_module_request;
struct{
NDR_record_t NDR;
boolean_t inconsistent_data_ok;
module_t module;
} is_module_bound_request;
struct{
NDR_record_t NDR;
boolean_t inconsistent_data_ok;
module_t module;
} module_name_request;
struct{
NDR_record_t NDR;
boolean_t inconsistent_data_ok;
module_t module;
} bind_module_request;
}u;
mach_msg_trailer_t trailer;
#else
msg_header_t head;
msg_type_t inconsistent_data_okType;
boolean_t inconsistent_data_ok;
union{
struct{
msg_type_t subscriberType;
mach_port_t subscriber;
} subscribe_to_events_request;
struct{
msg_type_long_t nameType;
string_t name;
} defining_module_request;
struct{
msg_type_t moduleType;
module_t module;
} is_module_bound_request;
struct{
msg_type_t moduleType;
module_t module;
} module_name_request;
struct{
msg_type_t moduleType;
module_t module;
} bind_module_request;
}u;
#endif
};
struct inbound_message_reply {
#ifdef __MACH30__
mach_msg_header_t head;
union{
struct{
NDR_record_t NDR;
kern_return_t RetCode;
} subscribe_to_events_reply;
struct{
NDR_record_t NDR;
kern_return_t RetCode;
module_t module;
dyld_debug_return_t return_value;
} defining_module_reply;
struct{
NDR_record_t NDR;
kern_return_t RetCode;
boolean_t bound;
dyld_debug_return_t return_value;
} is_module_bound_reply;
struct{
mach_msg_body_t msgh_body;
mach_msg_ool_descriptor_t image_name;
mach_msg_ool_descriptor_t module_name;
NDR_record_t NDR;
mach_msg_type_number_t image_nameCnt;
mach_msg_type_number_t module_nameCnt;
dyld_debug_return_t return_value;
} module_name_reply;
struct{
NDR_record_t NDR;
kern_return_t RetCode;
dyld_debug_return_t return_value;
} bind_module_reply;
}u;
#else
msg_header_t head;
msg_type_t RetCodeType;
kern_return_t RetCode;
msg_type_t _dyld_debug_RetCodeType;
enum dyld_debug_return _dyld_debug_RetCode;
union{
#ifndef __MWERKS__
struct{
} subscribe_to_events_reply;
#endif
struct{
msg_type_t moduleType;
module_t module;
} defining_module_reply;
struct{
msg_type_t boundType;
boolean_t bound;
} is_module_bound_reply;
struct{
msg_type_long_t image_nameType;
string_t image_name;
msg_type_long_t module_nameType;
string_t module_name;
} module_name_reply;
#ifndef __MWERKS__
struct{
} bind_module_reply;
#endif
}u;
#endif
};
boolean_t _dyld_debug_server(
struct inbound_message_request *request,
struct inbound_message_reply *reply);
mach_port_t debug_port = MACH_PORT_NULL;
mach_port_t debug_thread = MACH_PORT_NULL;
struct event_port {
mach_port_t port;
struct event_port *next;
};
static struct event_port event_port_list = { MACH_PORT_NULL, NULL };
boolean_t dyld_image;
struct mach_header *dyld_image_header;
unsigned long dyld_image_vmaddr_slide;
char *dyld_image_name;
static boolean_t event_MsgError = FALSE;
static enum bool core_image = FALSE;
static enum dyld_debug_return set_dyld_data(
unsigned long offset,
unsigned long data);
static void server_loop(
void);
static enum dyld_debug_return send_past_events(
mach_port_t subscriber);
unsigned int gdb_dyld_version = 2;
unsigned int gdb_nobject_images = NOBJECT_IMAGES;
unsigned int gdb_nlibrary_images = NLIBRARY_IMAGES;
unsigned int gdb_object_image_size = sizeof(struct object_image);
unsigned int gdb_library_image_size = sizeof(struct library_image);
void
gdb_dyld_state_changed(
void)
{
}
volatile enum bool debug_thread_waiting_for_lock = FALSE;
volatile enum bool lock_in_multiply_defined_handler = FALSE;
static volatile enum bool lock_in_linkedit_error_handler = FALSE;
void
multiply_defined_enter(void)
{
lock_in_multiply_defined_handler = TRUE;
if(debug_thread != mach_thread_self())
return;
if(debug_thread_waiting_for_lock == TRUE)
thread_suspend(mach_thread_self());
}
void
multiply_defined_exit(void)
{
lock_in_multiply_defined_handler = FALSE;
}
void
linkedit_error_enter(void)
{
if(debug_thread != mach_thread_self())
return;
lock_in_linkedit_error_handler = TRUE;
if(debug_thread_waiting_for_lock == TRUE)
thread_suspend(mach_thread_self());
}
void
start_debug_thread(
enum bool start_from_core)
{
kern_return_t r;
#ifdef CORE_DEBUG
set_dyld_data(24, 1);
#endif
if(dyld_debug_trace)
print("start_debug_thread called\n");
if(start_from_core == TRUE)
fork_mach_init();
#ifdef CORE_DEBUG
set_dyld_data(24, 2);
#endif
debug_thread = mach_thread_self();
if(dyld_debug_trace)
print("debug_thread %d\n", debug_thread);
#ifdef CORE_DEBUG
set_dyld_data(24, 3);
#endif
if(lock_is_set(debug_thread_lock)){
thread_terminate(mach_thread_self());
}
if(set_dyld_data(16, debug_thread) != DYLD_SUCCESS){
clear_lock(debug_thread_lock);
thread_terminate(mach_thread_self());
}
#ifdef CORE_DEBUG
set_dyld_data(24, 4);
#endif
core_image = start_from_core;
#ifdef __MACH30__
if((r = mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_RECEIVE, &debug_port)) != KERN_SUCCESS){
#else
if((r = port_allocate(mach_task_self(),
(int *)&debug_port)) != KERN_SUCCESS){
#endif
clear_lock(debug_thread_lock);
(void)set_dyld_data(16, MACH_PORT_NULL);
thread_terminate(mach_thread_self());
}
if(dyld_debug_trace)
print("debug_port %d\n", debug_port);
#ifdef CORE_DEBUG
set_dyld_data(24, 5);
#endif
(void)set_dyld_data(12, debug_port);
#ifdef CORE_DEBUG
set_dyld_data(24, 6);
#endif
server_loop();
}
static
enum dyld_debug_return
set_dyld_data(
unsigned long offset,
unsigned long data)
{
unsigned long i, j;
struct load_command *lc, *load_commands;
struct segment_command *sg;
struct section *s;
load_commands = (struct load_command *)
((char *)object_images.images[0].image.mh +
sizeof(struct mach_header));
lc = load_commands;
for(i = 0; i < object_images.images[0].image.mh->ncmds; i++){
switch(lc->cmd){
case LC_SEGMENT:
sg = (struct segment_command *)lc;
s = (struct section *)
((char *)sg + sizeof(struct segment_command));
for(j = 0; j < sg->nsects; j++){
if(strcmp(s->segname, "__DATA") == 0 &&
strcmp(s->sectname, "__dyld") == 0){
if(s->size >= offset + sizeof(unsigned long)){
*((long *)(s->addr + offset)) = data;
return(DYLD_SUCCESS);
}
}
s++;
}
}
lc = (struct load_command *)((char *)lc + lc->cmdsize);
}
return(DYLD_FAILURE);
}
static
void
server_loop(void)
{
struct inbound_message_request request;
struct inbound_message_reply reply;
kern_return_t r;
boolean_t b;
struct thread_basic_info info;
unsigned int info_count, suspend_count, resume_count, i;
mach_port_t resumed_thread;
while(TRUE){
#ifdef __MACH30__
r = mach_msg(
&request.head,
MACH_RCV_MSG,
0,
sizeof(struct inbound_message_request),
debug_port,
MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL);
#else
request.head.msg_local_port = debug_port;
request.head.msg_size = sizeof(struct inbound_message_request);
r = msg_receive(&request.head, MACH_MSG_OPTION_NONE, 0);
#endif
#ifdef CORE_DEBUG
set_dyld_data(24, 7);
#endif
#ifdef __MACH30__
if(r != MACH_MSG_SUCCESS)
#else
if(r != RCV_SUCCESS)
#endif
continue;
if(core_image == TRUE)
goto cant_unlock;
resume_count = 0;
resumed_thread = MACH_PORT_NULL;
debug_thread_waiting_for_lock = TRUE;
if(dyld_lock == TRUE &&
thread_that_has_dyld_lock != MACH_PORT_NULL &&
lock_in_multiply_defined_handler == FALSE &&
lock_in_linkedit_error_handler == FALSE){
info_count = THREAD_BASIC_INFO_COUNT;
r = thread_info(thread_that_has_dyld_lock, THREAD_BASIC_INFO,
(thread_info_t)&info, &info_count);
if(r != KERN_SUCCESS)
goto cant_unlock;
if(resumed_thread == MACH_PORT_NULL)
resumed_thread = thread_that_has_dyld_lock;
for(suspend_count = info.suspend_count;
suspend_count > 0;
suspend_count--){
r = thread_resume(resumed_thread);
resume_count++;
if(r == KERN_FAILURE)
break;
if(r != KERN_SUCCESS)
goto cant_unlock;
}
r = thread_switch(resumed_thread,
SWITCH_OPTION_NONE, 0);
if(r != KERN_SUCCESS)
goto cant_unlock;
}
while((dyld_lock == TRUE ||
thread_that_has_dyld_lock != MACH_PORT_NULL) &&
lock_in_multiply_defined_handler == FALSE &&
lock_in_linkedit_error_handler == FALSE);
if(resume_count != 0){
if(dyld_lock == FALSE)
resume_count--;
#if !defined(__GONZO_BUNSEN_BEAKER__) && !defined(__HERA__) && !defined(__OPENSTEP__)
usleep(20000);
#endif
for(i = 0; i < resume_count; i++){
r = thread_suspend(resumed_thread);
if(r != KERN_SUCCESS)
break;
}
resumed_thread = MACH_PORT_NULL;
}
cant_unlock:
if(core_image == FALSE)
debug_thread_waiting_for_lock = FALSE;
b = _dyld_debug_server(&request, &reply);
if(b == FALSE){
continue;
}
#ifdef __MACH30__
r = mach_msg(
&reply.head,
MACH_SEND_MSG,
reply.head.msgh_size,
0,
MACH_PORT_NULL,
MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL);
#else
reply.head.msg_local_port = debug_port;
msg_send(&reply.head, MACH_MSG_OPTION_NONE, 0);
#endif
}
}
#ifdef __MACH30__
kern_return_t
#else
enum dyld_debug_return
#endif
server_dyld_debug_defining_module(
mach_port_t debug_port,
boolean_t inconsistent_data_ok,
char *name,
unsigned int nameCnt,
struct dyld_debug_module *module
#ifdef __MACH30__
, dyld_debug_return_t *retval
#endif
)
{
struct nlist *defined_symbol;
module_state *defined_module;
struct image *defined_image;
struct library_image *defined_library_image;
enum dyld_debug_return return_value;
memset(module, '\0', sizeof(struct dyld_debug_module));
if(dyld_lock == TRUE && inconsistent_data_ok == FALSE){
return_value = DYLD_INCONSISTENT_DATA;
goto done;
}
lookup_symbol(name, NULL, NULL, FALSE, &defined_symbol, &defined_module,
&defined_image, &defined_library_image, NULL);
if(defined_symbol == NULL){
return_value = DYLD_INVALID_ARGUMENTS;
goto done;
}
module->header = defined_image->mh;
module->vmaddr_slide = defined_image->vmaddr_slide;
if(defined_library_image != NULL)
module->module_index =
defined_module - defined_library_image->modules;
return_value = DYLD_SUCCESS;
done:
(void)vm_deallocate(mach_task_self(), (vm_address_t)name,
(vm_size_t)nameCnt);
#ifdef __MACH30__
*retval = return_value;
return(KERN_SUCCESS);
#else
return(return_value);
#endif
}
#ifdef __MACH30__
kern_return_t
#else
enum dyld_debug_return
#endif
server_dyld_debug_is_module_bound(
mach_port_t debug_port,
boolean_t inconsistent_data_ok,
struct dyld_debug_module module,
boolean_t *bound
#ifdef __MACH30__
, dyld_debug_return_t *retval
#endif
)
{
unsigned long i, j;
struct object_images *p;
struct library_images *q;
enum link_state link_state;
enum dyld_debug_return return_value;
*bound = FALSE;
if(dyld_lock == TRUE && inconsistent_data_ok == FALSE){
return_value = DYLD_INCONSISTENT_DATA;
goto done;
}
for(p = &object_images ; ; p = p->next_images){
for(i = 0; i < p->nimages; i++){
link_state = GET_LINK_STATE(p->images[i].module);
if(link_state == UNUSED)
continue;
if(module.header == p->images[i].image.mh){
if(module.module_index != 0)
return(DYLD_INVALID_ARGUMENTS);
if(link_state == LINKED || link_state == FULLY_LINKED)
*bound = TRUE;
return_value = DYLD_SUCCESS;
goto done;
}
}
if(p->next_images == NULL)
break;
}
for(q = &library_images ; ; q = q->next_images){
for(i = 0; i < q->nimages; i++){
if(module.header == q->images[i].image.mh){
if(module.module_index >= q->images[i].image.dyst->nmodtab)
return(DYLD_INVALID_ARGUMENTS);
j = module.module_index;
link_state = GET_LINK_STATE(q->images[i].modules[j]);
if(link_state == LINKED || link_state == FULLY_LINKED)
*bound = TRUE;
return_value = DYLD_SUCCESS;
goto done;
}
}
if(q->next_images == NULL)
break;
}
return_value = DYLD_FAILURE;
done:
#ifdef __MACH30__
*retval = return_value;
return(KERN_SUCCESS);
#else
return(return_value);
#endif
}
#ifdef __MACH30__
kern_return_t
#else
enum dyld_debug_return
#endif
server_dyld_debug_bind_module(
mach_port_t debug_port,
boolean_t inconsistent_data_ok,
struct dyld_debug_module module
#ifdef __MACH30__
, dyld_debug_return_t *retval
#endif
)
{
unsigned long i, j;
struct object_images *p;
struct library_images *q;
enum link_state link_state;
enum dyld_debug_return return_value;
if(dyld_lock == TRUE && inconsistent_data_ok == FALSE){
return_value = DYLD_INCONSISTENT_DATA;
goto done;
}
for(p = &object_images ; ; p = p->next_images){
for(i = 0; i < p->nimages; i++){
link_state = GET_LINK_STATE(p->images[i].module);
if(link_state == UNUSED)
continue;
if(module.header == p->images[i].image.mh){
if(module.module_index != 0){
return_value = DYLD_INVALID_ARGUMENTS;
goto done;
}
if(link_state == LINKED || link_state == FULLY_LINKED){
return_value = DYLD_SUCCESS;
goto done;
}
else{
return_value = DYLD_INVALID_ARGUMENTS;
goto done;
}
}
}
if(p->next_images == NULL)
break;
}
for(q = &library_images ; ; q = q->next_images){
for(i = 0; i < q->nimages; i++){
if(module.header == q->images[i].image.mh){
if(module.module_index >= q->images[i].image.dyst->nmodtab){
return_value = DYLD_INVALID_ARGUMENTS;
goto done;
}
j = module.module_index;
link_state = GET_LINK_STATE(q->images[i].modules[j]);
if(dyld_lock == TRUE ||
lock_in_multiply_defined_handler == TRUE ||
lock_in_linkedit_error_handler == TRUE){
return_value = DYLD_INCONSISTENT_DATA;
goto done;
}
if(link_state == LINKED || link_state == FULLY_LINKED){
return_value = DYLD_SUCCESS;
goto done;
}
if(link_state != UNLINKED &&
link_state != PREBOUND_UNLINKED){
return_value = DYLD_INVALID_ARGUMENTS;
goto done;
}
set_lock();
if(link_state == PREBOUND_UNLINKED){
undo_prebinding_for_library_module(
q->images[i].modules + j,
&(q->images[i].image),
q->images + i);
SET_LINK_STATE(q->images[i].modules[j], UNLINKED);
}
link_library_module(q->images + i,
&(q->images[i].image),
q->images[i].modules + j,
FALSE, FALSE, FALSE);
resolve_undefineds(FALSE, FALSE);
relocate_modules_being_linked(FALSE);
check_and_report_undefineds(FALSE);
call_registered_funcs_for_add_images();
call_registered_funcs_for_linked_modules();
call_image_init_routines(FALSE);
call_module_initializers(FALSE, FALSE, FALSE);
release_lock();
return_value = DYLD_SUCCESS;
goto done;
}
}
if(q->next_images == NULL)
break;
}
return_value = DYLD_FAILURE;
done:
#ifdef __MACH30__
*retval = return_value;
return(KERN_SUCCESS);
#else
return(return_value);
#endif
}
#ifdef __MACH30__
kern_return_t
#else
enum dyld_debug_return
#endif
server_dyld_debug_module_name(
mach_port_t debug_port,
boolean_t inconsistent_data_ok,
struct dyld_debug_module module,
char **image_name,
unsigned int *image_nameCnt,
char **module_name,
unsigned int *module_nameCnt
#ifdef __MACH30__
, dyld_debug_return_t *retval
#endif
)
{
unsigned long i, j;
struct object_images *p;
struct library_images *q;
struct segment_command *linkedit_segment;
struct symtab_command *st;
struct dysymtab_command *dyst;
char *strings;
struct dylib_module *dylib_modules;
struct load_command *lc;
struct dylinker_command *dyld;
enum dyld_debug_return return_value;
enum link_state link_state;
*image_name = NULL;
*image_nameCnt = 0;
*module_name = NULL;
*module_nameCnt = 0;
if(dyld_lock == TRUE && inconsistent_data_ok == FALSE){
return_value = DYLD_INCONSISTENT_DATA;
goto done;
}
for(p = &object_images ; ; p = p->next_images){
for(i = 0; i < p->nimages; i++){
link_state = GET_LINK_STATE(p->images[i].module);
if(link_state == UNUSED)
continue;
if(module.header == p->images[i].image.mh){
if(module.module_index != 0){
return_value = DYLD_INVALID_ARGUMENTS;
goto done;
}
*image_name = p->images[i].image.name;
*image_nameCnt = strlen(*image_name);
return_value = DYLD_SUCCESS;
goto done;
}
}
if(p->next_images == NULL)
break;
}
for(q = &library_images ; ; q = q->next_images){
for(i = 0; i < q->nimages; i++){
if(module.header == q->images[i].image.mh){
if(module.module_index >= q->images[i].image.dyst->nmodtab){
return_value = DYLD_INVALID_ARGUMENTS;
goto done;
}
j = module.module_index;
*image_name = q->images[i].image.name;
*image_nameCnt = strlen(*image_name);
linkedit_segment = q->images[i].image.linkedit_segment;
st = q->images[i].image.st;
dyst = q->images[i].image.dyst;
strings = (char *)
(q->images[i].image.vmaddr_slide +
linkedit_segment->vmaddr +
st->stroff -
linkedit_segment->fileoff);
dylib_modules = (struct dylib_module *)
(q->images[i].image.vmaddr_slide +
linkedit_segment->vmaddr +
dyst->modtaboff -
linkedit_segment->fileoff);
*module_name = strings + dylib_modules[j].module_name,
*module_nameCnt = strlen(*module_name);
return_value = DYLD_SUCCESS;
goto done;
}
}
if(q->next_images == NULL)
break;
}
if(module.header == dyld_image_header){
if(dyld_image_name == NULL){
lc = (struct load_command *)
((char *)dyld_image_header + sizeof(struct mach_header));
dyld = NULL;
for(i = 0; i < dyld_image_header->ncmds; i++){
switch(lc->cmd){
case LC_ID_DYLINKER:
if(dyld == NULL){
dyld = (struct dylinker_command *)lc;
dyld_image_name = (char *)dyld + dyld->name.offset;
}
break;
}
lc = (struct load_command *)((char *)lc + lc->cmdsize);
}
}
if(dyld_image_name != NULL){
*image_name = dyld_image_name;
*image_nameCnt = strlen(*image_name);
return_value = DYLD_SUCCESS;
goto done;
}
}
return_value = DYLD_FAILURE;
done:
#ifdef __MACH30__
*retval = return_value;
return(KERN_SUCCESS);
#else
return(return_value);
#endif
}
#ifdef DYLD_PROFILING
#ifdef __MACH30__
kern_return_t
#else
enum dyld_debug_return
#endif
server_dyld_debug_monoutput(
mach_port_t debug_port
#ifdef __MACH30__
, dyld_debug_return_t *retval
#endif
)
{
dyld_monoutput();
#ifdef __MACH30__
*retval = DYLD_SUCCESS;
return(KERN_SUCCESS);
#else
return(DYLD_SUCCESS);
#endif
}
#endif
#ifdef __MACH30__
kern_return_t
#else
enum dyld_debug_return
#endif
server_dyld_debug_add_event_subscriber(
mach_port_t debug_port,
boolean_t inconsistent_data_ok,
mach_port_t subscriber
#ifdef __MACH30__
, dyld_debug_return_t *retval
#endif
)
{
struct event_port *event_port;
enum dyld_debug_return return_value;
if(dyld_lock == TRUE && inconsistent_data_ok == FALSE){
return_value = DYLD_INCONSISTENT_DATA;
goto done;
}
if(send_past_events(subscriber) != DYLD_SUCCESS){
return_value = DYLD_FAILURE;
goto done;
}
if(event_port_list.port == MACH_PORT_NULL){
event_port_list.port = subscriber;
}
else{
event_port = allocate_with_no_error_check(
sizeof(struct event_port));
if(event_port == NULL){
return_value = DYLD_FAILURE;
goto done;
}
event_port->port = subscriber;
event_port->next = event_port_list.next;
event_port_list.next = event_port;
}
return_value = DYLD_SUCCESS;
done:
#ifdef __MACH30__
*retval = return_value;
return(KERN_SUCCESS);
#else
return(return_value);
#endif
}
static
enum dyld_debug_return
send_past_events(
mach_port_t subscriber)
{
unsigned long i, j;
struct object_images *p;
struct library_images *q;
struct dyld_event event;
enum link_state link_state;
memset(&event, '\0', sizeof(struct dyld_event));
event.type = DYLD_IMAGE_ADDED;
if(dyld_image == TRUE){
event.arg[0].header = dyld_image_header;
event.arg[0].vmaddr_slide = dyld_image_vmaddr_slide;
event_MsgError = FALSE;
user_dyld_event_server_callback(subscriber, rcv_timeout,
#ifndef __MACH30__
send_timeout,
#endif
event);
if(event_MsgError == TRUE)
return(DYLD_FAILURE);
}
for(p = &object_images ; ; p = p->next_images){
for(i = 0; i < p->nimages; i++){
link_state = GET_LINK_STATE(p->images[i].module);
if(link_state == UNUSED)
continue;
event.arg[0].header = p->images[i].image.mh;
event.arg[0].vmaddr_slide = p->images[i].image.vmaddr_slide;
event_MsgError = FALSE;
user_dyld_event_server_callback(subscriber, rcv_timeout,
#ifndef __MACH30__
send_timeout,
#endif
event);
if(event_MsgError == TRUE)
return(DYLD_FAILURE);
}
if(p->next_images == NULL)
break;
}
for(q = &library_images ; ; q = q->next_images){
for(i = 0; i < q->nimages; i++){
event.arg[0].header = q->images[i].image.mh;
event.arg[0].vmaddr_slide = q->images[i].image.vmaddr_slide;
event_MsgError = FALSE;
user_dyld_event_server_callback(subscriber, rcv_timeout,
#ifndef __MACH30__
send_timeout,
#endif
event);
if(event_MsgError == TRUE)
return(DYLD_FAILURE);
}
if(q->next_images == NULL)
break;
}
memset(&event, '\0', sizeof(struct dyld_event));
event.type = DYLD_MODULE_BOUND;
for(p = &object_images ; ; p = p->next_images){
for(i = 0; i < p->nimages; i++){
link_state = GET_LINK_STATE(p->images[i].module);
if(link_state != LINKED && link_state != FULLY_LINKED)
continue;
event.arg[0].header = p->images[i].image.mh;
event.arg[0].vmaddr_slide = p->images[i].image.vmaddr_slide;
event_MsgError = FALSE;
user_dyld_event_server_callback(subscriber, rcv_timeout,
#ifndef __MACH30__
send_timeout,
#endif
event);
if(event_MsgError == TRUE)
return(DYLD_FAILURE);
}
if(p->next_images == NULL)
break;
}
for(q = &library_images ; ; q = q->next_images){
for(i = 0; i < q->nimages; i++){
for(j = 0; j < q->images[i].image.dyst->nmodtab; j++){
link_state = GET_LINK_STATE(q->images[i].modules[j]);
if(link_state != LINKED && link_state != FULLY_LINKED)
continue;
event.arg[0].header = q->images[i].image.mh;
event.arg[0].vmaddr_slide = q->images[i].image.vmaddr_slide;
event.arg[0].module_index = j;
event_MsgError = FALSE;
user_dyld_event_server_callback(subscriber, rcv_timeout,
#ifndef __MACH30__
send_timeout,
#endif
event);
if(event_MsgError == TRUE)
return(DYLD_FAILURE);
}
}
if(q->next_images == NULL)
break;
}
memset(&event, '\0', sizeof(struct dyld_event));
event.type = DYLD_PAST_EVENTS_END;
event_MsgError = FALSE;
user_dyld_event_server_callback(subscriber, rcv_timeout,
#ifndef __MACH30__
send_timeout,
#endif
event);
if(event_MsgError == TRUE)
return(DYLD_FAILURE);
return(DYLD_SUCCESS);
}
void
send_event(
struct dyld_event *event)
{
struct event_port *event_port, *prev;
prev = NULL;
for(event_port = &event_port_list;
event_port->port != MACH_PORT_NULL;
event_port = event_port->next){
event_MsgError = FALSE;
user_dyld_event_server_callback(event_port->port, rcv_timeout,
#ifndef __MACH30__
send_timeout,
#endif
*event);
if(event_MsgError == TRUE){
#ifdef __MACH30__
(void)mach_port_deallocate(mach_task_self(), event_port->port);
#else
(void)port_deallocate(mach_task_self(), event_port->port);
#endif
event_port->port = MACH_PORT_NULL;
if(prev != NULL){
prev->next = event_port->next;
free(event_port);
}
}
else{
prev = event_port;
}
if(event_port->next == NULL)
return;
}
}
#ifndef __MACH30__
void
dyld_event_MsgError(
msg_return_t msg_result)
{
event_MsgError = TRUE;
}
#endif