4
4
#include <glib.h>
5
5
6
6
#include "frame_buffer.h"
7
+ #include "qemu-plugin.h"
7
8
#include "tracing.h"
8
9
9
10
static TraceState state ;
@@ -51,12 +52,39 @@ static void add_new_insn_frame(VCPU *vcpu, unsigned int vcpu_index,
51
52
insn -> size );
52
53
}
53
54
55
+ static GPtrArray * registers_init (void ) {
56
+ GArray * reg_list = qemu_plugin_get_registers ();
57
+
58
+ if (reg_list -> len == 0 ) {
59
+ g_array_free (reg_list , false);
60
+ return NULL ;
61
+ }
62
+ GPtrArray * registers = g_ptr_array_new ();
63
+ for (size_t r = 0 ; r < reg_list -> len ; r ++ ) {
64
+ qemu_plugin_reg_descriptor * rd =
65
+ & g_array_index (reg_list , qemu_plugin_reg_descriptor , r );
66
+ Register * reg = init_vcpu_register (rd );
67
+ g_ptr_array_add (registers , reg );
68
+ }
69
+
70
+ return registers -> len ? g_steal_pointer (& registers ) : NULL ;
71
+ }
72
+
54
73
static void log_insn_reg_access (unsigned int vcpu_index , void * udata ) {
55
74
g_rw_lock_reader_lock (& state .vcpus_array_lock );
56
75
g_rw_lock_reader_lock (& state .frame_buffer_lock );
57
76
58
77
FrameBuffer * fbuf = g_ptr_array_index (state .frame_buffer , vcpu_index );
59
- VCPU * vcpu = & g_array_index (state .vcpus , VCPU , vcpu_index );
78
+ VCPU * vcpu = g_ptr_array_index (state .vcpus , vcpu_index );
79
+ g_assert (vcpu );
80
+ if (!vcpu -> registers ) {
81
+ vcpu -> registers = registers_init ();
82
+ if (!vcpu -> registers ) {
83
+ // Registers are still not available. So return until the VCPU is
84
+ // sufficiently initialized.
85
+ goto unlock_return ;
86
+ }
87
+ }
60
88
GArray * current_regs = qemu_plugin_get_registers ();
61
89
g_assert (current_regs -> len == vcpu -> registers -> len );
62
90
@@ -73,51 +101,34 @@ static void log_insn_reg_access(unsigned int vcpu_index, void *udata) {
73
101
add_new_insn_frame (vcpu , vcpu_index , fbuf , insn );
74
102
add_pre_reg_state (vcpu , vcpu_index , current_regs , fbuf );
75
103
104
+ unlock_return :
76
105
g_rw_lock_reader_unlock (& state .frame_buffer_lock );
77
106
g_rw_lock_reader_unlock (& state .vcpus_array_lock );
78
107
}
79
108
80
109
Register * init_vcpu_register (qemu_plugin_reg_descriptor * desc ) {
81
110
Register * reg = g_new0 (Register , 1 );
82
111
g_autofree gchar * lower = g_utf8_strdown (desc -> name , -1 );
83
- int r ;
84
112
85
113
reg -> handle = desc -> handle ;
86
114
reg -> name = g_intern_string (lower );
87
115
reg -> content = g_byte_array_new ();
88
116
89
117
/* read the initial value */
90
- r = qemu_plugin_read_register (reg -> handle , reg -> content );
118
+ int r = qemu_plugin_read_register (reg -> handle , reg -> content );
91
119
g_assert (r > 0 );
92
120
return reg ;
93
121
}
94
122
95
- static GPtrArray * registers_init (int vcpu_index ) {
96
- g_autoptr (GPtrArray ) registers = g_ptr_array_new ();
97
- g_autoptr (GArray ) reg_list = qemu_plugin_get_registers ();
98
-
99
- if (!reg_list -> len ) {
100
- return NULL ;
101
- }
102
- for (int r = 0 ; r < reg_list -> len ; r ++ ) {
103
- qemu_plugin_reg_descriptor * rd =
104
- & g_array_index (reg_list , qemu_plugin_reg_descriptor , r );
105
- Register * reg = init_vcpu_register (rd );
106
- g_ptr_array_add (registers , reg );
107
- }
108
-
109
- return registers -> len ? g_steal_pointer (& registers ) : NULL ;
110
- }
111
-
112
123
static void vcpu_init (qemu_plugin_id_t id , unsigned int vcpu_index ) {
113
124
g_rw_lock_writer_lock (& state .vcpus_array_lock );
114
125
g_rw_lock_writer_lock (& state .frame_buffer_lock );
115
126
116
127
VCPU * vcpu = g_malloc0 (sizeof (VCPU ));
117
- vcpu -> registers = registers_init ( vcpu_index );
118
- g_array_insert_vals ( state . vcpus , vcpu_index , & vcpu , 1 );
128
+ g_ptr_array_insert ( state . vcpus , vcpu_index , vcpu );
129
+
119
130
FrameBuffer * vcpu_frame_buffer = frame_buffer_new (FRAME_BUFFER_SIZE_DEFAULT );
120
- g_ptr_array_insert (state .frame_buffer , vcpu_index , & vcpu_frame_buffer );
131
+ g_ptr_array_insert (state .frame_buffer , vcpu_index , vcpu_frame_buffer );
121
132
122
133
g_rw_lock_writer_unlock (& state .frame_buffer_lock );
123
134
g_rw_lock_writer_unlock (& state .vcpus_array_lock );
@@ -155,11 +166,14 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
155
166
char * * argv ) {
156
167
const char * target_path = "/tmp/test.trace" ;
157
168
state .frame_buffer = g_ptr_array_new ();
158
- state .vcpus = g_array_new (false, true, sizeof ( VCPU ) );
169
+ state .vcpus = g_ptr_array_new ( );
159
170
state .file = fopen (target_path , "wb" );
160
171
if (!(state .frame_buffer || state .vcpus || state .file )) {
161
172
return 1 ;
162
173
}
174
+ for (size_t i = 0 ; i < argc ; ++ i ) {
175
+ qemu_plugin_outs (argv [i ]);
176
+ }
163
177
// write_header();
164
178
// write_meta(argv, envp, target_argv, target_envp);
165
179
0 commit comments