[PATCH v3 4/7] Implement apigetctype call back function

Atsushi Kumagai kumagai-atsushi at mxc.nes.nec.co.jp
Thu Dec 20 03:45:39 EST 2012


Hello Aravinda,

On Fri, 14 Dec 2012 14:56:32 +0530
Aravinda Prasad <aravinda at linux.vnet.ibm.com> wrote:

> libeppic will call apigetctype call back function whenever it
> encounters a token in the eppic macro. The call back function will use
> DWARF to query information related to the requested token and will
> pass it back to eppic using libeppic API calls. If the token does not
> exist, then apigetctype call returns 0.
> 
> Signed-off-by: Aravinda Prasad <aravinda at linux.vnet.ibm.com>
> ---
>  dwarf_info.c      |  109 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  dwarf_info.h      |    9 ++++
>  extension_eppic.c |   28 +++++++++++++-
>  3 files changed, 145 insertions(+), 1 deletions(-)
> 
> diff --git a/dwarf_info.c b/dwarf_info.c
> index 09a8e1e..a8a87e1 100644
> --- a/dwarf_info.c
> +++ b/dwarf_info.c
> @@ -51,6 +51,7 @@ struct dwarf_info {
>  	long	enum_number;		/* OUT */
>  	unsigned char	type_flag;	/* OUT */
>  	char	src_name[LEN_SRCFILE];	/* OUT */
> +	Dwarf_Off die_offset;		/* OUT */
>  };
>  static struct dwarf_info	dwarf_info;
>  
> @@ -102,6 +103,22 @@ is_search_typedef(int cmd)
>  }
>  
>  static int
> +is_search_domain(int cmd)
> +{
> +	if ((cmd == DWARF_INFO_GET_DOMAIN_STRUCT)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_TYPEDEF)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_ARRAY)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_UNION)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_ENUM)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_REF)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_STRING)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_BASE))
> +		return TRUE;
> +	else
> +		return FALSE;
> +}
> +
> +static int
>  process_module (Dwfl_Module *dwflmod,
>  		void **userdata __attribute__ ((unused)),
>  		const char *name __attribute__ ((unused)),
> @@ -750,6 +767,74 @@ search_symbol(Dwarf_Die *die, int *found)
>  }
>  
>  static void
> +search_domain(Dwarf_Die *die, int *found)
> +{
> +	int tag;
> +	const char *name;
> +	short flag = 0;
> +	Dwarf_Die die_type;
> +
> +	do {
> +		tag  = dwarf_tag(die);
> +		name = dwarf_diename(die);
> +
> +		/*
> +		 * Descend into members and search for the
> +		 * needed domain there.
> +		 */
> +		if (!name) {
> +			if (!get_die_type(die, &die_type))
> +				continue;
> +
> +			if (is_container(&die_type)) {
> +				Dwarf_Die child;
> +
> +				if (dwarf_child(&die_type, &child) != 0)
> +					continue;
> +
> +				search_domain(&child, found);
> +
> +				if (*found)
> +					return;
> +			}
> +		}
> +
> +		if ((!name) || strcmp(name, dwarf_info.symbol_name))
> +			continue;

I commented for search_domain() in v1 patch:

  http://lists.infradead.org/pipermail/kexec/2012-October/007024.html

  > I assume that search_domain() needs to descend into struct/union for
  > a nested member, like how we fixed search_member() in commit:ecff242c.
  > I want to make sure that your patches can treat even a nested member.

And I still think so, it should be fixed as below:


diff --git a/dwarf_info.c b/dwarf_info.c
index 22c9e2f..a11b6ad 100644
--- a/dwarf_info.c
+++ b/dwarf_info.c
@@ -814,7 +814,7 @@ search_domain(Dwarf_Die *die, int *found)
                 * Descend into members and search for the
                 * needed domain there.
                 */
-               if (!name) {
+               if ((!name) || strcmp(name, dwarf_info.symbol_name)) {
                        if (!get_die_type(die, &die_type))
                                continue;

Do you agree with me ?


Thanks
Atsushi Kumagai

> +
> +		switch (dwarf_info.cmd) {
> +		case DWARF_INFO_GET_DOMAIN_STRUCT:
> +			if (tag == DW_TAG_structure_type)
> +				flag = 1;
> +			break;
> +		case DWARF_INFO_GET_DOMAIN_UNION:
> +			if (tag == DW_TAG_union_type)
> +				flag = 1;
> +			break;
> +		case DWARF_INFO_GET_DOMAIN_TYPEDEF:
> +			if (tag == DW_TAG_typedef)
> +				flag = 1;
> +			break;
> +		/* TODO
> +		 * Implement functionality for the rest of the domains
> +		 */
> +		}
> +
> +		if (!flag)
> +			continue;
> +
> +		dwarf_info.struct_size = dwarf_bytesize(die);
> +
> +		if (dwarf_info.struct_size > 0) {
> +			if (found)
> +				*found = TRUE;
> +			dwarf_info.die_offset = dwarf_dieoffset(die);
> +			break;
> +		}
> +	} while (!dwarf_siblingof(die, die));
> +}
> +
> +static void
>  search_die_tree(Dwarf_Die *die, int *found)
>  {
>  	Dwarf_Die child;
> @@ -774,6 +859,9 @@ search_die_tree(Dwarf_Die *die, int *found)
>  
>  	else if (is_search_typedef(dwarf_info.cmd))
>  		search_typedef(die, found);
> +
> +	else if (is_search_domain(dwarf_info.cmd))
> +		search_domain(die, found);
>  }
>  
>  static int
> @@ -1166,6 +1254,27 @@ get_source_filename(char *structname, char *src_name, int cmd)
>  }
>  
>  /*
> + * Get the domain information of the symbol
> + */
> +long
> +get_domain(char *symname, int cmd, unsigned long long *die)
> +{
> +	dwarf_info.cmd         = cmd;
> +	dwarf_info.symbol_name = symname;
> +	dwarf_info.type_name   = NULL;
> +	dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
> +	dwarf_info.die_offset  = 0;
> +
> +	if (!get_debug_info())
> +		return 0;
> +
> +	if (die)
> +		*die = (unsigned long long) dwarf_info.die_offset;
> +
> +	return dwarf_info.struct_size;
> +}
> +
> +/*
>   * Set the dwarf_info with kernel/module debuginfo file information.
>   */
>  int
> diff --git a/dwarf_info.h b/dwarf_info.h
> index 185cbb6..074b5cc 100644
> --- a/dwarf_info.h
> +++ b/dwarf_info.h
> @@ -47,6 +47,14 @@ enum {
>  	DWARF_INFO_GET_SYMBOL_TYPE,
>  	DWARF_INFO_GET_MEMBER_TYPE,
>  	DWARF_INFO_GET_ENUMERATION_TYPE_SIZE,
> +	DWARF_INFO_GET_DOMAIN_STRUCT,
> +	DWARF_INFO_GET_DOMAIN_TYPEDEF,
> +	DWARF_INFO_GET_DOMAIN_ARRAY,
> +	DWARF_INFO_GET_DOMAIN_UNION,
> +	DWARF_INFO_GET_DOMAIN_ENUM,
> +	DWARF_INFO_GET_DOMAIN_REF,
> +	DWARF_INFO_GET_DOMAIN_STRING,
> +	DWARF_INFO_GET_DOMAIN_BASE,
>  };
>  
>  char *get_dwarf_module_name(void);
> @@ -61,6 +69,7 @@ char *get_member_type_name(char *structname, char *membername, int cmd, long *si
>  long get_array_length(char *name01, char *name02, unsigned int cmd);
>  long get_enum_number(char *enum_name);
>  int get_source_filename(char *structname, char *src_name, int cmd);
> +long get_domain(char *symname, int cmd, unsigned long long *die);
>  int set_dwarf_debuginfo(char *mod_name, char *os_release, char *name_debuginfo, int fd_debuginfo);
>  
>  #endif  /* DWARF_INFO_H */
> diff --git a/extension_eppic.c b/extension_eppic.c
> index 774d16e..3fa3e88 100644
> --- a/extension_eppic.c
> +++ b/extension_eppic.c
> @@ -91,7 +91,33 @@ apimember(char *mname, ull pidx, type_t *tm,
>  static int
>  apigetctype(int ctype, char *name, type_t *tout)
>  {
> -	return 0;
> +	long size = 0;
> +	unsigned long long die = 0;
> +
> +	switch (ctype) {
> +	case V_TYPEDEF:
> +		size = get_domain(name, DWARF_INFO_GET_DOMAIN_TYPEDEF, &die);
> +		break;
> +	case V_STRUCT:
> +		size = get_domain(name, DWARF_INFO_GET_DOMAIN_STRUCT, &die);
> +		break;
> +	case V_UNION:
> +		size = get_domain(name, DWARF_INFO_GET_DOMAIN_UNION, &die);
> +		break;
> +	/* TODO
> +	 * Implement for all the domains
> +	 */
> +	}
> +
> +	if (size <= 0 || !die)
> +		return 0;
> +
> +	/* populate */
> +	eppic_type_settype(tout, ctype);
> +	eppic_type_setsize(tout, size);
> +	eppic_type_setidx(tout, (ull)(unsigned long)die);
> +	eppic_pushref(tout, 0);
> +	return 1;
>  }
>  
>  static char *
> 



More information about the kexec mailing list