Exemplo n.º 1
0
    def find_mm(self, ramdump):
        thread_addr = None
        offset_comm = ramdump.field_offset('struct task_struct', 'comm')
        for task in ramdump.for_each_process():
            task_name = cleanupString(
                ramdump.read_cstring(task + offset_comm, 16))
            if task_name == 'logd':
                for thread in ramdump.for_each_thread(task):
                    thread_name = cleanupString(
                        ramdump.read_cstring(thread + offset_comm, 16))
                    if thread_name == 'logd.writer':
                        thread_addr = thread
                        break
                break

        if not thread_addr:
            print_out_str("!!!No logd.writer service found !\n")
            return

        mm_addr = ramdump.read_structure_field(thread_addr,
                                               'struct task_struct', 'mm')

        pgd_addr = ramdump.read_structure_field(mm_addr, 'struct mm_struct',
                                                'pgd')

        pgd_addr = ramdump.virt_to_phys(pgd_addr)
        self.mmu = type(ramdump.mmu)(ramdump, pgd_addr)
        self.mm_addr = mm_addr
Exemplo n.º 2
0
    def dump_args(self, ramdump, mm):
        names = (
            ("env_start", "env_end"),
            ("arg_start", "arg_end"),
            ("start_stack", ""),
            ("start_brk", "brk"),
            ("start_data", "end_data"),
            ("mmap_base", ""),
            ("start_code", "end_code"),
        )
        print_out_str("{:10}\t{:8}\t{:8}".format("name", "virt", "phys"))
        print_out_str("----------------------------------")
        for start, end in names:
            if len(end) > 0:
                virt = ramdump.read_structure_field(mm, 'struct mm_struct',
                                                    end)
                phys = self.mmu.virt_to_phys(virt) or 0
                print_out_str("{:10}\t0x{:08x}\t0x{:08x}".format(
                    end, virt, phys))

            if len(start) > 0:
                virt = ramdump.read_structure_field(mm, 'struct mm_struct',
                                                    start)
                phys = self.mmu.virt_to_phys(virt) or 0
                print_out_str("{:10}\t0x{:08x}\t0x{:08x}".format(
                    start, virt, phys))

            print_out_str("----------------------------------")
Exemplo n.º 3
0
 def parse(self):
     if not self.ramdump.is_config_defined('CONFIG_FUNCTION_TRACER') or not self.ramdump.is_config_defined('CONFIG_HAVE_FUNCTION_TRACER'):
         print_out_str ("function tracer is not enabled")
         return
     self.getsrd()
     for core in range(0, self.srd_ncpu):
         self.readtrace(self.srd_r_pa, core)
Exemplo n.º 4
0
    def parse(self):
        if self.ramdump.Is_Dakota():
            regs = DebugImage_v2()
            client_start = 0x87b000e0
            client_end = 0x500
            client_name = "Dump"
            numcpus = self.ramdump.get_num_cpus()
            regs.parse_cpu_ctx(numcpus - 1, client_start, client_end, 1,
                               self.ramdump)
            return

        if self.ramdump.Is_Hawkeye():
            regs = DebugImage_v3()
            client_start = 0x08600658
            client_end = 0x500
            client_name = "Dump"
            regs.parse_cpu_ctx(3, client_start, client_end, 1, self.ramdump)
            return

        # use the mem_dump_data variable to detect if debug image feature was compiled in,
        # and memdump data variable for debug image v2 feature, rather than relying on
        # configuration option.
        if self.ramdump.addr_lookup('mem_dump_data'):
            self.parse_dump()
        elif self.ramdump.addr_lookup('memdump'):
            regs = DebugImage_v2()
            regs.parse_dump_v2(self.ramdump)
        else:
            print_out_str(
                '!!! Debug image was not enabled. No debug dump will be provided'
            )
            return
Exemplo n.º 5
0
    def parse(self):
        self.output_file = self.ramdump.open_file('timerlist.txt')

        self.get_timer_list()

        self.output_file.close()
        print_out_str("--- Wrote the output to timerlist.txt")
Exemplo n.º 6
0
    def parse(self):
        self.output_file = self.ramdump.open_file('thermal_info.txt')

        self.tmdev_data(self.ramdump)

        self.output_file.close()
        print_out_str("--- Wrote the output to thermal_info.txt")
Exemplo n.º 7
0
    def print_regs(self, outfile, ramdump):
        for reg_name, t32_name, print_pc in tzbsp_register_names:
            if print_pc:
                modname = None
                symname = None
                symtab_st_size = None
                offset = None
                a = ramdump.unwind_lookup(self.regs[reg_name])
                if a is not None and len(a) > 3:
                    symname, offset, modname, symtab_st_size = a
                    if (modname is not None and symtab_st_size is not None):
                        pc_string = '[{0}+0x{1:x}/0x{3:x}] <{2}.ko>'.format(
                            symname, offset, modname, symtab_st_size)
                    else:
                        pc_string = '[{0}+0x{1:x}/0x{2:x}]'.format(
                            symname, offset, symtab_st_size)

                elif a is not None:
                    symname, offset, modname = a
                    if (modname is not None):
                        pc_string = '[{0}+0x{1:x}] <{2}.ko>'.format(
                            symname, offset, modname)
                    else:
                        pc_string = '[{0}+0x{1:x}]'.format(symname, offset)
                else:
                    pc_string = ''
            else:
                pc_string = ''
            print_out_str('   {0} = 0x{1:08x} {2}'.format(
                reg_name, self.regs[reg_name], pc_string))
            if t32_name is not None:
                outfile.write('r.s {0} 0x{1:x}\n'.format(
                    t32_name, self.regs[reg_name]))
    def parse(self):
        try:
            crashtool = local_settings.crashtool
        except AttributeError:
            print_out_str("crashtool is missing from local-settings.py")
            crashtool = "crash"

        crashargs = [crashtool]

        kaslr_offset = self.ramdump.get_kaslr_offset()
        if kaslr_offset != 0:
            crashargs.append("--kaslr {0}".format(hex(kaslr_offset)))

        if self.ramdump.kimage_voffset is not None:
            kimagevoff = "kimage_voffset={0}".format(
                    hex(self.ramdump.kimage_voffset).replace('L',''))
            crashargs.append("--machdep {0}".format(kimagevoff))

        crashargs.append(os.path.abspath(self.ramdump.vmlinux))

        dumps = []
        for ram in self.ramdump.ebi_files:
            ebi_path = os.path.abspath(ram[3])
            dumps.append('{0}@0x{1:x}'.format(ebi_path, ram[1]))

        crashargs.append(",".join(dumps))

        with self.ramdump.open_file("launch_crash.sh") as f:
            f.write("#!/bin/sh\n\n")
            f.write(" ".join(crashargs))
            f.write("\n")
            os.chmod(f.name, stat.S_IRWXU)
            print_out_str("Run Crash Utility by exec: '{0}'".format(f.name))
