[PATCH v2] makedumpfile: Add support to module data structures
Atsushi Kumagai
kumagai-atsushi at mxc.nes.nec.co.jp
Sun Nov 17 19:51:04 EST 2013
(2013/11/08 14:52), Aruna Balakrishnaiah wrote:
> Current version of makedumpfile/eppic integration patches works only for
> data structures in vmlinux. This patch adds support to module data structures.
>
> Signed-off-by: Aruna Balakrishnaiah <aruna at linux.vnet.ibm.com>
Thanks, I've reviewed this patch.
Acked-by: Atsushi Kumagai <kumagai-atsushi at mxc.nes.nec.co.jp>
--
Atsushi Kumagai
> ---
> Changes from v1:
> Fix return value when failed to set dwarf_debuginfo
>
> erase_info.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> erase_info.h | 10 ++-
> extension_eppic.c | 11 ++--
> extension_eppic.h | 4 +
> 4 files changed, 176 insertions(+), 12 deletions(-)
>
> diff --git a/erase_info.c b/erase_info.c
> index f8f52d6..a789389 100644
> --- a/erase_info.c
> +++ b/erase_info.c
> @@ -27,13 +27,13 @@ struct erase_info *erase_info = NULL;
> unsigned long num_erase_info = 1; /* Node 0 is unused. */
>
> struct call_back eppic_cb = {
> - &get_domain,
> + &get_domain_all,
> &readmem,
> &get_die_attr_type,
> &get_die_name,
> &get_die_offset,
> &get_die_length,
> - &get_die_member,
> + &get_die_member_all,
> &get_die_nfields,
> &get_symbol_addr_all,
> &update_filter_info_raw
> @@ -1950,6 +1950,165 @@ get_symbol_addr_all(char *name) {
> }
>
>
> +/*
> + * Search for domain in modules as well as vmlinux
> + */
> +long
> +get_domain_all(char *symname, int cmd, unsigned long long *die) {
> +
> + short vmlinux_searched = 0;
> + long size = 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")) {
> + size = get_domain(symname, cmd, die);
> + if (size > 0 && die)
> + return size;
> +
> + 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_STRUCTURE;
> + }
> + }
> +
> + size = get_domain(symname, cmd, die);
> + if (size > 0 && die)
> + return size;
> +
> + /* 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;
> + }
> +
> + size = get_domain(symname, cmd, die);
> +
> + if (size <= 0 || !die)
> + continue;
> +
> + /*
> + * Domain found. Set the current_mod to this module index, a
> + * minor optimization for fast lookup next time
> + */
> + mod_st.current_mod = i;
> + return size;
> + }
> +
> + /* Domain not found in any module. Set debuginfo back to vmlinux */
> + set_dwarf_debuginfo("vmlinux", NULL, info->name_vmlinux,
> + info->fd_vmlinux);
> +
> + if (!vmlinux_searched)
> + return get_domain(symname, cmd, die);
> + else
> + return NOT_FOUND_STRUCTURE;
> +}
> +
> +/*
> + * Search for die member in modules as well as vmlinux
> + */
> +int
> +get_die_member_all(unsigned long long die_off, int index, long *offset,
> + char **name, int *nbits, int *fbits, unsigned long long *m_die)
> +{
> + short vmlinux_searched = 0;
> + long size = -1;
> + 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")) {
> + size = get_die_member(die_off, index, offset, name,
> + nbits, fbits, m_die);
> + if (size >= 0)
> + return size;
> +
> + 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 -1;
> + }
> + }
> +
> + size = get_die_member(die_off, index, offset, name,
> + nbits, fbits, m_die);
> + if (size >= 0)
> + return size;
> +
> + /* 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;
> + }
> +
> + size = get_die_member(die_off, index, offset, name,
> + nbits, fbits, m_die);
> +
> + if (size < 0)
> + continue;
> +
> + /*
> + * Die member found. Set the current_mod to this module index,
> + * a minor optimization for fast lookup next time
> + */
> + mod_st.current_mod = i;
> + return size;
> + }
> +
> + /* Die member not found in any module. Set debuginfo back to vmlinux */
> + set_dwarf_debuginfo("vmlinux", NULL, info->name_vmlinux,
> + info->fd_vmlinux);
> +
> + if (!vmlinux_searched)
> + return get_die_member(die_off, index, offset, name,
> + nbits, fbits, m_die);
> + else
> + return -1;
> +}
> +
> /* Process the eppic macro using eppic library */
> static int
> process_eppic_file(char *name_config)
> diff --git a/erase_info.h b/erase_info.h
> index ae740ce..a90fac0 100644
> --- a/erase_info.h
> +++ b/erase_info.h
> @@ -32,9 +32,12 @@ struct erase_info {
> };
>
> unsigned long long get_symbol_addr_all(char *);
> +long get_domain_all(char *, int, unsigned long long *);
> +int get_die_member_all(unsigned long long die_off, int index, long *offset,
> + char **name, int *nbits, int *fbits, unsigned long long *m_die);
>
> struct call_back {
> - long (*get_domain)(char *, int, unsigned long long *);
> + long (*get_domain_all)(char *, int, unsigned long long *);
> int (*readmem)(int type_addr, unsigned long long addr, void *bufptr,
> size_t size);
> int (*get_die_attr_type)(unsigned long long die_off, int *type_flag,
> @@ -42,8 +45,9 @@ struct call_back {
> char * (*get_die_name)(unsigned long long die_off);
> unsigned long long (*get_die_offset)(char *sysname);
> int (*get_die_length)(unsigned long long die_off, int flag);
> - 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_member_all)(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_all)(char *symname);
> int (*update_filter_info_raw)(unsigned long long, int, int);
> diff --git a/extension_eppic.c b/extension_eppic.c
> index d5e5ad0..7e045c9 100644
> --- a/extension_eppic.c
> +++ b/extension_eppic.c
> @@ -236,8 +236,8 @@ apimember(char *mname, ull idx, type_t *tm, member_t *m, ull *last_index)
> index = 0;
>
> while (index < nfields) {
> - size = GET_DIE_MEMBER(die_off, index, &offset, &name, &nbits,
> - &fbits, &m_die);
> + size = GET_DIE_MEMBER_ALL(die_off, index, &offset, &name,
> + &nbits, &fbits, &m_die);
>
> if (size < 0)
> return NULL;
> @@ -272,13 +272,14 @@ apigetctype(int ctype, char *name, type_t *tout)
>
> switch (ctype) {
> case V_TYPEDEF:
> - size = GET_DOMAIN(name, DWARF_INFO_GET_DOMAIN_TYPEDEF, &die);
> + size = GET_DOMAIN_ALL(name, DWARF_INFO_GET_DOMAIN_TYPEDEF,
> + &die);
> break;
> case V_STRUCT:
> - size = GET_DOMAIN(name, DWARF_INFO_GET_DOMAIN_STRUCT, &die);
> + size = GET_DOMAIN_ALL(name, DWARF_INFO_GET_DOMAIN_STRUCT, &die);
> break;
> case V_UNION:
> - size = GET_DOMAIN(name, DWARF_INFO_GET_DOMAIN_UNION, &die);
> + size = GET_DOMAIN_ALL(name, DWARF_INFO_GET_DOMAIN_UNION, &die);
> break;
> /* TODO
> * Implement for all the domains
> diff --git a/extension_eppic.h b/extension_eppic.h
> index caa44dc..42437f2 100644
> --- a/extension_eppic.h
> +++ b/extension_eppic.h
> @@ -81,13 +81,13 @@ do { \
>
> struct call_back *cb;
>
> -#define GET_DOMAIN cb->get_domain
> +#define GET_DOMAIN_ALL cb->get_domain_all
> #define READMEM cb->readmem
> #define GET_DIE_ATTR_TYPE cb->get_die_attr_type
> #define GET_DIE_NAME cb->get_die_name
> #define GET_DIE_OFFSET cb->get_die_offset
> #define GET_DIE_LENGTH cb->get_die_length
> -#define GET_DIE_MEMBER cb->get_die_member
> +#define GET_DIE_MEMBER_ALL cb->get_die_member_all
> #define GET_DIE_NFIELDS cb->get_die_nfields
> #define GET_SYMBOL_ADDR_ALL cb->get_symbol_addr_all
> #define UPDATE_FILTER_INFO_RAW cb->update_filter_info_raw
>
>
>
More information about the kexec
mailing list