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 flags = fmtf->flags; unsigned int n_items; unsigned int i; unsigned int offset; unsigned int len; int ret; name = fmtf->alias; 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 &= 0xffff; }
static char * get_pevent_field_str(void *trace, struct event_format *event, struct format_field *field) { unsigned long long offset, len; if (field->flags & FIELD_IS_DYNAMIC) { offset = field->offset; len = field->size; offset = pevent_read_number(event->pevent, (char *)trace + offset, len); offset &= 0xffff; return (char *)trace + offset; } /** no __data_loc field type*/ return (char *)trace + field->offset; }
static int get_common_field(struct scripting_context *context, int *offset, int *size, const char *type) { struct pevent *pevent = context->pevent; struct event_format *event; struct format_field *field; if (!*size) { if (!pevent->events) return 0; event = pevent->events[0]; field = pevent_find_common_field(event, type); if (!field) return 0; *offset = field->offset; *size = field->size; } return pevent_read_number(pevent, context->event_data + *offset, *size); }
unsigned long long read_size(struct pevent *pevent, void *ptr, int size) { return pevent_read_number(pevent, ptr, size); }
unsigned long long read_size(struct event_format *event, void *ptr, int size) { return pevent_read_number(event->pevent, ptr, size); }
static void process_kernel_stack(struct pevent *pevent, struct pevent_record *record) { struct format_field *field = kernel_stack_caller_field; unsigned long long val; void *data = record->data; int do_restore = 0; int pid; int ret; ret = pevent_read_number_field(common_pid_field, record->data, &val); if (ret < 0) die("no pid field for function?"); pid = val; if (pending_pid >= 0 && pid != pending_pid) { reset_pending_stack(); return; } if (!field) die("no caller field for kernel stack?"); if (pending_pid >= 0) { if (current_pid >= 0) { save_stack(); do_restore = 1; } } else { /* function stack trace? */ if (current_pid >= 0) { copy_stack_to_pending(current_pid); free(ips); reset_stack(); } } current_pid = pid; /* Need to start at the end of the callers and work up */ for (data += field->offset; data < record->data + record->size; data += long_size) { unsigned long long addr; addr = pevent_read_number(pevent, data, long_size); if ((long_size == 8 && addr == (unsigned long long)-1) || ((int)addr == -1)) break; } for (data -= long_size; data >= record->data + field->offset; data -= long_size) { unsigned long long addr; const char *func; addr = pevent_read_number(pevent, data, long_size); func = pevent_find_function(pevent, addr); if (func) push_stack_func(func); } if (pending_pid >= 0) { push_stack_func(pending_ips[pending_ips_idx - 1]); reset_pending_stack(); } save_call_chain(current_pid, ips, ips_idx, 1); if (do_restore) restore_stack(current_pid); }