[PATCH 5/8] perf data: Add tracepoint events fields CTF conversion support

2015-01-15 Thread Jiri Olsa
From: Sebastian Andrzej Siewior 

Adding support to convert tracepoint event fields into CTF
event fields.

We parse each tracepoint event for CTF conversion and add
tracepoint fields as regular CTF event fields, so they
appear in babeltrace output like:

  $ babeltrace ./ctf-data/
  ...
  [09:02:00.950703057] (+?.?) sched:sched_stat_runtime: { }, { perf_ip 
= ... SNIP ... common_type = 298, common_flags = 1, \
  common_preempt_count = 0, common_pid = 31813, comm = "perf", pid = 31813, 
runtime = 458800, vruntime = 52059858071 }
  ...

Cc: Arnaldo Carvalho de Melo 
Cc: David Ahern 
Cc: Frederic Weisbecker 
Cc: Jeremie Galarneau 
Cc: Jiri Olsa 
Cc: Namhyung Kim 
Cc: Paul Mackerras 
Cc: Peter Zijlstra 
Cc: Sebastian Andrzej Siewior 
Cc: Tom Zanussi 
Signed-off-by: Jiri Olsa 
Signed-off-by: Sebastian Andrzej Siewior 
---
 tools/perf/util/data-convert-bt.c | 242 ++
 1 file changed, 242 insertions(+)

diff --git a/tools/perf/util/data-convert-bt.c 
b/tools/perf/util/data-convert-bt.c
index e372e03ff480..6fa5c3ef336b 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -126,6 +126,177 @@ FUNC_VALUE_SET(s64)
 FUNC_VALUE_SET(u64)
 __FUNC_VALUE_SET(u64_hex, u64)
 
