The "dis" command offers a well known "-r" option, which allows the user to display all instructions from the start of the routine up to and including the designated address. Currently there is no option to go in the opposite direction.
This patch introduces the "-f" (forward) option. As the option suggests, it is to be used to displays all instructions from the given text address to the end of the routine. The given address may be expressed by value, symbol or expression. For example: crash> dis -f do_fork+430 0xffffffff8013804b <do_fork+430>: callq 0xffffffff80143aac <ptrace_notify> 0xffffffff80138050 <do_fork+435>: jmp 0xffffffff8013805d <do_fork+448> 0xffffffff80138052 <do_fork+437>: mov %r13d,%edi 0xffffffff80138055 <do_fork+440>: mov %rbx,%r13 0xffffffff80138058 <do_fork+443>: callq 0xffffffff80149060 <free_pidmap> 0xffffffff8013805d <do_fork+448>: mov %r13,%rax 0xffffffff80138060 <do_fork+451>: add $0x38,%rsp 0xffffffff80138064 <do_fork+455>: pop %rbx 0xffffffff80138065 <do_fork+456>: pop %rbp 0xffffffff80138066 <do_fork+457>: pop %r12 0xffffffff80138068 <do_fork+459>: pop %r13 0xffffffff8013806a <do_fork+461>: pop %r14 0xffffffff8013806c <do_fork+463>: pop %r15 0xffffffff8013806e <do_fork+465>: retq 0xffffffff8013806f <do_fork+466>: nop Signed-off-by: Aaron Tomlin <[email protected]> --- help.c | 2 ++ kernel.c | 44 ++++++++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/help.c b/help.c index 2848ead..6f3965b 100644 --- a/help.c +++ b/help.c @@ -6152,6 +6152,8 @@ char *help_dis[] = { " a text address that may be expressed by value, symbol or expression:\n", " -r (reverse) displays all instructions from the start of the ", " routine up to and including the designated address.", +" -f (forward) displays all instructions from the given address ", +" to the end of the routine.", " -l displays source code line number data in addition to the ", " disassembly output.", " -u address is a user virtual address in the current context;", diff --git a/kernel.c b/kernel.c index 846cf71..77ca271 100644 --- a/kernel.c +++ b/kernel.c @@ -1427,11 +1427,11 @@ void cmd_dis(void) { int c; - int do_load_module_filter, do_machdep_filter, reverse; + int do_load_module_filter, do_machdep_filter, reverse, forward; int unfiltered, user_mode, count_entered, bug_bytes_entered; unsigned int radix; ulong curaddr; - ulong revtarget; + ulong target; ulong count; ulong offset; struct syment *sp; @@ -1453,17 +1453,18 @@ cmd_dis(void) return; } - reverse = count_entered = bug_bytes_entered = FALSE; + reverse = forward = count_entered = bug_bytes_entered = FALSE; sp = NULL; unfiltered = user_mode = do_machdep_filter = do_load_module_filter = 0; radix = 0; + target = 0; req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request)); req->buf = GETBUF(BUFSIZE); req->flags |= GNU_FROM_TTY_OFF|GNU_RETURN_ON_ERROR; req->count = 1; - while ((c = getopt(argcnt, args, "dxhulrUb:B:")) != EOF) { + while ((c = getopt(argcnt, args, "dxhulrfUb:B:")) != EOF) { switch(c) { case 'd': @@ -1493,6 +1494,10 @@ cmd_dis(void) reverse = TRUE; break; + case 'f': + forward = TRUE; + break; + case 'l': if (NO_LINE_NUMBERS()) error(INFO, "line numbers are not available\n"); @@ -1559,9 +1564,10 @@ cmd_dis(void) } if (args[++optind]) { - if (reverse) { + if (reverse || forward) { error(INFO, - "count argument ignored with -r option\n"); + "count argument ignored with -%s option\n", + reverse ? "r" : "f"); } else { req->count = stol(args[optind], FAULT_ON_ERROR, NULL); @@ -1592,7 +1598,7 @@ cmd_dis(void) req->command = GNU_RESOLVE_TEXT_ADDR; gdb_interface(req); req->flags &= ~GNU_COMMAND_FAILED; - if (reverse || req->flags & GNU_FUNCTION_ONLY) { + if (reverse || forward || req->flags & GNU_FUNCTION_ONLY) { if (sp) { savename = sp->name; if ((sp = next_symbol(NULL, sp))) @@ -1610,12 +1616,11 @@ cmd_dis(void) } } - if (reverse) { - revtarget = req->addr; - if ((sp = value_search(revtarget, NULL)) == NULL) - error(FATAL, "cannot resolve address: %lx\n", revtarget); + if (reverse || forward) { + target = req->addr; + if ((sp = value_search(target, NULL)) == NULL) + error(FATAL, "cannot resolve address: %lx\n", target); - sprintf(buf1, "0x%lx", revtarget); req->addr = sp->value; } else count = 0; @@ -1627,12 +1632,12 @@ cmd_dis(void) if (reverse) sprintf(buf5, "x/%ldi 0x%lx", - (revtarget - req->addr) ? revtarget - req->addr : 1, + (target - req->addr) ? target - req->addr : 1, req->addr); else sprintf(buf5, "x/%ldi 0x%lx", count_entered && req->count ? req->count : - req->flags & GNU_FUNCTION_ONLY ? + forward || req->flags & GNU_FUNCTION_ONLY ? req->addr2 - req->addr : 1, req->addr); gdb_pass_through(buf5, NULL, GNU_RETURN_ON_ERROR); @@ -1655,8 +1660,15 @@ cmd_dis(void) extract_hex(buf2, &curaddr, ':', TRUE); + if (forward) { + if (curaddr != target) + continue; + else + forward = FALSE; + } + if (!reverse) - if ((req->flags & GNU_FUNCTION_ONLY) && + if (!count_entered && (curaddr >= req->addr2)) break; @@ -1677,7 +1689,7 @@ cmd_dis(void) print_verbatim(pc->saved_fp, buf2); if (reverse) { - if (STRNEQ(buf2, buf1)) { + if (curaddr == target) { if (LASTCHAR(clean_line(buf2)) != ':') break; -- 2.4.3 -- Crash-utility mailing list [email protected] https://www.redhat.com/mailman/listinfo/crash-utility
