#
# gdb helper commands and functions for Linux kernel debugging
#
#  kernel log buffer dump
#
# Copyright (c) Siemens AG, 2011, 2012
#
# Authors:
#  Jan Kiszka <jan.kiszka@siemens.com>
#
# This work is licensed under the terms of the GNU GPL version 2.
#

import gdb
import sys

from linux import utils

printk_info_type = utils.CachedType("struct printk_info")
prb_data_blk_lpos_type = utils.CachedType("struct prb_data_blk_lpos")
prb_desc_type = utils.CachedType("struct prb_desc")
prb_desc_ring_type = utils.CachedType("struct prb_desc_ring")
prb_data_ring_type = utils.CachedType("struct prb_data_ring")
printk_ringbuffer_type = utils.CachedType("struct printk_ringbuffer")

class LxDmesg(gdb.Command):
    """Print Linux kernel log buffer."""

    def __init__(self):
        super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA)

    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 count, size, and address
        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
        desc_addr = utils.read_ulong(desc_ring, off)

        # read in info size and address
        info_sz = printk_info_type.get_type().sizeof
        off = prb_desc_ring_type.get_type()['infos'].bitpos // 8
        info_addr = utils.read_ulong(desc_ring, off)

        # 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 size and address
        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
        text_data_addr = utils.read_ulong(text_data_ring, off)

        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)

        ts_off = printk_info_type.get_type()['ts_nsec'].bitpos // 8
        len_off = printk_info_type.get_type()['text_len'].bitpos // 8

        # definitions from kernel/printk/printk_ringbuffer.h
        desc_committed = 1
        desc_finalized = 2
        desc_sv_bits = utils.get_long_type().sizeof * 8
        desc_flags_shift = desc_sv_bits - 2
        desc_flags_mask = 3 << desc_flags_shift
        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_atomic_long(desc_ring, off)
        off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8
        head_id = utils.read_atomic_long(desc_ring, off)

        did = tail_id
        while True:
            ind = did % desc_ring_count
            desc_off = desc_sz * ind
            info_off = info_sz * ind

            desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes()

            # skip non-committed record
            state = 3 & (utils.read_atomic_long(desc, sv_off) >> desc_flags_shift)
            if state != desc_committed and state != desc_finalized:
                if did == head_id:
                    break
                did = (did + 1) & desc_id_mask
                continue

            begin = utils.read_ulong(desc, begin_off) % text_data_sz
            end = utils.read_ulong(desc, next_off) % text_data_sz

            info = utils.read_memoryview(inf, info_addr + info_off, info_sz).tobytes()

            # 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(info, len_off)

                # handle truncated message
                if end - text_start < text_len:
                    text_len = end - text_start

                text_data = utils.read_memoryview(inf, text_data_addr + text_start,
                                                  text_len).tobytes()
                text = text_data[0:text_len].decode(encoding='utf8', errors='replace')

            time_stamp = utils.read_u64(info, 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


LxDmesg()
