1/*
2 *  dtrace_dyld.cpp
3 *  dtrace
4 *
5 *  Created by James McIlree on 3/30/09.
6 *  Copyright 2009 Apple Inc.. All rights reserved.
7 *
8 */
9
10#include <unistd.h>
11#include <stdio.h>
12#include <stdint.h>
13#include <stdlib.h>
14#include <stdbool.h>
15#include <mach/mach.h>
16
17#include <mach-o/dyld_images.h>
18
19#include "CSCppTimeoutLock.hpp"
20#include "CSCppDyldSharedMemoryPage.hpp"
21
22static
23void prepareDTraceRPC() __attribute__((constructor));
24
25static
26void prepareDTraceRPC()
27{
28	unsetenv("DYLD_INSERT_LIBRARIES"); /* children must not have this present in their env */
29
30	task_dyld_info_data_t task_dyld_info;
31	mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
32
33	if (kern_return_t err = task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count)) {
34		mach_error("Call to task_info failed ", err);
35		exit(1);
36	}
37
38	// This should NEVER happen. We're running in process, so we have to be initialized...
39	if (task_dyld_info.all_image_info_addr == 0) {
40		fprintf(stderr, "Impossible failure, task_dyld_info returned NULL all_image_info_addr. Please report this bug!\n");
41		exit(1);
42	}
43
44	struct dyld_all_image_infos* aii = (struct dyld_all_image_infos*)task_dyld_info.all_image_info_addr;
45	if (CSCppDyldSharedMemoryPage* connection = (CSCppDyldSharedMemoryPage*)aii->coreSymbolicationShmPage) {
46		bool should_send_notice = false;
47
48		//
49		// First we encode data for the ping
50		//
51		{
52			CSCppTimeoutLock lock(connection->lock_addr(), connection->timeout());
53			if (lock.is_locked()) {
54				connection->increment_data_generation();
55				uint64_t* data = (uint64_t*)connection->data();
56				data[0] = 666;
57				should_send_notice = true;
58			}
59		}
60
61		//
62		// Now we ping everyone
63		//
64		if (should_send_notice) {
65			uint32_t sent, recv;
66			connection->send_notice(CORESYMBOLICATION_DYLD_PING_MSGH_ID, sent, recv);
67		}
68	}
69}
70