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 <ar...@linux.vnet.ibm.com>
---
 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..aeda9dd 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_SYMBOL;
+               }
+       }
+
+       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 NOT_FOUND_SYMBOL;
+               }
+       }
+
+       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


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to