This patch enables stack unwind (on ia64) when using a kerntypes
file for a namelist.

When using a kerntypes file, we have just the address of variable unw
and the definition of an unw structure.

As you can see, I didn't change the indentation of the normal code.
Simple to do, but I didn't want to clutter this patch for a first pass.

I tested this against a live 2.6.16 (sles) kernel.
Diffed against crash-4.0-7.6

Signed-off-by: Cliff Wickman <[email protected]>

---
 unwind.c |   34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

Index: crash-4.0-7.6.ia64/unwind.c
===================================================================
--- crash-4.0-7.6.ia64.orig/unwind.c
+++ crash-4.0-7.6.ia64/unwind.c
@@ -1395,10 +1395,43 @@ unwind_init_v2(void)
 unwind_init_v3(void)
 #endif
 {
+       int len;
        struct gnu_request request, *req;
 
        req = &request;
 
+       if (LKCD_KERNTYPES()) {
+               if ((len = STRUCT_SIZE("unw")) == 0) {
+                       error(WARNING,
+                       "cannot determine unw.tables offset; no struct unw\n");
+                       machdep->flags |= UNW_OUT_OF_SYNC;
+                       return;
+               }
+               machdep->machspec->unw_tables_offset =
+                       MEMBER_OFFSET("unw", "tables");
+               if (MEMBER_EXISTS("unw", "r0"))
+                       machdep->flags |= UNW_R0;
+               /*
+                * no verification of save_order, sw_off, preg_index as
+                * we're purely depending on the structure definition.
+                */
+               if (MEMBER_EXISTS("unw", "pt_regs_offsets")) {
+                       machdep->machspec->unw_pt_regs_offsets =
+                               MEMBER_OFFSET("unw", "pt_regs_offsets") -
+                               machdep->machspec->unw_tables_offset;
+                       machdep->machspec->unw_kernel_table_offset =
+                               MEMBER_OFFSET("unw", "kernel_table") -
+                               machdep->machspec->unw_tables_offset;
+                       machdep->flags |= UNW_PTREGS;
+               }
+               if (!load_unw_table(CLEAR_SCRIPT_CACHE)) {
+                       error(WARNING,
+                               "unwind_init: cannot read kernel unw table\n");
+                       machdep->flags |= UNW_OUT_OF_SYNC;
+               }
+               machdep->machspec->unw = (void *)&unw;
+               /* fall to common structure size verifications */
+       } else {
         if (get_symbol_type("unw", "tables", req) == TYPE_CODE_UNDEF) {
                /*
                 *  KLUDGE ALERT:
@@ -1449,6 +1482,7 @@ unwind_init_v3(void)
 
                machdep->machspec->unw = (void *)&unw;
        }
+       }
 
        verify_common_struct("unw_frame_info", sizeof(struct unw_frame_info));
        verify_common_struct("unw_table", sizeof(struct unw_table));

--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to