Skip to content

Commit 3dc6e18

Browse files
committed
Fix the endian issue once and for all.
The GDB stub returned and the rmemory values are all in the endianess of the arch. Now they are normalize accordingly.
1 parent fe9340b commit 3dc6e18

File tree

6 files changed

+88
-64
lines changed

6 files changed

+88
-64
lines changed

contrib/plugins/bap-tracing/frame_buffer.c

Lines changed: 9 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -257,59 +257,9 @@ OperandInfo *frame_init_reg_operand_info(const char *name, const uint8_t *value,
257257
return oi;
258258
}
259259

260-
static size_t mval_type_to_int(enum qemu_plugin_mem_value_type type) {
261-
switch (type) {
262-
case QEMU_PLUGIN_MEM_VALUE_U8:
263-
return 8;
264-
case QEMU_PLUGIN_MEM_VALUE_U16:
265-
return 16;
266-
case QEMU_PLUGIN_MEM_VALUE_U32:
267-
return 32;
268-
case QEMU_PLUGIN_MEM_VALUE_U64:
269-
return 64;
270-
case QEMU_PLUGIN_MEM_VALUE_U128:
271-
return 128;
272-
default:
273-
g_assert(false);
274-
}
275-
return 0;
276-
}
277-
278-
static void mval_to_buf(qemu_plugin_mem_value *val, uint8_t *buf) {
279-
switch (val->type) {
280-
case QEMU_PLUGIN_MEM_VALUE_U8:
281-
buf[0] = val->data.u8;
282-
return;
283-
case QEMU_PLUGIN_MEM_VALUE_U16:
284-
buf[0] = (uint8_t)val->data.u16;
285-
buf[1] = (uint8_t)(val->data.u16 >> 8);
286-
return;
287-
case QEMU_PLUGIN_MEM_VALUE_U32:
288-
buf[0] = (uint8_t)val->data.u32;
289-
buf[1] = (uint8_t)(val->data.u32 >> 8);
290-
buf[2] = (uint8_t)(val->data.u32 >> 16);
291-
buf[3] = (uint8_t)(val->data.u32 >> 24);
292-
return;
293-
case QEMU_PLUGIN_MEM_VALUE_U64:
294-
for (size_t i = 0; i < 8; ++i) {
295-
buf[i] = (uint8_t)(val->data.u64 >> (i * 8));
296-
}
297-
return;
298-
case QEMU_PLUGIN_MEM_VALUE_U128:
299-
for (size_t i = 0; i < 8; ++i) {
300-
buf[i] = (uint8_t)(val->data.u128.low >> (i * 8));
301-
}
302-
for (size_t i = 0; i < 8; ++i) {
303-
buf[i + 8] = (uint8_t)(val->data.u128.high >> (i * 8));
304-
}
305-
return;
306-
default:
307-
g_assert(false);
308-
}
309-
}
310-
311260
static OperandInfo *frame_init_mem_operand_info(uint64_t vaddr,
312-
qemu_plugin_mem_value *mval,
261+
const uint8_t *mval,
262+
size_t mval_bits,
313263
bool is_store) {
314264
MemOperand *ro = g_new(MemOperand, 1);
315265
mem_operand__init(ro);
@@ -319,26 +269,28 @@ static OperandInfo *frame_init_mem_operand_info(uint64_t vaddr,
319269
operand_info_specific__init(ois);
320270
ois->mem_operand = ro;
321271

322-
size_t byte_width = mval_type_to_int(mval->type) / 8;
272+
size_t byte_width = mval_bits / 8;
323273
OperandUsage *ou = g_new(OperandUsage, 1);
324274
operand_usage__init(ou);
325275
ou->read = !is_store;
326276
ou->written = is_store;
327277
OperandInfo *oi = g_new(OperandInfo, 1);
328278
operand_info__init(oi);
329-
oi->bit_length = mval_type_to_int(mval->type);
279+
oi->bit_length = mval_bits;
330280
oi->operand_info_specific = ois;
331281
oi->operand_usage = ou;
332282
oi->value.len = byte_width;
333283
oi->value.data = g_malloc(oi->value.len);
334-
mval_to_buf(mval, oi->value.data);
284+
memcpy(oi->value.data, mval, oi->value.len);
335285

336286
return oi;
337287
}
338288

339289
bool frame_buffer_append_mem_info(FrameBuffer *fbuf, uint64_t vaddr,
340-
qemu_plugin_mem_value *mval, bool is_store) {
341-
OperandInfo *oi = frame_init_mem_operand_info(vaddr, mval, is_store);
290+
const uint8_t *mval, size_t mval_bits,
291+
bool is_store) {
292+
OperandInfo *oi =
293+
frame_init_mem_operand_info(vaddr, mval, mval_bits, is_store);
342294
g_assert(oi);
343295
return append_op_info(fbuf, oi);
344296
}

contrib/plugins/bap-tracing/frame_buffer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ bool frame_buffer_new_frame_std(FrameBuffer *buf, unsigned int thread_id,
4141
uint8_t *bytes, size_t bytes_len);
4242

4343
bool frame_buffer_append_mem_info(FrameBuffer *fbuf, uint64_t vaddr,
44-
qemu_plugin_mem_value *mval, bool is_store);
44+
const uint8_t *mval, size_t mval_bits,
45+
bool is_store);
4546

