diff options
Diffstat (limited to 'gdb/nat/x86-linux.c')
-rw-r--r-- | gdb/nat/x86-linux.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/gdb/nat/x86-linux.c b/gdb/nat/x86-linux.c index 7a21c8f..ad3ed3c 100644 --- a/gdb/nat/x86-linux.c +++ b/gdb/nat/x86-linux.c @@ -19,6 +19,8 @@ #include "x86-linux.h" #include "x86-linux-dregs.h" +#include "nat/gdb_ptrace.h" +#include <sys/user.h> /* Per-thread arch-specific data we want to keep. */ @@ -79,3 +81,48 @@ x86_linux_prepare_to_resume (struct lwp_info *lwp) { x86_linux_update_debug_registers (lwp); } + +#ifdef __x86_64__ +/* Value of CS segment register: + 64bit process: 0x33 + 32bit process: 0x23 */ +#define AMD64_LINUX_USER64_CS 0x33 + +/* Value of DS segment register: + LP64 process: 0x0 + X32 process: 0x2b */ +#define AMD64_LINUX_X32_DS 0x2b +#endif + +/* See nat/x86-linux.h. */ + +x86_linux_arch_size +x86_linux_ptrace_get_arch_size (int tid) +{ +#ifdef __x86_64__ + unsigned long cs; + unsigned long ds; + + /* Get CS register. */ + errno = 0; + cs = ptrace (PTRACE_PEEKUSER, tid, + offsetof (struct user_regs_struct, cs), 0); + if (errno != 0) + perror_with_name (_("Couldn't get CS register")); + + bool is_64bit = cs == AMD64_LINUX_USER64_CS; + + /* Get DS register. */ + errno = 0; + ds = ptrace (PTRACE_PEEKUSER, tid, + offsetof (struct user_regs_struct, ds), 0); + if (errno != 0) + perror_with_name (_("Couldn't get DS register")); + + bool is_x32 = ds == AMD64_LINUX_X32_DS; + + return x86_linux_arch_size (is_64bit, is_x32); +#else + return x86_linux_arch_size (false, false); +#endif +} |