diff options
Diffstat (limited to 'scripts/gdb/linux')
| -rw-r--r-- | scripts/gdb/linux/constants.py.in | 7 | ||||
| -rw-r--r-- | scripts/gdb/linux/dmesg.py | 15 | ||||
| -rw-r--r-- | scripts/gdb/linux/proc.py | 73 | 
3 files changed, 91 insertions, 4 deletions
diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index 7986f4e0da12..7aad82406422 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -14,6 +14,7 @@  #include <linux/fs.h>  #include <linux/mount.h> +#include <linux/of_fdt.h>  /* We need to stringify expanded macros so that they can be parsed */ @@ -50,3 +51,9 @@ LX_VALUE(MNT_NOEXEC)  LX_VALUE(MNT_NOATIME)  LX_VALUE(MNT_NODIRATIME)  LX_VALUE(MNT_RELATIME) + +/* linux/of_fdt.h> */ +LX_VALUE(OF_DT_HEADER) + +/* Kernel Configs */ +LX_CONFIG(CONFIG_OF) diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py index 5afd1098e33a..6d2e09a2ad2f 100644 --- a/scripts/gdb/linux/dmesg.py +++ b/scripts/gdb/linux/dmesg.py @@ -12,6 +12,7 @@  #  import gdb +import sys  from linux import utils @@ -24,7 +25,7 @@ class LxDmesg(gdb.Command):      def invoke(self, arg, from_tty):          log_buf_addr = int(str(gdb.parse_and_eval( -            "'printk.c'::log_buf")).split()[0], 16) +            "(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")) @@ -52,13 +53,19 @@ class LxDmesg(gdb.Command):                  continue              text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) -            text = log_buf[pos + 16:pos + 16 + text_len].decode() +            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(): -                gdb.write("[{time:12.6f}] {line}\n".format( +                msg = u"[{time:12.6f}] {line}\n".format(                      time=time_stamp / 1000000000.0, -                    line=line)) +                    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 diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py index 38b1f09d1cd9..086d27223c0c 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py @@ -16,6 +16,7 @@ from linux import constants  from linux import utils  from linux import tasks  from linux import lists +from struct import *  class LxCmdLine(gdb.Command): @@ -195,3 +196,75 @@ values of that process namespace"""                          info_opts(MNT_INFO, m_flags)))  LxMounts() + + +class LxFdtDump(gdb.Command): +    """Output Flattened Device Tree header and dump FDT blob to the filename +       specified as the command argument. Equivalent to +       'cat /proc/fdt > fdtdump.dtb' on a running target""" + +    def __init__(self): +        super(LxFdtDump, self).__init__("lx-fdtdump", gdb.COMMAND_DATA, +                                        gdb.COMPLETE_FILENAME) + +    def fdthdr_to_cpu(self, fdt_header): + +        fdt_header_be = ">IIIIIII" +        fdt_header_le = "<IIIIIII" + +        if utils.get_target_endianness() == 1: +            output_fmt = fdt_header_le +        else: +            output_fmt = fdt_header_be + +        return unpack(output_fmt, pack(fdt_header_be, +                                       fdt_header['magic'], +                                       fdt_header['totalsize'], +                                       fdt_header['off_dt_struct'], +                                       fdt_header['off_dt_strings'], +                                       fdt_header['off_mem_rsvmap'], +                                       fdt_header['version'], +                                       fdt_header['last_comp_version'])) + +    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") + +LxFdtDump()  | 