Exemplo n.º 9
0
 def parse(self):
     if not self.ramdump.is_config_defined('CONFIG_SLUB_DEBUG'):
         print_out_str ("slub_debug_on is not enabled")
         return
     slab_out = self.ramdump.open_file('slabsummary.txt')
     self.print_slab_summary(slab_out)
     slab_out.close()
Exemplo n.º 10
0
    def print_dbgui_registers(self, ram_dump):
        if self.dbgui_start is None:
            print_out_str(
                "!!!DBGUI address has not been  set! I can't continue!")
            return

        print_out_str('Now printing DBGUI registers to file')
        dbgui_out = ram_dump.open_file('dbgui.txt')
        for a, b in dbgui_registers.iteritems():
            offset, name = b
            dbgui_out.write('{0} ({1}): {2:x}\n'.format(
                a, name, ram_dump.read_u32(self.dbgui_start + offset, False)))

        addr = ram_dump.read_word(ram_dump.address_of('dbgui_drvdata'))
        addr_offset_offset = ram_dump.field_offset('struct dbgui_drvdata', 'addr_offset')
        data_offset_offset = ram_dump.field_offset('struct dbgui_drvdata', 'data_offset')
        size_offset = ram_dump.field_offset('struct dbgui_drvdata', 'size')
        addr_offset = ram_dump.read_u32(addr + addr_offset_offset, True)
        data_offset = ram_dump.read_u32(addr + data_offset_offset, True)
        size = ram_dump.read_u32(addr + size_offset, True)

        for i in range(0, size):
            dbgui_out.write('ADDR_{0} ({1:x}) : {2:x}\n'.format(
                i, ram_dump.read_u32(self.dbgui_start + addr_offset + (4 * i), False),
                ram_dump.read_u32(self.dbgui_start + data_offset + (4 * i), False)))
        dbgui_out.close()
Exemplo n.º 11
0
    def walk_prev(self, node_addr, func, *args):
        """Walk the linked list starting at `node_addr' previous node and traverse the list in
        reverse order, calling `func' on each node. `func' will be passed the current node and *args,
        if given.

        """
        node_addr = self.ram_dump.read_word(
            node_addr + self.ram_dump.field_offset('struct list_head', 'prev'))
        while True:
            if node_addr == 0:
                break

            funcargs = [node_addr - self.list_elem_offset] + list(args)
            func(*funcargs)

            prev_node_addr = node_addr + self.ram_dump.field_offset(
                'struct list_head', 'prev')
            prev_node = self.ram_dump.read_word(prev_node_addr)

            if prev_node == self.last_node:
                break

            if prev_node in self.seen_nodes:
                print_out_str(
                    '[!] WARNING: Cycle found in attach list. List is corrupted!'
                )
                break
            node_addr = prev_node
            self.seen_nodes.append(node_addr)
Exemplo n.º 12
0
def find_panic(ramdump, addr_stack, thread_task_name):
    if ramdump.arm64:
        stack_size = 0x4000
        increment = 8
    else:
        stack_size = 0x2000
        increment = 4
    for i in range(addr_stack, addr_stack + stack_size, increment):
        if ramdump.arm64:
            pc = ramdump.read_word(i + 8) - 4
            fp = ramdump.read_word(i)
            spx = i + 16
            lr = 0
        else:
            pc = ramdump.read_word(i)
            lr = ramdump.read_word(i + 4)
            spx = i + 4
            fp = 0
        l = ramdump.unwind_lookup(pc)
        if l is not None:
            s, offset = l
            if s == 'panic':
                print_out_str('Faulting process found! Name {0})'.format(thread_task_name))
                ramdump.unwind.unwind_backtrace(spx, fp, pc, lr, '')
                regspanic = ramdump.open_file('regs_panic.cmm')
                if ramdump.arm64:
                    regspanic.write('r.s pc 0x{0:x}\n'.format(pc))
                    regspanic.write('r.s sp 0x{0:x}\n'.format(spx))
                else:
                    regspanic.write('r.s pc 0x{0:x}\n'.format(pc))
                    regspanic.write('r.s r13 0x{0:x}\n'.format(i + 4))
                regspanic.close()
                return True
    return False
Exemplo n.º 13
0
def save_l1_dump(ram_dump, cache_base, size):
    with ram_dump.open_file('l1_cache_dump.bin') as cache_file:

        for i in range(0, size):
            val = ram_dump.read_byte(cache_base + i, False)
            cache_file.write(struct.pack('<B', val))
        print_out_str('--- Wrote cache dump to l1_cache_dump.bin')
Exemplo n.º 14
0
Arquivo: qdss.py Projeto: exl002/mem
    def save_etf_bin(self, ram_dump):
        tmc_etf = ram_dump.open_file('tmc-etf.bin')
        if self.tmc_etf_start is None or self.etf_start is None:
            print_out_str('!!! ETF was not the current sink!')
            tmc_etf.close()
            return

        ctl_offset, ctl_desc = tmc_registers['CTL']
        mode_offset, mode_desc = tmc_registers['MODE']
        rsz_offset, rsz_desc = tmc_registers['RSZ']

        ctl = ram_dump.read_u32(self.tmc_etf_start + ctl_offset, False)
        mode = ram_dump.read_u32(self.tmc_etf_start + mode_offset, False)
        rsz = ram_dump.read_u32(self.tmc_etf_start + rsz_offset, False)
        # rsz is given in words so convert to bytes
        rsz = 4 * rsz

        if (ctl & 0x1) == 1 and (mode == 0):
            for i in range(0, rsz):
                val = ram_dump.read_byte(self.etf_start + i, False)
                tmc_etf.write(struct.pack('<B', val))
        else:
            print_out_str('!!! ETF was not the current sink!')

        tmc_etf.close()
