lkml.org 
[lkml]   [2012]   [Apr]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[RFC PATCH -tip 14/16] x86: Indicate trapped address and probed address
    From
    Date
    Show trapped address as a comment style on disassembled
    code when kernel panicks.

    Signed-off-by: Masami Hiramatsu <masami.hiramatsu@gmail.com>
    ---
    arch/x86/kernel/dumpstack.c | 62 +++++++++++++++++++++++++++++++++----------
    1 files changed, 48 insertions(+), 14 deletions(-)

    diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
    index 2966142..098e61a 100644
    --- a/arch/x86/kernel/dumpstack.c
    +++ b/arch/x86/kernel/dumpstack.c
    @@ -322,22 +322,63 @@ static unsigned long find_instruction_boundary(unsigned long saddr,
    return addr;
    }

    +static int disasm_printk(unsigned long addr, unsigned long *next,
    + unsigned long ip)
    +{
    + char buf[DISASM_STR_LEN];
    + u8 kbuf[MAX_INSN_SIZE];
    + struct insn insn;
    + unsigned long fixed;
    + int i, ret;
    + u8 *v = (u8 *)addr;
    +
    + /* recover if the instruction is probed */
    + fixed = recover_probed_instruction(kbuf, addr);
    + kernel_insn_init(&insn, (void *)fixed);
    + insn_get_length(&insn);
    + insn.kaddr = (void *)addr;
    +
    + printk(KERN_CONT "%p: ", v);
    + for (i = 0; i < MAX_INSN_SIZE / 2 && i < insn.length; i++)
    + printk(KERN_CONT "%02x ", ((u8 *)v)[i]);
    + if (i != MAX_INSN_SIZE / 2)
    + printk(KERN_CONT "%*s", 3 * (MAX_INSN_SIZE / 2 - i), " ");
    +
    + /* print assembly code */
    + ret = disassemble(buf, DISASM_STR_LEN, &insn);
    + if (ret < 0)
    + return ret;
    + printk(KERN_CONT "%s%s%s\n", (fixed != addr) ? "(probed)" : "", buf,
    + (addr == ip) ? "\t<-- trapping instruction" : "");
    +
    + if (i < insn.length) {
    + printk(KERN_CONT "%p: ", v + i);
    + for (; i < insn.length - 1; i++)
    + printk(KERN_CONT "%02x ", ((u8 *)v)[i]);
    + printk(KERN_CONT "%02x\n", ((u8 *)v)[i]);
    + }
    +
    + if (next)
    + *next = addr + insn.length;
    +
    + return 0;
    +}
    +
    /* Disassemble between (ip - prologue) to (ip - prologue + length) */
    static int disassemble_code_dump(unsigned long ip, unsigned long prologue,
    unsigned long length)
    {
    - kprobe_opcode_t buf[MAX_INSN_SIZE];
    - unsigned long offs, addr, fixed;
    - unsigned long saddr = ip - prologue;
    + unsigned long offs;
    + unsigned long addr = ip - prologue;
    unsigned long eaddr = ip - prologue + length;
    char buf[KSYM_NAME_LEN] = {0};
    char *modname;

    /* given address must be in text area */
    - if (!kernel_text_address(saddr) || !kernel_text_address(eaddr))
    + if (!kernel_text_address(addr) || !kernel_text_address(eaddr))
    return -EINVAL;

    - addr = find_instruction_boundary(saddr, &offs, &modname, buf);
    + addr = find_instruction_boundary(addr, &offs, &modname, buf);
    if (!addr)
    return -EINVAL;

    @@ -348,15 +389,8 @@ static int disassemble_code_dump(unsigned long ip, unsigned long prologue,
    printk(KERN_CONT "\n<%s+0x%lx>:\n", buf, addr - (ip - offs));

    do {
    - if (addr == ip)
    - printk(KERN_CONT ">>");
    - fixed = recover_probed_instruction(buf, addr);
    - kernel_insn_init(&insn, (void *)fixed);
    - insn_get_length(&insn);
    - insn.kaddr = addr;
    - snprint_assembly(buf, sizeof(buf), &insn, DISASM_PR_ALL);
    - printk(KERN_CONT "%s", buf);
    - addr += insn.length;
    + if (disasm_printk(addr, &addr, ip) < 0)
    + break;
    } while (addr < eaddr);

    return 0;


    \
     
     \ /
      Last update: 2012-04-01 18:07    [W:4.402 / U:0.428 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site