File crash-Introduction-of-the-dis-f-address-option-which-disas.patch of Package crash.4081
From 4935c333a6cd1e7a8949eda53319b8550640cfc0 Mon Sep 17 00:00:00 2001
From: Dave Anderson <anderson@redhat.com>
Date: Wed, 12 Aug 2015 13:49:15 -0400
Subject: [PATCH] Introduction of the "dis -f <address>" option, which
disassembles from the target address until the end of the function.
(atomlin@redhat.com)
---
help.c | 39 ++++++--
kernel.c | 301 ++++++++++++++++++++++++---------------------------------------
2 files changed, 145 insertions(+), 195 deletions(-)
Index: crash-7.0.5/help.c
===================================================================
--- crash-7.0.5.orig/help.c
+++ crash-7.0.5/help.c
@@ -5869,11 +5869,13 @@ NULL
char *help_dis[] = {
"dis",
"disassemble",
-"[-rludx][-b [num]] [address | symbol | (expression)] [count]",
+"[-rfludx][-b [num]] [address | symbol | (expression)] [count]",
" This command disassembles source code instructions starting (or ending) at",
" 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;",
@@ -5986,15 +5988,32 @@ char *help_dis[] = {
" Override the current decimal output radix format:\n",
" %s> dis sys_read 10 -x",
" 0xffffffff8001178f <sys_read>: push %r13",
-" 0xffffffff80011791 <sys_read+0x2>: mov %rsi,%r13",
-" 0xffffffff80011794 <sys_read+0x5>: push %r12",
-" 0xffffffff80011796 <sys_read+0x7>: mov $0xfffffffffffffff7,%r12",
-" 0xffffffff8001179d <sys_read+0xe>: push %rbp",
-" 0xffffffff8001179e <sys_read+0xf>: mov %rdx,%rbp",
-" 0xffffffff800117a1 <sys_read+0x12>: push %rbx",
-" 0xffffffff800117a2 <sys_read+0x13>: sub $0x18,%rsp",
-" 0xffffffff800117a6 <sys_read+0x17>: lea 0x14(%rsp),%rsi",
-" 0xffffffff800117ab <sys_read+0x1c>: callq 0xffffffff8000b5b4 <fget_light>",
+" 0xffffffff80011791 <sys_read+0x2>: mov %rsi,%r13",
+" 0xffffffff80011794 <sys_read+0x5>: push %r12",
+" 0xffffffff80011796 <sys_read+0x7>: mov $0xfffffffffffffff7,%r12",
+" 0xffffffff8001179d <sys_read+0xe>: push %rbp",
+" 0xffffffff8001179e <sys_read+0xf>: mov %rdx,%rbp",
+" 0xffffffff800117a1 <sys_read+0x12>: push %rbx",
+" 0xffffffff800117a2 <sys_read+0x13>: sub $0x18,%rsp",
+" 0xffffffff800117a6 <sys_read+0x17>: lea 0x14(%rsp),%rsi",
+" 0xffffffff800117ab <sys_read+0x1c>: callq 0xffffffff8000b5b4 <fget_light>",
+" ",
+" Disassemble from vfs_read+320 until the end of the function:\n",
+" %s> dis -f vfs_read+320",
+" 0xffffffff8119d4e0 <vfs_read+320>: cmpq $0x0,0x20(%rax)",
+" 0xffffffff8119d4e5 <vfs_read+325>: jne 0xffffffff8119d3e8 <vfs_read+72>",
+" 0xffffffff8119d4eb <vfs_read+331>: mov $0xffffffffffffffea,%r12",
+" 0xffffffff8119d4f2 <vfs_read+338>: jmp 0xffffffff8119d4c3 <vfs_read+291>",
+" 0xffffffff8119d4f4 <vfs_read+340>: nopl 0x0(%rax)",
+" 0xffffffff8119d4f8 <vfs_read+344>: callq 0xffffffff8119cc40 <do_sync_read>",
+" 0xffffffff8119d4fd <vfs_read+349>: mov %rax,%r12",
+" 0xffffffff8119d500 <vfs_read+352>: jmpq 0xffffffff8119d44c <vfs_read+172>",
+" 0xffffffff8119d505 <vfs_read+357>: nopl (%rax)",
+" 0xffffffff8119d508 <vfs_read+360>: mov $0xfffffffffffffff7,%r12",
+" 0xffffffff8119d50f <vfs_read+367>: jmp 0xffffffff8119d4c3 <vfs_read+291>",
+" 0xffffffff8119d511 <vfs_read+369>: mov $0xfffffffffffffff2,%r12",
+" 0xffffffff8119d518 <vfs_read+376>: jmp 0xffffffff8119d4c3 <vfs_read+291>",
+" 0xffffffff8119d51a <vfs_read+378>: nopw 0x0(%rax,%rax,1)",
NULL
};
Index: crash-7.0.5/kernel.c
===================================================================
--- crash-7.0.5.orig/kernel.c
+++ crash-7.0.5/kernel.c
@@ -1332,11 +1332,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;
@@ -1358,17 +1358,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':
@@ -1395,9 +1396,19 @@ cmd_dis(void)
break;
case 'r':
+ if (forward)
+ error(FATAL,
+ "-r and -f are mutually exclusive\n");
reverse = TRUE;
break;
+ case 'f':
+ if (reverse)
+ error(FATAL,
+ "-r and -f are mutually exclusive\n");
+ forward = TRUE;
+ break;
+
case 'l':
if (GDB_PATCHED())
error(INFO, "line numbers are not available\n");
@@ -1450,9 +1461,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);
@@ -1480,212 +1492,131 @@ cmd_dis(void)
return;
}
+ req->command = GNU_RESOLVE_TEXT_ADDR;
+ gdb_interface(req);
+ req->flags &= ~GNU_COMMAND_FAILED;
+ if (reverse || forward || req->flags & GNU_FUNCTION_ONLY) {
+ if (sp) {
+ savename = sp->name;
+ if ((sp = next_symbol(NULL, sp)))
+ req->addr2 = sp->value;
+ else
+ error(FATAL,
+ "unable to determine symbol after %s\n",
+ savename);
+ } else {
+ if ((sp = value_search(req->addr, NULL))
+ && (sp = next_symbol(NULL, sp)))
+ req->addr2 = sp->value;
+ else
+ error(FATAL, dis_err, req->addr);
+ }
+ }
+
+ if (reverse || forward) {
+ target = req->addr;
+ if ((sp = value_search(target, NULL)) == NULL)
+ error(FATAL, "cannot resolve address: %lx\n", target);
+
+ req->addr = sp->value;
+ } else
+ count = 0;
do_load_module_filter = module_symbol(req->addr, NULL, NULL,
NULL, *gdb_output_radix);
- if (!reverse) {
- req->command = GNU_RESOLVE_TEXT_ADDR;
- gdb_interface(req);
- if ((req->flags & GNU_COMMAND_FAILED) ||
- do_load_module_filter ||
- (req->flags & GNU_FUNCTION_ONLY)) {
- req->flags &= ~GNU_COMMAND_FAILED;
- if (sp) {
- savename = sp->name;
- if ((sp = next_symbol(NULL, sp)))
- req->addr2 = sp->value;
- else
- error(FATAL,
- "unable to determine symbol after %s\n",
- savename);
- } else {
- if ((sp = value_search(req->addr, NULL))
- && (sp = next_symbol(NULL, sp)))
- req->addr2 = sp->value;
- else
- error(FATAL, dis_err, req->addr);
- }
- }
+ do_machdep_filter = machdep->dis_filter(req->addr, NULL, radix);
+ open_tmpfile();
- do_machdep_filter = machdep->dis_filter(req->addr, NULL, radix);
- count = 0;
- open_tmpfile();
-#ifdef OLDWAY
- req->command = GNU_DISASSEMBLE;
- req->fp = pc->tmpfile;
- gdb_interface(req);
-#else
- sprintf(buf1, "x/%ldi 0x%lx",
- count_entered && req->count ? req->count :
- req->flags & GNU_FUNCTION_ONLY ?
+ if (reverse)
+ sprintf(buf5, "x/%ldi 0x%lx",
+ (target - req->addr) ? target - req->addr : 1,
+ req->addr);
+ else
+ sprintf(buf5, "x/%ldi 0x%lx",
+ count_entered && req->count ? req->count :
+ forward || req->flags & GNU_FUNCTION_ONLY ?
req->addr2 - req->addr : 1,
req->addr);
- gdb_pass_through(buf1, NULL, GNU_RETURN_ON_ERROR);
-#endif
- if (req->flags & GNU_COMMAND_FAILED) {
- close_tmpfile();
- error(FATAL, dis_err, req->addr);
- }
+ gdb_pass_through(buf5, NULL, GNU_RETURN_ON_ERROR);
- rewind(pc->tmpfile);
- while (fgets(buf2, BUFSIZE, pc->tmpfile)) {
- if (STRNEQ(buf2, "Dump of") ||
- STRNEQ(buf2, "End of"))
- continue;
+ if (req->flags & GNU_COMMAND_FAILED) {
+ close_tmpfile();
+ error(FATAL, dis_err, req->addr);
+ }
+
+ rewind(pc->tmpfile);
+ while (fgets(buf2, BUFSIZE, pc->tmpfile)) {
+ if (STRNEQ(buf2, "Dump of") ||
+ STRNEQ(buf2, "End of"))
+ continue;
+
+ strip_beginning_whitespace(buf2);
- strip_beginning_whitespace(buf2);
+ if (do_load_module_filter)
+ load_module_filter(buf2, LM_DIS_FILTER);
- if (do_load_module_filter)
- load_module_filter(buf2, LM_DIS_FILTER);
+ if (STRNEQ(buf2, "0x"))
+ extract_hex(buf2, &curaddr, ':', TRUE);
- if (STRNEQ(buf2, "0x"))
- extract_hex(buf2, &curaddr, ':', TRUE);
+ if (forward) {
+ if (curaddr != target)
+ continue;
+ else
+ forward = FALSE;
+ }
- if ((req->flags & GNU_FUNCTION_ONLY) &&
+ if (!reverse)
+ if (!count_entered && req->addr2 &&
(curaddr >= req->addr2))
break;
- if (do_machdep_filter)
- machdep->dis_filter(curaddr, buf2, radix);
-
- if (req->flags & GNU_FUNCTION_ONLY) {
- if (req->flags &
- GNU_PRINT_LINE_NUMBERS) {
- get_line_number(curaddr, buf3,
- FALSE);
- if (!STREQ(buf3, buf4)) {
- print_verbatim(
- pc->saved_fp, buf3);
- print_verbatim(
- pc->saved_fp, "\n");
- strcpy(buf4, buf3);
- }
- }
+ if (do_machdep_filter)
+ machdep->dis_filter(curaddr, buf2, radix);
- print_verbatim(pc->saved_fp, buf2);
- continue;
- } else {
- if (curaddr < req->addr)
- continue;
-
- if (req->flags &
- GNU_PRINT_LINE_NUMBERS) {
- get_line_number(curaddr, buf3,
- FALSE);
- if (!STREQ(buf3, buf4)) {
- print_verbatim(
- pc->saved_fp, buf3);
- print_verbatim(
- pc->saved_fp, "\n");
- strcpy(buf4, buf3);
- }
- }
-
- print_verbatim(pc->saved_fp, buf2);
-
- if (LASTCHAR(clean_line(buf2))
- != ':') {
- if (++count == req->count)
- break;
- }
+ if (req->flags & GNU_PRINT_LINE_NUMBERS) {
+ get_line_number(curaddr, buf3,
+ FALSE);
+ if (!STREQ(buf3, buf4)) {
+ print_verbatim(
+ pc->saved_fp, buf3);
+ print_verbatim(
+ pc->saved_fp, "\n");
+ strcpy(buf4, buf3);
}
- }
- close_tmpfile();
- }
- }
- else if (bug_bytes_entered)
- return;
- else cmd_usage(pc->curcmd, SYNOPSIS);
-
- if (!reverse) {
- FREEBUF(req->buf);
- FREEBUF(req);
- return;
- }
-
- revtarget = req->addr;
- if ((sp = value_search(revtarget, NULL)) == NULL)
- error(FATAL, "cannot resolve address: %lx\n", revtarget);
-
- sprintf(buf1, "0x%lx", revtarget);
-
- open_tmpfile();
-
- req->addr = sp->value;
- req->flags |= GNU_FUNCTION_ONLY;
- req->command = GNU_RESOLVE_TEXT_ADDR;
- gdb_interface(req);
- req->flags &= ~GNU_COMMAND_FAILED;
- savename = sp->name;
- if ((sp = next_symbol(NULL, sp)))
- req->addr2 = sp->value;
- else {
- close_tmpfile();
- error(FATAL, "unable to determine symbol after %s\n", savename);
- }
-
- do_machdep_filter = machdep->dis_filter(req->addr, NULL, radix);
-#ifdef OLDWAY
- req->command = GNU_DISASSEMBLE;
- req->fp = pc->tmpfile;
- gdb_interface(req);
-#else
- sprintf(buf5, "x/%ldi 0x%lx",
- (revtarget - req->addr) ? revtarget - req->addr : 1,
- req->addr);
- gdb_pass_through(buf5, NULL, GNU_RETURN_ON_ERROR);
-#endif
- if (req->flags & GNU_COMMAND_FAILED) {
- close_tmpfile();
- error(FATAL, dis_err, req->addr);
- }
-
- rewind(pc->tmpfile);
- while (fgets(buf2, BUFSIZE, pc->tmpfile)) {
- if (STRNEQ(buf2, "Dump of") || STRNEQ(buf2, "End of"))
- continue;
-
- strip_beginning_whitespace(buf2);
-
- if (do_load_module_filter)
- load_module_filter(buf2, LM_DIS_FILTER);
-
- if (STRNEQ(buf2, "0x"))
- extract_hex(buf2, &curaddr, ':', TRUE);
-
- if (do_machdep_filter)
- machdep->dis_filter(curaddr, buf2, radix);
-
- if (req->flags & GNU_PRINT_LINE_NUMBERS) {
- get_line_number(curaddr, buf3, FALSE);
- if (!STREQ(buf3, buf4)) {
- print_verbatim(pc->saved_fp, buf3);
- print_verbatim(pc->saved_fp, "\n");
- strcpy(buf4, buf3);
}
- }
- print_verbatim(pc->saved_fp, buf2);
- if (STRNEQ(buf2, buf1)) {
- if (LASTCHAR(clean_line(buf2)) != ':')
- break;
+ print_verbatim(pc->saved_fp, buf2);
+ if (reverse) {
+ if (curaddr == target) {
+ if (LASTCHAR(clean_line(buf2)) != ':')
+ break;
- ret = fgets(buf2, BUFSIZE, pc->tmpfile);
+ ret = fgets(buf2, BUFSIZE, pc->tmpfile);
- if (do_load_module_filter)
- load_module_filter(buf2, LM_DIS_FILTER);
+ if (do_load_module_filter)
+ load_module_filter(buf2, LM_DIS_FILTER);
- if (do_machdep_filter)
- machdep->dis_filter(curaddr, buf2, radix);
+ if (do_machdep_filter)
+ machdep->dis_filter(curaddr, buf2, radix);
- print_verbatim(pc->saved_fp, buf2);
- break;
+ print_verbatim(pc->saved_fp, buf2);
+ break;
+ }
+ }
+
+ if (count_entered && LASTCHAR(clean_line(buf2)) != ':')
+ if (++count == req->count)
+ break;
}
+ close_tmpfile();
}
+ else if (bug_bytes_entered)
+ return;
+ else cmd_usage(pc->curcmd, SYNOPSIS);
- close_tmpfile();
FREEBUF(req->buf);
FREEBUF(req);
+ return;
}
/*