trace.c revision b91980562344f6a3b719bfe4be007fa9406e585f
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful, 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Virtual hardware for bridging the FUSE kernel module 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the emulated OS and outside file system 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu_file.h" 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "goldfish_trace.h" 185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck/memcheck.h" 205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//#define DEBUG 1 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void cpu_loop_exit(void); 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern int tracing; 275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineextern const char *trace_filename; 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for execve */ 30b91980562344f6a3b719bfe4be007fa9406e585fDavid Turnerstatic char exec_path[CLIENT_PAGE_SIZE]; 31b91980562344f6a3b719bfe4be007fa9406e585fDavid Turnerstatic char exec_arg[CLIENT_PAGE_SIZE]; 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long vstart; // VM start 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long vend; // VM end 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long eoff; // offset in EXE file 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned cmdlen; // cmdline length 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned pid; // PID (really thread id) 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned tgid; // thread group id (really process id) 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long dsaddr; // dynamic symbol address 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long unmap_start; // start address to unmap 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for context switch */ 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//static unsigned long cs_pid; // context switch PID 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* I/O write */ 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void trace_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value) 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_state *s = (trace_dev_state *)opaque; 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (offset >> 2) { 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_SWITCH: // context switch, switch to pid 515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine trace_switch(value); 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine printf("QEMU.trace: kernel, context switch %u\n", value); 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_switch(value); 605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_TGID: // save the tgid for the following fork/clone 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tgid = value; 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine printf("QEMU.trace: kernel, tgid %u\n", value); 685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_FORK: // fork, fork new pid 725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine trace_fork(tgid, value); 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine printf("QEMU.trace: kernel, fork %u\n", value); 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_fork(tgid, value); 815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_CLONE: // fork, clone new pid (i.e. thread) 855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine trace_clone(tgid, value); 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine printf("QEMU.trace: kernel, clone %u\n", value); 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_clone(tgid, value); 945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXECVE_VMSTART: // execve, vstart 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vstart = value; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXECVE_VMEND: // execve, vend 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vend = value; 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXECVE_OFFSET: // execve, offset in EXE 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project eoff = value; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXECVE_EXEPATH: // init exec, path of EXE 107b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_path, CLIENT_PAGE_SIZE); 1085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 109b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner trace_init_exec(vstart, vend, eoff, exec_path); 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 1115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine printf("QEMU.trace: kernel, init exec [%lx,%lx]@%lx [%s]\n", 112b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstart, vend, eoff, exec_path); 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 1165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 117b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner if (exec_path[0] == '\0') { 1185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // vstrcpy may fail to copy path. In this case lets do it 1195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // differently. 120b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_get_guest_kernel_string(exec_path, value, CLIENT_PAGE_SIZE); 1215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 122b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_mmap_exepath(vstart, vend, eoff, exec_path); 1235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 125b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[0] = 0; 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_CMDLINE_LEN: // execve, process cmdline length 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cmdlen = value; 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_CMDLINE: // execve, process cmdline 131b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner cpu_memory_rw_debug(cpu_single_env, value, exec_arg, cmdlen, 0); 1325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 133b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner trace_execve(exec_arg, cmdlen); 1345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 1365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 137b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_set_cmd_line(exec_arg, cmdlen); 1385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 1415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < cmdlen; i ++) 144b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner if (i != cmdlen - 1 && exec_arg[i] == 0) 145b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_arg[i] = ' '; 146b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner printf("QEMU.trace: kernel, execve %s[%d]\n", exec_arg, cmdlen); 147b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_arg[0] = 0; 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXIT: // exit, exit current process with exit code 1525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 1535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine trace_exit(value); 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 1555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine printf("QEMU.trace: kernel, exit %x\n", value); 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 1595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 1605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_exit(value); 1615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_NAME: // record thread name 165b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_path, CLIENT_PAGE_SIZE); 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // Remove the trailing newline if it exists 168b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner int len = strlen(exec_path); 169b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner if (exec_path[len - 1] == '\n') { 170b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[len - 1] = 0; 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 173b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner trace_name(exec_path); 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 175b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner printf("QEMU.trace: kernel, name %s\n", exec_path); 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_MMAP_EXEPATH: // mmap, path of EXE, the others are same as execve 180b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_path, CLIENT_PAGE_SIZE); 1815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 182b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner trace_mmap(vstart, vend, eoff, exec_path); 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 184b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner printf("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, exec_path); 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 1885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 189b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner if (exec_path[0] == '\0') { 1905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // vstrcpy may fail to copy path. In this case lets do it 1915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // differently. 192b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_get_guest_kernel_string(exec_path, value, CLIENT_PAGE_SIZE); 1935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 194b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_mmap_exepath(vstart, vend, eoff, exec_path); 1955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 197b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[0] = 0; 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_INIT_PID: // init, name the pid that starts before device registered 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pid = value; 2015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 2025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 2035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_init_pid(value); 2045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_INIT_NAME: // init, the comm of the init pid 208b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_path, CLIENT_PAGE_SIZE); 2095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 210b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner trace_init_name(tgid, pid, exec_path); 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 212b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner printf("QEMU.trace: kernel, init name %u [%s]\n", pid, exec_path); 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 215b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[0] = 0; 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_DYN_SYM_ADDR: // dynamic symbol address 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dsaddr = value; 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_DYN_SYM: // add dynamic symbol 222b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE); 2235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 224b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner trace_dynamic_symbol_add(dsaddr, exec_arg); 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 226b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner printf("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, exec_arg); 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 229b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_arg[0] = 0; 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_REMOVE_ADDR: // remove dynamic symbol addr 2325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 2335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine trace_dynamic_symbol_remove(value); 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 2355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine printf("QEMU.trace: dynamic symbol remove %lx\n", dsaddr); 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_PRINT_STR: // print string 241b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE); 242b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner printf("%s", exec_arg); 243b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_arg[0] = 0; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_PRINT_NUM_DEC: // print number in decimal 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("%d", value); 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_PRINT_NUM_HEX: // print number in hexical 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("%x", value); 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_STOP_EMU: // stop the VM execution 2535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 2545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // To ensure that the number of instructions executed in this 2555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // block is correct, we pretend that there was an exception. 2565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine trace_exception(0); 2575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_single_env->exception_index = EXCP_HLT; 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_single_env->halted = 1; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_system_shutdown_request(); 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_loop_exit(); 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_ENABLE: // tracing enable: 0 = stop, 1 = start 2655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (value == 1) { 2665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 2675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine start_tracing(); 2685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (value == 0) { 2715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 2725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine stop_tracing(); 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // To ensure that the number of instructions executed in this 2755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // block is correct, we pretend that there was an exception. 2765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine trace_exception(0); 2775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_UNMAP_START: 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unmap_start = value; 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_UNMAP_END: 2855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 2865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine trace_munmap(unmap_start, value); 2875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 2895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 2905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_unmap(unmap_start, value); 2915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2959980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra case TRACE_DEV_REG_METHOD_ENTRY: 2969980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra case TRACE_DEV_REG_METHOD_EXIT: 2979980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra case TRACE_DEV_REG_METHOD_EXCEPTION: 298e3ea32ffa04468eddaf9c6ce2d36090f7bf43e49Jack Veenstra case TRACE_DEV_REG_NATIVE_ENTRY: 299e3ea32ffa04468eddaf9c6ce2d36090f7bf43e49Jack Veenstra case TRACE_DEV_REG_NATIVE_EXIT: 300e3ea32ffa04468eddaf9c6ce2d36090f7bf43e49Jack Veenstra case TRACE_DEV_REG_NATIVE_EXCEPTION: 3015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 3025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (tracing) { 3035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine int call_type = (offset - 4096) >> 2; 3045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine trace_interpreted_method(value, call_type); 3055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 3065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 3075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 3085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 3095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 3105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_MALLOC: 3115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 3125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_alloc(value); 3135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 3145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 3155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 3165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_FREE_PTR: 3175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 3185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_free(value); 3195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 3205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 3215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 3225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_QUERY_MALLOC: 3235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 3245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_query_malloc(value); 3255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 3265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 3275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 3285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_LIBC_INIT: 3295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 3305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_libc_initialized(value); 3315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 3325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 3335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 3345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_PRINT_USER_STR: 3355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 3365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_print_str(value); 3379980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra } 3389980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra break; 3395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 3409980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 3429980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra if (offset < 4096) { 3439980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra cpu_abort(cpu_single_env, "trace_dev_write: Bad offset %x\n", offset); 3449980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra } 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* I/O read */ 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t trace_dev_read(void *opaque, target_phys_addr_t offset) 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_state *s = (trace_dev_state *)opaque; 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (offset >> 2) { 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_ENABLE: // tracing enable 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return tracing; 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 3589980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra if (offset < 4096) { 3599980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra cpu_abort(cpu_single_env, "trace_dev_read: Bad offset %x\n", offset); 3609980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra } 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUReadMemoryFunc *trace_dev_readfn[] = { 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_read, 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_read, 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_read 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUWriteMemoryFunc *trace_dev_writefn[] = { 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_write, 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_write, 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_write 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* initialize the trace device */ 3799980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstravoid trace_dev_init() 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int iomemtype; 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_state *s; 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s = (trace_dev_state *)qemu_mallocz(sizeof(trace_dev_state)); 3859980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.name = "qemu_trace"; 3869980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.id = -1; 3879980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.base = 0; // will be allocated dynamically 3889980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.size = 0x2000; 3899980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.irq = 0; 3909980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.irq_count = 0; 3919980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra 3929980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra goldfish_device_add(&s->dev, trace_dev_readfn, trace_dev_writefn, s); 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 394b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[0] = exec_arg[0] = '\0'; 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 396