Skip to content

Commit f690488

Browse files
committed
Trace memory accesses
1 parent 363aefe commit f690488

File tree

3 files changed

+142
-18
lines changed

3 files changed

+142
-18
lines changed

contrib/plugins/bap-tracing/frame_buffer.c

Lines changed: 105 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@ char *frame_buffer_as_str(const FrameBuffer *buf) {
127127
StdFrame *sframe = frame->std_frame;
128128
for (size_t i = 0; i < sframe->operand_pre_list->n_elem; i++) {
129129
OperandInfo *oi = sframe->operand_pre_list->elem[i];
130-
APPEND("r:%s=", oi->operand_info_specific->reg_operand->name);
130+
if (oi->operand_info_specific->reg_operand) {
131+
APPEND("r:%s=", oi->operand_info_specific->reg_operand->name);
132+
} else {
133+
APPEND("m:0x%016lx=", oi->operand_info_specific->mem_operand->address);
134+
}
131135

132136
for (size_t k = 0; k < oi->value.len; ++k) {
133137
APPEND("%02x", oi->value.data[k]);
@@ -137,7 +141,11 @@ char *frame_buffer_as_str(const FrameBuffer *buf) {
137141
APPEND(" ], post: [ ");
138142
for (size_t i = 0; i < sframe->operand_post_list->n_elem; i++) {
139143
OperandInfo *oi = sframe->operand_post_list->elem[i];
140-
APPEND("r:%s=", oi->operand_info_specific->reg_operand->name);
144+
if (oi->operand_info_specific->reg_operand) {
145+
APPEND("r:%s=", oi->operand_info_specific->reg_operand->name);
146+
} else {
147+
APPEND("m:0x%016lx=", oi->operand_info_specific->mem_operand->address);
148+
}
141149

142150
for (size_t k = 0; k < oi->value.len; ++k) {
143151
APPEND("%02x", oi->value.data[k]);
@@ -202,12 +210,7 @@ bool frame_buffer_new_frame_std(FrameBuffer *buf, unsigned int thread_id,
202210
return true;
203211
}
204212

205-
bool frame_buffer_append_reg_info(FrameBuffer *buf, const char *name,
206-
const GByteArray *content, size_t reg_size,
207-
OperandAccess acc) {
208-
OperandInfo *oi = frame_init_reg_operand_info(
209-
name, content->data + content->len - reg_size, reg_size, acc);
210-
g_assert(oi);
213+
static bool append_op_info(FrameBuffer *buf, OperandInfo *oi) {
211214
Frame *frame = buf->fbuf[buf->idx];
212215
if (!frame || !frame->std_frame) {
213216
qemu_plugin_outs(
@@ -217,6 +220,15 @@ bool frame_buffer_append_reg_info(FrameBuffer *buf, const char *name,
217220
return std_frame_add_operand(frame->std_frame, oi);
218221
}
219222

223+
bool frame_buffer_append_reg_info(FrameBuffer *buf, const char *name,
224+
const GByteArray *content, size_t reg_size,
225+
OperandAccess acc) {
226+
OperandInfo *oi = frame_init_reg_operand_info(
227+
name, content->data + content->len - reg_size, reg_size, acc);
228+
g_assert(oi);
229+
return append_op_info(buf, oi);
230+
}
231+
220232
OperandInfo *frame_init_reg_operand_info(const char *name, const uint8_t *value,
221233
size_t value_size,
222234
OperandAccess access) {
@@ -243,3 +255,88 @@ OperandInfo *frame_init_reg_operand_info(const char *name, const uint8_t *value,
243255

244256
return oi;
245257
}
258+
259+
static size_t mval_type_to_int(enum qemu_plugin_mem_value_type type) {
260+
switch (type) {
261+
case QEMU_PLUGIN_MEM_VALUE_U8:
262+
return 8;
263+
case QEMU_PLUGIN_MEM_VALUE_U16:
264+
return 16;
265+
case QEMU_PLUGIN_MEM_VALUE_U32:
266+
return 32;
267+
case QEMU_PLUGIN_MEM_VALUE_U64:
268+
return 64;
269+
case QEMU_PLUGIN_MEM_VALUE_U128:
270+
return 128;
271+
default:
272+
g_assert(false);
273+
}
274+
}
275+
276+
static void mval_to_buf(qemu_plugin_mem_value *val, uint8_t *buf) {
277+
switch (val->type) {
278+
case QEMU_PLUGIN_MEM_VALUE_U8:
279+
buf[0] = val->data.u8;
280+
return;
281+
case QEMU_PLUGIN_MEM_VALUE_U16:
282+
buf[0] = (uint8_t)val->data.u16;
283+
buf[1] = (uint8_t)(val->data.u16 >> 8);
284+
return;
285+
case QEMU_PLUGIN_MEM_VALUE_U32:
286+
buf[0] = (uint8_t)val->data.u32;
287+
buf[1] = (uint8_t)(val->data.u32 >> 8);
288+
buf[2] = (uint8_t)(val->data.u32 >> 16);
289+
buf[3] = (uint8_t)(val->data.u32 >> 24);
290+
return;
291+
case QEMU_PLUGIN_MEM_VALUE_U64:
292+
for (size_t i = 0; i < 8; ++i) {
293+
buf[i] = (uint8_t)(val->data.u64 >> (i * 8));
294+
}
295+
return;
296+
case QEMU_PLUGIN_MEM_VALUE_U128:
297+
for (size_t i = 0; i < 8; ++i) {
298+
buf[i] = (uint8_t)(val->data.u128.low >> (i * 8));
299+
}
300+
for (size_t i = 0; i < 8; ++i) {
301+
buf[i + 8] = (uint8_t)(val->data.u128.high >> (i * 8));
302+
}
303+
return;
304+
default:
305+
g_assert(false);
306+
}
307+
}
308+
309+
static OperandInfo *frame_init_mem_operand_info(uint64_t vaddr,
310+
qemu_plugin_mem_value *mval,
311+
bool is_store) {
312+
MemOperand *ro = g_new(MemOperand, 1);
313+
mem_operand__init(ro);
314+
ro->address = vaddr;
315+
316+
OperandInfoSpecific *ois = g_new(OperandInfoSpecific, 1);
317+
operand_info_specific__init(ois);
318+
ois->mem_operand = ro;
319+
320+
size_t byte_width = mval_type_to_int(mval->type) / 8;
321+
OperandUsage *ou = g_new(OperandUsage, 1);
322+
operand_usage__init(ou);
323+
ou->read = !is_store;
324+
ou->written = is_store;
325+
OperandInfo *oi = g_new(OperandInfo, 1);
326+
operand_info__init(oi);
327+
oi->bit_length = mval_type_to_int(mval->type);
328+
oi->operand_info_specific = ois;
329+
oi->operand_usage = ou;
330+
oi->value.len = byte_width;
331+
oi->value.data = g_malloc(oi->value.len);
332+
mval_to_buf(mval, oi->value.data);
333+
334+
return oi;
335+
}
336+
337+
bool frame_buffer_append_mem_info(FrameBuffer *fbuf, uint64_t vaddr,
338+
qemu_plugin_mem_value *mval, bool is_store) {
339+
OperandInfo *oi = frame_init_mem_operand_info(vaddr, mval, is_store);
340+
g_assert(oi);
341+
return append_op_info(fbuf, oi);
342+
}

contrib/plugins/bap-tracing/frame_buffer.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88
#include <qemu-plugin.h>
99
#include <stdio.h>
1010

11-
#include "trace_meta.h"
1211
#include "frame.piqi.pb-c-patched.h"
12+
#include "trace_meta.h"
1313

1414
typedef enum {
1515
OperandRead = 1,
1616
OperandWritten = 2,
1717
} OperandAccess;
1818

1919
typedef struct {
20-
Frame **fbuf; ///< The frames buffered.
21-
size_t idx; ///< Points to currently open frame.
22-
size_t max_size; ///< Maximum number of elements fbuf can hold.
20+
Frame **fbuf; ///< The frames buffered.
21+
size_t idx; ///< Points to currently open frame.
22+
size_t max_size; ///< Maximum number of elements fbuf can hold.
2323
size_t frames_written; ///< Number of frames written from buffer to file.
2424
} FrameBuffer;
2525

@@ -35,9 +35,12 @@ bool frame_buffer_is_empty(const FrameBuffer *buf);
3535
void frame_buffer_close_frame(FrameBuffer *buf);
3636
char *frame_buffer_as_str(const FrameBuffer *buf);
3737

38-
bool frame_buffer_new_frame_std(FrameBuffer *buf,
39-
unsigned int thread_id, uint64_t vaddr,
40-
uint8_t *bytes, size_t bytes_len);
38+
bool frame_buffer_new_frame_std(FrameBuffer *buf, unsigned int thread_id,
39+
uint64_t vaddr, uint8_t *bytes,
40+
size_t bytes_len);
41+
42+
bool frame_buffer_append_mem_info(FrameBuffer *fbuf, uint64_t vaddr,
43+
qemu_plugin_mem_value *mval, bool is_store);
4144

4245
/**
4346
* \brief Appends the given operand info to the open frame.

contrib/plugins/bap-tracing/tracing.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,33 @@
99

1010
static TraceState state;
1111

12+
static void add_mem_op(VCPU *vcpu, unsigned int vcpu_index, FrameBuffer *fbuf,
13+
uint64_t vaddr, qemu_plugin_mem_value *mval,
14+
bool is_store) {
15+
if (!frame_buffer_append_mem_info(fbuf, vaddr, mval, is_store)) {
16+
qemu_plugin_outs("Failed to append memory info\n");
17+
}
18+
return;
19+
}
20+
1221
static void log_insn_mem_access(unsigned int vcpu_index,
1322
qemu_plugin_meminfo_t info, uint64_t vaddr,
14-
void *userdata) {}
23+
void *userdata) {
24+
g_rw_lock_reader_lock(&state.vcpus_array_lock);
25+
g_rw_lock_reader_lock(&state.frame_buffer_lock);
26+
27+
VCPU *vcpu = g_ptr_array_index(state.vcpus, vcpu_index);
28+
g_assert(vcpu);
29+
FrameBuffer *fbuf = g_ptr_array_index(state.frame_buffer, vcpu_index);
30+
31+
bool is_store = qemu_plugin_mem_is_store(info);
32+
qemu_plugin_mem_value mval = qemu_plugin_mem_get_value(info);
33+
34+
add_mem_op(vcpu, vcpu_index, fbuf, vaddr, &mval, is_store);
35+
36+
g_rw_lock_writer_unlock(&state.frame_buffer_lock);
37+
g_rw_lock_writer_unlock(&state.vcpus_array_lock);
38+
}
1539

1640
static void add_post_reg_state(VCPU *vcpu, unsigned int vcpu_index,
1741
GArray *current_regs, FrameBuffer *fbuf) {
@@ -32,7 +56,7 @@ static void add_post_reg_state(VCPU *vcpu, unsigned int vcpu_index,
3256
if (!frame_buffer_append_reg_info(fbuf, reg->name, rdata, s,
3357
OperandWritten)) {
3458
qemu_plugin_outs("Failed to append opinfo.\n");
35-
g_assert(false);
59+
return;
3660
}
3761
}
3862
}
@@ -152,7 +176,7 @@ static void cb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) {
152176
qemu_plugin_register_vcpu_insn_exec_cb(tb_insn, log_insn_reg_access,
153177
QEMU_PLUGIN_CB_R_REGS, insn_data);
154178
qemu_plugin_register_vcpu_mem_cb(tb_insn, log_insn_mem_access,
155-
QEMU_PLUGIN_CB_R_REGS, QEMU_PLUGIN_MEM_R,
179+
QEMU_PLUGIN_CB_NO_REGS, QEMU_PLUGIN_MEM_R,
156180
NULL);
157181
}
158182
}

0 commit comments

Comments
 (0)