@@ -11,20 +11,43 @@ static void log_insn_mem_access(unsigned int vcpu_index,
11
11
qemu_plugin_meminfo_t info , uint64_t vaddr ,
12
12
void * userdata ) {}
13
13
14
+ static void add_post_state_regs (VCPU * vcpu , unsigned int vcpu_index , GArray * current_regs ) {
15
+ GByteArray * rtmp = g_byte_array_new ();
16
+ for (size_t i = 0 ; i < current_regs -> len ; ++ i ) {
17
+ Register * prev_reg = vcpu -> registers -> pdata [i ];
18
+
19
+ qemu_plugin_reg_descriptor * reg =
20
+ & g_array_index (current_regs , qemu_plugin_reg_descriptor , i );
21
+ int s = qemu_plugin_read_register (reg -> handle , rtmp );
22
+ assert (s == prev_reg -> content -> len );
23
+ if (!memcmp (rtmp -> data , prev_reg -> content -> data , s )) {
24
+ // No change
25
+ continue ;
26
+ }
27
+
28
+ OperandInfo * rinfo = init_reg_operand_info (prev_reg -> name , rtmp -> data ,
29
+ rtmp -> len , OperandRead );
30
+ g_assert (rinfo );
31
+
32
+ g_rw_lock_writer_lock (& state .frame_buffer_lock );
33
+ FrameBuffer * fb = g_ptr_array_index (state .frame_buffer , vcpu_index );
34
+ frame_buffer_append_op_info (fb , rinfo );
35
+ g_rw_lock_writer_unlock (& state .frame_buffer_lock );
36
+ }
37
+ }
38
+
14
39
static void log_insn_reg_access (unsigned int vcpu_index , void * udata ) {
15
- Instruction * insn = udata ;
16
40
g_rw_lock_reader_lock (& state .vcpus_array_lock );
17
- g_rw_lock_writer_lock (& state .frame_buffer_lock );
18
41
19
42
VCPU * vcpu = & g_array_index (state .vcpus , VCPU , vcpu_index );
20
43
GArray * current_regs = qemu_plugin_get_registers ();
21
44
g_assert (current_regs -> len == vcpu -> registers -> len );
22
45
23
- // Add change to previous frame
24
- // Finish previous frame
46
+ add_post_state_regs (vcpu , vcpu_index , current_regs );
25
47
// Check if buffer should be dumped to file.
48
+
26
49
// Open new one.
27
- g_rw_lock_writer_unlock ( & state . frame_buffer_lock ) ;
50
+ Instruction * insn = udata ;
28
51
g_rw_lock_reader_unlock (& state .vcpus_array_lock );
29
52
30
53
return ;
@@ -64,14 +87,42 @@ static GPtrArray *registers_init(int vcpu_index) {
64
87
65
88
static void vcpu_init (qemu_plugin_id_t id , unsigned int vcpu_index ) {
66
89
g_rw_lock_writer_lock (& state .vcpus_array_lock );
90
+ g_rw_lock_writer_lock (& state .frame_buffer_lock );
91
+
67
92
VCPU * vcpu = g_malloc0 (sizeof (VCPU ));
68
93
vcpu -> registers = registers_init (vcpu_index );
69
94
g_array_insert_vals (state .vcpus , vcpu_index , & vcpu , 1 );
95
+ FrameBuffer * vcpu_frame_buffer = frame_buffer_init (FRAME_BUFFER_SIZE_DEFAULT );
96
+ g_ptr_array_insert (state .frame_buffer , vcpu_index , & vcpu_frame_buffer );
97
+
98
+ g_rw_lock_writer_unlock (& state .frame_buffer_lock );
70
99
g_rw_lock_writer_unlock (& state .vcpus_array_lock );
71
100
}
72
101
73
- static void plugin_exit (qemu_plugin_id_t id , void * udata ) {
74
- // Dump rest of frames to file.
102
+ OperandInfo * init_reg_operand_info (const char * name , const uint8_t * value ,
103
+ size_t value_size , OperandAccess access ) {
104
+ RegOperand * ro = g_new (RegOperand , 1 );
105
+ reg_operand__init (ro );
106
+ ro -> name = strdup (name );
107
+
108
+ OperandInfoSpecific * ois = g_new (OperandInfoSpecific , 1 );
109
+ operand_info_specific__init (ois );
110
+ ois -> reg_operand = ro ;
111
+
112
+ OperandUsage * ou = g_new (OperandUsage , 1 );
113
+ operand_usage__init (ou );
114
+ ou -> read = access & OperandRead ;
115
+ ou -> written = access & OperandWritten ;
116
+ OperandInfo * oi = g_new (OperandInfo , 1 );
117
+ operand_info__init (oi );
118
+ oi -> bit_length = 0 ;
119
+ oi -> operand_info_specific = ois ;
120
+ oi -> operand_usage = ou ;
121
+ oi -> value .len = value_size ;
122
+ oi -> value .data = g_malloc (oi -> value .len );
123
+ memcpy (oi -> value .data , value , value_size );
124
+
125
+ return oi ;
75
126
}
76
127
77
128
Instruction * init_insn (struct qemu_plugin_insn * tb_insn ) {
@@ -97,11 +148,15 @@ static void cb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) {
97
148
}
98
149
}
99
150
151
+ static void plugin_exit (qemu_plugin_id_t id , void * udata ) {
152
+ // Dump rest of frames to file.
153
+ }
154
+
100
155
QEMU_PLUGIN_EXPORT int qemu_plugin_install (qemu_plugin_id_t id ,
101
156
const qemu_info_t * info , int argc ,
102
157
char * * argv ) {
103
158
const char * target_path = "/tmp/test.trace" ;
104
- state .frame_buffer = frame_buffer_init ( FRAME_BUFFER_SIZE_DEFAULT );
159
+ state .frame_buffer = g_ptr_array_new ( );
105
160
state .vcpus = g_array_new (false, true, sizeof (VCPU ));
106
161
state .file = fopen (target_path , "r" );
107
162
if (!(state .frame_buffer || state .vcpus || state .file )) {
0 commit comments