diff options
author | Jeff Dike <jdike@addtoit.com> | 2006-09-27 04:50:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-27 11:26:16 -0400 |
commit | a8b4fc4d7c3ccf80d4fa1805cee85c06c2aa653e (patch) | |
tree | 55cc6eed8fccc96d5a50b2e947cc85f8caba7242 /arch/um/include/sysdep-x86_64/ptrace.h | |
parent | 0715501bf1d915002d92e34e8a78ea889e5a0049 (diff) |
[PATCH] uml: fix missing x86_64 register definitions
The UML/x86_64 headers were missing ptrace support for some segment registers.
The underlying problem was that the x86_64 kernel uses user_regs_struct
rather than the ptrace register definitions in ptrace. This patch switches
UML/x86_64 to using user_regs_struct for its definitions of the host's
registers.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/include/sysdep-x86_64/ptrace.h')
-rw-r--r-- | arch/um/include/sysdep-x86_64/ptrace.h | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h index 8d353f0feec1..617bb9efc934 100644 --- a/arch/um/include/sysdep-x86_64/ptrace.h +++ b/arch/um/include/sysdep-x86_64/ptrace.h | |||
@@ -50,6 +50,21 @@ | |||
50 | #define HOST_FS 25 | 50 | #define HOST_FS 25 |
51 | #define HOST_GS 26 | 51 | #define HOST_GS 26 |
52 | 52 | ||
53 | /* Also defined in asm/ptrace-x86_64.h, but not in libc headers. So, these | ||
54 | * are already defined for kernel code, but not for userspace code. | ||
55 | */ | ||
56 | #ifndef FS_BASE | ||
57 | /* These aren't defined in ptrace.h, but exist in struct user_regs_struct, | ||
58 | * which is what x86_64 ptrace actually uses. | ||
59 | */ | ||
60 | #define FS_BASE (HOST_FS_BASE * sizeof(long)) | ||
61 | #define GS_BASE (HOST_GS_BASE * sizeof(long)) | ||
62 | #define DS (HOST_DS * sizeof(long)) | ||
63 | #define ES (HOST_ES * sizeof(long)) | ||
64 | #define FS (HOST_FS * sizeof(long)) | ||
65 | #define GS (HOST_GS * sizeof(long)) | ||
66 | #endif | ||
67 | |||
53 | #define REGS_FS_BASE(r) ((r)[HOST_FS_BASE]) | 68 | #define REGS_FS_BASE(r) ((r)[HOST_FS_BASE]) |
54 | #define REGS_GS_BASE(r) ((r)[HOST_GS_BASE]) | 69 | #define REGS_GS_BASE(r) ((r)[HOST_GS_BASE]) |
55 | #define REGS_DS(r) ((r)[HOST_DS]) | 70 | #define REGS_DS(r) ((r)[HOST_DS]) |
@@ -89,9 +104,12 @@ union uml_pt_regs { | |||
89 | #endif | 104 | #endif |
90 | #ifdef UML_CONFIG_MODE_SKAS | 105 | #ifdef UML_CONFIG_MODE_SKAS |
91 | struct skas_regs { | 106 | struct skas_regs { |
92 | /* XXX */ | 107 | /* x86_64 ptrace uses sizeof(user_regs_struct) as its register |
93 | unsigned long regs[27]; | 108 | * file size, while i386 uses FRAME_SIZE. Therefore, we need |
94 | unsigned long fp[65]; | 109 | * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE. |
110 | */ | ||
111 | unsigned long regs[UM_FRAME_SIZE]; | ||
112 | unsigned long fp[HOST_FP_SIZE]; | ||
95 | struct faultinfo faultinfo; | 113 | struct faultinfo faultinfo; |
96 | long syscall; | 114 | long syscall; |
97 | int is_user; | 115 | int is_user; |
@@ -120,11 +138,16 @@ extern int mode_tt; | |||
120 | #define UPT_R14(r) __CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs)) | 138 | #define UPT_R14(r) __CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs)) |
121 | #define UPT_R15(r) __CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs)) | 139 | #define UPT_R15(r) __CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs)) |
122 | #define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) | 140 | #define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) |
141 | #define UPT_FS_BASE(r) \ | ||
142 | __CHOOSE_MODE(SC_FS_BASE(UPT_SC(r)), REGS_FS_BASE((r)->skas.regs)) | ||
123 | #define UPT_FS(r) __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs)) | 143 | #define UPT_FS(r) __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs)) |
144 | #define UPT_GS_BASE(r) \ | ||
145 | __CHOOSE_MODE(SC_GS_BASE(UPT_SC(r)), REGS_GS_BASE((r)->skas.regs)) | ||
124 | #define UPT_GS(r) __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs)) | 146 | #define UPT_GS(r) __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs)) |
125 | #define UPT_DS(r) __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs)) | 147 | #define UPT_DS(r) __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs)) |
126 | #define UPT_ES(r) __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs)) | 148 | #define UPT_ES(r) __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs)) |
127 | #define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) | 149 | #define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) |
150 | #define UPT_SS(r) __CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs)) | ||
128 | #define UPT_ORIG_RAX(r) \ | 151 | #define UPT_ORIG_RAX(r) \ |
129 | __CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs)) | 152 | __CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs)) |
130 | 153 | ||
@@ -183,6 +206,13 @@ struct syscall_args { | |||
183 | case RBP: val = UPT_RBP(regs); break; \ | 206 | case RBP: val = UPT_RBP(regs); break; \ |
184 | case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ | 207 | case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ |
185 | case CS: val = UPT_CS(regs); break; \ | 208 | case CS: val = UPT_CS(regs); break; \ |
209 | case SS: val = UPT_SS(regs); break; \ | ||
210 | case FS_BASE: val = UPT_FS_BASE(regs); break; \ | ||
211 | case GS_BASE: val = UPT_GS_BASE(regs); break; \ | ||
212 | case DS: val = UPT_DS(regs); break; \ | ||
213 | case ES: val = UPT_ES(regs); break; \ | ||
214 | case FS : val = UPT_FS (regs); break; \ | ||
215 | case GS: val = UPT_GS(regs); break; \ | ||
186 | case EFLAGS: val = UPT_EFLAGS(regs); break; \ | 216 | case EFLAGS: val = UPT_EFLAGS(regs); break; \ |
187 | default : \ | 217 | default : \ |
188 | panic("Bad register in UPT_REG : %d\n", reg); \ | 218 | panic("Bad register in UPT_REG : %d\n", reg); \ |
@@ -214,6 +244,13 @@ struct syscall_args { | |||
214 | case RBP: UPT_RBP(regs) = __upt_val; break; \ | 244 | case RBP: UPT_RBP(regs) = __upt_val; break; \ |
215 | case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ | 245 | case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ |
216 | case CS: UPT_CS(regs) = __upt_val; break; \ | 246 | case CS: UPT_CS(regs) = __upt_val; break; \ |
247 | case SS: UPT_SS(regs) = __upt_val; break; \ | ||
248 | case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \ | ||
249 | case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \ | ||
250 | case DS: UPT_DS(regs) = __upt_val; break; \ | ||
251 | case ES: UPT_ES(regs) = __upt_val; break; \ | ||
252 | case FS: UPT_FS(regs) = __upt_val; break; \ | ||
253 | case GS: UPT_GS(regs) = __upt_val; break; \ | ||
217 | case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ | 254 | case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ |
218 | default : \ | 255 | default : \ |
219 | panic("Bad register in UPT_SET : %d\n", reg); \ | 256 | panic("Bad register in UPT_SET : %d\n", reg); \ |