@@ -77,7 +77,8 @@ static void add_pre_reg_state(VCPU *vcpu, unsigned int vcpu_index,
77
77
& g_array_index (current_regs , qemu_plugin_reg_descriptor , i );
78
78
size_t s = qemu_plugin_read_register (reg -> handle , rdata );
79
79
Register * prev_reg = g_ptr_array_index (vcpu -> registers , i );
80
- g_assert (!strcmp (prev_reg -> name , reg -> name ) && prev_reg -> handle == reg -> handle );
80
+ g_assert (!strcmp (prev_reg -> name , reg -> name ) &&
81
+ prev_reg -> handle == reg -> handle );
81
82
memcpy (prev_reg -> content -> data , rdata -> data , prev_reg -> content -> len );
82
83
frame_buffer_append_reg_info (fbuf , reg -> name , rdata , s , OperandRead );
83
84
// Flush byte array
@@ -103,13 +104,12 @@ static GPtrArray *registers_init(void) {
103
104
return registers -> len ? g_steal_pointer (& registers ) : NULL ;
104
105
}
105
106
106
- static void write_toc_entry (FrameBuffer * fbuf , bool add_padding ) {
107
+ static void flush_and_write_toc_entry (FrameBuffer * fbuf ) {
107
108
g_rw_lock_writer_lock (& state .file_lock );
108
109
g_rw_lock_writer_lock (& state .toc_entries_offsets_lock );
109
110
g_rw_lock_writer_lock (& state .total_num_frames_lock );
110
111
111
- state .total_num_frames +=
112
- frame_buffer_flush_to_file (fbuf , state .file , add_padding );
112
+ state .total_num_frames += frame_buffer_flush_to_file (fbuf , state .file );
113
113
uint64_t next_toc_entry = ftell (state .file );
114
114
g_array_append_val (state .toc_entries_offsets , next_toc_entry );
115
115
@@ -118,6 +118,54 @@ static void write_toc_entry(FrameBuffer *fbuf, bool add_padding) {
118
118
g_rw_lock_writer_unlock (& state .file_lock );
119
119
}
120
120
121
+ static void flush_all_frame_bufs (void ) {
122
+ g_rw_lock_writer_lock (& state .file_lock );
123
+ g_rw_lock_writer_lock (& state .toc_entries_offsets_lock );
124
+ g_rw_lock_writer_lock (& state .total_num_frames_lock );
125
+ g_rw_lock_writer_lock (& state .frame_buffer_lock );
126
+
127
+ FILE * file = state .file ;
128
+
129
+ // Dump the rest of the frames but be mindeful about the
130
+ // maximum number of frames per TOC entry.
131
+
132
+ size_t total_to_write = 0 ;
133
+ for (size_t i = 0 ; i < state .vcpus -> len ; ++ i ) {
134
+ // Add post operands to last instructions.
135
+ FrameBuffer * fbuf = g_ptr_array_index (state .frame_buffer , i );
136
+ VCPU * vcpu = g_ptr_array_index (state .vcpus , i );
137
+ g_assert (vcpu );
138
+ GArray * current_regs = qemu_plugin_get_registers ();
139
+ g_assert (current_regs -> len == vcpu -> registers -> len );
140
+ add_post_reg_state (vcpu , i , current_regs , fbuf );
141
+ frame_buffer_close_frame (fbuf );
142
+
143
+ total_to_write += fbuf -> idx ;
144
+ }
145
+
146
+ size_t entry_count = 0 ;
147
+ for (size_t i = 0 ; i < state .vcpus -> len && total_to_write > 0 ; ++ i ) {
148
+ if (entry_count == frames_per_toc_entry ) {
149
+ entry_count = 0 ;
150
+ uint64_t next_toc_entry = ftell (state .file );
151
+ g_array_append_val (state .toc_entries_offsets , next_toc_entry );
152
+ }
153
+
154
+ FrameBuffer * fbuf = g_ptr_array_index (state .frame_buffer , i );
155
+ for (size_t k = 0 ; k < fbuf -> idx ; ++ k ) {
156
+ frame_buffer_write_frame_to_file (fbuf , file , k );
157
+ entry_count ++ ;
158
+ state .total_num_frames ++ ;
159
+ total_to_write -- ;
160
+ }
161
+ }
162
+
163
+ g_rw_lock_writer_unlock (& state .frame_buffer_lock );
164
+ g_rw_lock_writer_unlock (& state .total_num_frames_lock );
165
+ g_rw_lock_writer_unlock (& state .toc_entries_offsets_lock );
166
+ g_rw_lock_writer_unlock (& state .file_lock );
167
+ }
168
+
121
169
static void log_insn_reg_access (unsigned int vcpu_index , void * udata ) {
122
170
g_rw_lock_reader_lock (& state .vcpus_array_lock );
123
171
g_rw_lock_writer_lock (& state .frame_buffer_lock );
@@ -134,7 +182,7 @@ static void log_insn_reg_access(unsigned int vcpu_index, void *udata) {
134
182
}
135
183
136
184
if (frame_buffer_is_full (fbuf )) {
137
- write_toc_entry (fbuf , false );
185
+ flush_and_write_toc_entry (fbuf );
138
186
}
139
187
140
188
// Open new one.
@@ -225,13 +273,7 @@ static void cb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) {
225
273
}
226
274
227
275
static void plugin_exit (qemu_plugin_id_t id , void * udata ) {
228
- g_rw_lock_writer_lock (& state .frame_buffer_lock );
229
- // Dump the rest of the frames.
230
- for (size_t i = 0 ; i < state .vcpus -> len ; ++ i ) {
231
- FrameBuffer * fbuf = g_ptr_array_index (state .frame_buffer , i );
232
- write_toc_entry (fbuf , true);
233
- }
234
- g_rw_lock_writer_unlock (& state .frame_buffer_lock );
276
+ flush_all_frame_bufs ();
235
277
236
278
g_rw_lock_writer_lock (& state .file_lock );
237
279
g_rw_lock_reader_lock (& state .toc_entries_offsets_lock );
0 commit comments