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