Exemplo n.º 15
0
Arquivo: qdss.py Projeto: exl002/mem
    def print_dbgui_registers(self, ram_dump):
        if self.dbgui_start is None:
            print_out_str(
                "!!!DBGUI address has not been  set! I can't continue!")
            return

        print_out_str('Now printing DBGUI registers to file')
        dbgui_out = ram_dump.open_file('dbgui.txt')
        for a, b in dbgui_registers.iteritems():
            offset, name = b
            dbgui_out.write('{0} ({1}): {2:x}\n'.format(
                a, name, ram_dump.read_u32(self.dbgui_start + offset, False)))

        addr = ram_dump.read_word(ram_dump.address_of('dbgui_drvdata'))
        addr_offset_offset = ram_dump.field_offset('struct dbgui_drvdata',
                                                   'addr_offset')
        data_offset_offset = ram_dump.field_offset('struct dbgui_drvdata',
                                                   'data_offset')
        size_offset = ram_dump.field_offset('struct dbgui_drvdata', 'size')
        addr_offset = ram_dump.read_u32(addr + addr_offset_offset, True)
        data_offset = ram_dump.read_u32(addr + data_offset_offset, True)
        size = ram_dump.read_u32(addr + size_offset, True)

        for i in range(0, size):
            dbgui_out.write('ADDR_{0} ({1:x}) : {2:x}\n'.format(
                i,
                ram_dump.read_u32(self.dbgui_start + addr_offset + (4 * i),
                                  False),
                ram_dump.read_u32(self.dbgui_start + data_offset + (4 * i),
                                  False)))
        dbgui_out.close()
Exemplo n.º 16
0
    def run(self):
        """
            Main
        """

        if self.ramdump.arm64 is None:
            print_out_str('[Caution] this script supports on ARM64')
            return False

        if self.ramdump.wlan == "INTEGRATED":
            print_out_str('self.wlan doen\'t exist, skip')
        else:
            print_out_str('self.wlan exist {}'.format(self.ramdump.wlan))
            self.wlan_path = self.ramdump.wlan

            if self.get_sections_of_wlan() is False:
                print_out_str('wlan.ko is not loaded.')
                return False
            else:
                print_out_str('** Find WLAN Module **')
                self.load_wlan_ko()

        self.get_wmi_command_log_buffer()
        self.get_host_wmi_command_tx_cmp_buf()
        self.get_host_wmi_event_buf()
        self.get_host_wmi_rx_event_buf()
        self.get_host_extract_log()

        return True
Exemplo n.º 17
0
 def set_sym_path(self, sym_path):
     if os.path.isfile(sym_path):
         self.sym_path = sym_path
         return True
     else:
         print_out_str('sym_path: ' + sym_path + ' not valid or file doesn\'t exist')
         return False
Exemplo n.º 18
0
 def print_regs(self, outfile, ramdump):
     if ramdump.arm64:
         register_names = sysdbg_cpu64_register_names[self.version]
     else:
         register_names = sysdbg_cpu32_register_names[self.version]
     for reg_name, t32_name, print_pc in register_names:
         if re.match('(.*)reserved(.*)', reg_name):
             continue
         if print_pc:
             a = ramdump.unwind_lookup(self.regs[reg_name])
             if a is not None:
                 symname, offset = ramdump.unwind_lookup(
                     self.regs[reg_name])
                 pc_string = '[{0}+0x{1:x}]'.format(symname, offset)
             else:
                 pc_string = None
         else:
             pc_string = None
         if pc_string is not None:
             print_out_str('   {0:8} = 0x{1:016x} {2}'.format(
                           reg_name, self.regs[reg_name], pc_string))
         else:
             print_out_str('   {0:8} = 0x{1:016x}'.format(
                           reg_name, self.regs[reg_name]))
         if t32_name is not None:
             if reg_name.startswith('cpu_state_'):
                 continue
             outfile.write(
                 'r.s {0} 0x{1:x}\n'.format(t32_name, self.regs[reg_name]))
Exemplo n.º 19
0
    def walk(self, node_addr, func, *args):
        """Walk the linked list starting at `node_addr', calling `func' on
        each node. `func' will be passed the current node and *args,
        if given.

        """
        if self.is_empty() == True:
            return

        while True:
            if node_addr == 0:
                break

            funcargs = [node_addr - self.list_elem_offset] + list(args)
            func(*funcargs)

            next_node_addr = node_addr + self.ram_dump.field_offset("struct list_head", "next")
            next_node = self.ram_dump.read_word(next_node_addr)

            if next_node == self.last_node:
                break

            if next_node in self.seen_nodes:
                print_out_str("[!] WARNING: Cycle found in attach list. List is corrupted!")
                break
            node_addr = next_node
            self.seen_nodes.append(node_addr)
Exemplo n.º 20
0
 def read_tz_offset(self):
     if self.tz_addr == 0:
         print_out_str(
             'No TZ address was given, cannot read the magic value!')
         return None
     else:
         return self.read_word(self.tz_addr, False)
Exemplo n.º 21
0
    def walk(self, node_addr, func, *args):
        """Walk the linked list starting at `node_addr', calling `func' on
        each node. `func' will be passed the current node and *args,
        if given.

        """
        if self.is_empty() == True:
            return

        while True:
            if node_addr == 0:
                break

            funcargs = [node_addr - self.list_elem_offset] + list(args)
            func(*funcargs)

            next_node_addr = node_addr + self.ram_dump.field_offset(
                'struct list_head', 'next')
            next_node = self.ram_dump.read_word(next_node_addr)

            if next_node == self.last_node:
                break

            if next_node in self.seen_nodes:
                print_out_str(
                    '[!] WARNING: Cycle found in attach list. List is corrupted!'
                )
                break
            node_addr = next_node
            self.seen_nodes.append(node_addr)
Exemplo n.º 22
0
def save_l1_dump(ram_dump, cache_base, size):
    with ram_dump.open_file('l1_cache_dump.bin') as cache_file:

        for i in range(0, size):
            val = ram_dump.read_byte(cache_base + i, False)
            cache_file.write(struct.pack('<B', val))
        print_out_str('--- Wrote cache dump to l1_cache_dump.bin')
