Patchwork [16/36] x86 Linux/ptrace: fix offsetof usage in C++ mode

login
register
mail settings
Submitter Pedro Alves
Date Feb. 9, 2015, 11:20 p.m.
Message ID <1423524046-20605-17-git-send-email-palves@redhat.com>
Download mbox | patch
Permalink /patch/4991/
State New
Headers show

Comments

Pedro Alves - Feb. 9, 2015, 11:20 p.m.
In C++ mode, we get:

  gdb/gdbserver/linux-x86-low.c: In function ‘void x86_linux_dr_set(ptid_t, int, long unsigned int)’:
  gdb/gdbserver/linux-x86-low.c:558:38: error: ‘regnum’ cannot appear in a constant-expression
      offsetof (struct user, u_debugreg[regnum]), value);
                                      ^
gdb/gdbserver/ChangeLog:
2015-02-09  Pedro Alves  <palves@redhat.com>

	* linux-x86-low.c (u_debugreg_offset): New function.
	(x86_linux_dr_get, x86_linux_dr_set): Use it.

gdb/ChangeLog:
2015-02-09  Pedro Alves  <palves@redhat.com>

	* x86-linux-nat.c (u_debugreg_offset): New function.
	(x86_linux_dr_get, x86_linux_dr_set): Use it.
---
 gdb/gdbserver/linux-x86-low.c | 18 ++++++++++++++----
 gdb/x86-linux-nat.c           | 17 +++++++++++++----
 2 files changed, 27 insertions(+), 8 deletions(-)

Patch

diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index eff2847..c70da3d 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -527,6 +527,18 @@  x86_breakpoint_at (CORE_ADDR pc)
   return 0;
 }
 
+
+/* Return the offset of REGNUM in the u_debugreg field of struct
+   user.  */
+
+static int
+u_debugreg_offset (int regnum)
+{
+  return (offsetof (struct user, u_debugreg)
+	  + sizeof (((struct user *) 0)->u_debugreg[0]) * regnum);
+}
+
+
 /* Support for debug registers.  */
 
 static unsigned long
@@ -538,8 +550,7 @@  x86_linux_dr_get (ptid_t ptid, int regnum)
   tid = ptid_get_lwp (ptid);
 
   errno = 0;
-  value = ptrace (PTRACE_PEEKUSER, tid,
-		  offsetof (struct user, u_debugreg[regnum]), 0);
+  value = ptrace (PTRACE_PEEKUSER, tid, u_debugreg_offset (regnum), 0);
   if (errno != 0)
     error ("Couldn't read debug register");
 
@@ -554,8 +565,7 @@  x86_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
   tid = ptid_get_lwp (ptid);
 
   errno = 0;
-  ptrace (PTRACE_POKEUSER, tid,
-	  offsetof (struct user, u_debugreg[regnum]), value);
+  ptrace (PTRACE_POKEUSER, tid, u_debugreg_offset (regnum), value);
   if (errno != 0)
     error ("Couldn't write debug register");
 }
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
index 9d82be2..c58c01a 100644
--- a/gdb/x86-linux-nat.c
+++ b/gdb/x86-linux-nat.c
@@ -51,6 +51,16 @@  struct arch_lwp_info
 int have_ptrace_getregset = -1;
 
 
+/* Return the offset of REGNUM in the u_debugreg field of struct
+   user.  */
+
+static int
+u_debugreg_offset (int regnum)
+{
+  return (offsetof (struct user, u_debugreg)
+	  + sizeof (((struct user *) 0)->u_debugreg[0]) * regnum);
+}
+
 /* Support for debug registers.  */
 
 /* Get debug register REGNUM value from only the one LWP of PTID.  */
@@ -65,8 +75,8 @@  x86_linux_dr_get (ptid_t ptid, int regnum)
   tid = ptid_get_lwp (ptid);
 
   errno = 0;
-  value = ptrace (PTRACE_PEEKUSER, tid,
-		  offsetof (struct user, u_debugreg[regnum]), 0);
+  value = ptrace (PTRACE_PEEKUSER, tid, u_debugreg_offset (regnum), 0);
+
   if (errno != 0)
     perror_with_name (_("Couldn't read debug register"));
 
@@ -84,8 +94,7 @@  x86_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
   tid = ptid_get_lwp (ptid);
 
   errno = 0;
-  ptrace (PTRACE_POKEUSER, tid,
-	  offsetof (struct user, u_debugreg[regnum]), value);
+  ptrace (PTRACE_POKEUSER, tid, u_debugreg_offset (regnum), value);
   if (errno != 0)
     perror_with_name (_("Couldn't write debug register"));
 }