diff --git a/linux-ramdump-parser-v2/mmu.py b/linux-ramdump-parser-v2/mmu.py index 16bc2220d102337991cf16275edf1e9a5a90e933..fe21488621b601e1632fd22dca4804033209c84e 100644 --- a/linux-ramdump-parser-v2/mmu.py +++ b/linux-ramdump-parser-v2/mmu.py @@ -1,4 +1,4 @@ -# Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +# Copyright (c) 2013-2016, 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 @@ -81,7 +81,8 @@ class Armv7MMU(MMU): self.secondary_page_tables = [ [0 for col in range(256)] for row in range(4096)] - msm_ttbr0 = self.ramdump.phys_offset + self.ramdump.swapper_pg_dir_addr + msm_ttbr0 = self.ramdump.kernel_virt_to_phys( + self.ramdump.swapper_pg_dir_addr) self.ttbr = msm_ttbr0 virt_address = 0x0 gb_i = 0 @@ -392,7 +393,8 @@ class Armv7LPAEMMU(MMU): pass def page_table_walk(self, virt): - self.ttbr = self.ramdump.swapper_pg_dir_addr + self.ramdump.phys_offset + self.ttbr = self.ramdump.kernel_virt_to_phys( + self.ramdump.swapper_pg_dir_addr) info = self.translate(virt) return info.phys if info is not None else None @@ -577,7 +579,8 @@ class Armv8MMU(MMU): def page_table_walk(self, virt): - self.ttbr = self.ramdump.swapper_pg_dir_addr + self.ramdump.phys_offset + self.ttbr = self.ramdump.kernel_virt_to_phys( + self.ramdump.swapper_pg_dir_addr) virt_r = Register(virt, zl_index=(47,39), diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py old mode 100755 new mode 100644 index 3030038c8ea297d0b2d10c0538c2b9f325962804..e385f85e718e5f6d66bc2ac05239d160fd92c9a6 --- a/linux-ramdump-parser-v2/ramdump.py +++ b/linux-ramdump-parser-v2/ramdump.py @@ -551,6 +551,7 @@ class RamDump(): '[!!!] Phys offset was set to {0:x}'.format(\ options.phys_offset)) self.phys_offset = options.phys_offset + self.lookup_table = [] self.config = [] self.config_dict = {} @@ -563,21 +564,46 @@ class RamDump(): self.page_offset = options.page_offset self.setup_symbol_tables() + va_bits = 39 + modules_vsize = 0x08000000 + self.va_start = (0xffffffffffffffff << va_bits) \ + & 0xffffffffffffffff + if self.address_of("kasan_init") is None: + self.kasan_shadow_size = 0 + else: + self.kasan_shadow_size = 1 << (va_bits - 3) + + self.kimage_vaddr = self.va_start + self.kasan_shadow_size + \ + modules_vsize + + self.modules_end = self.page_offset + self.kimage_voffset = self.address_of("kimage_voffset") + if self.kimage_voffset is not None: + self.kimage_voffset = self.kimage_vaddr - self.phys_offset + self.modules_end = self.kimage_vaddr + # The address of swapper_pg_dir can be used to determine # whether or not we're running with LPAE enabled since an # extra 4k is needed for LPAE. If it's 0x5000 below # PAGE_OFFSET + TEXT_OFFSET then we know we're using LPAE. For # non-LPAE it should be 0x4000 below PAGE_OFFSET + TEXT_OFFSET - swapper_pg_dir = self.address_of('swapper_pg_dir') - if swapper_pg_dir is None: + self.swapper_pg_dir_addr = self.address_of('swapper_pg_dir') + if self.swapper_pg_dir_addr is None: print_out_str('!!! Could not get the swapper page directory!') print_out_str( '!!! Your vmlinux is probably wrong for these dumps') print_out_str('!!! Exiting now') sys.exit(1) - self.swapper_pg_dir_addr = swapper_pg_dir - self.page_offset - self.kernel_text_offset = self.address_of('stext') - self.page_offset - pg_dir_size = self.kernel_text_offset - self.swapper_pg_dir_addr + + stext = self.address_of('stext') + if self.kimage_voffset is None: + self.kernel_text_offset = stext - self.page_offset + else: + self.kernel_text_offset = stext - self.kimage_vaddr + + pg_dir_size = self.kernel_text_offset + self.page_offset \ + - self.swapper_pg_dir_addr + if self.arm64: print_out_str('Using 64bit MMU') self.mmu = Armv8MMU(self) @@ -633,6 +659,7 @@ class RamDump(): print_out_str( '!!! This is really bad and probably indicates RAM corruption') print_out_str('!!! Some features may be disabled!') + self.unwind = self.Unwinder(self) def __del__(self): @@ -704,11 +731,20 @@ class RamDump(): s = config + '=y' return s in self.config + def kernel_virt_to_phys(self, addr): + va_bits = 39 + if self.kimage_voffset is None: + return addr - self.page_offset + self.phys_offset + else: + if addr & (1 << (va_bits - 1)): + return addr - self.page_offset + self.phys_offset + else: + return addr - (self.kimage_voffset) + def get_version(self): banner_addr = self.address_of('linux_banner') if banner_addr is not None: - # Don't try virt to phys yet, compute manually - banner_addr = banner_addr - self.page_offset + self.phys_offset + banner_addr = self.kernel_virt_to_phys(banner_addr) b = self.read_cstring(banner_addr, 256, False) if b is None: print_out_str('!!! Could not read banner address!') @@ -811,7 +847,9 @@ class RamDump(): ebi_path, ram[1]).encode('ascii', 'ignore')) if self.arm64: startup_script.write('Register.Set NS 1\n'.encode('ascii', 'ignore')) - startup_script.write('Data.Set SPR:0x30201 %Quad 0x{0:x}\n'.format(self.swapper_pg_dir_addr + self.phys_offset).encode('ascii', 'ignore')) + startup_script.write('Data.Set SPR:0x30201 %Quad 0x{0:x}\n'.format( + self.kernel_virt_to_phys(self.swapper_pg_dir_addr)) + .encode('ascii', 'ignore')) if is_cortex_a53: startup_script.write('Data.Set SPR:0x30202 %Quad 0x00000012B5193519\n'.encode('ascii', 'ignore')) @@ -1117,7 +1155,7 @@ class RamDump(): # modules are not supported so just print out an address # instead of a confusing symbol - if (addr < self.page_offset): + if (addr < self.modules_end): return ('(No symbol for address {0:x})'.format(addr), 0x0) low = 0