mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-01 13:26:47 +08:00
Add support for "orig_eax" pseudo register on Linux/x86.
* i386-linux-tdep.c: Include "inferior.h". (i386_linux_register_name, i386_linux_register_byte, i386_linux_register_raw_size): New functions. (i386_linux_write_pc): New function. * config/i386/tm-linux.h (I386_LINUX_ORIG_EAX_REGNUM): New define. (NUM_REGS, MAX_NUM_REGS, REGISTER_BYTES, REGISTER_NAME, REGISTER_BYTE, REGISTER_RAW_SIZE): Define to deal with additional register. (i386_linux_register_name, i386_linux_register_byte, i386_linux_register_raw_size): New prototypes. (TARGET_WRITE_PC): New define. (i386_linux_write_pc): New prototype.
This commit is contained in:
parent
1a11ba71e2
commit
6441c4a026
@ -1,5 +1,19 @@
|
||||
2001-11-04 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
Add support for "orig_eax" pseudo register on Linux/x86.
|
||||
* i386-linux-tdep.c: Include "inferior.h".
|
||||
(i386_linux_register_name, i386_linux_register_byte,
|
||||
i386_linux_register_raw_size): New functions.
|
||||
(i386_linux_write_pc): New function.
|
||||
* config/i386/tm-linux.h (I386_LINUX_ORIG_EAX_REGNUM): New define.
|
||||
(NUM_REGS, MAX_NUM_REGS, REGISTER_BYTES, REGISTER_NAME,
|
||||
REGISTER_BYTE, REGISTER_RAW_SIZE): Define to deal with additional
|
||||
register.
|
||||
(i386_linux_register_name, i386_linux_register_byte,
|
||||
i386_linux_register_raw_size): New prototypes.
|
||||
(TARGET_WRITE_PC): New define.
|
||||
(i386_linux_write_pc): New prototype.
|
||||
|
||||
* i386-tdep.c (i386_register_offset): Renamed from
|
||||
i386_register_byte. Made static.
|
||||
(i386_register_size): Renamed from i386_register_raw_size. Made
|
||||
|
@ -31,6 +31,35 @@
|
||||
#include "i386/tm-i386.h"
|
||||
#include "tm-linux.h"
|
||||
|
||||
/* Register number for the "orig_eax" pseudo-register. If this
|
||||
pseudo-register contains a value >= 0 it is interpreted as the
|
||||
system call number that the kernel is supposed to restart. */
|
||||
#define I386_LINUX_ORIG_EAX_REGNUM 41
|
||||
|
||||
/* Adjust a few macros to deal with this extra register. */
|
||||
|
||||
#undef NUM_REGS
|
||||
#define NUM_REGS (NUM_GREGS + NUM_FREGS + NUM_SSE_REGS + 1)
|
||||
|
||||
#undef MAX_NUM_REGS
|
||||
#define MAX_NUM_REGS (16 + 16 + 9 + 1)
|
||||
|
||||
#undef REGISTER_BYTES
|
||||
#define REGISTER_BYTES \
|
||||
(SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS + 4)
|
||||
|
||||
#undef REGISTER_NAME
|
||||
#define REGISTER_NAME(reg) i386_linux_register_name ((reg))
|
||||
extern char *i386_linux_register_name (int reg);
|
||||
|
||||
#undef REGISTER_BYTE
|
||||
#define REGISTER_BYTE(reg) i386_linux_register_byte ((reg))
|
||||
extern int i386_linux_register_byte (int reg);
|
||||
|
||||
#undef REGISTER_RAW_SIZE
|
||||
#define REGISTER_RAW_SIZE(reg) i386_linux_register_raw_size ((reg))
|
||||
extern int i386_linux_register_raw_size (int reg);
|
||||
|
||||
/* Linux/ELF uses stabs-in-ELF with the DWARF register numbering
|
||||
scheme by default, so we must redefine STAB_REG_TO_REGNUM. This
|
||||
messes up the floating-point registers for a.out, but there is not
|
||||
@ -65,6 +94,9 @@ extern CORE_ADDR i386_linux_frame_saved_pc (struct frame_info *frame);
|
||||
#define SAVED_PC_AFTER_CALL(frame) i386_linux_saved_pc_after_call (frame)
|
||||
extern CORE_ADDR i386_linux_saved_pc_after_call (struct frame_info *);
|
||||
|
||||
#define TARGET_WRITE_PC(pc, ptid) i386_linux_write_pc (pc, ptid)
|
||||
extern void i386_linux_write_pc (CORE_ADDR pc, ptid_t ptid);
|
||||
|
||||
/* When we call a function in a shared library, and the PLT sends us
|
||||
into the dynamic linker to find the function's real address, we
|
||||
need to skip over the dynamic linker call. This function decides
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "frame.h"
|
||||
#include "value.h"
|
||||
#include "regcache.h"
|
||||
#include "inferior.h"
|
||||
|
||||
/* For i386_linux_skip_solib_resolver. */
|
||||
#include "symtab.h"
|
||||
@ -31,6 +32,38 @@
|
||||
|
||||
#include "solib-svr4.h" /* For struct link_map_offsets. */
|
||||
|
||||
/* Return the name of register REG. */
|
||||
|
||||
char *
|
||||
i386_linux_register_name (int reg)
|
||||
{
|
||||
/* Deal with the extra "orig_eax" pseudo register. */
|
||||
if (reg == I386_LINUX_ORIG_EAX_REGNUM)
|
||||
return "orig_eax";
|
||||
|
||||
return i386_register_name (reg);
|
||||
}
|
||||
|
||||
int
|
||||
i386_linux_register_byte (int reg)
|
||||
{
|
||||
/* Deal with the extra "orig_eax" pseudo register. */
|
||||
if (reg == I386_LINUX_ORIG_EAX_REGNUM)
|
||||
return (i386_register_byte (I386_LINUX_ORIG_EAX_REGNUM - 1)
|
||||
+ i386_register_raw_size (I386_LINUX_ORIG_EAX_REGNUM - 1));
|
||||
|
||||
return i386_register_byte (reg);
|
||||
}
|
||||
|
||||
int
|
||||
i386_linux_register_raw_size (int reg)
|
||||
{
|
||||
/* Deal with the extra "orig_eax" pseudo register. */
|
||||
if (reg == I386_LINUX_ORIG_EAX_REGNUM)
|
||||
return 4;
|
||||
|
||||
return i386_register_raw_size (reg);
|
||||
}
|
||||
|
||||
/* Recognizing signal handler frames. */
|
||||
|
||||
@ -342,9 +375,33 @@ i386_linux_saved_pc_after_call (struct frame_info *frame)
|
||||
|
||||
return read_memory_unsigned_integer (read_register (SP_REGNUM), 4);
|
||||
}
|
||||
|
||||
|
||||
/* Set the program counter for process PTID to PC. */
|
||||
|
||||
void
|
||||
i386_linux_write_pc (CORE_ADDR pc, ptid_t ptid)
|
||||
{
|
||||
write_register_pid (PC_REGNUM, pc, ptid);
|
||||
|
||||
/* We must be careful with modifying the program counter. If we
|
||||
just interrupted a system call, the kernel might try to restart
|
||||
it when we resume the inferior. On restarting the system call,
|
||||
the kernel will try backing up the program counter even though it
|
||||
no longer points at the system call. This typically results in a
|
||||
SIGSEGV or SIGILL. We can prevent this by writing `-1' in the
|
||||
"orig_eax" pseudo-register.
|
||||
|
||||
Note that "orig_eax" is saved when setting up a dummy call frame.
|
||||
This means that it is properly restored when that frame is
|
||||
popped, and that the interrupted system call will be restarted
|
||||
when we resume the inferior on return from a function call from
|
||||
within GDB. In all other cases the system call will not be
|
||||
restarted. */
|
||||
write_register_pid (I386_LINUX_ORIG_EAX_REGNUM, -1, ptid);
|
||||
}
|
||||
|
||||
/* Calling functions in shared libraries. */
|
||||
|
||||
/* Find the minimal symbol named NAME, and return both the minsym
|
||||
struct and its objfile. This probably ought to be in minsym.c, but
|
||||
everything there is trying to deal with things like C++ and
|
||||
|
Loading…
Reference in New Issue
Block a user