Exemplo n.º 23
0
    def save_etf_bin(self, ram_dump):
        tmc_etf = ram_dump.open_file('tmc-etf.bin')
        if self.tmc_etf_start is None or self.etf_start is None:
            print_out_str('!!! ETF was not the current sink!')
            tmc_etf.close()
            return

        ctl_offset, ctl_desc = tmc_registers['CTL']
        mode_offset, mode_desc = tmc_registers['MODE']
        rsz_offset, rsz_desc = tmc_registers['RSZ']

        ctl = ram_dump.read_u32(self.tmc_etf_start + ctl_offset, False)
        mode = ram_dump.read_u32(self.tmc_etf_start + mode_offset, False)
        rsz = ram_dump.read_u32(self.tmc_etf_start + rsz_offset, False)
        # rsz is given in words so convert to bytes
        rsz = 4 * rsz

        if (ctl & 0x1) == 1 and (mode == 0):
            for i in range(0, rsz):
                val = ram_dump.read_byte(self.etf_start + i, False)
                tmc_etf.write(struct.pack('<B', val))
        else:
            print_out_str('!!! ETF was not the current sink!')

        tmc_etf.close()
Exemplo n.º 24
0
    def parse(self):
        self.output_file = self.ramdump.open_file('thermal_info.txt')

        self.tmdev_data(self.ramdump)

        self.output_file.close()
        print_out_str("--- Wrote the output to thermal_info.txt")
Exemplo n.º 25
0
        def unwind_frame_tables(self, frame, trace=False):
            low = frame.sp
            high = ((low + (self.ramdump.thread_size - 1)) & \
                ~(self.ramdump.thread_size - 1)) + self.ramdump.thread_size
            idx = self.search_idx(frame.pc)

            if (idx is None):
                if trace:
                    print_out_str("can't find %x" % frame.pc)
                return -1

            ctrl = self.UnwindCtrlBlock()
            ctrl.vrs[FP] = frame.fp
            ctrl.vrs[SP] = frame.sp
            ctrl.vrs[LR] = frame.lr
            ctrl.vrs[PC] = 0

            if (idx[1] == 1):
                return -1

            elif ((idx[1] & 0x80000000) == 0):
                ctrl.insn = self.prel31_to_addr(idx[2] + 4)

            elif (idx[1] & 0xff000000) == 0x80000000:
                ctrl.insn = idx[2] + 4
            else:
                print_out_str('not supported')
                return -1

            val = self.ramdump.read_word(ctrl.insn)

            if ((val & 0xff000000) == 0x80000000):
                ctrl.byte = 2
                ctrl.entries = 1
            elif ((val & 0xff000000) == 0x81000000):
                ctrl.byte = 1
                ctrl.entries = 1 + ((val & 0x00ff0000) >> 16)
            else:
                return -1

            while (ctrl.entries > 0):
                urc = self.unwind_exec_insn(ctrl, trace)
                if (urc < 0):
                    return urc
                if (ctrl.vrs[SP] < low or ctrl.vrs[SP] >= high):
                    return -1

            if (ctrl.vrs[PC] == 0):
                ctrl.vrs[PC] = ctrl.vrs[LR]

            # check for infinite loop */
            if (frame.pc == ctrl.vrs[PC]):
                return -1

            frame.fp = ctrl.vrs[FP]
            frame.sp = ctrl.vrs[SP]
            frame.lr = ctrl.vrs[LR]
            frame.pc = ctrl.vrs[PC]

            return 0
Exemplo n.º 26
0
    def walk_prev(self, node_addr, func, *args):
        """Walk the linked list starting at `node_addr' previous node and traverse the list in
        reverse order, calling `func' on each node. `func' will be passed the current node and *args,
        if given.

        """
        node_addr = self.ram_dump.read_word(node_addr + self.ram_dump.field_offset('struct list_head', 'prev'))
        while True:
            if node_addr == 0:
                break

            funcargs = [node_addr - self.list_elem_offset] + list(args)
            func(*funcargs)

            prev_node_addr = node_addr + self.ram_dump.field_offset('struct list_head', 'prev')
            prev_node = self.ram_dump.read_word(prev_node_addr)

            if prev_node == self.last_node:
                break

            if prev_node in self.seen_nodes:
                print_out_str(
                   '[!] WARNING: Cycle found in attach list. List is corrupted!')
                break
            node_addr = prev_node
            self.seen_nodes.append(node_addr)
Exemplo n.º 27
0
    def walk_workers(self, worker_addr, state):
        worker_task_offset = self.ramdump.field_offset('struct worker', 'task')
        offset_comm = self.ramdump.field_offset('struct task_struct', 'comm')
        current_work_offset = self.ramdump.field_offset(
            'struct worker', 'current_work')
        work_func_offset = self.ramdump.field_offset('struct work_struct', 'func')

        worker_task_addr = self.ramdump.read_word(
                                 worker_addr + worker_task_offset)

        taskname = self.ramdump.read_cstring(
                                 worker_task_addr + offset_comm, 16)
        current_work_addr = self.ramdump.read_word(
                                 worker_addr + current_work_offset)
        try:
            phys = self.ramdump.virt_to_phys(current_work_func)
            current_work_func = self.ramdump.read_word(
                                     current_work_addr + work_func_offset)
            wname = self.ramdump.unwind_lookup(current_work_func)
            if wname is not None:
                worker_name, a = wname
            else:
                worker_name = 'Worker at 0x{0:x}'.format(
                                    current_work_func)
        except:
            worker_name = '(None)'

        print_out_str(
            '{2} Workqueue worker: {0} current_work: {1}'.format(taskname, worker_name, state))
Exemplo n.º 28
0
def find_panic(ramdump, addr_stack, thread_task_name):
    if ramdump.arm64:
        stack_size = 0x4000
        increment = 8
    else:
        stack_size = 0x2000
        increment = 4
    for i in range(addr_stack, addr_stack + stack_size, increment):
        if ramdump.arm64:
            pc = ramdump.read_word(i + 8) - 4
            fp = ramdump.read_word(i)
            spx = i + 16
            lr = 0
        else:
            pc = ramdump.read_word(i)
            lr = ramdump.read_word(i + 4)
            spx = i + 4
            fp = 0
        l = ramdump.unwind_lookup(pc)
        if l is not None:
            s, offset = l
            if s == 'panic':
                print_out_str('Faulting process found! Name {0})'.format(
                    thread_task_name))
                ramdump.unwind.unwind_backtrace(spx, fp, pc, lr, '')
                regspanic = ramdump.open_file('regs_panic.cmm')
                if ramdump.arm64:
                    regspanic.write('r.s pc 0x{0:x}\n'.format(pc))
                    regspanic.write('r.s sp 0x{0:x}\n'.format(spx))
                else:
                    regspanic.write('r.s pc 0x{0:x}\n'.format(pc))
                    regspanic.write('r.s r13 0x{0:x}\n'.format(i + 4))
                regspanic.close()
                return True
    return False
