def invoke(self, arg, from_tty): log_buf_addr = int( str(gdb.parse_and_eval("(void *)'printk.c'::log_buf")).split()[0], 16) log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx")) log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx")) log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len")) inf = gdb.inferiors()[0] start = log_buf_addr + log_first_idx if log_first_idx < log_next_idx: log_buf_2nd_half = -1 length = log_next_idx - log_first_idx log_buf = utils.read_memoryview(inf, start, length).tobytes() else: log_buf_2nd_half = log_buf_len - log_first_idx a = utils.read_memoryview(inf, start, log_buf_2nd_half) b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) log_buf = a.tobytes() + b.tobytes() length_offset = printk_log_type.get_type()['len'].bitpos // 8 text_len_offset = printk_log_type.get_type()['text_len'].bitpos // 8 time_stamp_offset = printk_log_type.get_type()['ts_nsec'].bitpos // 8 text_offset = printk_log_type.get_type().sizeof pos = 0 while pos < log_buf.__len__(): length = utils.read_u16(log_buf, pos + length_offset) if length == 0: if log_buf_2nd_half == -1: gdb.write("Corrupted log buffer!\n") break pos = log_buf_2nd_half continue text_len = utils.read_u16(log_buf, pos + text_len_offset) text_start = pos + text_offset text = log_buf[text_start:text_start + text_len].decode( encoding='utf8', errors='replace') time_stamp = utils.read_u64(log_buf, pos + time_stamp_offset) for line in text.splitlines(): msg = u"[{time:12.6f}] {line}\n".format(time=time_stamp / 1000000000.0, line=line) # With python2 gdb.write will attempt to convert unicode to # ascii and might fail so pass an utf8-encoded str instead. if sys.hexversion < 0x03000000: msg = msg.encode(encoding='utf8', errors='replace') gdb.write(msg) pos += length
def pr_cpumask(mask): nr_cpu_ids = 1 if constants.LX_NR_CPUS > 1: nr_cpu_ids = gdb.parse_and_eval("nr_cpu_ids") inf = gdb.inferiors()[0] bits = mask['bits'] num_bytes = (nr_cpu_ids + 7) / 8 buf = utils.read_memoryview(inf, bits, num_bytes).tobytes() buf = binascii.b2a_hex(buf) chunks = [] i = num_bytes while i > 0: i -= 1 start = i * 2 end = start + 2 chunks.append(buf[start:end]) if i != 0 and i % 4 == 0: chunks.append(',') extra = nr_cpu_ids % 8 if 0 < extra <= 4: chunks[0] = chunks[0][0] # Cut off the first 0 return "".join(chunks)
def invoke(self, arg, from_tty): log_buf_addr = int(str(gdb.parse_and_eval( "(void *)'printk.c'::log_buf")).split()[0], 16) log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx")) log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx")) log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len")) inf = gdb.inferiors()[0] start = log_buf_addr + log_first_idx if log_first_idx < log_next_idx: log_buf_2nd_half = -1 length = log_next_idx - log_first_idx log_buf = utils.read_memoryview(inf, start, length).tobytes() else: log_buf_2nd_half = log_buf_len - log_first_idx a = utils.read_memoryview(inf, start, log_buf_2nd_half) b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) log_buf = a.tobytes() + b.tobytes() pos = 0 while pos < log_buf.__len__(): length = utils.read_u16(log_buf[pos + 8:pos + 10]) if length == 0: if log_buf_2nd_half == -1: gdb.write("Corrupted log buffer!\n") break pos = log_buf_2nd_half continue text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) text = log_buf[pos + 16:pos + 16 + text_len].decode( encoding='utf8', errors='replace') time_stamp = utils.read_u64(log_buf[pos:pos + 8]) for line in text.splitlines(): msg = u"[{time:12.6f}] {line}\n".format( time=time_stamp / 1000000000.0, line=line) # With python2 gdb.write will attempt to convert unicode to # ascii and might fail so pass an utf8-encoded str instead. if sys.hexversion < 0x03000000: msg = msg.encode(encoding='utf8', errors='replace') gdb.write(msg) pos += length
def invoke(self, arg, from_tty): log_buf_addr = int(str(gdb.parse_and_eval( "'printk.c'::log_buf")).split()[0], 16) log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx")) log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx")) log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len")) inf = gdb.inferiors()[0] start = log_buf_addr + log_first_idx if log_first_idx < log_next_idx: log_buf_2nd_half = -1 length = log_next_idx - log_first_idx log_buf = utils.read_memoryview(inf, start, length).tobytes() else: log_buf_2nd_half = log_buf_len - log_first_idx a = utils.read_memoryview(inf, start, log_buf_2nd_half) b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) log_buf = a.tobytes() + b.tobytes() pos = 0 while pos < log_buf.__len__(): length = utils.read_u16(log_buf[pos + 8:pos + 10]) if length == 0: if log_buf_2nd_half == -1: gdb.write("Corrupted log buffer!\n") break pos = log_buf_2nd_half continue text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) text = log_buf[pos + 16:pos + 16 + text_len].decode() time_stamp = utils.read_u64(log_buf[pos:pos + 8]) for line in text.splitlines(): gdb.write("[{time:12.6f}] {line}\n".format( time=time_stamp / 1000000000.0, line=line)) pos += length
def invoke(self, arg, from_tty): log_buf_addr = int( str(gdb.parse_and_eval("'printk.c'::log_buf")).split()[0], 16) log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx")) log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx")) log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len")) inf = gdb.inferiors()[0] start = log_buf_addr + log_first_idx if log_first_idx < log_next_idx: log_buf_2nd_half = -1 length = log_next_idx - log_first_idx log_buf = utils.read_memoryview(inf, start, length).tobytes() else: log_buf_2nd_half = log_buf_len - log_first_idx a = utils.read_memoryview(inf, start, log_buf_2nd_half) b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) log_buf = a.tobytes() + b.tobytes() pos = 0 while pos < log_buf.__len__(): length = utils.read_u16(log_buf[pos + 8:pos + 10]) if length == 0: if log_buf_2nd_half == -1: gdb.write("Corrupted log buffer!\n") break pos = log_buf_2nd_half continue text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) text = log_buf[pos + 16:pos + 16 + text_len].decode() time_stamp = utils.read_u64(log_buf[pos:pos + 8]) for line in text.splitlines(): gdb.write("[{time:12.6f}] {line}\n".format(time=time_stamp / 1000000000.0, line=line)) pos += length
def invoke(self, arg, from_tty): if not constants.LX_CONFIG_OF: raise gdb.GdbError("Kernel not compiled with CONFIG_OF\n") if len(arg) == 0: filename = "fdtdump.dtb" else: filename = arg py_fdt_header_ptr = gdb.parse_and_eval( "(const struct fdt_header *) initial_boot_params") py_fdt_header = py_fdt_header_ptr.dereference() fdt_header = self.fdthdr_to_cpu(py_fdt_header) if fdt_header[0] != constants.LX_OF_DT_HEADER: raise gdb.GdbError("No flattened device tree magic found\n") gdb.write("fdt_magic: 0x{:02X}\n".format(fdt_header[0])) gdb.write("fdt_totalsize: 0x{:02X}\n".format(fdt_header[1])) gdb.write("off_dt_struct: 0x{:02X}\n".format(fdt_header[2])) gdb.write("off_dt_strings: 0x{:02X}\n".format(fdt_header[3])) gdb.write("off_mem_rsvmap: 0x{:02X}\n".format(fdt_header[4])) gdb.write("version: {}\n".format(fdt_header[5])) gdb.write("last_comp_version: {}\n".format(fdt_header[6])) inf = gdb.inferiors()[0] fdt_buf = utils.read_memoryview(inf, py_fdt_header_ptr, fdt_header[1]).tobytes() try: f = open(filename, 'wb') except: raise gdb.GdbError("Could not open file to dump fdt") f.write(fdt_buf) f.close() gdb.write("Dumped fdt blob to " + filename + "\n")
def invoke(self, arg, from_tty): if len(arg) == 0: filename = "config.txt" else: filename = arg try: py_config_ptr = gdb.parse_and_eval("kernel_config_data + 8") py_config_size = gdb.parse_and_eval( "sizeof(kernel_config_data) - 1 - 8 * 2") except gdb.error as e: raise gdb.GdbError("Can't find config, enable CONFIG_IKCONFIG?") inf = gdb.inferiors()[0] zconfig_buf = utils.read_memoryview(inf, py_config_ptr, py_config_size).tobytes() config_buf = zlib.decompress(zconfig_buf, 16) with open(filename, 'wb') as f: f.write(config_buf) gdb.write("Dumped config to " + filename + "\n")
def invoke(self, arg, from_tty): inf = gdb.inferiors()[0] # read in prb structure prb_addr = int( str(gdb.parse_and_eval("(void *)'printk.c'::prb")).split()[0], 16) sz = printk_ringbuffer_type.get_type().sizeof prb = utils.read_memoryview(inf, prb_addr, sz).tobytes() # read in descriptor ring structure off = printk_ringbuffer_type.get_type()['desc_ring'].bitpos // 8 addr = prb_addr + off sz = prb_desc_ring_type.get_type().sizeof desc_ring = utils.read_memoryview(inf, addr, sz).tobytes() # read in descriptor array off = prb_desc_ring_type.get_type()['count_bits'].bitpos // 8 desc_ring_count = 1 << utils.read_u32(desc_ring, off) desc_sz = prb_desc_type.get_type().sizeof off = prb_desc_ring_type.get_type()['descs'].bitpos // 8 addr = utils.read_ulong(desc_ring, off) descs = utils.read_memoryview(inf, addr, desc_sz * desc_ring_count).tobytes() # read in text data ring structure off = printk_ringbuffer_type.get_type()['text_data_ring'].bitpos // 8 addr = prb_addr + off sz = prb_data_ring_type.get_type().sizeof text_data_ring = utils.read_memoryview(inf, addr, sz).tobytes() # read in text data off = prb_data_ring_type.get_type()['size_bits'].bitpos // 8 text_data_sz = 1 << utils.read_u32(text_data_ring, off) off = prb_data_ring_type.get_type()['data'].bitpos // 8 addr = utils.read_ulong(text_data_ring, off) text_data = utils.read_memoryview(inf, addr, text_data_sz).tobytes() counter_off = atomic_long_type.get_type()['counter'].bitpos // 8 sv_off = prb_desc_type.get_type()['state_var'].bitpos // 8 off = prb_desc_type.get_type()['text_blk_lpos'].bitpos // 8 begin_off = off + (prb_data_blk_lpos_type.get_type()['begin'].bitpos // 8) next_off = off + (prb_data_blk_lpos_type.get_type()['next'].bitpos // 8) off = prb_desc_type.get_type()['info'].bitpos // 8 ts_off = off + printk_info_type.get_type()['ts_nsec'].bitpos // 8 len_off = off + printk_info_type.get_type()['text_len'].bitpos // 8 # definitions from kernel/printk/printk_ringbuffer.h desc_sv_bits = utils.get_long_type().sizeof * 8 desc_committed_mask = 1 << (desc_sv_bits - 1) desc_reuse_mask = 1 << (desc_sv_bits - 2) desc_flags_mask = desc_committed_mask | desc_reuse_mask desc_id_mask = ~desc_flags_mask # read in tail and head descriptor ids off = prb_desc_ring_type.get_type()['tail_id'].bitpos // 8 tail_id = utils.read_u64(desc_ring, off + counter_off) off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8 head_id = utils.read_u64(desc_ring, off + counter_off) did = tail_id while True: ind = did % desc_ring_count desc_off = desc_sz * ind # skip non-committed record state = utils.read_u64( descs, desc_off + sv_off + counter_off) & desc_flags_mask if state != desc_committed_mask: if did == head_id: break did = (did + 1) & desc_id_mask continue begin = utils.read_ulong(descs, desc_off + begin_off) % text_data_sz end = utils.read_ulong(descs, desc_off + next_off) % text_data_sz # handle data-less record if begin & 1 == 1: text = "" else: # handle wrapping data block if begin > end: begin = 0 # skip over descriptor id text_start = begin + utils.get_long_type().sizeof text_len = utils.read_u16(descs, desc_off + len_off) # handle truncated message if end - text_start < text_len: text_len = end - text_start text = text_data[text_start:text_start + text_len].decode( encoding='utf8', errors='replace') time_stamp = utils.read_u64(descs, desc_off + ts_off) for line in text.splitlines(): msg = u"[{time:12.6f}] {line}\n".format(time=time_stamp / 1000000000.0, line=line) # With python2 gdb.write will attempt to convert unicode to # ascii and might fail so pass an utf8-encoded str instead. if sys.hexversion < 0x03000000: msg = msg.encode(encoding='utf8', errors='replace') gdb.write(msg) if did == head_id: break did = (did + 1) & desc_id_mask