[PATCH] makedumpfile: Add support to module symbols

Atsushi Kumagai kumagai-atsushi at mxc.nes.nec.co.jp
Mon Mar 18 02:29:23 EDT 2013


Hello Aravinda,

On Mon, 11 Mar 2013 13:56:21 +0530
Aravinda Prasad <aravinda at linux.vnet.ibm.com> wrote:

> Current version of makedumpfile/eppic integration patches
> works only for symbols in vmlinux. This patch adds support
> to module symbols.
> 
> I have tested the patch on dynamically linked version of
> makedumpfile with EPPIC_LEGACY_MODE=1. However it should
> work on non-legacy mode also.
> 
> Signed-off-by: Aravinda Prasad <aravinda at linux.vnet.ibm.com>
> Signed-off-by: Mahesh Salgaonkar <mahesh at linux.vnet.ibm.com>

Looks good, applied.


Thanks
Atsushi Kumagai

> ---
>  erase_info.c      |  115 +++++++++++++++++++++++++++++++++++++++++++++++------
>  erase_info.h      |    4 +-
>  extension_eppic.c |    3 +
>  extension_eppic.h |    2 -
>  4 files changed, 109 insertions(+), 15 deletions(-)
> 
> diff --git a/erase_info.c b/erase_info.c
> index 61fe637..2fa8387 100644
> --- a/erase_info.c
> +++ b/erase_info.c
> @@ -35,7 +35,7 @@ struct call_back eppic_cb = {
>  	&get_die_length,
>  	&get_die_member,
>  	&get_die_nfields,
> -	&get_symbol_addr,
> +	&get_symbol_addr_all,
>  	&update_filter_info_raw
>  };
>  
> @@ -161,13 +161,27 @@ get_loaded_module(char *mod_name)
>  	return &modules[mod_st.current_mod];
>  }
>  
> +static unsigned long long
> +find_module_symbol(struct module_info *module_ptr, char *symname)
> +{
> +	int i;
> +	struct symbol_info *sym_info;
> +
> +	sym_info = module_ptr->sym_info;
> +	if (!sym_info)
> +		return FALSE;
> +	for (i = 1; i < module_ptr->num_syms; i++) {
> +		if (sym_info[i].name && !strcmp(sym_info[i].name, symname))
> +			return sym_info[i].value;
> +	}
> +	return NOT_FOUND_SYMBOL;
> +}
> +
>  static int
>  sym_in_module(char *symname, unsigned long long *symbol_addr)
>  {
> -	int i;
>  	char *module_name;
>  	struct module_info *module_ptr;
> -	struct symbol_info *sym_info;
>  
>  	module_name = get_dwarf_module_name();
>  	if (!mod_st.num_modules
> @@ -178,16 +192,11 @@ sym_in_module(char *symname, unsigned long long *symbol_addr)
>  	module_ptr = get_loaded_module(module_name);
>  	if (!module_ptr)
>  		return FALSE;
> -	sym_info = module_ptr->sym_info;
> -	if (!sym_info)
> +	*symbol_addr = find_module_symbol(module_ptr, symname);
> +	if (*symbol_addr == NOT_FOUND_SYMBOL)
>  		return FALSE;
> -	for (i = 1; i < module_ptr->num_syms; i++) {
> -		if (sym_info[i].name && !strcmp(sym_info[i].name, symname)) {
> -			*symbol_addr = sym_info[i].value;
> -			return TRUE;
> -		}
> -	}
> -	return FALSE;
> +	else
> +		return TRUE;
>  }
>  
>  static unsigned int
> @@ -1858,6 +1867,88 @@ process_config_file(const char *name_config)
>  	return TRUE;
>  }
>  
> +/*
> + * Search for symbol in modules as well as vmlinux
> + */
> +unsigned long long
> +get_symbol_addr_all(char *name) {
> +
> +	short vmlinux_searched = 0;
> +	unsigned long long symbol_addr = 0;
> +	unsigned int i, current_mod;
> +	struct module_info *modules;
> +
> +	/* Search in vmlinux if debuginfo is set to vmlinux */
> +	if (!strcmp(get_dwarf_module_name(), "vmlinux")) {
> +		symbol_addr = get_symbol_addr(name);
> +		if (symbol_addr)
> +			return symbol_addr;
> +
> +		vmlinux_searched = 1;
> +	}
> +
> +	/*
> +	 * Proceed the search in modules. Try in the module
> +	 * which resulted in a hit in the previous search
> +	 */
> +
> +	modules = mod_st.modules;
> +	current_mod = mod_st.current_mod;
> +
> +	if (strcmp(get_dwarf_module_name(), modules[current_mod].name)) {
> +		if (!set_dwarf_debuginfo(modules[current_mod].name,
> +				info->system_utsname.release, NULL, -1)) {
> +			ERRMSG("Cannot set to current module %s\n",
> +					modules[current_mod].name);
> +			return NOT_FOUND_SYMBOL;
> +		}
> +	}
> +
> +	symbol_addr = find_module_symbol(&modules[current_mod], name);
> +	if (symbol_addr)
> +		return symbol_addr;
> +
> +	/* Search in all modules */
> +	for (i = 0; i < mod_st.num_modules; i++) {
> +
> +		/* Already searched. Skip */
> +		if (i == current_mod)
> +			continue;
> +
> +		if (!set_dwarf_debuginfo(modules[i].name,
> +				info->system_utsname.release, NULL, -1)) {
> +			ERRMSG("Skipping Module section %s\n", modules[i].name);
> +			continue;
> +		}
> +
> +		symbol_addr = find_module_symbol(&modules[i], name);
> +
> +		if (!symbol_addr)
> +			continue;
> +
> +		/*
> +		 * Symbol found. Set the current_mod to this module index, a
> +		 * minor optimization for fast lookup next time
> +		 */
> +		mod_st.current_mod = i;
> +		return symbol_addr;
> +	}
> +
> +	/* Symbol not found in any module. Set debuginfo back to vmlinux  */
> +	set_dwarf_debuginfo("vmlinux", NULL, info->name_vmlinux,
> +			info->fd_vmlinux);
> +
> +	/*
> +	 * Search vmlinux if not already searched. This can happen when
> +	 * this function is called with debuginfo set to a particular
> +	 * kernel module and we are looking for symbol in vmlinux
> +	 */
> +	if (!vmlinux_searched)
> +		return get_symbol_addr(name);
> +	else
> +		return NOT_FOUND_SYMBOL;
> +}
> +
>  
>  /* Process the eppic macro using eppic library */
>  static int
> diff --git a/erase_info.h b/erase_info.h
> index 1822034..b1a8895 100644
> --- a/erase_info.h
> +++ b/erase_info.h
> @@ -31,6 +31,8 @@ struct erase_info {
>  	int		erased;		/* 1= erased, 0= Not erased */
>  };
>  
> +unsigned long long get_symbol_addr_all(char *);
> +
>  struct call_back {
>      long (*get_domain)(char *, int, unsigned long long *);
>      int (*readmem)(int type_addr, unsigned long long addr, void *bufptr,
> @@ -43,7 +45,7 @@ struct call_back {
>      int (*get_die_member)(unsigned long long die_off, int index, long *offset,
>              char **name, int *nbits, int *fbits, unsigned long long *m_die);
>      int (*get_die_nfields)(unsigned long long die_off);
> -    unsigned long long (*get_symbol_addr)(char *symname);
> +	unsigned long long (*get_symbol_addr_all)(char *symname);
>      int (*update_filter_info_raw)(unsigned long long, int, int);
>  };
>  
> diff --git a/extension_eppic.c b/extension_eppic.c
> index e8591fd..a1981eb 100644
> --- a/extension_eppic.c
> +++ b/extension_eppic.c
> @@ -307,7 +307,8 @@ apigetval(char *name, ull *val, VALUE_S *value)
>  {
>  	ull ptr = 0;
>  
> -	ptr = GET_SYMBOL_ADDR(name);
> +	ptr = GET_SYMBOL_ADDR_ALL(name);
> +
>  	if (!ptr)
>  		return 0;
>  
> diff --git a/extension_eppic.h b/extension_eppic.h
> index 6edc318..caa44dc 100644
> --- a/extension_eppic.h
> +++ b/extension_eppic.h
> @@ -89,7 +89,7 @@ struct call_back *cb;
>  #define GET_DIE_LENGTH cb->get_die_length
>  #define GET_DIE_MEMBER cb->get_die_member
>  #define GET_DIE_NFIELDS cb->get_die_nfields
> -#define GET_SYMBOL_ADDR cb->get_symbol_addr
> +#define GET_SYMBOL_ADDR_ALL cb->get_symbol_addr_all
>  #define UPDATE_FILTER_INFO_RAW cb->update_filter_info_raw
>  
>  #endif /* _EXTENSION_EPPIC_H */
> 



More information about the kexec mailing list