trace.c revision aaef275467ba13162d52ef6f690fd97f9733eb58
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 */ 1628a09b6fe8d8f3e92ffee9263609a6da881b8818David 'Digit' Turner#include "migration/qemu-file.h" 17f5bc01c356e1fa924ed07aadf589b3663873593eDavid 'Digit' Turner#include "hw/android/goldfish/trace.h" 18f5bc01c356e1fa924ed07aadf589b3663873593eDavid 'Digit' Turner#include "hw/android/goldfish/vmem.h" 1934c48ff1e3ad5cd2084ca40188754d45f423750bDavid 'Digit' Turner#include "sysemu/sysemu.h" 205bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 2196e493a7f0be0193cb17b24c3492d998411b5031David 'Digit' Turner#include "android/qemu/memcheck/memcheck.h" 2296e493a7f0be0193cb17b24c3492d998411b5031David 'Digit' Turner#include "android/qemu/memcheck/memcheck_util.h" 235bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner/* Set to 1 to debug tracing */ 26335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#define DEBUG 0 27335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner 28335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#if DEBUG 29335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner# define D(...) printf(__VA_ARGS__), fflush(stdout) 30335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#else 31335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner# define D(...) ((void)0) 32335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#endif 33335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner 34335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner/* Set to 1 to debug PID tracking */ 35335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#define DEBUG_PID 0 36335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner 37335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#if DEBUG_PID 38335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner# define DPID(...) printf(__VA_ARGS__), fflush(stdout) 39335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#else 40335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner# define DPID(...) ((void)0) 41335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#endif 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 43171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner// TODO(digit): Re-enable tracing some day? 44171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner#define tracing 0 45171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner 4685c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerextern void cpu_loop_exit(CPUArchState* env); 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineextern const char *trace_filename; 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for execve */ 51b91980562344f6a3b719bfe4be007fa9406e585fDavid Turnerstatic char exec_path[CLIENT_PAGE_SIZE]; 52b91980562344f6a3b719bfe4be007fa9406e585fDavid Turnerstatic char exec_arg[CLIENT_PAGE_SIZE]; 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long vstart; // VM start 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long vend; // VM end 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long eoff; // offset in EXE file 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned cmdlen; // cmdline length 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned pid; // PID (really thread id) 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned tgid; // thread group id (really process id) 59335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turnerstatic unsigned tid; // current thread id (same as pid, most of the time) 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long dsaddr; // dynamic symbol address 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long unmap_start; // start address to unmap 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for context switch */ 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//static unsigned long cs_pid; // context switch PID 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* I/O write */ 67bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic void trace_dev_write(void *opaque, hwaddr offset, uint32_t value) 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_state *s = (trace_dev_state *)opaque; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 714e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner (void)s; 724e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (offset >> 2) { 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_SWITCH: // context switch, switch to pid 75335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner DPID("QEMU.trace: context switch tid=%u\n", value); 765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 77335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: kernel, context switch %u\n", value); 785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 795bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_switch(value); 825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 835bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 84335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner tid = (unsigned) value; 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_TGID: // save the tgid for the following fork/clone 87335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner DPID("QEMU.trace: tgid=%u\n", value); 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tgid = value; 895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 90335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: kernel, tgid %u\n", value); 915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_FORK: // fork, fork new pid 94335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner DPID("QEMU.trace: fork (pid=%d tgid=%d value=%d)\n", pid, tgid, value); 955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 96335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: kernel, fork %u\n", value); 975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 985bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 1005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_fork(tgid, value); 1015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1025bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_CLONE: // fork, clone new pid (i.e. thread) 105335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner DPID("QEMU.trace: clone (pid=%d tgid=%d value=%d)\n", pid, tgid, value); 1065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 107335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: kernel, clone %u\n", value); 1085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1095bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 1105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 1115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_clone(tgid, value); 1125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1135bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXECVE_VMSTART: // execve, vstart 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vstart = value; 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXECVE_VMEND: // execve, vend 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vend = value; 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXECVE_OFFSET: // execve, offset in EXE 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project eoff = value; 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXECVE_EXEPATH: // init exec, path of EXE 125b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_path, CLIENT_PAGE_SIZE); 1265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 127335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: kernel, init exec [%lx,%lx]@%lx [%s]\n", 128335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner vstart, vend, eoff, exec_path); 1295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1305bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 1315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 132b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner if (exec_path[0] == '\0') { 1335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // vstrcpy may fail to copy path. In this case lets do it 1345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // differently. 135b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_get_guest_kernel_string(exec_path, value, CLIENT_PAGE_SIZE); 1365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 137b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_mmap_exepath(vstart, vend, eoff, exec_path); 1385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1395bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 140b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[0] = 0; 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_CMDLINE_LEN: // execve, process cmdline length 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cmdlen = value; 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_CMDLINE: // execve, process cmdline 146aaef275467ba13162d52ef6f690fd97f9733eb58David 'Digit' Turner safe_memory_rw_debug(current_cpu, value, (uint8_t*)exec_arg, cmdlen, 0); 1475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 148171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner D("QEMU.trace: kernel, execve [%.*s]\n", cmdlen, exec_arg); 1495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1505bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 1515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 152b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_set_cmd_line(exec_arg, cmdlen); 1535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1545bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 155335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#if DEBUG || DEBUG_PID 1565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < cmdlen; i ++) 159b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner if (i != cmdlen - 1 && exec_arg[i] == 0) 160b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_arg[i] = ' '; 161b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner printf("QEMU.trace: kernel, execve %s[%d]\n", exec_arg, cmdlen); 162b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_arg[0] = 0; 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_EXIT: // exit, exit current process with exit code 167335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner DPID("QEMU.trace: exit tid=%u\n", value); 1685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 169335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: kernel, exit %x\n", value); 1705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1715bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 1725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 1735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_exit(value); 1745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1755bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_NAME: // record thread name 178b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_path, CLIENT_PAGE_SIZE); 179335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner DPID("QEMU.trace: thread name=%s\n", exec_path); 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // Remove the trailing newline if it exists 182b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner int len = strlen(exec_path); 183b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner if (exec_path[len - 1] == '\n') { 184b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[len - 1] = 0; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 187335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: kernel, name %s\n", exec_path); 1885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_MMAP_EXEPATH: // mmap, path of EXE, the others are same as execve 191b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_path, CLIENT_PAGE_SIZE); 192335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner DPID("QEMU.trace: mmap exe=%s\n", exec_path); 1935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 194335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, exec_path); 1955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 1965bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 1975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 198b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner if (exec_path[0] == '\0') { 1995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // vstrcpy may fail to copy path. In this case lets do it 2005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine // differently. 201b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_get_guest_kernel_string(exec_path, value, CLIENT_PAGE_SIZE); 2025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 203b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner memcheck_mmap_exepath(vstart, vend, eoff, exec_path); 2045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2055bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 206b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[0] = 0; 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_INIT_PID: // init, name the pid that starts before device registered 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pid = value; 210335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner DPID("QEMU.trace: pid=%d\n", value); 2115bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 2125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 2135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_init_pid(value); 2145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2155bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_INIT_NAME: // init, the comm of the init pid 218b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_path, CLIENT_PAGE_SIZE); 219335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner DPID("QEMU.trace: tgid=%d pid=%d name=%s\n", tgid, pid, exec_path); 2205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 221335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: kernel, init name %u [%s]\n", pid, exec_path); 2225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 223b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[0] = 0; 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_DYN_SYM_ADDR: // dynamic symbol address 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dsaddr = value; 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_DYN_SYM: // add dynamic symbol 230b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE); 2315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 232335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, exec_arg); 2335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 234b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_arg[0] = 0; 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_REMOVE_ADDR: // remove dynamic symbol addr 2375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 238335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("QEMU.trace: dynamic symbol remove %lx\n", dsaddr); 2395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_PRINT_STR: // print string 243b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE); 244b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner printf("%s", exec_arg); 245b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_arg[0] = 0; 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_PRINT_NUM_DEC: // print number in decimal 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("%d", value); 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_PRINT_NUM_HEX: // print number in hexical 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("%x", value); 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_STOP_EMU: // stop the VM execution 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_single_env->exception_index = EXCP_HLT; 2566657678c3d86395084f6a699e73614195f06c445David 'Digit' Turner current_cpu->halted = 1; 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_system_shutdown_request(); 25885c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner cpu_loop_exit(cpu_single_env); 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_ENABLE: // tracing enable: 0 = stop, 1 = start 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_UNMAP_START: 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unmap_start = value; 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_UNMAP_END: 2685bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 2695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 2705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_unmap(unmap_start, value); 2715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2725bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2759980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra case TRACE_DEV_REG_METHOD_ENTRY: 2769980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra case TRACE_DEV_REG_METHOD_EXIT: 2779980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra case TRACE_DEV_REG_METHOD_EXCEPTION: 278e3ea32ffa04468eddaf9c6ce2d36090f7bf43e49Jack Veenstra case TRACE_DEV_REG_NATIVE_ENTRY: 279e3ea32ffa04468eddaf9c6ce2d36090f7bf43e49Jack Veenstra case TRACE_DEV_REG_NATIVE_EXIT: 280e3ea32ffa04468eddaf9c6ce2d36090f7bf43e49Jack Veenstra case TRACE_DEV_REG_NATIVE_EXCEPTION: 2815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (trace_filename != NULL) { 2825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (tracing) { 283171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner int __attribute__((unused)) call_type = (offset - 4096) >> 2; 284171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner //trace_interpreted_method(value, call_type); 2855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 2885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 2895bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 2905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_MALLOC: 2915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 2925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_alloc(value); 2935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 2955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 2965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_FREE_PTR: 2975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 2985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_free(value); 2995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 3005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 3015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 3025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_QUERY_MALLOC: 3035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 3045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_query_malloc(value); 3055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 3065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 3075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 3085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_LIBC_INIT: 3095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 3105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_libc_initialized(value); 3115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 3125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine break; 3135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 3145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine case TRACE_DEV_REG_PRINT_USER_STR: 3155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (memcheck_enabled) { 3165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_guest_print_str(value); 3179980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra } 3189980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra break; 3195bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 3209980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 3229980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra if (offset < 4096) { 3239980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra cpu_abort(cpu_single_env, "trace_dev_write: Bad offset %x\n", offset); 324335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner } else { 325335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("%s: offset=%d (0x%x) value=%d (0x%x)\n", __FUNCTION__, offset, 326335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner offset, value, value); 3279980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra } 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* I/O read */ 333bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic uint32_t trace_dev_read(void *opaque, hwaddr offset) 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_state *s = (trace_dev_state *)opaque; 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3374e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner (void)s; 3384e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (offset >> 2) { 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TRACE_DEV_REG_ENABLE: // tracing enable 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return tracing; 342335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 3449980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra if (offset < 4096) { 3459980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra cpu_abort(cpu_single_env, "trace_dev_read: Bad offset %x\n", offset); 346335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner } else { 347335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner D("%s: offset=%d (0x%x)\n", __FUNCTION__, offset, offset); 3489980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra } 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUReadMemoryFunc *trace_dev_readfn[] = { 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_read, 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_read, 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_read 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUWriteMemoryFunc *trace_dev_writefn[] = { 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_write, 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_write, 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_write 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* initialize the trace device */ 3679980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstravoid trace_dev_init() 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_dev_state *s; 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 371aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner s = (trace_dev_state *)g_malloc0(sizeof(trace_dev_state)); 3729980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.name = "qemu_trace"; 3739980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.id = -1; 3749980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.base = 0; // will be allocated dynamically 3759980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.size = 0x2000; 3769980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.irq = 0; 3779980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra s->dev.irq_count = 0; 3789980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra 3799980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra goldfish_device_add(&s->dev, trace_dev_readfn, trace_dev_writefn, s); 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 381b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner exec_path[0] = exec_arg[0] = '\0'; 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 383