Messages in this thread Patch in this message | | | From | Wang Nan <> | Subject | [PATCH 2/2] perf: convert: fix signess of value. | Date | Tue, 20 Jan 2015 19:07:09 +0800 |
| |
When converting int values, perf first extractes it to a ulonglong, then feeds it to babeltrace as a signed value. For negative 32 bit values (for example, return values of failed syscalls), the extracted data should be something like 0xfffffffe (-2). It becomes a large int64 value. Babeltrace denies to insert it with bt_ctf_field_signed_integer_set_value() because it is larger than 0x7fffffff, the largest positive value a signed 32 bit int can be.
This patch introduces adjust_signess(), which fills high bits of ulonglong with 1 if the value is negative.
Signed-off-by: Wang Nan <wangnan0@huawei.com> --- tools/perf/util/data-convert-bt.c | 41 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 2b87097..d43b8a1 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -165,6 +165,44 @@ get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field) return cw->data.u32; } +static unsigned long long adjust_signess(unsigned long long value_int, int size) +{ + int signbit; + unsigned long long value_mask; + + /* + * value_mask = (1 << (size * 8 - 1)) - 1. + * Directly set value_mask for code readers. + */ + switch (size) { + case 1: + value_mask = 0x7fULL; + break; + case 2: + value_mask = 0x7fffULL; + break; + case 4: + value_mask = 0x7fffffffULL; + break; + case 8: + /* + * For 64 bit value, return it self. There is no need + * to fill high bit. + */ + /* Fall through */ + default: + /* BUG! */ + return value_int; + } + + /* If it is a positive value, don't adjust. */ + if ((value_int & (~0ULL - value_mask)) == 0) + return value_int; + + /* Fill upper part of value_int with 1 to make it a negative long long. */ + return (value_int & value_mask) | ~value_mask; +} + static int add_tracepoint_field_value(struct ctf_writer *cw, struct bt_ctf_event_class *event_class, struct bt_ctf_event *event, @@ -243,7 +281,8 @@ static int add_tracepoint_field_value(struct ctf_writer *cw, field, value_int); else ret = bt_ctf_field_signed_integer_set_value( - field, value_int); + field, adjust_signess(value_int, len)); + if (ret) { pr_err("failed to set file value %s\n", name); goto err_put_field; -- 1.8.4
| |