From 351e249e8f4539d4a6ada46186f195c9a54469f0 Mon Sep 17 00:00:00 2001
From: Laura Abbott <lauraa@codeaurora.org>
Date: Tue, 11 Mar 2014 15:16:08 -0700
Subject: [PATCH] linux-ramdump-parser-v2: Cleanup task dumping

Several of the fields of the task are not being read out as
'true size'. Use more appropriate functions. At the same time,
factor out the reading of pc/fc/sp into a ramdump specific
functionality since that code may be architectur specific.

Change-Id: I5d7bd14031a4431aa665207e8e31e3ecb7dd1cdb
---
 linux-ramdump-parser-v2/parsers/taskdump.py | 55 +++++----------------
 linux-ramdump-parser-v2/ramdump.py          | 15 ++++++
 2 files changed, 26 insertions(+), 44 deletions(-)

diff --git a/linux-ramdump-parser-v2/parsers/taskdump.py b/linux-ramdump-parser-v2/parsers/taskdump.py
index 387c9dc..f00232c 100644
--- a/linux-ramdump-parser-v2/parsers/taskdump.py
+++ b/linux-ramdump-parser-v2/parsers/taskdump.py
@@ -13,43 +13,6 @@ import string
 from print_out import print_out_str
 from parser_util import register_parser, RamParser, cleanupString
 
-cpu_context_save_str = ''.join([
-    'I',  # __u32   r4
-    'I',  # __u32   r5
-    'I',  # __u32   r6
-    'I',  # __u32   r7
-    'I',  # __u32   r8
-    'I',  # __u32   r9
-    'I',  # __u32   sl
-    'I',  # __u32   fp 14
-    'I',  # __u32   sp 15
-    'I',  # __u32   pc 16
-    'II',  # __u32   extra[2]               /* Xscale 'acc' register, etc */
-])
-
-thread_info_str = ''.join([  # struct thread_info {
-    'I',  # flags          /* low level flags */
-    # int                     preempt_count  /* 0 => preemptable, <0 => bug */
-    'I',
-    'I',  # addr_limit     /* address limit */
-    'I',  # task
-    'I',  # exec_domain   /* execution domain */
-    'I',  # 5                 cpu            /* cpu */
-    'I',  # cpu_domain     /* cpu domain */
-    # struct cpu_context_save cpu_context    /* cpu context */
-    cpu_context_save_str,
-    'I',  # syscall        /* syscall number */
-    # unsigned char                    used_cp[16]    /* thread used copro */
-    'I',
-    'I',  # tp_value
-])
-
-thread_info_cpu_idx = 5
-thread_info_fp_idx = 14
-thread_info_sp_idx = 15
-thread_info_pc_idx = 16
-
-
 def find_panic(ramdump, addr_stack, thread_task_name):
     for i in range(addr_stack, addr_stack + 0x2000, 4):
         pc = ramdump.read_word(i)
@@ -79,6 +42,7 @@ def dump_thread_group(ramdump, thread_group, task_out, check_for_panic=0):
     offset_state = ramdump.field_offset('struct task_struct', 'state')
     offset_exit_state = ramdump.field_offset(
         'struct task_struct', 'exit_state')
+    offset_cpu = ramdump.field_offset('struct thread_info', 'cpu')
     orig_thread_group = thread_group
     first = 0
     seen_threads = []
@@ -93,33 +57,36 @@ def dump_thread_group(ramdump, thread_group, task_out, check_for_panic=0):
             ramdump.read_cstring(next_thread_comm, 16))
         if thread_task_name is None:
             return
-        thread_task_pid = ramdump.read_word(next_thread_pid)
+        thread_task_pid = ramdump.read_int(next_thread_pid)
         if thread_task_pid is None:
             return
         task_state = ramdump.read_word(next_thread_state)
         if task_state is None:
             return
-        task_exit_state = ramdump.read_word(next_thread_exit_state)
+        task_exit_state = ramdump.read_int(next_thread_exit_state)
         if task_exit_state is None:
             return
         addr_stack = ramdump.read_word(next_thread_stack)
         if addr_stack is None:
             return
-        threadinfo = ramdump.read_string(addr_stack, thread_info_str)
+        threadinfo = addr_stack
         if threadinfo is None:
             return
         if not check_for_panic:
             if not first:
                 task_out.write('Process: {0}, cpu: {1} pid: {2} start: 0x{3:x}\n'.format(
-                    thread_task_name, threadinfo[thread_info_cpu_idx], thread_task_pid, next_thread_start))
+                    thread_task_name, ramdump.read_int(threadinfo + offset_cpu), thread_task_pid, next_thread_start))
                 task_out.write(
                     '=====================================================\n')
                 first = 1
             task_out.write('    Task name: {0} pid: {1} cpu: {2}\n    state: 0x{3:x} exit_state: 0x{4:x} stack base: 0x{5:x}\n'.format(
-                thread_task_name, thread_task_pid, threadinfo[thread_info_cpu_idx], task_state, task_exit_state, addr_stack))
+                thread_task_name, thread_task_pid, ramdump.read_int(threadinfo + offset_cpu), task_state, task_exit_state, addr_stack))
             task_out.write('    Stack:')
-            ramdump.unwind.unwind_backtrace(threadinfo[thread_info_sp_idx], threadinfo[
-                                            thread_info_fp_idx], threadinfo[thread_info_pc_idx], 0, '    ', task_out)
+            ramdump.unwind.unwind_backtrace(
+                 ramdump.thread_saved_sp(next_thread_start),
+                 ramdump.thread_saved_fp(next_thread_start),
+                 ramdump.thread_saved_pc(next_thread_start),
+                 0, '    ', task_out)
             task_out.write(
                 '=======================================================\n')
         else:
diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py
index ea0904e..aa69be8 100644
--- a/linux-ramdump-parser-v2/ramdump.py
+++ b/linux-ramdump-parser-v2/ramdump.py
@@ -1022,3 +1022,18 @@ class RamDump():
 
     def iter_cpus(self):
         return xrange(self.get_num_cpus())
+
+    def thread_saved_field_common(self, task, reg_offset):
+        thread_info = self.read_word(task + self.field_offset('struct task_struct', 'stack'))
+        cpu_context_offset = self.field_offset('struct thread_info', 'cpu_context')
+        val = self.read_word(thread_info + cpu_context_offset + reg_offset)
+        return val
+
+    def thread_saved_pc(self, task):
+        return self.thread_saved_field_common(task, self.field_offset('struct cpu_context_save', 'pc'))
+
+    def thread_saved_sp(self, task):
+        return self.thread_saved_field_common(task, self.field_offset('struct cpu_context_save', 'sp'))
+
+    def thread_saved_fp(self, task):
+        return self.thread_saved_field_common(task, self.field_offset('struct cpu_context_save', 'fp'))
-- 
GitLab