diff options
| -rw-r--r-- | arch/arm64/kernel/ptrace.c | 35 | ||||
| -rw-r--r-- | include/uapi/linux/elf.h | 1 |
2 files changed, 36 insertions, 0 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 8a4ae8e73213..f576781d8d3b 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c | |||
| @@ -551,6 +551,32 @@ static int tls_set(struct task_struct *target, const struct user_regset *regset, | |||
| 551 | return ret; | 551 | return ret; |
| 552 | } | 552 | } |
| 553 | 553 | ||
| 554 | static int system_call_get(struct task_struct *target, | ||
| 555 | const struct user_regset *regset, | ||
| 556 | unsigned int pos, unsigned int count, | ||
| 557 | void *kbuf, void __user *ubuf) | ||
| 558 | { | ||
| 559 | int syscallno = task_pt_regs(target)->syscallno; | ||
| 560 | |||
| 561 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | ||
| 562 | &syscallno, 0, -1); | ||
| 563 | } | ||
| 564 | |||
| 565 | static int system_call_set(struct task_struct *target, | ||
| 566 | const struct user_regset *regset, | ||
| 567 | unsigned int pos, unsigned int count, | ||
| 568 | const void *kbuf, const void __user *ubuf) | ||
| 569 | { | ||
| 570 | int syscallno, ret; | ||
| 571 | |||
| 572 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &syscallno, 0, -1); | ||
| 573 | if (ret) | ||
| 574 | return ret; | ||
| 575 | |||
| 576 | task_pt_regs(target)->syscallno = syscallno; | ||
| 577 | return ret; | ||
| 578 | } | ||
| 579 | |||
| 554 | enum aarch64_regset { | 580 | enum aarch64_regset { |
| 555 | REGSET_GPR, | 581 | REGSET_GPR, |
| 556 | REGSET_FPR, | 582 | REGSET_FPR, |
| @@ -559,6 +585,7 @@ enum aarch64_regset { | |||
| 559 | REGSET_HW_BREAK, | 585 | REGSET_HW_BREAK, |
| 560 | REGSET_HW_WATCH, | 586 | REGSET_HW_WATCH, |
| 561 | #endif | 587 | #endif |
| 588 | REGSET_SYSTEM_CALL, | ||
| 562 | }; | 589 | }; |
| 563 | 590 | ||
| 564 | static const struct user_regset aarch64_regsets[] = { | 591 | static const struct user_regset aarch64_regsets[] = { |
| @@ -608,6 +635,14 @@ static const struct user_regset aarch64_regsets[] = { | |||
| 608 | .set = hw_break_set, | 635 | .set = hw_break_set, |
| 609 | }, | 636 | }, |
| 610 | #endif | 637 | #endif |
| 638 | [REGSET_SYSTEM_CALL] = { | ||
| 639 | .core_note_type = NT_ARM_SYSTEM_CALL, | ||
| 640 | .n = 1, | ||
| 641 | .size = sizeof(int), | ||
| 642 | .align = sizeof(int), | ||
| 643 | .get = system_call_get, | ||
| 644 | .set = system_call_set, | ||
| 645 | }, | ||
| 611 | }; | 646 | }; |
| 612 | 647 | ||
| 613 | static const struct user_regset_view user_aarch64_view = { | 648 | static const struct user_regset_view user_aarch64_view = { |
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index ea9bf2561b9e..71e1d0ed92f7 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h | |||
| @@ -397,6 +397,7 @@ typedef struct elf64_shdr { | |||
| 397 | #define NT_ARM_TLS 0x401 /* ARM TLS register */ | 397 | #define NT_ARM_TLS 0x401 /* ARM TLS register */ |
| 398 | #define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ | 398 | #define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ |
| 399 | #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ | 399 | #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ |
| 400 | #define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ | ||
| 400 | #define NT_METAG_CBUF 0x500 /* Metag catch buffer registers */ | 401 | #define NT_METAG_CBUF 0x500 /* Metag catch buffer registers */ |
| 401 | #define NT_METAG_RPIPE 0x501 /* Metag read pipeline state */ | 402 | #define NT_METAG_RPIPE 0x501 /* Metag read pipeline state */ |
| 402 | #define NT_METAG_TLS 0x502 /* Metag TLS pointer */ | 403 | #define NT_METAG_TLS 0x502 /* Metag TLS pointer */ |
