summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryar <yar@FreeBSD.org>2006-06-16 11:14:54 +0000
committeryar <yar@FreeBSD.org>2006-06-16 11:14:54 +0000
commitf92d46b4f1d86b12ff71fc0385f5f20e5513df52 (patch)
tree4255f927fbe812477a7443edaf01fec01543b9fd
parent335fc3bd44eef4c479b5c3138ecb4b8454f3106c (diff)
downloadFreeBSD-src-f92d46b4f1d86b12ff71fc0385f5f20e5513df52.zip
FreeBSD-src-f92d46b4f1d86b12ff71fc0385f5f20e5513df52.tar.gz
Guess the number of arguments to a function somewhat better.
Now GCC likes to stick a "mov %eax, %FOO" instruction before "addl $BAR, %esp" if the function just called returns an int, which is a very common case in the kernel. Sponsored by: RiNet (Cronyx Plus LLC)
-rw-r--r--sys/i386/i386/db_trace.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c
index fb8d0b0..91e91a0 100644
--- a/sys/i386/i386/db_trace.c
+++ b/sys/i386/i386/db_trace.c
@@ -201,25 +201,29 @@ static int
db_numargs(fp)
struct i386_frame *fp;
{
- int *argp;
+ char *argp;
int inst;
int args;
- argp = (int *)db_get_value((int)&fp->f_retaddr, 4, FALSE);
+ argp = (char *)db_get_value((int)&fp->f_retaddr, 4, FALSE);
/*
* XXX etext is wrong for LKMs. We should attempt to interpret
* the instruction at the return address in all cases. This
* may require better fault handling.
*/
- if (argp < (int *)btext || argp >= (int *)etext) {
+ if (argp < btext || argp >= etext) {
args = 5;
} else {
+retry:
inst = db_get_value((int)argp, 4, FALSE);
if ((inst & 0xff) == 0x59) /* popl %ecx */
args = 1;
else if ((inst & 0xffff) == 0xc483) /* addl $Ibs, %esp */
args = ((inst >> 16) & 0xff) / 4;
- else
+ else if ((inst & 0xf8ff) == 0xc089) { /* movl %eax, %Reg */
+ argp += 2;
+ goto retry;
+ } else
args = 5;
}
return (args);
OpenPOWER on IntegriCloud