diff options
author | yar <yar@FreeBSD.org> | 2006-06-16 11:14:54 +0000 |
---|---|---|
committer | yar <yar@FreeBSD.org> | 2006-06-16 11:14:54 +0000 |
commit | f92d46b4f1d86b12ff71fc0385f5f20e5513df52 (patch) | |
tree | 4255f927fbe812477a7443edaf01fec01543b9fd /sys/i386 | |
parent | 335fc3bd44eef4c479b5c3138ecb4b8454f3106c (diff) | |
download | FreeBSD-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)
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/db_trace.c | 12 |
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); |