diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/ptrace.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index ef349ff170a7..196cc27bd39a 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/ptrace.h> | 15 | #include <linux/ptrace.h> |
16 | #include <linux/regset.h> | 16 | #include <linux/regset.h> |
17 | #include <linux/user.h> | 17 | #include <linux/user.h> |
18 | #include <linux/elf.h> | ||
18 | #include <linux/security.h> | 19 | #include <linux/security.h> |
19 | #include <linux/audit.h> | 20 | #include <linux/audit.h> |
20 | #include <linux/seccomp.h> | 21 | #include <linux/seccomp.h> |
@@ -32,6 +33,14 @@ | |||
32 | #include <asm/proto.h> | 33 | #include <asm/proto.h> |
33 | #include <asm/ds.h> | 34 | #include <asm/ds.h> |
34 | 35 | ||
36 | #include "tls.h" | ||
37 | |||
38 | enum x86_regset { | ||
39 | REGSET_GENERAL, | ||
40 | REGSET_FP, | ||
41 | REGSET_XFP, | ||
42 | REGSET_TLS, | ||
43 | }; | ||
35 | 44 | ||
36 | /* | 45 | /* |
37 | * does not yet catch signals sent when the child dies. | 46 | * does not yet catch signals sent when the child dies. |
@@ -1335,6 +1344,84 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) | |||
1335 | 1344 | ||
1336 | #endif /* CONFIG_IA32_EMULATION */ | 1345 | #endif /* CONFIG_IA32_EMULATION */ |
1337 | 1346 | ||
1347 | #ifdef CONFIG_X86_64 | ||
1348 | |||
1349 | static const struct user_regset x86_64_regsets[] = { | ||
1350 | [REGSET_GENERAL] = { | ||
1351 | .core_note_type = NT_PRSTATUS, | ||
1352 | .n = sizeof(struct user_regs_struct) / sizeof(long), | ||
1353 | .size = sizeof(long), .align = sizeof(long), | ||
1354 | .get = genregs_get, .set = genregs_set | ||
1355 | }, | ||
1356 | [REGSET_FP] = { | ||
1357 | .core_note_type = NT_PRFPREG, | ||
1358 | .n = sizeof(struct user_i387_struct) / sizeof(long), | ||
1359 | .size = sizeof(long), .align = sizeof(long), | ||
1360 | .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set | ||
1361 | }, | ||
1362 | }; | ||
1363 | |||
1364 | static const struct user_regset_view user_x86_64_view = { | ||
1365 | .name = "x86_64", .e_machine = EM_X86_64, | ||
1366 | .regsets = x86_64_regsets, .n = ARRAY_SIZE(x86_64_regsets) | ||
1367 | }; | ||
1368 | |||
1369 | #else /* CONFIG_X86_32 */ | ||
1370 | |||
1371 | #define user_regs_struct32 user_regs_struct | ||
1372 | #define genregs32_get genregs_get | ||
1373 | #define genregs32_set genregs_set | ||
1374 | |||
1375 | #endif /* CONFIG_X86_64 */ | ||
1376 | |||
1377 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION | ||
1378 | static const struct user_regset x86_32_regsets[] = { | ||
1379 | [REGSET_GENERAL] = { | ||
1380 | .core_note_type = NT_PRSTATUS, | ||
1381 | .n = sizeof(struct user_regs_struct32) / sizeof(u32), | ||
1382 | .size = sizeof(u32), .align = sizeof(u32), | ||
1383 | .get = genregs32_get, .set = genregs32_set | ||
1384 | }, | ||
1385 | [REGSET_FP] = { | ||
1386 | .core_note_type = NT_PRFPREG, | ||
1387 | .n = sizeof(struct user_i387_struct) / sizeof(u32), | ||
1388 | .size = sizeof(u32), .align = sizeof(u32), | ||
1389 | .active = fpregs_active, .get = fpregs_get, .set = fpregs_set | ||
1390 | }, | ||
1391 | [REGSET_XFP] = { | ||
1392 | .core_note_type = NT_PRXFPREG, | ||
1393 | .n = sizeof(struct user_i387_struct) / sizeof(u32), | ||
1394 | .size = sizeof(u32), .align = sizeof(u32), | ||
1395 | .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set | ||
1396 | }, | ||
1397 | [REGSET_TLS] = { | ||
1398 | .n = GDT_ENTRY_TLS_ENTRIES, .bias = GDT_ENTRY_TLS_MIN, | ||
1399 | .size = sizeof(struct user_desc), | ||
1400 | .align = sizeof(struct user_desc), | ||
1401 | .active = regset_tls_active, | ||
1402 | .get = regset_tls_get, .set = regset_tls_set | ||
1403 | }, | ||
1404 | }; | ||
1405 | |||
1406 | static const struct user_regset_view user_x86_32_view = { | ||
1407 | .name = "i386", .e_machine = EM_386, | ||
1408 | .regsets = x86_32_regsets, .n = ARRAY_SIZE(x86_32_regsets) | ||
1409 | }; | ||
1410 | #endif | ||
1411 | |||
1412 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) | ||
1413 | { | ||
1414 | #ifdef CONFIG_IA32_EMULATION | ||
1415 | if (test_tsk_thread_flag(task, TIF_IA32)) | ||
1416 | #endif | ||
1417 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION | ||
1418 | return &user_x86_32_view; | ||
1419 | #endif | ||
1420 | #ifdef CONFIG_X86_64 | ||
1421 | return &user_x86_64_view; | ||
1422 | #endif | ||
1423 | } | ||
1424 | |||
1338 | #ifdef CONFIG_X86_32 | 1425 | #ifdef CONFIG_X86_32 |
1339 | 1426 | ||
1340 | void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) | 1427 | void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) |