diff --git a/linux-ramdump-parser-v2/parsers/ddrcompare.py b/linux-ramdump-parser-v2/parsers/ddrcompare.py index 5a4866ffbdd41deb2f398b27a4d12d3cba8aaaf3..61585b498d66173a46447cc6a59f9e9248e0a091 100644 --- a/linux-ramdump-parser-v2/parsers/ddrcompare.py +++ b/linux-ramdump-parser-v2/parsers/ddrcompare.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +# Copyright (c) 2014-2015, 2017, 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 @@ -45,7 +45,7 @@ class DDRCompare(RamParser) : bitcheck = virtual & 0x3 if bitcheck: virtual = virtual - bitcheck - physical = self.ramdump.virt_to_phys(virtual) + physical = self.ramdump.virt_to_phys(virtual + self.ramdump.get_kaslr_offset()) magic = hex(self.ramdump.read_u32(physical, False)).rstrip("L").lstrip("0x").zfill(8) if (m.group(2) != magic): @@ -79,16 +79,17 @@ class DDRCompare(RamParser) : return -1; def validate_task_struct(self, address): - thread_info_address = address + self.ramdump.field_offset('struct task_struct', 'stack'); - thread_info_pointer = self.ramdump.read_word(thread_info_address, True) - - task_address = thread_info_pointer + self.ramdump.field_offset('struct thread_info', 'task'); - task_struct = self.ramdump.read_word(task_address, True) + thread_info_address = self.ramdump.get_thread_info_addr(address) + if self.ramdump.is_thread_info_in_task(): + #Task is no longer found in thread_info + task_struct = address + else: + task_address = thread_info_address + self.ramdump.field_offset('struct thread_info', 'task'); + task_struct = self.ramdump.read_word(task_address, True) - cpu_address = thread_info_pointer + self.ramdump.field_offset('struct thread_info', 'cpu'); - cpu_number = self.ramdump.read_u32(cpu_address, True) + cpu_number = self.ramdump.get_task_cpu(task_struct, thread_info_address) - if((address != task_struct) or (thread_info_pointer == 0x0)): + if((address != task_struct) or (thread_info_address == 0x0)): self.output_file.write(hex(address) + " seems to be corrupted! Please check task_struct and thread_info to find corruptions\n") return -1 diff --git a/linux-ramdump-parser-v2/parsers/ftrace.py b/linux-ramdump-parser-v2/parsers/ftrace.py index 90ea0765a5902adc3b725f580302220c16a12b15..8c92690dec9ca4fe19ea09a36d32c8c28f573b97 100644 --- a/linux-ramdump-parser-v2/parsers/ftrace.py +++ b/linux-ramdump-parser-v2/parsers/ftrace.py @@ -88,8 +88,9 @@ class FtraceParser(RamParser): crashargs = [crashtool] - if self.ramdump.kaslr_offset is not None: - kaslroffset = "--kaslr={0}".format(hex(self.ramdump.kaslr_offset)) + kaslr_offset = self.ramdump.get_kaslr_offset() + if kaslr_offset != 0: + kaslroffset = "--kaslr={0}".format(hex(kaslr_offset)) crashargs.append(kaslroffset) if self.ramdump.kimage_voffset is not None: diff --git a/linux-ramdump-parser-v2/parsers/taskdump.py b/linux-ramdump-parser-v2/parsers/taskdump.py index d81b10c977781abf3fdce731753a1fc25e000cf8..3fce780a392679fc0813241711696c64dd91e37c 100755 --- a/linux-ramdump-parser-v2/parsers/taskdump.py +++ b/linux-ramdump-parser-v2/parsers/taskdump.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2013, 2015 The Linux Foundation. All rights reserved. +# Copyright (c) 2012-2013, 2015, 2017 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 @@ -58,7 +58,6 @@ 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 = [] @@ -69,6 +68,7 @@ def dump_thread_group(ramdump, thread_group, task_out, check_for_panic=0): next_thread_stack = next_thread_start + offset_stack next_thread_state = next_thread_start + offset_state next_thread_exit_state = next_thread_start + offset_exit_state + next_thread_info = ramdump.get_thread_info_addr(next_thread_start) thread_task_name = cleanupString( ramdump.read_cstring(next_thread_comm, 16)) if thread_task_name is None: @@ -85,18 +85,19 @@ def dump_thread_group(ramdump, thread_group, task_out, check_for_panic=0): addr_stack = ramdump.read_word(next_thread_stack) if addr_stack is None: return - threadinfo = addr_stack + threadinfo = next_thread_info if threadinfo is None: return if not check_for_panic: + task_cpu = ramdump.get_task_cpu(next_thread_start, threadinfo) if not first: task_out.write('Process: {0}, cpu: {1} pid: {2} start: 0x{3:x}\n'.format( - thread_task_name, ramdump.read_int(threadinfo + offset_cpu), thread_task_pid, next_thread_start)) + thread_task_name, task_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, ramdump.read_int(threadinfo + offset_cpu), task_state, task_exit_state, addr_stack)) + thread_task_name, thread_task_pid, task_cpu, task_state, task_exit_state, addr_stack)) task_out.write(' Stack:\n') ramdump.unwind.unwind_backtrace( ramdump.thread_saved_sp(next_thread_start), @@ -225,7 +226,6 @@ def dump_thread_group_timestamps(ramdump, thread_group, t): 'struct task_struct', 'thread_group') offset_comm = ramdump.field_offset('struct task_struct', 'comm') offset_pid = ramdump.field_offset('struct task_struct', 'pid') - offset_cpu = ramdump.field_offset('struct thread_info', 'cpu') offset_task = ramdump.field_offset('struct thread_info', 'task') offset_stack = ramdump.field_offset('struct task_struct', 'stack') offset_schedinfo = ramdump.field_offset('struct task_struct', 'sched_info') @@ -246,19 +246,21 @@ def dump_thread_group_timestamps(ramdump, thread_group, t): next_thread_pcount = next_thread_start + offset_last_pcount next_thread_run_delay = next_thread_start + offset_last_rundelay next_thread_stack = next_thread_start + offset_stack + next_thread_info = ramdump.get_thread_info_addr(next_thread_start) addr_stack = ramdump.read_word(next_thread_stack) if addr_stack is None: print_out_str('!!!! Task list corruption\n') return False - threadinfo = addr_stack + threadinfo = next_thread_info thread_task_name = cleanupString( ramdump.read_cstring(next_thread_comm, 16)) thread_task_pid = ramdump.read_int(next_thread_pid) - cpu_no = ramdump.read_int(threadinfo + offset_cpu) - thread_info_task = ramdump.read_word(threadinfo + offset_task) - if next_thread_start != thread_info_task: - print_out_str('!!!! Task list or Thread info corruption\n{0} {1}'.format(next_thread_start,thread_info_task)) - return False + cpu_no = ramdump.get_task_cpu(next_thread_start, threadinfo) + if not ramdump.is_thread_info_in_task(): + thread_info_task = ramdump.read_word(threadinfo + offset_task) + if next_thread_start != thread_info_task: + print_out_str('!!!! Task list or Thread info corruption\n{0} {1}'.format(next_thread_start,thread_info_task)) + return False t[cpu_no].append([thread_task_name, thread_task_pid, ramdump.read_u64(next_thread_last_arrival), ramdump.read_u64(next_thread_last_queued), ramdump.read_u64(next_thread_run_delay),ramdump.read_word(next_thread_pcount)]) diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py index 48778af43af2598658d667c4c3668d1851f90d4f..cbef95da42e3b1c2729425a0abd3571ca586e4f9 100644 --- a/linux-ramdump-parser-v2/ramdump.py +++ b/linux-ramdump-parser-v2/ramdump.py @@ -590,9 +590,8 @@ class RamDump(): self.get_hw_id() if self.kaslr_offset is None: - self.get_kaslr_offset() - if self.kaslr_offset is not None: - self.gdbmi.kaslr_offset = self.kaslr_offset + self.determine_kaslr_offset() + self.gdbmi.kaslr_offset = self.get_kaslr_offset() if options.phys_offset is not None: print_out_str( @@ -624,8 +623,7 @@ class RamDump(): self.kimage_vaddr = self.va_start + self.kasan_shadow_size + \ modules_vsize - if self.kaslr_offset is not None: - self.kimage_vaddr = self.kimage_vaddr + self.kaslr_offset + self.kimage_vaddr = self.kimage_vaddr + self.get_kaslr_offset() self.modules_end = self.page_offset self.kimage_voffset = self.address_of("kimage_voffset") if self.kimage_voffset is not None: @@ -1003,8 +1001,9 @@ class RamDump(): startup_script.write('mmu.scan\n'.encode('ascii', 'ignore')) where = os.path.abspath(self.vmlinux) - if self.kaslr_offset is not None: - where += ' 0x{0:x}'.format(self.kaslr_offset) + kaslr_offset = self.get_kaslr_offset() + if kaslr_offset != 0: + where += ' 0x{0:x}'.format(kaslr_offset) dloadelf = 'data.load.elf {} /nocode\n'.format(where) startup_script.write(dloadelf.encode('ascii', 'ignore')) @@ -1080,13 +1079,16 @@ class RamDump(): return self.read_word(self.tz_addr, False) def get_kaslr_offset(self): - if(self.kaslr_addr is None): + return self.kaslr_offset + + def determine_kaslr_offset(self): + self.kaslr_offset = 0 + if self.kaslr_addr is None: print_out_str('!!!! Kaslr addr is not provided.') else: kaslr_magic = self.read_u32(self.kaslr_addr, False) if kaslr_magic != 0xdead4ead: print_out_str('!!!! Kaslr magic does not match.') - self.kaslr_offset = None else: self.kaslr_offset = self.read_u64(self.kaslr_addr + 4, False) print_out_str("The kaslr_offset extracted is: " + str(hex(self.kaslr_offset))) @@ -1210,10 +1212,7 @@ class RamDump(): def setup_symbol_tables(self): stream = os.popen(self.nm_path + ' -n ' + self.vmlinux) symbols = stream.readlines() - kaslr = 0 - - if self.kaslr_offset is not None: - kaslr = int(self.kaslr_offset) + kaslr = self.get_kaslr_offset() for line in symbols: s = line.split(' ') @@ -1549,8 +1548,28 @@ class RamDump(): """ return xrange(self.get_num_cpus()) + def is_thread_info_in_task(self): + return self.is_config_defined('CONFIG_THREAD_INFO_IN_TASK') + + def get_thread_info_addr(self, task_addr): + if self.is_thread_info_in_task(): + thread_info_address = task_addr + self.field_offset('struct task_struct', 'thread_info') + else: + thread_info_ptr = task_addr + self.field_offset('struct task_struct', 'stack') + thread_info_address = self.read_word(thread_info_ptr, True) + return thread_info_address + + def get_task_cpu(self, task_struct_addr, thread_info_struct_addr): + if self.is_thread_info_in_task(): + offset_cpu = self.field_offset('struct task_struct', 'cpu') + cpu = self.read_int(task_struct_addr + offset_cpu) + else: + offset_cpu = self.field_offset('struct thread_info', 'cpu') + cpu = self.read_int(thread_info_struct_addr + offset_cpu) + return cpu + def thread_saved_field_common_32(self, task, reg_offset): - thread_info = self.read_word(task + self.field_offset('struct task_struct', 'stack')) + thread_info = self.read_word(self.get_thread_info_addr(task)) cpu_context_offset = self.field_offset('struct thread_info', 'cpu_context') val = self.read_word(thread_info + cpu_context_offset + reg_offset) return val