* config/i386/tm-i386v4.h (I386V4_SIGTRAMP_SAVED_PC, IN_SIGTRAMP,

FRAME_CHAIN, FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC):
	Define to make backtracing through the various sigtramp handlers
	work.
	* i386-tdep.c (i386v4_sigtramp_saved_pc):  New routine to fetch
	the saved pc from ucontext on the stack for SVR4 signal handling.
This commit is contained in:
Peter Schauer 1994-02-27 21:24:16 +00:00
parent e08b9ad7a1
commit 28ee4b4289
2 changed files with 118 additions and 35 deletions

View File

@ -1,3 +1,12 @@
Sun Feb 27 21:39:48 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
* config/i386/tm-i386v4.h (I386V4_SIGTRAMP_SAVED_PC, IN_SIGTRAMP,
FRAME_CHAIN, FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC):
Define to make backtracing through the various sigtramp handlers
work.
* i386-tdep.c (i386v4_sigtramp_saved_pc): New routine to fetch
the saved pc from ucontext on the stack for SVR4 signal handling.
Fri Feb 25 09:41:11 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
* remote.c, remote-mon.c, remote-utils.c, remote-utils.h,

View File

@ -1,5 +1,5 @@
/* Intel 386 target-dependent stuff.
Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1991, 1994 Free Software Foundation, Inc.
This file is part of GDB.
@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "inferior.h"
#include "gdbcore.h"
#include "target.h"
#include "symtab.h"
static long
i386_get_frame_setup PARAMS ((int));
@ -115,42 +116,48 @@ codestream_read (buf, count)
static void
i386_follow_jump ()
{
int long_delta;
short short_delta;
char byte_delta;
unsigned char buf[4];
long delta;
int data16;
int pos;
CORE_ADDR pos;
pos = codestream_tell ();
data16 = 0;
if (codestream_peek () == 0x66)
{
codestream_get ();
data16 = 1;
}
switch (codestream_get ())
{
case 0xe9:
/* relative jump: if data16 == 0, disp32, else disp16 */
if (data16)
{
codestream_read ((unsigned char *)&short_delta, 2);
codestream_read (buf, 2);
delta = extract_signed_integer (buf, 2);
/* include size of jmp inst (including the 0x66 prefix). */
pos += short_delta + 4;
pos += delta + 4;
}
else
{
codestream_read ((unsigned char *)&long_delta, 4);
pos += long_delta + 5;
codestream_read (buf, 4);
delta = extract_signed_integer (buf, 4);
pos += delta + 5;
}
break;
case 0xeb:
/* relative jump, disp8 (ignore data16) */
codestream_read ((unsigned char *)&byte_delta, 1);
pos += byte_delta + 2;
codestream_read (buf, 1);
/* Sign-extend it. */
delta = extract_signed_integer (buf, 1);
pos += delta + 2;
break;
}
codestream_seek (pos);
@ -169,13 +176,13 @@ i386_get_frame_setup (pc)
int pc;
{
unsigned char op;
codestream_seek (pc);
i386_follow_jump ();
op = codestream_get ();
if (op == 0x58) /* popl %eax */
{
/*
@ -202,11 +209,11 @@ i386_get_frame_setup (pc)
pos += 3;
else if (memcmp (buf, proto2, 4) == 0)
pos += 4;
codestream_seek (pos);
op = codestream_get (); /* update next opcode */
}
if (op == 0x55) /* pushl %ebp */
{
/* check for movl %esp, %ebp - can be written two ways */
@ -441,6 +448,10 @@ i386_skip_prologue (pc)
{
unsigned char op;
int i;
static unsigned char pic_pat[6] = { 0xe8, 0, 0, 0, 0, /* call 0x0 */
0x5b, /* popl %ebx */
};
CORE_ADDR pos;
if (i386_get_frame_setup (pc) < 0)
return (pc);
@ -458,6 +469,54 @@ i386_skip_prologue (pc)
break;
codestream_get ();
}
/* The native cc on SVR4 in -K PIC mode inserts the following code to get
the address of the global offset table (GOT) into register %ebx.
call 0x0
popl %ebx
movl %ebx,x(%ebp) (optional)
addl y,%ebx
This code is with the rest of the prologue (at the end of the
function), so we have to skip it to get to the first real
instruction at the start of the function. */
pos = codestream_tell ();
for (i = 0; i < 6; i++)
{
op = codestream_get ();
if (pic_pat [i] != op)
break;
}
if (i == 6)
{
unsigned char buf[4];
long delta = 6;
op = codestream_get ();
if (op == 0x89) /* movl %ebx, x(%ebp) */
{
op = codestream_get ();
if (op == 0x5d) /* one byte offset from %ebp */
{
delta += 3;
codestream_read (buf, 1);
}
else if (op == 0x9d) /* four byte offset from %ebp */
{
delta += 6;
codestream_read (buf, 4);
}
else /* unexpected instruction */
delta = -1;
op = codestream_get ();
}
/* addl y,%ebx */
if (delta > 0 && op == 0x81 && codestream_get () == 0xc3)
{
pos += delta + 6;
}
}
codestream_seek (pos);
i386_follow_jump ();
@ -565,21 +624,7 @@ i386_extract_return_value(type, regbuf, valbuf)
ieee_extended_to_double (&ext_format_i387,
&regbuf[REGISTER_BYTE(FP0_REGNUM)],
&d);
switch (TYPE_LENGTH(type))
{
case 4: /* float */
{
float f = (float) d;
memcpy (valbuf, &f, 4);
break;
}
case 8: /* double */
memcpy (valbuf, &d, 8);
break;
default:
error("Unknown floating point size");
break;
}
store_floating (valbuf, TYPE_LENGTH (type), d);
}
else
{
@ -587,3 +632,32 @@ i386_extract_return_value(type, regbuf, valbuf)
}
}
#endif /* I386_AIX_TARGET */
#ifdef I386V4_SIGTRAMP_SAVED_PC
/* Get saved user PC for sigtramp from the pushed ucontext on the stack
for all three variants of SVR4 sigtramps. */
CORE_ADDR
i386v4_sigtramp_saved_pc (frame)
FRAME frame;
{
CORE_ADDR saved_pc_offset = 4;
char *name = NULL;
find_pc_partial_function (frame->pc, &name,
(CORE_ADDR *)NULL,(CORE_ADDR *)NULL);
if (name)
{
if (STREQ (name, "_sigreturn"))
saved_pc_offset = 132 + 14 * 4;
if (STREQ (name, "_sigacthandler"))
saved_pc_offset = 80 + 14 * 4;
if (STREQ (name, "sigvechandler"))
saved_pc_offset = 120 + 14 * 4;
}
if (frame->next)
return read_memory_integer (frame->next->frame + saved_pc_offset, 4);
return read_memory_integer (read_register (SP_REGNUM) + saved_pc_offset, 4);
}
#endif /* I386V4_SIGTRAMP_SAVED_PC */