[PATCH 2/2] dis: Introduce the -f option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <atomlin@xxxxxxxxxx>
---
 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
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility



[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux