Skip to content

Commit 0c058f3

Browse files
committed
Implement update of register operands.
1 parent e1f7bdc commit 0c058f3

File tree

3 files changed

+81
-13
lines changed

3 files changed

+81
-13
lines changed

contrib/plugins/bap-tracing/frame.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ Frame *frame_new_std(uint64_t addr, int vcpu_id) {
2323
return frame;
2424
}
2525

26-
void frame_add_operand(Frame *frame, OperandInfo *oi, bool is_post) {
26+
void frame_add_operand(Frame *frame, OperandInfo *oi) {
2727
OperandValueList *ol;
28-
if (is_post) {
28+
if (oi->operand_usage->written) {
2929
ol = frame->std_frame->operand_post_list;
3030
} else {
3131
ol = frame->std_frame->operand_pre_list;

contrib/plugins/bap-tracing/tracing.c

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,43 @@ static void log_insn_mem_access(unsigned int vcpu_index,
1111
qemu_plugin_meminfo_t info, uint64_t vaddr,
1212
void *userdata) {}
1313

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+
1439
static void log_insn_reg_access(unsigned int vcpu_index, void *udata) {
15-
Instruction *insn = udata;
1640
g_rw_lock_reader_lock(&state.vcpus_array_lock);
17-
g_rw_lock_writer_lock(&state.frame_buffer_lock);
1841

1942
VCPU *vcpu = &g_array_index(state.vcpus, VCPU, vcpu_index);
2043
GArray *current_regs = qemu_plugin_get_registers();
2144
g_assert(current_regs->len == vcpu->registers->len);
2245

23-
// Add change to previous frame
24-
// Finish previous frame
46+
add_post_state_regs(vcpu, vcpu_index, current_regs);
2547
// Check if buffer should be dumped to file.
48+
2649
// Open new one.
27-
g_rw_lock_writer_unlock(&state.frame_buffer_lock);
50+
Instruction *insn = udata;
2851
g_rw_lock_reader_unlock(&state.vcpus_array_lock);
2952

3053
return;
@@ -64,14 +87,42 @@ static GPtrArray *registers_init(int vcpu_index) {
6487

6588
static void vcpu_init(qemu_plugin_id_t id, unsigned int vcpu_index) {
6689
g_rw_lock_writer_lock(&state.vcpus_array_lock);
90+
g_rw_lock_writer_lock(&state.frame_buffer_lock);
91+
6792
VCPU *vcpu = g_malloc0(sizeof(VCPU));
6893
vcpu->registers = registers_init(vcpu_index);
6994
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);
7099
g_rw_lock_writer_unlock(&state.vcpus_array_lock);
71100
}
72101

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;
75126
}
76127

77128
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) {
97148
}
98149
}
99150

151+
static void plugin_exit(qemu_plugin_id_t id, void *udata) {
152+
// Dump rest of frames to file.
153+
}
154+
100155
QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
101156
const qemu_info_t *info, int argc,
102157
char **argv) {
103158
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();
105160
state.vcpus = g_array_new(false, true, sizeof(VCPU));
106161
state.file = fopen(target_path, "r");
107162
if (!(state.frame_buffer || state.vcpus || state.file)) {

contrib/plugins/bap-tracing/tracing.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@
44
#include <qemu-plugin.h>
55
#include <stdio.h>
66

7+
#include "frame.piqi.pb-c-patched.h"
8+
#include "glib.h"
79
#include "tracewrap.h"
810

911
QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
1012

1113
#define FRAME_BUFFER_SIZE_DEFAULT 1024
1214

15+
typedef enum {
16+
OperandRead = 1,
17+
OperandWritten = 2,
18+
} OperandAccess;
19+
1320
/**
1421
* \brief VLIW architecture have instructions longer than 4 or 8bytes.
1522
*/
@@ -41,7 +48,7 @@ typedef struct {
4148
GArray /*<VCPU>*/ *vcpus;
4249

4350
GRWLock frame_buffer_lock;
44-
FrameBuffer *frame_buffer;
51+
GPtrArray /*<FrameBuffer>*/ *frame_buffer; ///< Indexed by vcpu id
4552

4653
GRWLock file_lock;
4754
FILE *file;
@@ -62,19 +69,25 @@ FrameBuffer *frame_buffer_init(size_t size);
6269
bool frame_buffer_push(FrameBuffer *buf, Frame *frame);
6370

6471
/**
65-
* \brief Flusehs the buffer and returns it's content.
72+
* \brief Flushs the buffer and returns it's content.
6673
* The size of the returned buffer is written to \p fbuf_size.
6774
*/
6875
Frame **frame_buffer_flush(FrameBuffer *buf, size_t *fbuf_size);
6976

77+
void frame_buffer_new_frame(FrameBuffer *buf);
78+
void frame_buffer_append_op_info(FrameBuffer *buf, OperandInfo *oi);
79+
7080
/**
7181
* \brief Create new std frame
7282
*/
7383
Frame *frame_new_std(uint64_t addr, int vcpu_id);
7484

75-
void frame_add_operand(Frame *frame, OperandInfo *oi, bool is_out);
85+
void frame_add_operand(Frame *frame, OperandInfo *oi);
7686

7787
Register *init_vcpu_register(qemu_plugin_reg_descriptor *desc);
7888
Instruction *init_insn(struct qemu_plugin_insn *insn);
7989

90+
OperandInfo *init_reg_operand_info(const char *name, const uint8_t *value,
91+
size_t value_size, OperandAccess access);
92+
8093
#endif

0 commit comments

Comments
 (0)