Exemplo n.º 29
0
 def read_tz_offset(self):
     if self.tz_addr == 0:
         print_out_str(
             'No TZ address was given, cannot read the magic value!')
         return None
     else:
         return self.read_word(self.tz_addr, False)
Exemplo n.º 30
0
    def parse(self):
        self.output_file = self.ramdump.open_file('timerlist.txt')

        self.get_timer_list()

        self.output_file.close()
        print_out_str("--- Wrote the output to timerlist.txt")
Exemplo n.º 31
0
        def unwind_backtrace(self, sp, fp, pc, lr, extra_str='',
                             out_file=None):
            offset = 0
            frame = self.Stackframe(fp, sp, lr, pc)
            frame.fp = fp
            frame.sp = sp
            frame.lr = lr
            frame.pc = pc

            while True:
                where = frame.pc
                offset = 0

                if frame.pc is None:
                    break

                r = self.ramdump.unwind_lookup(frame.pc)
                if r is None:
                    symname = 'UNKNOWN'
                    offset = 0x0
                else:
                    symname, offset = r
                pstring = (
                    extra_str + '[<{0:x}>] {1}+0x{2:x}'.format(frame.pc, symname, offset))
                if out_file:
                    out_file.write(pstring + '\n')
                else:
                    print_out_str(pstring)

                urc = self.unwind_frame(frame)
                if urc < 0:
                    break
Exemplo n.º 32
0
        def unwind_frame_tables(self, frame, trace=False):
            low = frame.sp
            high = ((low + (self.ramdump.thread_size - 1)) & \
                ~(self.ramdump.thread_size - 1)) + self.ramdump.thread_size
            idx = self.search_idx(frame.pc)

            if (idx is None):
                if trace:
                    print_out_str("can't find %x" % frame.pc)
                return -1

            ctrl = self.UnwindCtrlBlock()
            ctrl.vrs[FP] = frame.fp
            ctrl.vrs[SP] = frame.sp
            ctrl.vrs[LR] = frame.lr
            ctrl.vrs[PC] = 0

            if (idx[1] == 1):
                return -1

            elif ((idx[1] & 0x80000000) == 0):
                ctrl.insn = self.prel31_to_addr(idx[2] + 4)

            elif (idx[1] & 0xff000000) == 0x80000000:
                ctrl.insn = idx[2] + 4
            else:
                print_out_str('not supported')
                return -1

            val = self.ramdump.read_word(ctrl.insn)

            if ((val & 0xff000000) == 0x80000000):
                ctrl.byte = 2
                ctrl.entries = 1
            elif ((val & 0xff000000) == 0x81000000):
                ctrl.byte = 1
                ctrl.entries = 1 + ((val & 0x00ff0000) >> 16)
            else:
                return -1

            while (ctrl.entries > 0):
                urc = self.unwind_exec_insn(ctrl, trace)
                if (urc < 0):
                    return urc
                if (ctrl.vrs[SP] < low or ctrl.vrs[SP] >= high):
                    return -1

            if (ctrl.vrs[PC] == 0):
                ctrl.vrs[PC] = ctrl.vrs[LR]

            # check for infinite loop */
            if (frame.pc == ctrl.vrs[PC]):
                return -1

            frame.fp = ctrl.vrs[FP]
            frame.sp = ctrl.vrs[SP]
            frame.lr = ctrl.vrs[LR]
            frame.pc = ctrl.vrs[PC]

            return 0
Exemplo n.º 33
0
 def read_string(self,
                 address,
                 format_string,
                 virtual=True,
                 trace=False,
                 cpu=None):
     addr = address
     per_cpu_string = ''
     if virtual:
         if cpu is not None:
             pcpu_offset = self.per_cpu_offset(cpu)
             address += pcpu_offset
             per_cpu_string = ' with per-cpu offset of ' + hex(pcpu_offset)
         addr = self.virt_to_phys(address)
     if trace:
         if addr is not None:
             print_out_str('reading from phys {0:x}{1}'.format(
                 addr, per_cpu_string))
     s = self.read_physical(addr, struct.calcsize(format_string), trace)
     if (s is None) or (s == ''):
         if trace and addr is not None:
             print_out_str(
                 'address {0:x} failed hard core (v {1} t{2})'.format(
                     addr, virtual, trace))
         return None
     return struct.unpack(format_string, s)
Exemplo n.º 34
0
    def walk_workers(self, worker_addr, state):
        worker_task_offset = self.ramdump.field_offset('struct worker', 'task')
        offset_comm = self.ramdump.field_offset('struct task_struct', 'comm')
        current_work_offset = self.ramdump.field_offset(
            'struct worker', 'current_work')
        work_func_offset = self.ramdump.field_offset('struct work_struct', 'func')

        worker_task_addr = self.ramdump.read_word(
                                 worker_addr + worker_task_offset)

        taskname = self.ramdump.read_cstring(
                                 worker_task_addr + offset_comm, 16)
        current_work_addr = self.ramdump.read_word(
                                 worker_addr + current_work_offset)
        try:
            phys = self.ramdump.virt_to_phys(current_work_func)
            current_work_func = self.ramdump.read_word(
                                     current_work_addr + work_func_offset)
            wname = self.ramdump.unwind_lookup(current_work_func)
            if wname is not None:
                worker_name, a = wname
            else:
                worker_name = 'Worker at 0x{0:x}'.format(
                                    current_work_func)
        except:
            worker_name = '(None)'

        print_out_str(
            '{2} Workqueue worker: {0} current_work: {1}'.format(taskname, worker_name, state))