4647
/**
4748
* \brief Appends the given operand info to the open frame.

contrib/plugins/bap-tracing/trace_meta.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ void write_meta(WLOCKED FILE *file, char **plugin_argv, size_t plugin_argc) {
193193
}
194194

195195
/// Copies src to dst. dst will always be in little endian byte order.
196-
void memcpy_le(uint8_t *dst, uint8_t *src, size_t len, bool big_endian) {
196+
void memcpy_le(uint8_t *dst, const uint8_t *src, size_t len, bool big_endian) {
197197
if (!big_endian) {
198198
memcpy(dst, src, len);
199199
return;

contrib/plugins/bap-tracing/trace_meta.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
void write_meta(WLOCKED FILE *file, char **plugin_argv, size_t plugin_argc);
3737
char *get_argv_val(char **argv, int argc, const char *key);
3838
void file_exists_exit(const char *file);
39-
void memcpy_le(uint8_t *dst, uint8_t *src, size_t len, bool big_endian);
39+
void memcpy_le(uint8_t *dst, const uint8_t *src, size_t len, bool big_endian);
4040
void swap_to_le(uint8_t *buf, size_t len, bool big_endian);
4141

4242
#endif

contrib/plugins/bap-tracing/tracing.c

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,71 @@
1515

1616
static TraceState state = {0};
1717

18+
static void mval_to_buf(qemu_plugin_mem_value *val, uint8_t *buf) {
19+
size_t mem_val_size = 0;
20+
switch (val->type) {
21+
case QEMU_PLUGIN_MEM_VALUE_U8:
22+
buf[0] = val->data.u8;
23+
mem_val_size = 1;
24+
break;
25+
case QEMU_PLUGIN_MEM_VALUE_U16:
26+
buf[0] = (uint8_t)val->data.u16;
27+
buf[1] = (uint8_t)(val->data.u16 >> 8);
28+
mem_val_size = 2;
29+
break;
30+
case QEMU_PLUGIN_MEM_VALUE_U32:
31+
buf[0] = (uint8_t)val->data.u32;
32+
buf[1] = (uint8_t)(val->data.u32 >> 8);
33+
buf[2] = (uint8_t)(val->data.u32 >> 16);
34+
buf[3] = (uint8_t)(val->data.u32 >> 24);
35+
mem_val_size = 4;
36+
break;
37+
case QEMU_PLUGIN_MEM_VALUE_U64:
38+
for (size_t i = 0; i < 8; ++i) {
39+
buf[i] = (uint8_t)(val->data.u64 >> (i * 8));
40+
}
41+
mem_val_size = 8;
42+
break;
43+
case QEMU_PLUGIN_MEM_VALUE_U128:
44+
for (size_t i = 0; i < 8; ++i) {
45+
buf[i] = (uint8_t)(val->data.u128.low >> (i * 8));
46+
}
47+
for (size_t i = 0; i < 8; ++i) {
48+
buf[i + 8] = (uint8_t)(val->data.u128.high >> (i * 8));
49+
}
50+
mem_val_size = 16;
51+
break;
52+
default:
53+
g_assert(false);
54+
}
55+
swap_to_le(buf, mem_val_size, state.is_big_endian);
56+
}
57+
58+
static size_t mval_type_to_int(enum qemu_plugin_mem_value_type type) {
59+
switch (type) {
60+
case QEMU_PLUGIN_MEM_VALUE_U8:
61+
return 8;
62+
case QEMU_PLUGIN_MEM_VALUE_U16:
63+
return 16;
64+
case QEMU_PLUGIN_MEM_VALUE_U32:
65+
return 32;
66+
case QEMU_PLUGIN_MEM_VALUE_U64:
67+
return 64;
68+
case QEMU_PLUGIN_MEM_VALUE_U128:
69+
return 128;
70+
default:
71+
g_assert(false);
72+
}
73+
return 0;
74+
}
75+
1876
static void add_mem_op(VCPU *vcpu, unsigned int vcpu_index, FrameBuffer *fbuf,
1977
uint64_t vaddr, qemu_plugin_mem_value *mval,
2078
bool is_store) {
21-
if (!frame_buffer_append_mem_info(fbuf, vaddr, mval, is_store)) {
79+
size_t mval_bits = mval_type_to_int(mval->type);
80+
uint8_t *buf = g_malloc(mval_bits / 8);
81+
mval_to_buf(mval, buf);
82+
if (!frame_buffer_append_mem_info(fbuf, vaddr, buf, mval_bits, is_store)) {
2283
qemu_plugin_outs("Failed to append memory info\n");
2384
}
2485
return;
@@ -54,7 +115,7 @@ static void add_post_reg_state(VCPU *vcpu, unsigned int vcpu_index,
54115
&g_array_index(current_regs, qemu_plugin_reg_descriptor, i);
55116
int s = qemu_plugin_read_register(reg->handle, rdata);
56117
assert(s == prev_reg->content->len);
57-
swap_to_le(rdata->data, s, HOST_BIG_ENDIAN);
118+
swap_to_le(rdata->data, s, state.is_big_endian);
58119
if (!memcmp(rdata->data, prev_reg->content->data, s)) {
59120
// No change
60121
// Flush byte array
@@ -83,8 +144,9 @@ static void add_pre_reg_state(VCPU *vcpu, unsigned int vcpu_index,
83144
g_assert(!strcmp(prev_reg->name, reg->name) &&
84145
prev_reg->handle == reg->handle);
85146
memcpy_le(prev_reg->content->data, rdata->data, prev_reg->content->len,
86-
HOST_BIG_ENDIAN);
87-
frame_buffer_append_reg_info(fbuf, reg->name, rdata, s, OperandRead);
147+
state.is_big_endian);
148+
frame_buffer_append_reg_info(fbuf, reg->name, prev_reg->content, s,
149+
OperandRead);
88150
// Flush byte array
89151
g_byte_array_set_size(rdata, 0);
90152
}
@@ -342,6 +404,14 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
342404
qemu_plugin_outs("Pass it with 'out=<output_file>'.\n\n");
343405
exit(1);
344406
}
407+
char *endianess = get_argv_val(argv, argc, "endianess");
408+
if (!endianess || (strcmp(endianess, "b") && strcmp(endianess, "l"))) {
409+
qemu_plugin_outs("'endianess' argument is missing or is not 'b' or 'l'.\n");
410+
qemu_plugin_outs("This is required until QEMU plugins get a richer API.\n");
411+
qemu_plugin_outs("Pass it with 'endianess=[b/l]'.\n\n");
412+
exit(1);
413+
}
414+
state.is_big_endian = endianess[0] == 'b';
345415

346416
state.target_name = g_strdup(info->target_name);
347417
state.frame_buffer = g_ptr_array_new();

contrib/plugins/bap-tracing/tracing.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ typedef struct {
171171
GPtrArray /*<const char *>*/ *vcpu_modes; ///< Indexed by vcpu id.
172172

173173
const char *target_name;
174+
bool is_big_endian;
174175
} TraceState;
175176

176177
VCPU *vcpu_new(void);

0 commit comments

Comments
 (0)