Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e080e6f1 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

tools lib traceevent: Add support for __print_hex()



Since the __print_hex() function is used in print fmt now, add
corresponding parser routines. This makes the output of perf script on
the kvm_emulate_insn event not to fail any more.

 before:
      kvm_emulate_insn:     [FAILED TO PARSE] rip=3238197797 ...

 after:
      kvm_emulate_insn:     0:c102fa25:89 10 (prot32)

Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1340757701-10711-4-git-send-email-namhyung@kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent b7008071
Loading
Loading
Loading
Loading
+74 −1
Original line number Diff line number Diff line
@@ -697,6 +697,10 @@ static void free_arg(struct print_arg *arg)
		free_arg(arg->symbol.field);
		free_flag_sym(arg->symbol.symbols);
		break;
	case PRINT_HEX:
		free_arg(arg->hex.field);
		free_arg(arg->hex.size);
		break;
	case PRINT_TYPE:
		free(arg->typecast.type);
		free_arg(arg->typecast.item);
@@ -2259,6 +2263,45 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
	return EVENT_ERROR;
}

static enum event_type
process_hex(struct event_format *event, struct print_arg *arg, char **tok)
{
	struct print_arg *field;
	enum event_type type;
	char *token;

	memset(arg, 0, sizeof(*arg));
	arg->type = PRINT_HEX;

	field = alloc_arg();
	type = process_arg(event, field, &token);

	if (test_type_token(type, token, EVENT_DELIM, ","))
		goto out_free;

	arg->hex.field = field;

	free_token(token);

	field = alloc_arg();
	type = process_arg(event, field, &token);

	if (test_type_token(type, token, EVENT_DELIM, ")"))
		goto out_free;

	arg->hex.size = field;

	free_token(token);
	type = read_token_item(tok);
	return type;

 out_free:
	free_arg(field);
	free_token(token);
	*tok = NULL;
	return EVENT_ERROR;
}

static enum event_type
process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok)
{
@@ -2488,6 +2531,10 @@ process_function(struct event_format *event, struct print_arg *arg,
		is_symbolic_field = 1;
		return process_symbols(event, arg, tok);
	}
	if (strcmp(token, "__print_hex") == 0) {
		free_token(token);
		return process_hex(event, arg, tok);
	}
	if (strcmp(token, "__get_str") == 0) {
		free_token(token);
		return process_str(event, arg, tok);
@@ -2995,6 +3042,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
		break;
	case PRINT_FLAGS:
	case PRINT_SYMBOL:
	case PRINT_HEX:
		break;
	case PRINT_TYPE:
		val = eval_num_arg(data, size, event, arg->typecast.item);
@@ -3218,8 +3266,9 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
	unsigned long long val, fval;
	unsigned long addr;
	char *str;
	unsigned char *hex;
	int print;
	int len;
	int i, len;

	switch (arg->type) {
	case PRINT_NULL:
@@ -3284,6 +3333,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
			}
		}
		break;
	case PRINT_HEX:
		field = arg->hex.field->field.field;
		if (!field) {
			str = arg->hex.field->field.name;
			field = pevent_find_any_field(event, str);
			if (!field)
				die("field %s not found", str);
			arg->hex.field->field.field = field;
		}
		hex = data + field->offset;
		len = eval_num_arg(data, size, event, arg->hex.size);
		for (i = 0; i < len; i++) {
			if (i)
				trace_seq_putc(s, ' ');
			trace_seq_printf(s, "%02x", hex[i]);
		}
		break;

	case PRINT_TYPE:
		break;
@@ -4294,6 +4360,13 @@ static void print_args(struct print_arg *args)
		trace_seq_destroy(&s);
		printf(")");
		break;
	case PRINT_HEX:
		printf("__print_hex(");
		print_args(args->hex.field);
		printf(", ");
		print_args(args->hex.size);
		printf(")");
		break;
	case PRINT_STRING:
	case PRINT_BSTRING:
		printf("__get_str(%s)", args->string.string);
+7 −0
Original line number Diff line number Diff line
@@ -226,6 +226,11 @@ struct print_arg_symbol {
	struct print_flag_sym	*symbols;
};

struct print_arg_hex {
	struct print_arg	*field;
	struct print_arg	*size;
};

struct print_arg_dynarray {
	struct format_field	*field;
	struct print_arg	*index;
@@ -253,6 +258,7 @@ enum print_arg_type {
	PRINT_FIELD,
	PRINT_FLAGS,
	PRINT_SYMBOL,
	PRINT_HEX,
	PRINT_TYPE,
	PRINT_STRING,
	PRINT_BSTRING,
@@ -270,6 +276,7 @@ struct print_arg {
		struct print_arg_typecast	typecast;
		struct print_arg_flags		flags;
		struct print_arg_symbol		symbol;
		struct print_arg_hex		hex;
		struct print_arg_func		func;
		struct print_arg_string		string;
		struct print_arg_op		op;
+4 −0
Original line number Diff line number Diff line
@@ -209,6 +209,10 @@ static void define_event_symbols(struct event_format *event,
		define_symbolic_values(args->symbol.symbols, ev_name,
				       cur_field_name);
		break;
	case PRINT_HEX:
		define_event_symbols(event, ev_name, args->hex.field);
		define_event_symbols(event, ev_name, args->hex.size);
		break;
	case PRINT_BSTRING:
	case PRINT_DYNAMIC_ARRAY:
	case PRINT_STRING:
+4 −0
Original line number Diff line number Diff line
@@ -166,6 +166,10 @@ static void define_event_symbols(struct event_format *event,
		define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name,
			      cur_field_name);
		break;
	case PRINT_HEX:
		define_event_symbols(event, ev_name, args->hex.field);
		define_event_symbols(event, ev_name, args->hex.size);
		break;
	case PRINT_STRING:
		break;
	case PRINT_TYPE: