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