blob: 02f9b8dfb245179e7a597286f94b1cb190839a47 [file] [log] [blame]
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001/* Copyright (C) 2007-2008 The Android Open Source Project
2**
3** This software is licensed under the terms of the GNU General Public
4** License version 2, as published by the Free Software Foundation, and
5** may be copied, distributed, and modified under those terms.
6**
7** This program is distributed in the hope that it will be useful,
8** but WITHOUT ANY WARRANTY; without even the implied warranty of
9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10** GNU General Public License for more details.
11*/
12/*
13 * Virtual hardware for bridging the FUSE kernel module
14 * in the emulated OS and outside file system
15 */
16#include "qemu_file.h"
17#include "goldfish_trace.h"
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +020018#include "sysemu.h"
19#include "trace.h"
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080020#ifdef CONFIG_MEMCHECK
21#include "memcheck/memcheck.h"
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +020022#include "memcheck/memcheck_util.h"
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080023#endif // CONFIG_MEMCHECK
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080024
David 'Digit' Turner335d2c12011-03-21 22:24:45 +010025/* Set to 1 to debug tracing */
26#define DEBUG 0
27
28#if DEBUG
29# define D(...) printf(__VA_ARGS__), fflush(stdout)
30#else
31# define D(...) ((void)0)
32#endif
33
34/* Set to 1 to debug PID tracking */
35#define DEBUG_PID 0
36
37#if DEBUG_PID
38# define DPID(...) printf(__VA_ARGS__), fflush(stdout)
39#else
40# define DPID(...) ((void)0)
41#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080042
43extern void cpu_loop_exit(void);
44
45extern int tracing;
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080046extern const char *trace_filename;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080047
48/* for execve */
David Turnerb9198052010-09-10 11:50:34 +020049static char exec_path[CLIENT_PAGE_SIZE];
50static char exec_arg[CLIENT_PAGE_SIZE];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080051static unsigned long vstart; // VM start
52static unsigned long vend; // VM end
53static unsigned long eoff; // offset in EXE file
54static unsigned cmdlen; // cmdline length
55static unsigned pid; // PID (really thread id)
56static unsigned tgid; // thread group id (really process id)
David 'Digit' Turner335d2c12011-03-21 22:24:45 +010057static unsigned tid; // current thread id (same as pid, most of the time)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080058static unsigned long dsaddr; // dynamic symbol address
59static unsigned long unmap_start; // start address to unmap
60
61/* for context switch */
62//static unsigned long cs_pid; // context switch PID
63
64/* I/O write */
65static void trace_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value)
66{
67 trace_dev_state *s = (trace_dev_state *)opaque;
68
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +020069 (void)s;
70
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080071 switch (offset >> 2) {
72 case TRACE_DEV_REG_SWITCH: // context switch, switch to pid
David 'Digit' Turner335d2c12011-03-21 22:24:45 +010073 DPID("QEMU.trace: context switch tid=%u\n", value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080074 if (trace_filename != NULL) {
75 trace_switch(value);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +010076 D("QEMU.trace: kernel, context switch %u\n", value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080077 }
78#ifdef CONFIG_MEMCHECK
79 if (memcheck_enabled) {
80 memcheck_switch(value);
81 }
82#endif // CONFIG_MEMCHECK
David 'Digit' Turner335d2c12011-03-21 22:24:45 +010083 tid = (unsigned) value;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080084 break;
85 case TRACE_DEV_REG_TGID: // save the tgid for the following fork/clone
David 'Digit' Turner335d2c12011-03-21 22:24:45 +010086 DPID("QEMU.trace: tgid=%u\n", value);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080087 tgid = value;
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080088 if (trace_filename != NULL) {
David 'Digit' Turner335d2c12011-03-21 22:24:45 +010089 D("QEMU.trace: kernel, tgid %u\n", value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080090 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080091 break;
92 case TRACE_DEV_REG_FORK: // fork, fork new pid
David 'Digit' Turner335d2c12011-03-21 22:24:45 +010093 DPID("QEMU.trace: fork (pid=%d tgid=%d value=%d)\n", pid, tgid, value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080094 if (trace_filename != NULL) {
95 trace_fork(tgid, value);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +010096 D("QEMU.trace: kernel, fork %u\n", value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080097 }
98#ifdef CONFIG_MEMCHECK
99 if (memcheck_enabled) {
100 memcheck_fork(tgid, value);
101 }
102#endif // CONFIG_MEMCHECK
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800103 break;
104 case TRACE_DEV_REG_CLONE: // fork, clone new pid (i.e. thread)
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100105 DPID("QEMU.trace: clone (pid=%d tgid=%d value=%d)\n", pid, tgid, value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800106 if (trace_filename != NULL) {
107 trace_clone(tgid, value);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100108 D("QEMU.trace: kernel, clone %u\n", value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800109 }
110#ifdef CONFIG_MEMCHECK
111 if (memcheck_enabled) {
112 memcheck_clone(tgid, value);
113 }
114#endif // CONFIG_MEMCHECK
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800115 break;
116 case TRACE_DEV_REG_EXECVE_VMSTART: // execve, vstart
117 vstart = value;
118 break;
119 case TRACE_DEV_REG_EXECVE_VMEND: // execve, vend
120 vend = value;
121 break;
122 case TRACE_DEV_REG_EXECVE_OFFSET: // execve, offset in EXE
123 eoff = value;
124 break;
125 case TRACE_DEV_REG_EXECVE_EXEPATH: // init exec, path of EXE
David Turnerb9198052010-09-10 11:50:34 +0200126 vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800127 if (trace_filename != NULL) {
David Turnerb9198052010-09-10 11:50:34 +0200128 trace_init_exec(vstart, vend, eoff, exec_path);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100129 D("QEMU.trace: kernel, init exec [%lx,%lx]@%lx [%s]\n",
130 vstart, vend, eoff, exec_path);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800131 }
132#ifdef CONFIG_MEMCHECK
133 if (memcheck_enabled) {
David Turnerb9198052010-09-10 11:50:34 +0200134 if (exec_path[0] == '\0') {
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800135 // vstrcpy may fail to copy path. In this case lets do it
136 // differently.
David Turnerb9198052010-09-10 11:50:34 +0200137 memcheck_get_guest_kernel_string(exec_path, value, CLIENT_PAGE_SIZE);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800138 }
David Turnerb9198052010-09-10 11:50:34 +0200139 memcheck_mmap_exepath(vstart, vend, eoff, exec_path);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800140 }
141#endif // CONFIG_MEMCHECK
David Turnerb9198052010-09-10 11:50:34 +0200142 exec_path[0] = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800143 break;
144 case TRACE_DEV_REG_CMDLINE_LEN: // execve, process cmdline length
145 cmdlen = value;
146 break;
147 case TRACE_DEV_REG_CMDLINE: // execve, process cmdline
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +0200148 cpu_memory_rw_debug(cpu_single_env, value, (uint8_t*)exec_arg, cmdlen, 0);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800149 if (trace_filename != NULL) {
David Turnerb9198052010-09-10 11:50:34 +0200150 trace_execve(exec_arg, cmdlen);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800151 }
152#ifdef CONFIG_MEMCHECK
153 if (memcheck_enabled) {
David Turnerb9198052010-09-10 11:50:34 +0200154 memcheck_set_cmd_line(exec_arg, cmdlen);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800155 }
156#endif // CONFIG_MEMCHECK
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100157#if DEBUG || DEBUG_PID
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800158 if (trace_filename != NULL) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800159 int i;
160 for (i = 0; i < cmdlen; i ++)
David Turnerb9198052010-09-10 11:50:34 +0200161 if (i != cmdlen - 1 && exec_arg[i] == 0)
162 exec_arg[i] = ' ';
163 printf("QEMU.trace: kernel, execve %s[%d]\n", exec_arg, cmdlen);
164 exec_arg[0] = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800165 }
166#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800167 break;
168 case TRACE_DEV_REG_EXIT: // exit, exit current process with exit code
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100169 DPID("QEMU.trace: exit tid=%u\n", value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800170 if (trace_filename != NULL) {
171 trace_exit(value);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100172 D("QEMU.trace: kernel, exit %x\n", value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800173 }
174#ifdef CONFIG_MEMCHECK
175 if (memcheck_enabled) {
176 memcheck_exit(value);
177 }
178#endif // CONFIG_MEMCHECK
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800179 break;
180 case TRACE_DEV_REG_NAME: // record thread name
David Turnerb9198052010-09-10 11:50:34 +0200181 vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100182 DPID("QEMU.trace: thread name=%s\n", exec_path);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800183
184 // Remove the trailing newline if it exists
David Turnerb9198052010-09-10 11:50:34 +0200185 int len = strlen(exec_path);
186 if (exec_path[len - 1] == '\n') {
187 exec_path[len - 1] = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800188 }
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800189 if (trace_filename != NULL) {
David Turnerb9198052010-09-10 11:50:34 +0200190 trace_name(exec_path);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100191 D("QEMU.trace: kernel, name %s\n", exec_path);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800192 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800193 break;
194 case TRACE_DEV_REG_MMAP_EXEPATH: // mmap, path of EXE, the others are same as execve
David Turnerb9198052010-09-10 11:50:34 +0200195 vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100196 DPID("QEMU.trace: mmap exe=%s\n", exec_path);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800197 if (trace_filename != NULL) {
David Turnerb9198052010-09-10 11:50:34 +0200198 trace_mmap(vstart, vend, eoff, exec_path);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100199 D("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, exec_path);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800200 }
201#ifdef CONFIG_MEMCHECK
202 if (memcheck_enabled) {
David Turnerb9198052010-09-10 11:50:34 +0200203 if (exec_path[0] == '\0') {
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800204 // vstrcpy may fail to copy path. In this case lets do it
205 // differently.
David Turnerb9198052010-09-10 11:50:34 +0200206 memcheck_get_guest_kernel_string(exec_path, value, CLIENT_PAGE_SIZE);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800207 }
David Turnerb9198052010-09-10 11:50:34 +0200208 memcheck_mmap_exepath(vstart, vend, eoff, exec_path);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800209 }
210#endif // CONFIG_MEMCHECK
David Turnerb9198052010-09-10 11:50:34 +0200211 exec_path[0] = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800212 break;
213 case TRACE_DEV_REG_INIT_PID: // init, name the pid that starts before device registered
214 pid = value;
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100215 DPID("QEMU.trace: pid=%d\n", value);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800216#ifdef CONFIG_MEMCHECK
217 if (memcheck_enabled) {
218 memcheck_init_pid(value);
219 }
220#endif // CONFIG_MEMCHECK
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800221 break;
222 case TRACE_DEV_REG_INIT_NAME: // init, the comm of the init pid
David Turnerb9198052010-09-10 11:50:34 +0200223 vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100224 DPID("QEMU.trace: tgid=%d pid=%d name=%s\n", tgid, pid, exec_path);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800225 if (trace_filename != NULL) {
David Turnerb9198052010-09-10 11:50:34 +0200226 trace_init_name(tgid, pid, exec_path);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100227 D("QEMU.trace: kernel, init name %u [%s]\n", pid, exec_path);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800228 }
David Turnerb9198052010-09-10 11:50:34 +0200229 exec_path[0] = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800230 break;
231
232 case TRACE_DEV_REG_DYN_SYM_ADDR: // dynamic symbol address
233 dsaddr = value;
234 break;
235 case TRACE_DEV_REG_DYN_SYM: // add dynamic symbol
David Turnerb9198052010-09-10 11:50:34 +0200236 vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800237 if (trace_filename != NULL) {
David Turnerb9198052010-09-10 11:50:34 +0200238 trace_dynamic_symbol_add(dsaddr, exec_arg);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100239 D("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, exec_arg);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800240 }
David Turnerb9198052010-09-10 11:50:34 +0200241 exec_arg[0] = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800242 break;
243 case TRACE_DEV_REG_REMOVE_ADDR: // remove dynamic symbol addr
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800244 if (trace_filename != NULL) {
245 trace_dynamic_symbol_remove(value);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100246 D("QEMU.trace: dynamic symbol remove %lx\n", dsaddr);
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800247 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800248 break;
249
250 case TRACE_DEV_REG_PRINT_STR: // print string
David Turnerb9198052010-09-10 11:50:34 +0200251 vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE);
252 printf("%s", exec_arg);
253 exec_arg[0] = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800254 break;
255 case TRACE_DEV_REG_PRINT_NUM_DEC: // print number in decimal
256 printf("%d", value);
257 break;
258 case TRACE_DEV_REG_PRINT_NUM_HEX: // print number in hexical
259 printf("%x", value);
260 break;
261
262 case TRACE_DEV_REG_STOP_EMU: // stop the VM execution
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800263 if (trace_filename != NULL) {
264 // To ensure that the number of instructions executed in this
265 // block is correct, we pretend that there was an exception.
266 trace_exception(0);
267 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800268 cpu_single_env->exception_index = EXCP_HLT;
269 cpu_single_env->halted = 1;
270 qemu_system_shutdown_request();
271 cpu_loop_exit();
272 break;
273
274 case TRACE_DEV_REG_ENABLE: // tracing enable: 0 = stop, 1 = start
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800275 if (value == 1) {
276 if (trace_filename != NULL) {
277 start_tracing();
278 }
279 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800280 else if (value == 0) {
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800281 if (trace_filename != NULL) {
282 stop_tracing();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800283
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800284 // To ensure that the number of instructions executed in this
285 // block is correct, we pretend that there was an exception.
286 trace_exception(0);
287 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800288 }
289 break;
290
291 case TRACE_DEV_REG_UNMAP_START:
292 unmap_start = value;
293 break;
294 case TRACE_DEV_REG_UNMAP_END:
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800295 if (trace_filename != NULL) {
296 trace_munmap(unmap_start, value);
297 }
298#ifdef CONFIG_MEMCHECK
299 if (memcheck_enabled) {
300 memcheck_unmap(unmap_start, value);
301 }
302#endif // CONFIG_MEMCHECK
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800303 break;
304
Jack Veenstra9980bbb2009-05-05 10:35:03 -0700305 case TRACE_DEV_REG_METHOD_ENTRY:
306 case TRACE_DEV_REG_METHOD_EXIT:
307 case TRACE_DEV_REG_METHOD_EXCEPTION:
Jack Veenstrae3ea32f2009-05-19 14:41:14 -0700308 case TRACE_DEV_REG_NATIVE_ENTRY:
309 case TRACE_DEV_REG_NATIVE_EXIT:
310 case TRACE_DEV_REG_NATIVE_EXCEPTION:
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800311 if (trace_filename != NULL) {
312 if (tracing) {
313 int call_type = (offset - 4096) >> 2;
314 trace_interpreted_method(value, call_type);
315 }
Jack Veenstra9980bbb2009-05-05 10:35:03 -0700316 }
317 break;
318
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800319#ifdef CONFIG_MEMCHECK
320 case TRACE_DEV_REG_MALLOC:
321 if (memcheck_enabled) {
322 memcheck_guest_alloc(value);
323 }
324 break;
325
326 case TRACE_DEV_REG_FREE_PTR:
327 if (memcheck_enabled) {
328 memcheck_guest_free(value);
329 }
330 break;
331
332 case TRACE_DEV_REG_QUERY_MALLOC:
333 if (memcheck_enabled) {
334 memcheck_guest_query_malloc(value);
335 }
336 break;
337
338 case TRACE_DEV_REG_LIBC_INIT:
339 if (memcheck_enabled) {
340 memcheck_guest_libc_initialized(value);
341 }
342 break;
343
344 case TRACE_DEV_REG_PRINT_USER_STR:
345 if (memcheck_enabled) {
346 memcheck_guest_print_str(value);
347 }
348 break;
349#endif // CONFIG_MEMCHECK
350
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800351 default:
Jack Veenstra9980bbb2009-05-05 10:35:03 -0700352 if (offset < 4096) {
353 cpu_abort(cpu_single_env, "trace_dev_write: Bad offset %x\n", offset);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100354 } else {
355 D("%s: offset=%d (0x%x) value=%d (0x%x)\n", __FUNCTION__, offset,
356 offset, value, value);
Jack Veenstra9980bbb2009-05-05 10:35:03 -0700357 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800358 break;
359 }
360}
361
362/* I/O read */
363static uint32_t trace_dev_read(void *opaque, target_phys_addr_t offset)
364{
365 trace_dev_state *s = (trace_dev_state *)opaque;
366
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +0200367 (void)s;
368
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800369 switch (offset >> 2) {
370 case TRACE_DEV_REG_ENABLE: // tracing enable
371 return tracing;
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100372
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800373 default:
Jack Veenstra9980bbb2009-05-05 10:35:03 -0700374 if (offset < 4096) {
375 cpu_abort(cpu_single_env, "trace_dev_read: Bad offset %x\n", offset);
David 'Digit' Turner335d2c12011-03-21 22:24:45 +0100376 } else {
377 D("%s: offset=%d (0x%x)\n", __FUNCTION__, offset, offset);
Jack Veenstra9980bbb2009-05-05 10:35:03 -0700378 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800379 return 0;
380 }
381 return 0;
382}
383
384static CPUReadMemoryFunc *trace_dev_readfn[] = {
385 trace_dev_read,
386 trace_dev_read,
387 trace_dev_read
388};
389
390static CPUWriteMemoryFunc *trace_dev_writefn[] = {
391 trace_dev_write,
392 trace_dev_write,
393 trace_dev_write
394};
395
396/* initialize the trace device */
Jack Veenstra9980bbb2009-05-05 10:35:03 -0700397void trace_dev_init()
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800398{
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800399 trace_dev_state *s;
400
401 s = (trace_dev_state *)qemu_mallocz(sizeof(trace_dev_state));
Jack Veenstra9980bbb2009-05-05 10:35:03 -0700402 s->dev.name = "qemu_trace";
403 s->dev.id = -1;
404 s->dev.base = 0; // will be allocated dynamically
405 s->dev.size = 0x2000;
406 s->dev.irq = 0;
407 s->dev.irq_count = 0;
408
409 goldfish_device_add(&s->dev, trace_dev_readfn, trace_dev_writefn, s);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800410
David Turnerb9198052010-09-10 11:50:34 +0200411 exec_path[0] = exec_arg[0] = '\0';
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800412}