From eb3a8e76af24fb5f0d05c1f3b20d051401abea09 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" <isaacm@codeaurora.org> Date: Tue, 15 Jan 2019 16:17:58 -0800 Subject: [PATCH] lrdp-v2: Add support for timer_list structs without "data" field As of Linux 4.15, the data field in the timer_list data structure was removed, so update the timer list parsing so that it does not account for that field for kernels 4.15 and above. Change-Id: Id114e842823e747fa8132b7792fa202cbf1685d4 --- linux-ramdump-parser-v2/parsers/timerlist.py | 36 ++++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/linux-ramdump-parser-v2/parsers/timerlist.py b/linux-ramdump-parser-v2/parsers/timerlist.py index 5d6ba3c..3cac971 100644 --- a/linux-ramdump-parser-v2/parsers/timerlist.py +++ b/linux-ramdump-parser-v2/parsers/timerlist.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +# Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 and @@ -23,12 +23,16 @@ class TimerList(RamParser) : self.output = [] major, minor, patch = self.ramdump.kernel_version self.timer_42 = False + self.timer_has_data = True self.timer_jiffies = 'timer_jiffies' self.tvec_base = 'struct tvec_base' self.tvec_bases = 'tvec_bases' self.next_timer = 'next_timer' self.global_deferrable = 'tvec_base_deferrable' + # As of kernel 4.15, timer list structure no longer has data field + if (major, minor) >= (4, 15): + self.timer_has_data = False if (major, minor) >= (4, 9): self.vectors = {'vectors': 512} self.timer_jiffies = 'clk' @@ -49,18 +53,21 @@ class TimerList(RamParser) : remarks = '' function_addr = node + self.ramdump.field_offset('struct timer_list', 'function') expires_addr = node + self.ramdump.field_offset('struct timer_list', 'expires') - data_addr = node + self.ramdump.field_offset('struct timer_list', 'data') try: function = self.ramdump.unwind_lookup(self.ramdump.read_word(function_addr))[0] except TypeError: function = "<dynamic module>" expires = self.ramdump.read_word(expires_addr) - try: - data = hex(self.ramdump.read_word(data_addr)).rstrip('L') - except TypeError: - self.output_file.write("+ Corruption detected at index {0} in {1} list, found corrupted value: {2:x}\n".format(index, type, data_addr)) - return + if self.timer_has_data: + data_addr = node + self.ramdump.field_offset('struct timer_list', 'data') + try: + data = hex(self.ramdump.read_word(data_addr)).rstrip('L') + except TypeError: + self.output_file.write("+ Corruption detected at index {0} in {1} list, found corrupted value: {2:x}\n".format(index, type, data_addr)) + return + else: + data = "" if function == "delayed_work_timer_fn": timer_list_offset = self.ramdump.field_offset('struct delayed_work', 'timer') @@ -68,9 +75,15 @@ class TimerList(RamParser) : func_addr = work_addr + self.ramdump.field_offset('struct work_struct', 'func') try: work_func = self.ramdump.unwind_lookup(self.ramdump.read_word(func_addr))[0] - data += " / " + work_func + if self.timer_has_data: + data += " / " + work_func + else: + data = work_func except TypeError: - data += " / " + hex(self.ramdump.read_word(func_addr)) + "<MODULE>" + if self.timer_has_data: + data += " / " + hex(self.ramdump.read_word(func_addr)) + "<MODULE>" + else: + data = hex(self.ramdump.read_word(func_addr)) + "<MODULE>" if not self.timer_42: timer_base_addr = node + self.ramdump.field_offset( @@ -105,9 +118,12 @@ class TimerList(RamParser) : base) def print_vec(self, type): + headers = ['INDEX', 'TIMER_LIST_ADDR', 'EXPIRES', 'FUNCTION', 'DATA/WORK', 'REMARKS'] + if not self.timer_has_data: + headers[4] = 'WORK' if len(self.output): self.output_file.write("+ {0} Timers ({1})\n\n".format(type, len(self.output))) - self.output_file.write("\t{0:6} {1:18} {2:14} {3:40} {4:52} {5}\n".format('INDEX', 'TIMER_LIST ADDR', 'EXPIRES', 'FUNCTION', 'DATA / WORK', 'REMARKS')) + self.output_file.write("\t{0:6} {1:18} {2:14} {3:40} {4:52} {5}\n".format(headers[0], headers[1], headers[2], headers[3], headers[4], headers[5])) for out in self.output: self.output_file.write(out) self.output_file.write("\n") -- GitLab