Add support for "orig_eax" pseudo register on Linux/x86.
authorMark Kettenis <kettenis@gnu.org>
Sun, 4 Nov 2001 14:06:16 +0000 (14:06 +0000)
committerMark Kettenis <kettenis@gnu.org>
Sun, 4 Nov 2001 14:06:16 +0000 (14:06 +0000)
* 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.

gdb/ChangeLog
gdb/config/i386/tm-linux.h
gdb/i386-linux-tdep.c

index bf2af41990ab939f2d0662a603ecf80fe264bd1f..e1aac69c44a7722526e7bdea00b8411f699f1bb3 100644 (file)
@@ -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
index 77eb0c681ccc6e85b53dfdfda7d7d2f862d803c6..25d978235a40e94cdacc5e9a3e40c04d4f1df74f 100644 (file)
 #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
index 1949b0e203c0ab597126e7dda1f888a7384fda4c..aae44bcc4fc1f61471307ca46fa4fbd4d8590155 100644 (file)
@@ -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"
 
 #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);
+}
 \f
 /* 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);
 }
-\f
 
+/* 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);
+}
+\f
 /* 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