+static struct bt_ctf_field_type*
+get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field)
+{
+   unsigned long flags = field->flags;
+
+   if (flags & FIELD_IS_STRING)
+   return cw->data.string;
+
+   if (!(flags & FIELD_IS_SIGNED)) {
+   /* unsigned long are mostly pointers */
+   if (flags & FIELD_IS_LONG || flags & FIELD_IS_POINTER)
+   return cw->data.u64_hex;
+   }
+
+   if (flags & FIELD_IS_SIGNED) {
+   if (field->size == 8)
+   return cw->data.s64;
+   else
+   return cw->data.s32;
+   }
+
+   if (field->size == 8)
+   return cw->data.u64;
+   else
+   return cw->data.u32;
+}
+
+static int add_tracepoint_field_value(struct ctf_writer *cw,
+ struct bt_ctf_event_class *event_class,
+ struct bt_ctf_event *event,
+ struct perf_sample *sample,
+ struct format_field *fmtf)
+{
+   struct bt_ctf_field_type *type;
+   struct bt_ctf_field *array_field;
+   struct bt_ctf_field *field;
+   const char *name = fmtf->name;
+   void *data = sample->raw_data;
+   unsigned long long value_int;
+   unsigned long flags = fmtf->flags;
+   unsigned int n_items;
+   unsigned int i;
+   unsigned int offset;
+   unsigned int len;
+   int ret;
+
+   offset = fmtf->offset;
+   len = fmtf->size;
+   if (flags & FIELD_IS_STRING)
+   flags &= ~FIELD_IS_ARRAY;
+
+   if (flags & FIELD_IS_DYNAMIC) {
+   unsigned long long tmp_val;
+
+   tmp_val = pevent_read_number(fmtf->event->pevent,
+   data + offset, len);
+   offset = tmp_val;
+   len = offset >> 16;
+   offset &= 0x;
+   }
+
+   if (flags & FIELD_IS_ARRAY) {
+
+   type = bt_ctf_event_class_get_field_by_name(
+   event_class, name);
+   array_field = bt_ctf_field_create(type);
+   bt_ctf_field_type_put(type);
+   if (!array_field) {
+   pr_err("Failed to create array type %s\n", name);
+   return -1;
+   }
+
+   len = fmtf->size / fmtf->arraylen;
+   n_items = fmtf->arraylen;
+   } else {
+   n_items = 1;
+   array_field = NULL;
+   }
+
+   type = get_tracepoint_field_type(cw, fmtf);
+
+   for (i = 0; i < n_items; i++) {
+   if (!(flags & FIELD_IS_STRING))
+   value_int = pevent_read_number(
+   fmtf->event->pevent,
+   data + offset + i * len, len);
+
+   if (flags & FIELD_IS_ARRAY)
+   field = bt_ctf_field_array_get_field(array_field, i);
+   else
+   field = bt_ctf_field_create(type);
+
+   if (!field) {
+   pr_err("failed to create a field %s\n", name);
+   return -1;
+   }
+
+   if (flags & FIELD_IS_STRING)
+   ret = bt_ctf_field_string_set_value(field,
+   data + offset + i * len);
+   else if (!(flags & FIELD_IS_SIGNED))
+   ret = bt_ctf_field_unsigned_integer_set_value(
+   field, value_int);
+   else
+   ret = 

[PATCH 5/8] perf data: Add tracepoint events fields CTF conversion support

2015-01-15 Thread Jiri Olsa
From: Sebastian Andrzej Siewior bige...@linutronix.de

Adding support to convert tracepoint event fields into CTF
event fields.

We parse each tracepoint event for CTF conversion and add
tracepoint fields as regular CTF event fields, so they
appear in babeltrace output like:

  $ babeltrace ./ctf-data/
  ...
  [09:02:00.950703057] (+?.?) sched:sched_stat_runtime: { }, { perf_ip 
= ... SNIP ... common_type = 298, common_flags = 1, \
  common_preempt_count = 0, common_pid = 31813, comm = perf, pid = 31813, 
runtime = 458800, vruntime = 52059858071 }
  ...

Cc: Arnaldo Carvalho de Melo a...@redhat.com
Cc: David Ahern dsah...@gmail.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Jeremie Galarneau jga...@efficios.com
Cc: Jiri Olsa jo...@kernel.org
Cc: Namhyung Kim namhy...@gmail.com
Cc: Paul Mackerras pau...@samba.org
Cc: Peter Zijlstra pet...@infradead.org
Cc: Sebastian Andrzej Siewior bige...@linutronix.de
Cc: Tom Zanussi tzanu...@gmail.com
Signed-off-by: Jiri Olsa jo...@kernel.org
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 tools/perf/util/data-convert-bt.c | 242 ++
 1 file changed, 242 insertions(+)

diff --git a/tools/perf/util/data-convert-bt.c 
b/tools/perf/util/data-convert-bt.c
index e372e03ff480..6fa5c3ef336b 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -126,6 +126,177 @@ FUNC_VALUE_SET(s64)
 FUNC_VALUE_SET(u64)
 __FUNC_VALUE_SET(u64_hex, u64)
 
+static struct bt_ctf_field_type*
+get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field)
+{
+   unsigned long flags = field-flags;
+
+   if (flags  FIELD_IS_STRING)
+   return cw-data.string;
+
+   if (!(flags  FIELD_IS_SIGNED)) {
+   /* unsigned long are mostly pointers */
+   if (flags  FIELD_IS_LONG || flags  FIELD_IS_POINTER)
+   return cw-data.u64_hex;
+   }
+
+   if (flags  FIELD_IS_SIGNED) {
+   if (field-size == 8)
+   return cw-data.s64;
+   else
+   return cw-data.s32;
+   }
+
+   if (field-size == 8)
+   return cw-data.u64;
+   else
+   return cw-data.u32;
+}
+
+static int add_tracepoint_field_value(struct ctf_writer *cw,
+ struct bt_ctf_event_class *event_class,
+ struct bt_ctf_event *event,
+ struct perf_sample *sample,
+ struct format_field *fmtf)
+{
+   struct bt_ctf_field_type *type;
+   struct bt_ctf_field *array_field;
+   struct bt_ctf_field *field;
+   const char *name = fmtf-name;
+   void *data = sample-raw_data;
+   unsigned long long value_int;
+   unsigned long flags = fmtf-flags;
+   unsigned int n_items;
+   unsigned int i;
+   unsigned int offset;
+   unsigned int len;
+   int ret;
+
+   offset = fmtf-offset;
+   len = fmtf-size;
+   if (flags  FIELD_IS_STRING)
+   flags = ~FIELD_IS_ARRAY;
+
+   if (flags  FIELD_IS_DYNAMIC) {
+   unsigned long long tmp_val;
+
+   tmp_val = pevent_read_number(fmtf-event-pevent,
+   data + offset, len);
+   offset = tmp_val;
+   len = offset  16;
+   offset = 0x;
+   }
+
+   if (flags  FIELD_IS_ARRAY) {
+
+   type = bt_ctf_event_class_get_field_by_name(
+   event_class, name);
+   array_field = bt_ctf_field_create(type);
+   bt_ctf_field_type_put(type);
+   if (!array_field) {
+   pr_err(Failed to create array type %s\n, name);
+   return -1;
+   }
+
+   len = fmtf-size / fmtf-arraylen;
+   n_items = fmtf-arraylen;
+   } else {
+   n_items = 1;
+   array_field = NULL;
+   }
+
+   type = get_tracepoint_field_type(cw, fmtf);
+
+   for (i = 0; i  n_items; i++) {
+   if (!(flags  FIELD_IS_STRING))
+   value_int = pevent_read_number(
+   fmtf-event-pevent,
+   data + offset + i * len, len);
+
+   if (flags  FIELD_IS_ARRAY)
+   field = bt_ctf_field_array_get_field(array_field, i);
+   else
+   field = bt_ctf_field_create(type);
+
+   if (!field) {
+   pr_err(failed to create a field %s\n, name);
+   return -1;
+   }
+
+   if (flags  FIELD_IS_STRING)
+   ret = bt_ctf_field_string_set_value(field,
+   data + offset + i * len);
+   else if (!(flags  FIELD_IS_SIGNED))
+   

[PATCH 5/8] perf data: Add tracepoint events fields CTF conversion support

2014-12-11 Thread Jiri Olsa
From: Sebastian Andrzej Siewior 

Adding support to convert tracepoint event fields into CTF
event fields.

We parse each tracepoint event for CTF conversion and add
tracepoint fields as regular CTF event fields, so they
appear in babeltrace output like:

  $ babeltrace ./ctf-data/
  ...
  [09:02:00.950703057] (+?.?) sched:sched_stat_runtime: { }, { perf_ip 
= ... SNIP ... common_type = 298, common_flags = 1, \
  common_preempt_count = 0, common_pid = 31813, comm = "perf", pid = 31813, 
runtime = 458800, vruntime = 52059858071 }
  ...

Cc: Arnaldo Carvalho de Melo 
Cc: David Ahern 
Cc: Frederic Weisbecker 
Cc: Jeremie Galarneau 
Cc: Jiri Olsa 
Cc: Namhyung Kim 
Cc: Paul Mackerras 
Cc: Peter Zijlstra 
Cc: Sebastian Andrzej Siewior 
Cc: Tom Zanussi 
Signed-off-by: Jiri Olsa 
Signed-off-by: Sebastian Andrzej Siewior 
---
 tools/perf/util/data-convert-bt.c | 242 ++
 1 file changed, 242 insertions(+)

diff --git a/tools/perf/util/data-convert-bt.c 
b/tools/perf/util/data-convert-bt.c
index e372e03ff480..6fa5c3ef336b 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -126,6 +126,177 @@ FUNC_VALUE_SET(s64)
 FUNC_VALUE_SET(u64)
 __FUNC_VALUE_SET(u64_hex, u64)
 
+static struct bt_ctf_field_type*
+get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field)
+{
+   unsigned long flags = field->flags;
+
+   if (flags & FIELD_IS_STRING)
+   return cw->data.string;
+
+   if (!(flags & FIELD_IS_SIGNED)) {
+   /* unsigned long are mostly pointers */
+   if (flags & FIELD_IS_LONG || flags & FIELD_IS_POINTER)
+   return cw->data.u64_hex;
+   }
+
+   if (flags & FIELD_IS_SIGNED) {
+   if (field->size == 8)
+   return cw->data.s64;
+   else
+   return cw->data.s32;
+   }
+
+   if (field->size == 8)
+   return cw->data.u64;
+   else
+   return cw->data.u32;
+}
+
+static int add_tracepoint_field_value(struct ctf_writer *cw,
+ struct bt_ctf_event_class *event_class,
+ struct bt_ctf_event *event,
+ struct perf_sample *sample,
+ struct format_field *fmtf)
+{
+   struct bt_ctf_field_type *type;
+   struct bt_ctf_field *array_field;
+   struct bt_ctf_field *field;
+   const char *name = fmtf->name;
+   void *data = sample->raw_data;
+   unsigned long long value_int;
+   unsigned long flags = fmtf->flags;
+   unsigned int n_items;
+   unsigned int i;
+   unsigned int offset;
+   unsigned int len;
+   int ret;
+
+   offset = fmtf->offset;
+   len = fmtf->size;
+   if (flags & FIELD_IS_STRING)
+   flags &= ~FIELD_IS_ARRAY;
+
+   if (flags & FIELD_IS_DYNAMIC) {
+   unsigned long long tmp_val;
+
+   tmp_val = pevent_read_number(fmtf->event->pevent,
+   data + offset, len);
+   offset = tmp_val;
+   len = offset >> 16;
+   offset &= 0x;
+   }
+
+   if (flags & FIELD_IS_ARRAY) {
+
+   type = bt_ctf_event_class_get_field_by_name(
+   event_class, name);
+   array_field = bt_ctf_field_create(type);
+   bt_ctf_field_type_put(type);
+   if (!array_field) {
+   pr_err("Failed to create array type %s\n", name);
+   return -1;
+   }
+
+   len = fmtf->size / fmtf->arraylen;
+   n_items = fmtf->arraylen;
+   } else {
+   n_items = 1;
+   array_field = NULL;
+   }
+
+   type = get_tracepoint_field_type(cw, fmtf);
+
+   for (i = 0; i < n_items; i++) {
+   if (!(flags & FIELD_IS_STRING))
+   value_int = pevent_read_number(
+   fmtf->event->pevent,
+   data + offset + i * len, len);
+
+   if (flags & FIELD_IS_ARRAY)
+   field = bt_ctf_field_array_get_field(array_field, i);
+   else
+   field = bt_ctf_field_create(type);
+
+   if (!field) {
+   pr_err("failed to create a field %s\n", name);
+   return -1;
+   }
+
+   if (flags & FIELD_IS_STRING)
+   ret = bt_ctf_field_string_set_value(field,
+   data + offset + i * len);
+   else if (!(flags & FIELD_IS_SIGNED))
+   ret = bt_ctf_field_unsigned_integer_set_value(
+   field, value_int);
+   else
+   ret = 

[PATCH 5/8] perf data: Add tracepoint events fields CTF conversion support

2014-12-11 Thread Jiri Olsa
From: Sebastian Andrzej Siewior bige...@linutronix.de

Adding support to convert tracepoint event fields into CTF
event fields.

We parse each tracepoint event for CTF conversion and add
tracepoint fields as regular CTF event fields, so they
appear in babeltrace output like:

  $ babeltrace ./ctf-data/
  ...
  [09:02:00.950703057] (+?.?) sched:sched_stat_runtime: { }, { perf_ip 
= ... SNIP ... common_type = 298, common_flags = 1, \
  common_preempt_count = 0, common_pid = 31813, comm = perf, pid = 31813, 
runtime = 458800, vruntime = 52059858071 }
  ...

Cc: Arnaldo Carvalho de Melo a...@redhat.com
Cc: David Ahern dsah...@gmail.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Jeremie Galarneau jga...@efficios.com
Cc: Jiri Olsa jo...@kernel.org
Cc: Namhyung Kim namhy...@gmail.com
Cc: Paul Mackerras pau...@samba.org
Cc: Peter Zijlstra pet...@infradead.org
Cc: Sebastian Andrzej Siewior bige...@linutronix.de
Cc: Tom Zanussi tzanu...@gmail.com
Signed-off-by: Jiri Olsa jo...@kernel.org
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 tools/perf/util/data-convert-bt.c | 242 ++
 1 file changed, 242 insertions(+)

diff --git a/tools/perf/util/data-convert-bt.c 
b/tools/perf/util/data-convert-bt.c
index e372e03ff480..6fa5c3ef336b 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -126,6 +126,177 @@ FUNC_VALUE_SET(s64)
 FUNC_VALUE_SET(u64)
 __FUNC_VALUE_SET(u64_hex, u64)
 
+static struct bt_ctf_field_type*
+get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field)
+{
+   unsigned long flags = field-flags;
+
+   if (flags  FIELD_IS_STRING)
+   return cw-data.string;
+
+   if (!(flags  FIELD_IS_SIGNED)) {
+   /* unsigned long are mostly pointers */
+   if (flags  FIELD_IS_LONG || flags  FIELD_IS_POINTER)
+   return cw-data.u64_hex;
+   }
+
+   if (flags  FIELD_IS_SIGNED) {
+   if (field-size == 8)
+   return cw-data.s64;
+   else
+   return cw-data.s32;
+   }
+
+   if (field-size == 8)
+   return cw-data.u64;
+   else
+   return cw-data.u32;
+}
+
+static int add_tracepoint_field_value(struct ctf_writer *cw,
+ struct bt_ctf_event_class *event_class,
+ struct bt_ctf_event *event,
+ struct perf_sample *sample,
+ struct format_field *fmtf)
+{
+   struct bt_ctf_field_type *type;
+   struct bt_ctf_field *array_field;
+   struct bt_ctf_field *field;
+   const char *name = fmtf-name;
+   void *data = sample-raw_data;
+   unsigned long long value_int;
+   unsigned long flags = fmtf-flags;
+   unsigned int n_items;
+   unsigned int i;
+   unsigned int offset;
+   unsigned int len;
+   int ret;
+
+   offset = fmtf-offset;
+   len = fmtf-size;
+   if (flags  FIELD_IS_STRING)
+   flags = ~FIELD_IS_ARRAY;
+
+   if (flags  FIELD_IS_DYNAMIC) {
+   unsigned long long tmp_val;
+
+   tmp_val = pevent_read_number(fmtf-event-pevent,
+   data + offset, len);
+   offset = tmp_val;
+   len = offset  16;
+   offset = 0x;
+   }
+
+   if (flags  FIELD_IS_ARRAY) {
+
+   type = bt_ctf_event_class_get_field_by_name(
+   event_class, name);
+   array_field = bt_ctf_field_create(type);
+   bt_ctf_field_type_put(type);
+   if (!array_field) {
+   pr_err(Failed to create array type %s\n, name);
+   return -1;
+   }
+
+   len = fmtf-size / fmtf-arraylen;
+   n_items = fmtf-arraylen;
+   } else {
+   n_items = 1;
+   array_field = NULL;
+   }
+
+   type = get_tracepoint_field_type(cw, fmtf);
+
+   for (i = 0; i  n_items; i++) {
+   if (!(flags  FIELD_IS_STRING))
+   value_int = pevent_read_number(
+   fmtf-event-pevent,
+   data + offset + i * len, len);
+
+   if (flags  FIELD_IS_ARRAY)
+   field = bt_ctf_field_array_get_field(array_field, i);
+   else
+   field = bt_ctf_field_create(type);
+
+   if (!field) {
+   pr_err(failed to create a field %s\n, name);
+   return -1;
+   }
+
+   if (flags  FIELD_IS_STRING)
+   ret = bt_ctf_field_string_set_value(field,
+   data + offset + i * len);
+   else if (!(flags  FIELD_IS_SIGNED))
+   

[PATCH 5/8] perf data: Add tracepoint events fields CTF conversion support

2014-12-03 Thread Jiri Olsa
From: Sebastian Andrzej Siewior 

Adding support to convert tracepoint event fields into CTF
event fields.

We parse each tracepoint event for CTF conversion and add
tracepoint fields as regular CTF event fields, so they
appear in babeltrace output like:

  $ babeltrace ./ctf-data/
  ...
  [09:02:00.950703057] (+?.?) sched:sched_stat_runtime: { }, { perf_ip 
= ... SNIP ... common_type = 298, common_flags = 1, \
  common_preempt_count = 0, common_pid = 31813, comm = "perf", pid = 31813, 
runtime = 458800, vruntime = 52059858071 }
  ...

Cc: Arnaldo Carvalho de Melo 
Cc: David Ahern 
Cc: Frederic Weisbecker 
Cc: Jeremie Galarneau 
Cc: Jiri Olsa 
Cc: Namhyung Kim 
Cc: Paul Mackerras 
Cc: Peter Zijlstra 
Cc: Sebastian Andrzej Siewior 
Cc: Tom Zanussi 
Signed-off-by: Jiri Olsa 
Signed-off-by: Sebastian Andrzej Siewior 
---
 tools/perf/util/data-convert-bt.c | 242 ++
 1 file changed, 242 insertions(+)

diff --git a/tools/perf/util/data-convert-bt.c 
b/tools/perf/util/data-convert-bt.c
index 3c39fae9c07e..cf1b16c89120 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -126,6 +126,177 @@ FUNC_VALUE_SET(s64)
 FUNC_VALUE_SET(u64)
 __FUNC_VALUE_SET(u64_hex, u64)
 
+static struct bt_ctf_field_type*
+get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field)
+{
+   unsigned long flags = field->flags;
+
+   if (flags & FIELD_IS_STRING)
+   return cw->data.string;
+
+   if (!(flags & FIELD_IS_SIGNED)) {
+   /* unsigned long are mostly pointers */
+   if (flags & FIELD_IS_LONG || flags & FIELD_IS_POINTER)
+   return cw->data.u64_hex;
+   }
+
+   if (flags & FIELD_IS_SIGNED) {
+   if (field->size == 8)
+   return cw->data.s64;
+   else
+   return cw->data.s32;
+   }
+
+   if (field->size == 8)
+   return cw->data.u64;
+   else
+   return cw->data.u32;
+}
+
+static int add_tracepoint_field_value(struct ctf_writer *cw,
+ struct bt_ctf_event_class *event_class,
+ struct bt_ctf_event *event,
+ struct perf_sample *sample,
+ struct format_field *fmtf)
+{
+   struct bt_ctf_field_type *type;
+   struct bt_ctf_field *array_field;
+   struct bt_ctf_field *field;
+   const char *name = fmtf->name;
+   void *data = sample->raw_data;
+   unsigned long long value_int;
+   unsigned long flags = fmtf->flags;
+   unsigned int n_items;
+   unsigned int i;
+   unsigned int offset;
+   unsigned int len;
+   int ret;
+
+   offset = fmtf->offset;
+   len = fmtf->size;
+   if (flags & FIELD_IS_STRING)
+   flags &= ~FIELD_IS_ARRAY;
+
+   if (flags & FIELD_IS_DYNAMIC) {
+   unsigned long long tmp_val;
+
+   tmp_val = pevent_read_number(fmtf->event->pevent,
+   data + offset, len);
+   offset = tmp_val;
+   len = offset >> 16;
+   offset &= 0x;
+   }
+
+   if (flags & FIELD_IS_ARRAY) {
+
+   type = bt_ctf_event_class_get_field_by_name(
+   event_class, name);
+   array_field = bt_ctf_field_create(type);
+   bt_ctf_field_type_put(type);
+   if (!array_field) {
+   pr_err("Failed to create array type %s\n", name);
+   return -1;
+   }
+
+   len = fmtf->size / fmtf->arraylen;
+   n_items = fmtf->arraylen;
+   } else {
+   n_items = 1;
+   array_field = NULL;
+   }
+
+   type = get_tracepoint_field_type(cw, fmtf);
+
+   for (i = 0; i < n_items; i++) {
+   if (!(flags & FIELD_IS_STRING))
+   value_int = pevent_read_number(
+   fmtf->event->pevent,
+   data + offset + i * len, len);
+
+   if (flags & FIELD_IS_ARRAY)
+   field = bt_ctf_field_array_get_field(array_field, i);
+   else
+   field = bt_ctf_field_create(type);
+
+   if (!field) {
+   pr_err("failed to create a field %s\n", name);
+   return -1;
+   }
+
+   if (flags & FIELD_IS_STRING)
+   ret = bt_ctf_field_string_set_value(field,
+   data + offset + i * len);
+   else if (!(flags & FIELD_IS_SIGNED))
+   ret = bt_ctf_field_unsigned_integer_set_value(
+   field, value_int);
+   else
+   ret = 

[PATCH 5/8] perf data: Add tracepoint events fields CTF conversion support

2014-12-03 Thread Jiri Olsa
From: Sebastian Andrzej Siewior bige...@linutronix.de

Adding support to convert tracepoint event fields into CTF
event fields.

We parse each tracepoint event for CTF conversion and add
tracepoint fields as regular CTF event fields, so they
appear in babeltrace output like:

  $ babeltrace ./ctf-data/
  ...
  [09:02:00.950703057] (+?.?) sched:sched_stat_runtime: { }, { perf_ip 
= ... SNIP ... common_type = 298, common_flags = 1, \
  common_preempt_count = 0, common_pid = 31813, comm = perf, pid = 31813, 
runtime = 458800, vruntime = 52059858071 }
  ...

Cc: Arnaldo Carvalho de Melo a...@redhat.com
Cc: David Ahern dsah...@gmail.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Jeremie Galarneau jga...@efficios.com
Cc: Jiri Olsa jo...@kernel.org
Cc: Namhyung Kim namhy...@gmail.com
Cc: Paul Mackerras pau...@samba.org
Cc: Peter Zijlstra pet...@infradead.org
Cc: Sebastian Andrzej Siewior bige...@linutronix.de
Cc: Tom Zanussi tzanu...@gmail.com
Signed-off-by: Jiri Olsa jo...@kernel.org
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 tools/perf/util/data-convert-bt.c | 242 ++
 1 file changed, 242 insertions(+)

diff --git a/tools/perf/util/data-convert-bt.c 
b/tools/perf/util/data-convert-bt.c
index 3c39fae9c07e..cf1b16c89120 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -126,6 +126,177 @@ FUNC_VALUE_SET(s64)
 FUNC_VALUE_SET(u64)
 __FUNC_VALUE_SET(u64_hex, u64)
 
+static struct bt_ctf_field_type*
+get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field)
+{
+   unsigned long flags = field-flags;
+
+   if (flags  FIELD_IS_STRING)
+   return cw-data.string;
+
+   if (!(flags  FIELD_IS_SIGNED)) {
+   /* unsigned long are mostly pointers */
+   if (flags  FIELD_IS_LONG || flags  FIELD_IS_POINTER)
+   return cw-data.u64_hex;
+   }
+
+   if (flags  FIELD_IS_SIGNED) {
+   if (field-size == 8)
+   return cw-data.s64;
+   else
+   return cw-data.s32;
+   }
+
+   if (field-size == 8)
+   return cw-data.u64;
+   else
+   return cw-data.u32;
+}
+
+static int add_tracepoint_field_value(struct ctf_writer *cw,
+ struct bt_ctf_event_class *event_class,
+ struct bt_ctf_event *event,
+ struct perf_sample *sample,
+ struct format_field *fmtf)
+{
+   struct bt_ctf_field_type *type;
+   struct bt_ctf_field *array_field;
+   struct bt_ctf_field *field;
+   const char *name = fmtf-name;
+   void *data = sample-raw_data;
+   unsigned long long value_int;
+   unsigned long flags = fmtf-flags;
+   unsigned int n_items;
+   unsigned int i;
+   unsigned int offset;
+   unsigned int len;
+   int ret;
+
+   offset = fmtf-offset;
+   len = fmtf-size;
+   if (flags  FIELD_IS_STRING)
+   flags = ~FIELD_IS_ARRAY;
+
+   if (flags  FIELD_IS_DYNAMIC) {
+   unsigned long long tmp_val;
+
+   tmp_val = pevent_read_number(fmtf-event-pevent,
+   data + offset, len);
+   offset = tmp_val;
+   len = offset  16;
+   offset = 0x;
+   }
+
+   if (flags  FIELD_IS_ARRAY) {
+
+   type = bt_ctf_event_class_get_field_by_name(
+   event_class, name);
+   array_field = bt_ctf_field_create(type);
+   bt_ctf_field_type_put(type);
+   if (!array_field) {
+   pr_err(Failed to create array type %s\n, name);
+   return -1;
+   }
+
+   len = fmtf-size / fmtf-arraylen;
+   n_items = fmtf-arraylen;
+   } else {
+   n_items = 1;
+   array_field = NULL;
+   }
+
+   type = get_tracepoint_field_type(cw, fmtf);
+
+   for (i = 0; i  n_items; i++) {
+   if (!(flags  FIELD_IS_STRING))
+   value_int = pevent_read_number(
+   fmtf-event-pevent,
+   data + offset + i * len, len);
+
+   if (flags  FIELD_IS_ARRAY)
+   field = bt_ctf_field_array_get_field(array_field, i);
+   else
+   field = bt_ctf_field_create(type);
+
+   if (!field) {
+   pr_err(failed to create a field %s\n, name);
+   return -1;
+   }
+
+   if (flags  FIELD_IS_STRING)
+   ret = bt_ctf_field_string_set_value(field,
+   data + offset + i * len);
+   else if (!(flags  FIELD_IS_SIGNED))
+