All of lore.kernel.org
 help / color / mirror / Atom feed
From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
To: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>,
	Namhyung Kim <namhyung.kim@lge.com>,
	Hyeoncheol Lee <cheol.lee@lge.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
	Oleg Nesterov <oleg@redhat.com>,
	"zhangwei(Jovi)" <jovi.zhangwei@huawei.com>,
	Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Subject: Re: [PATCH 01/13] tracing/kprobes: Move fetch functions to trace_kprobe.c
Date: Mon, 05 Aug 2013 14:30:35 +0900	[thread overview]
Message-ID: <51FF387B.6080505@hitachi.com> (raw)
In-Reply-To: <1375261410-11219-2-git-send-email-namhyung@kernel.org>

(2013/07/31 18:03), Namhyung Kim wrote:
> From: Hyeoncheol Lee <cheol.lee@lge.com>
> 
> Move kprobes-specific fetch functions to the trace_kprobe.c file.
> Also define kprobes_fetch_type_table in the .c file.  This table is
> shared with uprobes for now, but the uprobes will get its own table
> in the later patch.
> 
> This is a preparation for supporting more fetch functions to uprobes
> and no functional changes are intended.
> 

Looks good for me :)

Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
> Cc: Oleg Nesterov <oleg@redhat.com>
> Cc: zhangwei(Jovi) <jovi.zhangwei@huawei.com>
> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
> Signed-off-by: Hyeoncheol Lee <cheol.lee@lge.com>
> [namhyung@kernel.org: Split original patch into pieces as requested]
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> ---
>  kernel/trace/trace_kprobe.c | 110 ++++++++++++++++++++
>  kernel/trace/trace_probe.c  | 242 +++++++-------------------------------------
>  kernel/trace/trace_probe.h  | 127 +++++++++++++++++++++++
>  3 files changed, 272 insertions(+), 207 deletions(-)
> 
> diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
> index 3811487e7a7a..c91eca015758 100644
> --- a/kernel/trace/trace_kprobe.c
> +++ b/kernel/trace/trace_kprobe.c
> @@ -749,6 +749,116 @@ static const struct file_operations kprobe_profile_ops = {
>  	.release        = seq_release,
>  };
>  
> +/*
> + * kprobes-specific fetch functions
> + */
> +#define DEFINE_FETCH_stack(type)					\
> +__kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,	\
> +					  void *offset, void *dest)	\
> +{									\
> +	*(type *)dest = (type)regs_get_kernel_stack_nth(regs,		\
> +				(unsigned int)((unsigned long)offset));	\
> +}
> +DEFINE_BASIC_FETCH_FUNCS(stack)
> +/* No string on the stack entry */
> +#define fetch_stack_string	NULL
> +#define fetch_stack_string_size	NULL
> +
> +#define DEFINE_FETCH_memory(type)					\
> +__kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,	\
> +					  void *addr, void *dest)	\
> +{									\
> +	type retval;							\
> +	if (probe_kernel_address(addr, retval))				\
> +		*(type *)dest = 0;					\
> +	else								\
> +		*(type *)dest = retval;					\
> +}
> +DEFINE_BASIC_FETCH_FUNCS(memory)
> +/*
> + * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
> + * length and relative data location.
> + */
> +__kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
> +					       void *addr, void *dest)
> +{
> +	long ret;
> +	int maxlen = get_rloc_len(*(u32 *)dest);
> +	u8 *dst = get_rloc_data(dest);
> +	u8 *src = addr;
> +	mm_segment_t old_fs = get_fs();
> +
> +	if (!maxlen)
> +		return;
> +
> +	/*
> +	 * Try to get string again, since the string can be changed while
> +	 * probing.
> +	 */
> +	set_fs(KERNEL_DS);
> +	pagefault_disable();
> +
> +	do
> +		ret = __copy_from_user_inatomic(dst++, src++, 1);
> +	while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen);
> +
> +	dst[-1] = '\0';
> +	pagefault_enable();
> +	set_fs(old_fs);
> +
> +	if (ret < 0) {	/* Failed to fetch string */
> +		((u8 *)get_rloc_data(dest))[0] = '\0';
> +		*(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
> +	} else {
> +		*(u32 *)dest = make_data_rloc(src - (u8 *)addr,
> +					      get_rloc_offs(*(u32 *)dest));
> +	}
> +}
> +
> +/* Return the length of string -- including null terminal byte */
> +__kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
> +						    void *addr, void *dest)
> +{
> +	mm_segment_t old_fs;
> +	int ret, len = 0;
> +	u8 c;
> +
> +	old_fs = get_fs();
> +	set_fs(KERNEL_DS);
> +	pagefault_disable();
> +
> +	do {
> +		ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
> +		len++;
> +	} while (c && ret == 0 && len < MAX_STRING_SIZE);
> +
> +	pagefault_enable();
> +	set_fs(old_fs);
> +
> +	if (ret < 0)	/* Failed to check the length */
> +		*(u32 *)dest = 0;
> +	else
> +		*(u32 *)dest = len;
> +}
> +
> +/* Fetch type information table */
> +const struct fetch_type kprobes_fetch_type_table[] = {
> +	/* Special types */
> +	[FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
> +					sizeof(u32), 1, "__data_loc char[]"),
> +	[FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
> +					string_size, sizeof(u32), 0, "u32"),
> +	/* Basic types */
> +	ASSIGN_FETCH_TYPE(u8,  u8,  0),
> +	ASSIGN_FETCH_TYPE(u16, u16, 0),
> +	ASSIGN_FETCH_TYPE(u32, u32, 0),
> +	ASSIGN_FETCH_TYPE(u64, u64, 0),
> +	ASSIGN_FETCH_TYPE(s8,  u8,  1),
> +	ASSIGN_FETCH_TYPE(s16, u16, 1),
> +	ASSIGN_FETCH_TYPE(s32, u32, 1),
> +	ASSIGN_FETCH_TYPE(s64, u64, 1),
> +};
> +
>  /* Sum up total data length for dynamic arraies (strings) */
>  static __kprobes int __get_data_size(struct trace_probe *tp,
>  				     struct pt_regs *regs)
> diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
> index 412e959709b4..c58c25d81591 100644
> --- a/kernel/trace/trace_probe.c
> +++ b/kernel/trace/trace_probe.c
> @@ -35,19 +35,15 @@ const char *reserved_field_names[] = {
>  	FIELD_STRING_FUNC,
>  };
>  
> -/* Printing function type */
> -#define PRINT_TYPE_FUNC_NAME(type)	print_type_##type
> -#define PRINT_TYPE_FMT_NAME(type)	print_type_format_##type
> -
>  /* Printing  in basic type function template */
>  #define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast)			\
> -static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,	\
> +__kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,		\
>  						const char *name,	\
> -						void *data, void *ent)\
> +						void *data, void *ent)	\
>  {									\
>  	return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\
>  }									\
> -static const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
> +const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
>  
>  DEFINE_BASIC_PRINT_TYPE_FUNC(u8, "%x", unsigned int)
>  DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "%x", unsigned int)
> @@ -58,25 +54,10 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int)
>  DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long)
>  DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long)
>  
> -static inline void *get_rloc_data(u32 *dl)
> -{
> -	return (u8 *)dl + get_rloc_offs(*dl);
> -}
> -
> -/* For data_loc conversion */
> -static inline void *get_loc_data(u32 *dl, void *ent)
> -{
> -	return (u8 *)ent + get_rloc_offs(*dl);
> -}
> -
> -/* For defining macros, define string/string_size types */
> -typedef u32 string;
> -typedef u32 string_size;
> -
>  /* Print type function for string type */
> -static __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
> -						  const char *name,
> -						  void *data, void *ent)
> +__kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
> +					   const char *name,
> +					   void *data, void *ent)
>  {
>  	int len = *(u32 *)data >> 16;
>  
> @@ -87,140 +68,25 @@ static __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
>  					(const char *)get_loc_data(data, ent));
>  }
>  
> -static const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
> -
> -#define FETCH_FUNC_NAME(method, type)	fetch_##method##_##type
> -/*
> - * Define macro for basic types - we don't need to define s* types, because
> - * we have to care only about bitwidth at recording time.
> - */
> -#define DEFINE_BASIC_FETCH_FUNCS(method) \
> -DEFINE_FETCH_##method(u8)		\
> -DEFINE_FETCH_##method(u16)		\
> -DEFINE_FETCH_##method(u32)		\
> -DEFINE_FETCH_##method(u64)
> -
> -#define CHECK_FETCH_FUNCS(method, fn)			\
> -	(((FETCH_FUNC_NAME(method, u8) == fn) ||	\
> -	  (FETCH_FUNC_NAME(method, u16) == fn) ||	\
> -	  (FETCH_FUNC_NAME(method, u32) == fn) ||	\
> -	  (FETCH_FUNC_NAME(method, u64) == fn) ||	\
> -	  (FETCH_FUNC_NAME(method, string) == fn) ||	\
> -	  (FETCH_FUNC_NAME(method, string_size) == fn)) \
> -	 && (fn != NULL))
> +const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
>  
>  /* Data fetch function templates */
>  #define DEFINE_FETCH_reg(type)						\
> -static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs,	\
> +__kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs,		\
>  					void *offset, void *dest)	\
>  {									\
>  	*(type *)dest = (type)regs_get_register(regs,			\
>  				(unsigned int)((unsigned long)offset));	\
>  }
>  DEFINE_BASIC_FETCH_FUNCS(reg)
> -/* No string on the register */
> -#define fetch_reg_string	NULL
> -#define fetch_reg_string_size	NULL
> -
> -#define DEFINE_FETCH_stack(type)					\
> -static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
> -					  void *offset, void *dest)	\
> -{									\
> -	*(type *)dest = (type)regs_get_kernel_stack_nth(regs,		\
> -				(unsigned int)((unsigned long)offset));	\
> -}
> -DEFINE_BASIC_FETCH_FUNCS(stack)
> -/* No string on the stack entry */
> -#define fetch_stack_string	NULL
> -#define fetch_stack_string_size	NULL
>  
>  #define DEFINE_FETCH_retval(type)					\
> -static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
> +__kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,	\
>  					  void *dummy, void *dest)	\
>  {									\
>  	*(type *)dest = (type)regs_return_value(regs);			\
>  }
>  DEFINE_BASIC_FETCH_FUNCS(retval)
> -/* No string on the retval */
> -#define fetch_retval_string		NULL
> -#define fetch_retval_string_size	NULL
> -
> -#define DEFINE_FETCH_memory(type)					\
> -static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
> -					  void *addr, void *dest)	\
> -{									\
> -	type retval;							\
> -	if (probe_kernel_address(addr, retval))				\
> -		*(type *)dest = 0;					\
> -	else								\
> -		*(type *)dest = retval;					\
> -}
> -DEFINE_BASIC_FETCH_FUNCS(memory)
> -/*
> - * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
> - * length and relative data location.
> - */
> -static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
> -						      void *addr, void *dest)
> -{
> -	long ret;
> -	int maxlen = get_rloc_len(*(u32 *)dest);
> -	u8 *dst = get_rloc_data(dest);
> -	u8 *src = addr;
> -	mm_segment_t old_fs = get_fs();
> -
> -	if (!maxlen)
> -		return;
> -
> -	/*
> -	 * Try to get string again, since the string can be changed while
> -	 * probing.
> -	 */
> -	set_fs(KERNEL_DS);
> -	pagefault_disable();
> -
> -	do
> -		ret = __copy_from_user_inatomic(dst++, src++, 1);
> -	while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen);
> -
> -	dst[-1] = '\0';
> -	pagefault_enable();
> -	set_fs(old_fs);
> -
> -	if (ret < 0) {	/* Failed to fetch string */
> -		((u8 *)get_rloc_data(dest))[0] = '\0';
> -		*(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
> -	} else {
> -		*(u32 *)dest = make_data_rloc(src - (u8 *)addr,
> -					      get_rloc_offs(*(u32 *)dest));
> -	}
> -}
> -
> -/* Return the length of string -- including null terminal byte */
> -static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
> -							void *addr, void *dest)
> -{
> -	mm_segment_t old_fs;
> -	int ret, len = 0;
> -	u8 c;
> -
> -	old_fs = get_fs();
> -	set_fs(KERNEL_DS);
> -	pagefault_disable();
> -
> -	do {
> -		ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
> -		len++;
> -	} while (c && ret == 0 && len < MAX_STRING_SIZE);
> -
> -	pagefault_enable();
> -	set_fs(old_fs);
> -
> -	if (ret < 0)	/* Failed to check the length */
> -		*(u32 *)dest = 0;
> -	else
> -		*(u32 *)dest = len;
> -}
>  
>  /* Memory fetching by symbol */
>  struct symbol_cache {
> @@ -268,7 +134,7 @@ static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
>  }
>  
>  #define DEFINE_FETCH_symbol(type)					\
> -static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\
> +__kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,	\
>  					  void *data, void *dest)	\
>  {									\
>  	struct symbol_cache *sc = data;					\
> @@ -288,7 +154,7 @@ struct deref_fetch_param {
>  };
>  
>  #define DEFINE_FETCH_deref(type)					\
> -static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\
> +__kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,	\
>  					    void *data, void *dest)	\
>  {									\
>  	struct deref_fetch_param *dprm = data;				\
> @@ -329,7 +195,7 @@ struct bitfield_fetch_param {
>  };
>  
>  #define DEFINE_FETCH_bitfield(type)					\
> -static __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs,\
> +__kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs,\
>  					    void *data, void *dest)	\
>  {									\
>  	struct bitfield_fetch_param *bprm = data;			\
> @@ -343,8 +209,6 @@ static __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs,\
>  }
>  
>  DEFINE_BASIC_FETCH_FUNCS(bitfield)
> -#define fetch_bitfield_string		NULL
> -#define fetch_bitfield_string_size	NULL
>  
>  static __kprobes void
>  update_bitfield_fetch_param(struct bitfield_fetch_param *data)
> @@ -380,52 +244,8 @@ free_bitfield_fetch_param(struct bitfield_fetch_param *data)
>  #define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
>  #define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
>  
> -#define ASSIGN_FETCH_FUNC(method, type)	\
> -	[FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type)
> -
> -#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype)	\
> -	{.name = _name,				\
> -	 .size = _size,					\
> -	 .is_signed = sign,				\
> -	 .print = PRINT_TYPE_FUNC_NAME(ptype),		\
> -	 .fmt = PRINT_TYPE_FMT_NAME(ptype),		\
> -	 .fmttype = _fmttype,				\
> -	 .fetch = {					\
> -ASSIGN_FETCH_FUNC(reg, ftype),				\
> -ASSIGN_FETCH_FUNC(stack, ftype),			\
> -ASSIGN_FETCH_FUNC(retval, ftype),			\
> -ASSIGN_FETCH_FUNC(memory, ftype),			\
> -ASSIGN_FETCH_FUNC(symbol, ftype),			\
> -ASSIGN_FETCH_FUNC(deref, ftype),			\
> -ASSIGN_FETCH_FUNC(bitfield, ftype),			\
> -	  }						\
> -	}
> -
> -#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)			\
> -	__ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype)
> -
> -#define FETCH_TYPE_STRING	0
> -#define FETCH_TYPE_STRSIZE	1
> -
> -/* Fetch type information table */
> -static const struct fetch_type fetch_type_table[] = {
> -	/* Special types */
> -	[FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
> -					sizeof(u32), 1, "__data_loc char[]"),
> -	[FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
> -					string_size, sizeof(u32), 0, "u32"),
> -	/* Basic types */
> -	ASSIGN_FETCH_TYPE(u8,  u8,  0),
> -	ASSIGN_FETCH_TYPE(u16, u16, 0),
> -	ASSIGN_FETCH_TYPE(u32, u32, 0),
> -	ASSIGN_FETCH_TYPE(u64, u64, 0),
> -	ASSIGN_FETCH_TYPE(s8,  u8,  1),
> -	ASSIGN_FETCH_TYPE(s16, u16, 1),
> -	ASSIGN_FETCH_TYPE(s32, u32, 1),
> -	ASSIGN_FETCH_TYPE(s64, u64, 1),
> -};
> -
> -static const struct fetch_type *find_fetch_type(const char *type)
> +static const struct fetch_type *find_fetch_type(const char *type,
> +						const struct fetch_type *ttbl)
>  {
>  	int i;
>  
> @@ -446,21 +266,21 @@ static const struct fetch_type *find_fetch_type(const char *type)
>  
>  		switch (bs) {
>  		case 8:
> -			return find_fetch_type("u8");
> +			return find_fetch_type("u8", ttbl);
>  		case 16:
> -			return find_fetch_type("u16");
> +			return find_fetch_type("u16", ttbl);
>  		case 32:
> -			return find_fetch_type("u32");
> +			return find_fetch_type("u32", ttbl);
>  		case 64:
> -			return find_fetch_type("u64");
> +			return find_fetch_type("u64", ttbl);
>  		default:
>  			goto fail;
>  		}
>  	}
>  
> -	for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++)
> -		if (strcmp(type, fetch_type_table[i].name) == 0)
> -			return &fetch_type_table[i];
> +	for (i = 0; i < NR_FETCH_TYPES; i++)
> +		if (strcmp(type, ttbl[i].name) == 0)
> +			return &ttbl[i];
>  
>  fail:
>  	return NULL;
> @@ -474,16 +294,17 @@ static __kprobes void fetch_stack_address(struct pt_regs *regs,
>  }
>  
>  static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
> -					fetch_func_t orig_fn)
> +					    fetch_func_t orig_fn,
> +					    const struct fetch_type *ttbl)
>  {
>  	int i;
>  
> -	if (type != &fetch_type_table[FETCH_TYPE_STRING])
> +	if (type != &ttbl[FETCH_TYPE_STRING])
>  		return NULL;	/* Only string type needs size function */
>  
>  	for (i = 0; i < FETCH_MTD_END; i++)
>  		if (type->fetch[i] == orig_fn)
> -			return fetch_type_table[FETCH_TYPE_STRSIZE].fetch[i];
> +			return ttbl[FETCH_TYPE_STRSIZE].fetch[i];
>  
>  	WARN_ON(1);	/* This should not happen */
>  
> @@ -556,6 +377,9 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
>  	long offset;
>  	char *tmp;
>  	int ret;
> +	const struct fetch_type *ttbl;
> +
> +	ttbl = kprobes_fetch_type_table;
>  
>  	ret = 0;
>  
> @@ -616,7 +440,7 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
>  			struct deref_fetch_param	*dprm;
>  			const struct fetch_type		*t2;
>  
> -			t2 = find_fetch_type(NULL);
> +			t2 = find_fetch_type(NULL, ttbl);
>  			*tmp = '\0';
>  			dprm = kzalloc(sizeof(struct deref_fetch_param), GFP_KERNEL);
>  
> @@ -687,6 +511,9 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
>  {
>  	const char *t;
>  	int ret;
> +	const struct fetch_type *ttbl;
> +
> +	ttbl = kprobes_fetch_type_table;
>  
>  	if (strlen(arg) > MAX_ARGSTR_LEN) {
>  		pr_info("Argument is too long.: %s\n",  arg);
> @@ -702,7 +529,7 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
>  		arg[t - parg->comm] = '\0';
>  		t++;
>  	}
> -	parg->type = find_fetch_type(t);
> +	parg->type = find_fetch_type(t, ttbl);
>  	if (!parg->type) {
>  		pr_info("Unsupported type: %s\n", t);
>  		return -EINVAL;
> @@ -716,7 +543,8 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
>  
>  	if (ret >= 0) {
>  		parg->fetch_size.fn = get_fetch_size_function(parg->type,
> -							      parg->fetch.fn);
> +							      parg->fetch.fn,
> +							      ttbl);
>  		parg->fetch_size.data = parg->fetch.data;
>  	}
>  
> diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
> index 5c7e09d10d74..1c37c813e5e5 100644
> --- a/kernel/trace/trace_probe.h
> +++ b/kernel/trace/trace_probe.h
> @@ -81,11 +81,46 @@
>   */
>  #define convert_rloc_to_loc(dl, offs)	((u32)(dl) + (offs))
>  
> +static inline void *get_rloc_data(u32 *dl)
> +{
> +	return (u8 *)dl + get_rloc_offs(*dl);
> +}
> +
> +/* For data_loc conversion */
> +static inline void *get_loc_data(u32 *dl, void *ent)
> +{
> +	return (u8 *)ent + get_rloc_offs(*dl);
> +}
> +
> +
> +/* For defining macros, define string/string_size types */
> +typedef u32 string;
> +typedef u32 string_size;
> +
>  /* Data fetch function type */
>  typedef	void (*fetch_func_t)(struct pt_regs *, void *, void *);
>  /* Printing function type */
>  typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *, void *);
>  
> +/* Printing function type */
> +#define PRINT_TYPE_FUNC_NAME(type)	print_type_##type
> +#define PRINT_TYPE_FMT_NAME(type)	print_type_format_##type
> +
> +#define DECLARE_PRINT_TYPE_FUNC(type)					\
> +extern int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *, const char *, \
> +				     void *, void *);			\
> +extern const char PRINT_TYPE_FMT_NAME(type)[]
> +
> +DECLARE_PRINT_TYPE_FUNC(u8);
> +DECLARE_PRINT_TYPE_FUNC(u16);
> +DECLARE_PRINT_TYPE_FUNC(u32);
> +DECLARE_PRINT_TYPE_FUNC(u64);
> +DECLARE_PRINT_TYPE_FUNC(s8);
> +DECLARE_PRINT_TYPE_FUNC(s16);
> +DECLARE_PRINT_TYPE_FUNC(s32);
> +DECLARE_PRINT_TYPE_FUNC(s64);
> +DECLARE_PRINT_TYPE_FUNC(string);
> +
>  /* Fetch types */
>  enum {
>  	FETCH_MTD_reg = 0,
> @@ -124,6 +159,98 @@ struct probe_arg {
>  	const struct fetch_type	*type;	/* Type of this argument */
>  };
>  
> +#define FETCH_FUNC_NAME(method, type)	fetch_##method##_##type
> +
> +#define DECLARE_FETCH_FUNC(method, type)				\
> +extern void FETCH_FUNC_NAME(method, type)(struct pt_regs *, void *, void *)
> +
> +#define DECLARE_BASIC_FETCH_FUNCS(method) 	\
> +DECLARE_FETCH_FUNC(method, u8);	  		\
> +DECLARE_FETCH_FUNC(method, u16);		\
> +DECLARE_FETCH_FUNC(method, u32);		\
> +DECLARE_FETCH_FUNC(method, u64)
> +
> +/*
> + * Declare fetch functions
> + */
> +DECLARE_BASIC_FETCH_FUNCS(reg);
> +#define fetch_reg_string		NULL
> +#define fetch_reg_string_size		NULL
> +
> +DECLARE_BASIC_FETCH_FUNCS(stack);
> +#define fetch_stack_string		NULL
> +#define fetch_stack_string_size		NULL
> +
> +DECLARE_BASIC_FETCH_FUNCS(retval);
> +#define fetch_retval_string		NULL
> +#define fetch_retval_string_size	NULL
> +
> +DECLARE_BASIC_FETCH_FUNCS(memory);
> +DECLARE_FETCH_FUNC(memory, string);
> +DECLARE_FETCH_FUNC(memory, string_size);
> +
> +DECLARE_BASIC_FETCH_FUNCS(symbol);
> +DECLARE_FETCH_FUNC(symbol, string);
> +DECLARE_FETCH_FUNC(symbol, string_size);
> +
> +DECLARE_BASIC_FETCH_FUNCS(deref);
> +DECLARE_FETCH_FUNC(deref, string);
> +DECLARE_FETCH_FUNC(deref, string_size);
> +
> +DECLARE_BASIC_FETCH_FUNCS(bitfield);
> +#define fetch_bitfield_string		NULL
> +#define fetch_bitfield_string_size	NULL
> +
> +/*
> + * Define macro for basic types - we don't need to define s* types, because
> + * we have to care only about bitwidth at recording time.
> + */
> +#define DEFINE_BASIC_FETCH_FUNCS(method) \
> +DEFINE_FETCH_##method(u8)		\
> +DEFINE_FETCH_##method(u16)		\
> +DEFINE_FETCH_##method(u32)		\
> +DEFINE_FETCH_##method(u64)
> +
> +#define CHECK_FETCH_FUNCS(method, fn)			\
> +	(((FETCH_FUNC_NAME(method, u8) == fn) ||	\
> +	  (FETCH_FUNC_NAME(method, u16) == fn) ||	\
> +	  (FETCH_FUNC_NAME(method, u32) == fn) ||	\
> +	  (FETCH_FUNC_NAME(method, u64) == fn) ||	\
> +	  (FETCH_FUNC_NAME(method, string) == fn) ||	\
> +	  (FETCH_FUNC_NAME(method, string_size) == fn)) \
> +	 && (fn != NULL))
> +
> +#define ASSIGN_FETCH_FUNC(method, type)	\
> +	[FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type)
> +
> +#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype)	\
> +	{.name = _name,				\
> +	 .size = _size,					\
> +	 .is_signed = sign,				\
> +	 .print = PRINT_TYPE_FUNC_NAME(ptype),		\
> +	 .fmt = PRINT_TYPE_FMT_NAME(ptype),		\
> +	 .fmttype = _fmttype,				\
> +	 .fetch = {					\
> +ASSIGN_FETCH_FUNC(reg, ftype),				\
> +ASSIGN_FETCH_FUNC(stack, ftype),			\
> +ASSIGN_FETCH_FUNC(retval, ftype),			\
> +ASSIGN_FETCH_FUNC(memory, ftype),			\
> +ASSIGN_FETCH_FUNC(symbol, ftype),			\
> +ASSIGN_FETCH_FUNC(deref, ftype),			\
> +ASSIGN_FETCH_FUNC(bitfield, ftype),			\
> +	  }						\
> +	}
> +
> +#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)			\
> +	__ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype)
> +
> +#define FETCH_TYPE_STRING	0
> +#define FETCH_TYPE_STRSIZE	1
> +
> +#define NR_FETCH_TYPES		10
> +
> +extern const struct fetch_type kprobes_fetch_type_table[];
> +
>  static inline __kprobes void call_fetch(struct fetch_param *fprm,
>  				 struct pt_regs *regs, void *dest)
>  {
> 


-- 
Masami HIRAMATSU
IT Management Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com



  reply	other threads:[~2013-08-05  5:30 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-31  9:03 [PATCHSET 00/13] tracing/uprobes: Add support for more fetch methods (v2) Namhyung Kim
2013-07-31  9:03 ` [PATCH 01/13] tracing/kprobes: Move fetch functions to trace_kprobe.c Namhyung Kim
2013-08-05  5:30   ` Masami Hiramatsu [this message]
2013-08-05  8:44     ` Namhyung Kim
2013-07-31  9:03 ` [PATCH 02/13] tracing/kprobes: Add fetch{,_size} member into symbol and deref fetch method Namhyung Kim
2013-08-05  8:19   ` Masami Hiramatsu
2013-08-05  8:58     ` Namhyung Kim
2013-07-31  9:03 ` [PATCH 03/13] tracing/kprobes: Make stack and memory fetch functions static Namhyung Kim
2013-08-05  9:04   ` Masami Hiramatsu
2013-08-09  7:35     ` Namhyung Kim
2013-08-09  9:15       ` Masami Hiramatsu
2013-07-31  9:03 ` [PATCH 04/13] tracing/kprobes: Factor out struct trace_probe Namhyung Kim
2013-08-05  6:00   ` Masami Hiramatsu
2013-08-05  8:49     ` Namhyung Kim
2013-07-31  9:03 ` [PATCH 05/13] tracing/uprobes: Convert to " Namhyung Kim
2013-07-31  9:03 ` [PATCH 06/13] tracing/kprobes: Move common functions to trace_probe.c Namhyung Kim
2013-08-05  6:03   ` Masami Hiramatsu
2013-08-05  8:50     ` Namhyung Kim
2013-07-31  9:03 ` [PATCH 07/13] tracing/kprobes: Remove duplicate set_print_fmt() Namhyung Kim
2013-08-05  6:46   ` Masami Hiramatsu
2013-07-31  9:03 ` [PATCH 08/13] tracing/uprobes: Fetch args before reserving a ring buffer Namhyung Kim
2013-07-31  9:03 ` [PATCH 09/13] tracing/uprobes: Fix a comment for uprobe registration syntax Namhyung Kim
2013-08-05  5:59   ` Masami Hiramatsu
2013-08-05  8:47     ` Namhyung Kim
2013-07-31  9:03 ` [PATCH 10/13] tracing/kprobes: Add priv argument to fetch functions Namhyung Kim
2013-07-31  9:03 ` [PATCH 11/13] tracing/uprobes: Add more " Namhyung Kim
2013-07-31  9:03 ` [PATCH 12/13] tracing/uprobes: Add support for full argument access methods Namhyung Kim
2013-07-31  9:03 ` [PATCH 13/13] tracing/probes: Fix basic print type functions Namhyung Kim
2013-08-05  6:22   ` Masami Hiramatsu
2013-08-05  6:31     ` Joe Perches
2013-08-05  7:27       ` Masami Hiramatsu
2013-08-05  8:55       ` Namhyung Kim
2013-08-05  8:51     ` Namhyung Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51FF387B.6080505@hitachi.com \
    --to=masami.hiramatsu.pt@hitachi.com \
    --cc=acme@ghostprotocols.net \
    --cc=cheol.lee@lge.com \
    --cc=jovi.zhangwei@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=namhyung.kim@lge.com \
    --cc=namhyung@kernel.org \
    --cc=oleg@redhat.com \
    --cc=rostedt@goodmis.org \
    --cc=srikar@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.