Exemplo n.º 35
0
def parse_long_form_tables(dump, d):
    fname = 'msm_iommu_domain_%02d.txt' % (d.domain_num)
    with dump.open_file(fname) as outfile:

        print_out_str('LPAE Iommu page tables: ' + fname)

        t0sz = 0
        mmu = Armv7LPAEMMU(dump, d.pg_table, t0sz, virt_for_fl=True)

        redirect = 'OFF'
        if d.redirect is None:
            redirect = 'UNKNOWN'
        elif d.redirect > 0:
            redirect = 'ON'
        iommu_context = ' '.join('%s (%s)' % (name, num)
                                 for (name, num) in d.ctx_list)
        iommu_context = iommu_context or 'None attached'

        outfile.write(
            'IOMMU Context: %s. Domain: %s (%d) [L2 cache redirect for page tables is %s]\n'
            % (iommu_context, d.client_name, d.domain_num, redirect))
        outfile.write(
            '[VA Start -- VA End  ] [Size      ] [PA Start   -- PA End  ] [Attributes][Page Table Entry Size]\n'
        )
        if d.pg_table == 0:
            outfile.write('No Page Table Found. (Probably a secure domain)\n')
        else:
            mappings = get_flat_mappings(d, mmu)
            print_lpae_mappings(get_coalesced_mappings(mappings), outfile)
            outfile.write('\n-------------\nRAW Dump\n')
            outfile.write('Raw: ' + str(d) + '\n')
            print_lpae_mappings(mappings, outfile)
Exemplo n.º 36
0
def parse_long_form_tables(dump, d):
    fname = 'msm_iommu_domain_%02d.txt' % (d.domain_num)
    with dump.open_file(fname) as outfile:

        print_out_str('LPAE Iommu page tables: ' + fname)

        t0sz = 0
        mmu = Armv7LPAEMMU(dump, d.pg_table, t0sz, virt_for_fl=True)

        redirect = 'OFF'
        if d.redirect is None:
            redirect = 'UNKNOWN'
        elif d.redirect > 0:
            redirect = 'ON'
        iommu_context = ' '.join('%s (%s)' % (name, num)
                                 for (name, num) in d.ctx_list)
        iommu_context = iommu_context or 'None attached'

        outfile.write('IOMMU Context: %s. Domain: %s (%d) [L2 cache redirect for page tables is %s]\n' % (
            iommu_context, d.client_name, d.domain_num, redirect))
        outfile.write(
            '[VA Start -- VA End  ] [Size      ] [PA Start   -- PA End  ] [Attributes][Page Table Entry Size]\n')
        if d.pg_table == 0:
            outfile.write(
                'No Page Table Found. (Probably a secure domain)\n')
        else:
            mappings = get_flat_mappings(d, mmu)
            print_lpae_mappings(get_coalesced_mappings(mappings), outfile)
            outfile.write('\n-------------\nRAW Dump\n')
            outfile.write('Raw: ' + str(d) + '\n')
            print_lpae_mappings(mappings, outfile)
Exemplo n.º 37
0
 def parse(self):
     self.output_file = self.ramdump.open_file('cpr3_info.txt')
     self.get_cpr()
     self.get_kryo()
     for i in self.output:
         self.output_file.write(i)
     print_out_str("--- Wrote the output to cpr3_info.txt")
     self.output_file.close()
Exemplo n.º 38
0
    def parse(self):
        saved_config = self.ramdump.open_file('kconfig.txt')

        for l in self.ramdump.config:
            saved_config.write(l + '\n')

        saved_config.close()
        print_out_str('---wrote saved kernel config to kconfig.txt')
Exemplo n.º 39
0
        def walk_stackframe_generic(self, frame):
            while True:
                symname = self.ramdump.addr_to_symbol(frame.pc)
                print_out_str(symname)

                ret = self.unwind_frame_generic(frame)
                if ret < 0:
                    break
Exemplo n.º 40
0
 def parse(self):
     self.output_file = self.ramdump.open_file('cpr3_info.txt')
     self.get_cpr()
     self.get_kryo()
     for i in self.output:
         self.output_file.write(i)
     print_out_str("--- Wrote the output to cpr3_info.txt")
     self.output_file.close()
Exemplo n.º 41
0
    def parse(self):
        self.output_file = self.ramdump.open_file('DDRCacheCompare.txt')

        self.compare_magic()
        self.corruptionchecker()

        self.output_file.close()
        print_out_str("--- Wrote the output to DDRCacheCompare.txt")
Exemplo n.º 42
0
    def parse(self):
        self.output_file = self.ramdump.open_file('DDRCacheCompare.txt')

        self.compare_magic()
        self.corruptionchecker()

        self.output_file.close()
        print_out_str("--- Wrote the output to DDRCacheCompare.txt")
Exemplo n.º 43
0
        def walk_stackframe_generic(self, frame):
            while True:
                symname = self.ramdump.addr_to_symbol(frame.pc)
                print_out_str(symname)

                ret = self.unwind_frame_generic(frame)
                if ret < 0:
                    break
Exemplo n.º 44
0
 def read_u16(self, address, virtual=True, trace=False, cpu=None):
     if trace:
         print_out_str('reading {0:x}'.format(address))
     s = self.read_string(address, '<H', virtual, trace, cpu)
     if s is None:
         return None
     else:
         return s[0]
Exemplo n.º 45
0
 def read_u16(self, address, virtual=True, trace=False, cpu=None):
     if trace:
         print_out_str('reading {0:x}'.format(address))
     s = self.read_string(address, '<H', virtual, trace, cpu)
     if s is None:
         return None
     else:
         return s[0]
Exemplo n.º 46
0
    def parse(self):
        if not self.ramdump.is_config_defined("CONFIG_MSM_CACHE_DUMP"):
            print_out_str("!!! Cache dumping was not enabled. No cache will be dumped")
            return

        cache_base_addr = self.ramdump.address_of("l2_dump")
        cache_base = self.ramdump.read_word(cache_base_addr)

        parse_cache_dump(self.ramdump, cache_base)
