xmon support for symbol lookup

olof at austin.ibm.com olof at austin.ibm.com
Thu Feb 26 09:46:05 EST 2004


Attached patch adds symbol lookup functions to xmon, similar to what Ben
added to ppc32 but not requiring a linked-in system.map.

It requires the kallsyms_lookupname patch (see previous post), so I won't
push this until I've heard back that it's accepted upstream.

Commands added are "la <symbol>" and "ls <address>". The syntax $<symbol>
can also be used to specify addresses, like on ppc32:

0:mon> di $.sysrq_handle_xmon
c000000000046b5c  7c0802a6      mflr    r0
c000000000046b60  fba1ffe8      std     r29,-24(r1)
c000000000046b64  7c9d2378      mr      r29,r4
c000000000046b68  f8010010      std     r0,16(r1)
c000000000046b6c  f821ff71      stdu    r1,-144(r1)
c000000000046b70  48004691      bl      0xc00000000004b200     # .xmon_init+0x0


(also notice the added comments in the disasm output with symbols)


-Olof

Olof Johansson                                        Office: 4E002/905
Linux on Power Development                            IBM Systems Group
Email: olof at austin.ibm.com                          Phone: 512-838-9858
All opinions are my own and not those of IBM

-------------- next part --------------
===== arch/ppc64/xmon/ppc-dis.c 1.1 vs edited =====
--- 1.1/arch/ppc64/xmon/ppc-dis.c	Thu Feb 14 06:14:36 2002
+++ edited/arch/ppc64/xmon/ppc-dis.c	Wed Feb 25 11:22:49 2004
@@ -18,6 +18,7 @@
 along with this file; see the file COPYING.  If not, write to the Free
 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
+#include <linux/kallsyms.h>
 #include "nonstdio.h"
 #include "ansidecl.h"
 #include "ppc.h"
@@ -61,6 +62,7 @@
       int invalid;
       int need_comma;
       int need_paren;
+      unsigned long addr;
 
       table_op = PPC_OP (opcode->opcode);
       if (op < table_op)
@@ -93,6 +95,7 @@
       /* Now extract and print the operands.  */
       need_comma = 0;
       need_paren = 0;
+      addr = 0;
       for (opindex = opcode->operands; *opindex != 0; opindex++)
 		{
 		  long value;
@@ -134,9 +137,10 @@
 		    fprintf(out, "r%ld", value);
 		  else if ((operand->flags & PPC_OPERAND_FPR) != 0)
 		    fprintf(out, "f%ld", value);
-		  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
+		  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) {
 		    print_address (memaddr + value);
-		  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+		    addr = memaddr + value;
+		  } else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
 		    print_address (value & 0xffffffff);
 		  else if ((operand->flags & PPC_OPERAND_CR) == 0
 			   || (dialect & PPC_OPCODE_PPC) == 0)
@@ -178,6 +182,21 @@
 	      need_paren = 1;
 	    }
 	}
+
+      if (addr) {
+          char namebuf[128];
+	  const char *name;
+	  char *modname;
+	  long size, offset;
+
+          name = kallsyms_lookup(addr, &size, &offset, &modname, namebuf);
+          if (name) {
+              if(modname)
+		      fprintf(out, "\t# [%s]%s+0x%lx", modname, name, offset);
+	      else
+	              fprintf(out, "\t# %s+0x%lx", name, offset);
+	  }
+      }
 
       /* We have found and printed an instruction; return.  */
       return 4;
===== arch/ppc64/xmon/xmon.c 1.34 vs edited =====
--- 1.34/arch/ppc64/xmon/xmon.c	Sat Feb 14 06:40:59 2004
+++ edited/arch/ppc64/xmon/xmon.c	Wed Feb 25 11:38:19 2004
@@ -115,6 +115,7 @@
 static void csum(void);
 static void bootcmds(void);
 void dump_segments(void);
+void symbol_lookup(void);
 
 static void debug_trace(void);
 
@@ -160,6 +161,8 @@
   dd	dump double values\n\
   e	print exception information\n\
   f	flush cache\n\
+  la	lookup address\n\
+  ls	lookup symbol\n\
   m	examine/change memory\n\
   mm	move a block of memory\n\
   ms	set a block of memory\n\
@@ -537,6 +540,9 @@
 		case 'd':
 			dump();
 			break;
+		case 'l':
+			symbol_lookup();
+			break;
 		case 'r':
 			if (excp != NULL)
 				prregs(excp);	/* print regs */
@@ -1142,6 +1148,7 @@
 extern char exc_prolog;
 extern char dec_exc;
 
+
 void
 super_regs()
 {
@@ -1644,6 +1651,7 @@
 	printf("0x%lx", addr);
 }
 
+
 /*
  * Memory operations - move, set, print differences
  */
@@ -1822,8 +1830,40 @@
 		return 0;
 	}
 
+	/* skip leading "0x" if any */
+
+	if (c == '0') {
+		c = inchar();
+		if (c == 'x')
+			c = inchar();
+	}
+
+	if (c == '0') {
+		c = inchar();
+		if (c == 'x')
+			c = inchar();
+	} else if (c == '$') {
+		static char symname[64];
+		int i;
+		for (i=0; i<63; i++) {
+                        c = inchar();
+			if (isspace(c)) {
+				termch = c;
+				break;
+			}
+			symname[i] = c;
+		}
+		symname[i++] = 0;
+		*vp = kallsyms_lookupname(symname);
+		if (!(*vp)) {
+			printf("unknown symbol '%s'\n", symname);
+			return 0;
+		}
+		return 1;
+	}
+	
 	d = hexdigit(c);
-	if( d == EOF ){
+	if (d == EOF) {
 		termch = c;
 		return 0;
 	}
@@ -1832,7 +1872,7 @@
 		v = (v << 4) + d;
 		c = inchar();
 		d = hexdigit(c);
-	} while( d != EOF );
+	} while (d != EOF);
 	termch = c;
 	*vp = v;
 	return 1;
@@ -1907,13 +1947,48 @@
 	lineptr = str;
 }
 
+
+void
+symbol_lookup(void)
+{
+        int type = inchar();
+        unsigned long addr;
+        static char tmp[64];
+
+        switch (type) {
+	case 'a':
+		if (scanhex(&addr)) {
+			printf("%lx: ", addr);
+			xmon_print_symbol("%s\n", addr);
+		}
+		termch = 0;
+		break;
+	case 's':
+		getstring(tmp, 64);
+		if (setjmp(bus_error_jmp) == 0) {
+			__debugger_fault_handler = handle_fault;
+			sync();
+			addr = kallsyms_lookupname(tmp);
+			if (addr) 
+				printf("%s: %lx\n", tmp, addr);
+			else
+				printf("Symbol '%s' not found.\n", tmp);
+			sync();
+		}
+		__debugger_fault_handler = 0;
+		termch = 0;
+		break;
+        }
+}
+
+
 /* xmon version of __print_symbol */
 void __xmon_print_symbol(const char *fmt, unsigned long address)
 {
 	char *modname;
 	const char *name;
 	unsigned long offset, size;
-	char namebuf[128];
+	static char namebuf[128];
 
 	if (setjmp(bus_error_jmp) == 0) {
 		__debugger_fault_handler = handle_fault;


More information about the Linuxppc64-dev mailing list