Exemplo n.º 47
0
    def print_irq_state_sparse_irq(self, ram_dump):
        h_irq_offset = ram_dump.field_offset('struct irq_desc', 'handle_irq')
        irq_num_offset = ram_dump.field_offset('struct irq_data', 'irq')
        irq_data_offset = ram_dump.field_offset('struct irq_desc', 'irq_data')
        irq_count_offset = ram_dump.field_offset('struct irq_desc',
                                                 'irq_count')
        irq_chip_offset = ram_dump.field_offset('struct irq_data', 'chip')
        irq_action_offset = ram_dump.field_offset('struct irq_desc', 'action')
        action_name_offset = ram_dump.field_offset('struct irqaction', 'name')
        kstat_irqs_offset = ram_dump.field_offset('struct irq_desc',
                                                  'kstat_irqs')
        chip_name_offset = ram_dump.field_offset('struct irq_chip', 'name')
        cpu_str = ''

        irq_desc_tree = ram_dump.address_of('irq_desc_tree')
        nr_irqs = ram_dump.read_int(ram_dump.address_of('nr_irqs'))

        for i in ram_dump.iter_cpus():
            cpu_str = cpu_str + '{0:10} '.format('CPU{0}'.format(i))

        print_out_str('{0:4} {1} {2:30} {3:15} {4:20}'.format(
            'IRQ', cpu_str, 'Name', 'Chip', 'IRQ Structure'))

        if nr_irqs > 50000:
            return

        for i in range(0, nr_irqs):
            irq_desc = self.radix_tree_lookup_element(ram_dump, irq_desc_tree,
                                                      i)
            if irq_desc is None:
                continue
            irqnum = ram_dump.read_int(irq_desc + irq_data_offset +
                                       irq_num_offset)
            irqcount = ram_dump.read_int(irq_desc + irq_count_offset)
            action = ram_dump.read_word(irq_desc + irq_action_offset)
            kstat_irqs_addr = ram_dump.read_word(irq_desc + kstat_irqs_offset)
            irq_stats_str = ''

            if kstat_irqs_addr is None:
                break

            for j in ram_dump.iter_cpus():
                irq_statsn = ram_dump.read_int(kstat_irqs_addr, cpu=j)
                irq_stats_str = irq_stats_str + \
                    '{0:10} '.format('{0}'.format(irq_statsn))

            chip = ram_dump.read_word(irq_desc + irq_data_offset +
                                      irq_chip_offset)
            chip_name_addr = ram_dump.read_word(chip + chip_name_offset)
            chip_name = ram_dump.read_cstring(chip_name_addr, 48)

            if action != 0:
                name_addr = ram_dump.read_word(action + action_name_offset)
                name = ram_dump.read_cstring(name_addr, 48)
                print_out_str(
                    '{0:4} {1} {2:30} {3:15} v.v (struct irq_desc *)0x{4:<20x}'
                    .format(irqnum, irq_stats_str, name, chip_name, irq_desc))
Exemplo n.º 48
0
    def parse(self) :
        out_path = self.ramdump.outdir
        saved_config = open(out_path+"/kconfig.txt","wb")

        for l in self.ramdump.config :
            saved_config.write(l+"\n")

        saved_config.close()
        print_out_str("---wrote saved kernel config to {0}/kconfig.txt".format(out_path))
Exemplo n.º 49
0
    def auto_parse(self, file_path):
        first_mem_path = None

        for f in first_mem_file_names:
            test_path = file_path + '/' + f
            if os.path.exists(test_path):
                first_mem_path = test_path
                break

        if first_mem_path is None:
            print_out_str('!!! Could not open a memory file. I give up')
            sys.exit(1)

        first_mem = open(first_mem_path, 'rb')
        # put some dummy data in for now
        self.ebi_files = [(first_mem, 0, 0xffff0000, first_mem_path)]
        if not self.get_hw_id(add_offset=False):
            return False

        base_addr = self.get_ddr_base_addr(file_path)
        if base_addr is not None:
            self.ebi_start = base_addr
            self.phys_offset = base_addr
        else:
            print_out_str('!!! WARNING !!! Using Static DDR Base Addresses.')

        first_mem_end = self.ebi_start + os.path.getsize(first_mem_path) - 1
        self.ebi_files = [
            (first_mem, self.ebi_start, first_mem_end, first_mem_path)]
        print_out_str(
            'Adding {0} {1:x}--{2:x}'.format(first_mem_path, self.ebi_start, first_mem_end))
        self.ebi_start = self.ebi_start + os.path.getsize(first_mem_path)

        for f in extra_mem_file_names:
            extra_path = file_path + '/' + f

            if os.path.exists(extra_path):
                extra = open(extra_path, 'rb')
                extra_start = self.ebi_start
                extra_end = extra_start + os.path.getsize(extra_path) - 1
                self.ebi_start = extra_end + 1
                print_out_str(
                    'Adding {0} {1:x}--{2:x}'.format(extra_path, extra_start, extra_end))
                self.ebi_files.append(
                    (extra, extra_start, extra_end, extra_path))

        if self.imem_fname is not None:
            imemc_path = file_path + '/' + self.imem_fname
            if os.path.exists(imemc_path):
                imemc = open(imemc_path, 'rb')
                imemc_start = self.tz_start
                imemc_end = imemc_start + os.path.getsize(imemc_path) - 1
                print_out_str(
                    'Adding {0} {1:x}--{2:x}'.format(imemc_path, imemc_start, imemc_end))
                self.ebi_files.append(
                    (imemc, imemc_start, imemc_end, imemc_path))
        return True
Exemplo n.º 50
0
 def wait_for_completion_timeout(self, task, timeout):
     delay = 2.0
     #while the process is still executing and we haven't timed-out yet
     while task.poll() is None and timeout > 0:
         time.sleep(delay)
         timeout -= delay
     if timeout <= 0:
         print_out_str("QTF command timed out")
         task.kill()
Exemplo n.º 51
0
    def parse(self):
        if not self.ramdump.is_config_defined('CONFIG_MSM_CACHE_DUMP'):
            print_out_str(
                '!!! Cache dumping was not enabled. No cache will be dumped')
            return

        cache_base_addr = self.ramdump.addr_lookup('l2_dump')
        cache_base = self.ramdump.read_word(cache_base_addr)

        parse_cache_dump(self.ramdump, cache_base)
Exemplo n.º 52
0
 def open_file(self, file_name, mode='wb'):
     file_path = os.path.join(self.outdir, file_name)
     f = None
     try:
         f = open(file_path, mode)
     except:
         print_out_str('Could not open path {0}'.format(file_path))
         print_out_str('Do you have write/read permissions on the path?')
         sys.exit(1)
     return f
Exemplo n.º 53
0
    def parse_qdss_common(self, start, end, client_id, ram_dump):
        client_name = self.dump_data_id_lookup_table[client_id]

        print_out_str(
            'Parsing {0} context start {1:x} end {2:x}'.format(client_name, start, end))

        if client_id == client.MSM_DUMP_DATA_TMC_ETF_REG:
            setattr(self.qdss, 'tmc_etf_start', start)
        else:
            setattr(self.qdss, qdss_tag_to_field_name[client_name], start)
Exemplo n.º 54
0
    def parse(self):
        self.output_file = self.ramdump.open_file('ClockDumps.txt')

        self.get_clocks()
        self.printclocks('CLOCKS')
        self.get_clk_providers()
        self.printclocks('CLK_PROVIDERS')

        self.output_file.close()
        print_out_str("--- Wrote the output to ClockDumps.txt")
Exemplo n.º 55
0
    def print_irq_state_sparse_irq(self, ram_dump):
        h_irq_offset = ram_dump.field_offset('struct irq_desc', 'handle_irq')
        irq_num_offset = ram_dump.field_offset('struct irq_data', 'irq')
        irq_data_offset = ram_dump.field_offset('struct irq_desc', 'irq_data')
        irq_count_offset = ram_dump.field_offset(
            'struct irq_desc', 'irq_count')
        irq_chip_offset = ram_dump.field_offset('struct irq_data', 'chip')
        irq_action_offset = ram_dump.field_offset('struct irq_desc', 'action')
        action_name_offset = ram_dump.field_offset('struct irqaction', 'name')
        kstat_irqs_offset = ram_dump.field_offset(
            'struct irq_desc', 'kstat_irqs')
        chip_name_offset = ram_dump.field_offset('struct irq_chip', 'name')
        cpu_str = ''

        irq_desc_tree = ram_dump.address_of('irq_desc_tree')
        nr_irqs = ram_dump.read_int(ram_dump.address_of('nr_irqs'))

        for i in ram_dump.iter_cpus():
            cpu_str = cpu_str + '{0:10} '.format('CPU{0}'.format(i))

        print_out_str(
            '{0:4} {1} {2:30} {3:15} {4:20}'.format('IRQ', cpu_str, 'Name', 'Chip', 'IRQ Structure'))

        if nr_irqs > 50000:
            return

        for i in range(0, nr_irqs):
            irq_desc = self.radix_tree_lookup_element(
                ram_dump, irq_desc_tree, i)
            if irq_desc is None:
                continue
            irqnum = ram_dump.read_int(irq_desc + irq_data_offset + irq_num_offset)
            irqcount = ram_dump.read_int(irq_desc + irq_count_offset)
            action = ram_dump.read_word(irq_desc + irq_action_offset)
            kstat_irqs_addr = ram_dump.read_word(irq_desc + kstat_irqs_offset)
            irq_stats_str = ''

            if kstat_irqs_addr is None:
                break

            for j in ram_dump.iter_cpus():
                irq_statsn = ram_dump.read_int(kstat_irqs_addr, cpu=j)
                irq_stats_str = irq_stats_str + \
                    '{0:10} '.format('{0}'.format(irq_statsn))

            chip = ram_dump.read_word(
                irq_desc + irq_data_offset + irq_chip_offset)
            chip_name_addr = ram_dump.read_word(chip + chip_name_offset)
            chip_name = ram_dump.read_cstring(chip_name_addr, 48)

            if action != 0:
                name_addr = ram_dump.read_word(action + action_name_offset)
                name = ram_dump.read_cstring(name_addr, 48)
                print_out_str(
                    '{0:4} {1} {2:30} {3:15} v.v (struct irq_desc *)0x{4:<20x}'.format(irqnum, irq_stats_str, name, chip_name, irq_desc))
Exemplo n.º 56
0
 def read_word(self, address, virtual=True, trace=False, cpu=None):
     if trace:
         print_out_str('reading {0:x}'.format(address))
     if self.arm64:
         s = self.read_string(address, '<Q', virtual, trace, cpu)
     else:
         s = self.read_string(address, '<I', virtual, trace, cpu)
     if s is None:
         return None
     else:
         return s[0]
Exemplo n.º 57
0
    def parse_vsens(self, version, start, end, client_id, ram_dump):
        client_name = self.dump_data_id_lookup_table[client_id]

        print_out_str(
            'Parsing {0} context start {1:x} end {2:x}'.format(client_name, start, end))

        regs = VsensData()
        if regs.init_dump_regs(start, end, ram_dump) is False:
            print_out_str('!!! Could not get registers from Vsens Dump')
            return
        regs.print_vsens_regs(ram_dump)
Exemplo n.º 58
0
    def print_workqueue_state_3_10(self, ram_dump):
        cpu_worker_pools_addr = ram_dump.address_of('cpu_worker_pools')

        busy_hash_offset = ram_dump.field_offset(
            'struct worker_pool', 'busy_hash')
        worker_entry_offset = ram_dump.field_offset('struct worker', 'entry')
        work_entry_offset = ram_dump.field_offset(
            'struct work_struct', 'entry')
        work_hentry_offset = ram_dump.field_offset('struct worker', 'hentry')
        pool_idle_offset = ram_dump.field_offset(
            'struct worker_pool', 'idle_list')
        worker_pool_size = ram_dump.sizeof('struct worker_pool')
        pending_work_offset = ram_dump.field_offset(
            'struct worker_pool', 'worklist')

        hash_size = 2 ** self.ramdump.gdbmi.get_value_of('BUSY_WORKER_HASH_ORDER')

        s = '<'
        if ram_dump.arm64:
            pool_char = 'Q'
        else:
            pool_char = 'I'
        for a in range(0, hash_size):
            s = s + pool_char

        for i in ram_dump.iter_cpus():
            busy_hash = []

            worker_pool = cpu_worker_pools_addr + ram_dump.per_cpu_offset(i)
            print_out_str('\nCPU {0}'.format(i))
            n_pools = self.ramdump.gdbmi.get_value_of('NR_STD_WORKER_POOLS')
            for k in range(0, n_pools):
                print_out_str('pool {0}'.format(k))
                worker_pool_i = worker_pool + k * worker_pool_size
                busy_hashi = ram_dump.read_string(
                    worker_pool_i + busy_hash_offset, s)
                for a in busy_hashi:
                    busy_hash.append(a)

                for k in range(0, hash_size):
                    next_busy_worker = busy_hash[k]
                    if busy_hash[k] != 0:
                        busy_list_walker = linux_list.ListWalker(ram_dump, next_busy_worker, work_hentry_offset)
                        busy_list_walker.walk(next_busy_worker, self.walk_workers, 'BUSY')

                idle_list_addr = worker_pool_i + pool_idle_offset

                idle_list_walker = linux_list.ListWalker(ram_dump, idle_list_addr, worker_entry_offset)
                idle_list_walker.walk(self.ramdump.read_word(idle_list_addr), self.walk_workers, 'IDLE')

                worklist_addr = worker_pool_i + pending_work_offset

                pending_list = linux_list.ListWalker(ram_dump, worklist_addr, work_entry_offset)
                pending_list.walk(self.ramdump.read_word(worklist_addr), self.pending_list_walk)