@@ -258,7 +258,7 @@ static int genregs64_get(struct task_struct *target,
258
258
ret = user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
259
259
regs -> u_regs ,
260
260
0 , 16 * sizeof (u64 ));
261
- if (!ret && count && pos < ( 32 * sizeof ( u64 )) ) {
261
+ if (!ret && count ) {
262
262
struct reg_window window ;
263
263
264
264
if (regwindow64_get (target , regs , & window ))
@@ -506,6 +506,57 @@ static const struct user_regset sparc64_regsets[] = {
506
506
},
507
507
};
508
508
509
+ static int getregs64_get (struct task_struct * target ,
510
+ const struct user_regset * regset ,
511
+ unsigned int pos , unsigned int count ,
512
+ void * kbuf , void __user * ubuf )
513
+ {
514
+ const struct pt_regs * regs = task_pt_regs (target );
515
+ int ret ;
516
+
517
+ if (target == current )
518
+ flushw_user ();
519
+
520
+ ret = user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
521
+ regs -> u_regs + 1 ,
522
+ 0 , 15 * sizeof (u64 ));
523
+ if (!ret )
524
+ ret = user_regset_copyout_zero (& pos , & count , & kbuf , & ubuf ,
525
+ 15 * sizeof (u64 ), 16 * sizeof (u64 ));
526
+ if (!ret ) {
527
+ /* TSTATE, TPC, TNPC */
528
+ ret = user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
529
+ & regs -> tstate ,
530
+ 16 * sizeof (u64 ),
531
+ 19 * sizeof (u64 ));
532
+ }
533
+ if (!ret ) {
534
+ unsigned long y = regs -> y ;
535
+
536
+ ret = user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
537
+ & y ,
538
+ 19 * sizeof (u64 ),
539
+ 20 * sizeof (u64 ));
540
+ }
541
+ return ret ;
542
+ }
543
+
544
+ static const struct user_regset ptrace64_regsets [] = {
545
+ /* Format is:
546
+ * G1 --> G7
547
+ * O0 --> O7
548
+ * 0
549
+ * TSTATE, TPC, TNPC, Y
550
+ */
551
+ [REGSET_GENERAL ] = {
552
+ .n = 20 , .size = sizeof (u64 ), .get = getregs64_get ,
553
+ },
554
+ };
555
+
556
+ static const struct user_regset_view ptrace64_view = {
557
+ .regsets = ptrace64_regsets , .n = ARRAY_SIZE (ptrace64_regsets )
558
+ };
559
+
509
560
static const struct user_regset_view user_sparc64_view = {
510
561
.name = "sparc64" , .e_machine = EM_SPARCV9 ,
511
562
.regsets = sparc64_regsets , .n = ARRAY_SIZE (sparc64_regsets )
@@ -533,7 +584,7 @@ static int genregs32_get(struct task_struct *target,
533
584
for (; count > 0 && pos < 16 ; count -- )
534
585
* k ++ = regs -> u_regs [pos ++ ];
535
586
536
- if (count && pos < 32 ) {
587
+ if (count ) {
537
588
if (get_from_target (target , regs -> u_regs [UREG_I6 ],
538
589
uregs , sizeof (uregs )))
539
590
return - EFAULT ;
@@ -545,7 +596,7 @@ static int genregs32_get(struct task_struct *target,
545
596
for (; count > 0 && pos < 16 ; count -- )
546
597
if (put_user ((compat_ulong_t ) regs -> u_regs [pos ++ ], u ++ ))
547
598
return - EFAULT ;
548
- if (count && pos < 32 ) {
599
+ if (count ) {
549
600
if (get_from_target (target , regs -> u_regs [UREG_I6 ],
550
601
uregs , sizeof (uregs )))
551
602
return - EFAULT ;
@@ -840,6 +891,76 @@ static const struct user_regset sparc32_regsets[] = {
840
891
},
841
892
};
842
893
894
+ static int getregs_get (struct task_struct * target ,
895
+ const struct user_regset * regset ,
896
+ unsigned int pos , unsigned int count ,
897
+ void * kbuf , void __user * ubuf )
898
+ {
899
+ const struct pt_regs * regs = task_pt_regs (target );
900
+ u32 uregs [19 ];
901
+ int i ;
902
+
903
+ if (target == current )
904
+ flushw_user ();
905
+
906
+ uregs [0 ] = tstate_to_psr (regs -> tstate );
907
+ uregs [1 ] = regs -> tpc ;
908
+ uregs [2 ] = regs -> tnpc ;
909
+ uregs [3 ] = regs -> y ;
910
+ for (i = 1 ; i < 16 ; i ++ )
911
+ uregs [3 + i ] = regs -> u_regs [i ];
912
+ return user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
913
+ uregs ,
914
+ 0 , 19 * sizeof (u32 ));
915
+ }
916
+
917
+ static int getfpregs_get (struct task_struct * target ,
918
+ const struct user_regset * regset ,
919
+ unsigned int pos , unsigned int count ,
920
+ void * kbuf , void __user * ubuf )
921
+ {
922
+ const unsigned long * fpregs = task_thread_info (target )-> fpregs ;
923
+ unsigned long fprs ;
924
+ compat_ulong_t fsr ;
925
+ int ret = 0 ;
926
+
927
+ if (target == current )
928
+ save_and_clear_fpu ();
929
+
930
+ fprs = task_thread_info (target )-> fpsaved [0 ];
931
+ if (fprs & FPRS_FEF ) {
932
+ fsr = task_thread_info (target )-> xfsr [0 ];
933
+ } else {
934
+ fsr = 0 ;
935
+ }
936
+
937
+ ret = user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
938
+ fpregs ,
939
+ 0 , 32 * sizeof (u32 ));
940
+ if (!ret )
941
+ ret = user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
942
+ & fsr ,
943
+ 32 * sizeof (u32 ),
944
+ 33 * sizeof (u32 ));
945
+ if (!ret )
946
+ ret = user_regset_copyout_zero (& pos , & count , & kbuf , & ubuf ,
947
+ 33 * sizeof (u32 ), 68 * sizeof (u32 ));
948
+ return ret ;
949
+ }
950
+
951
+ static const struct user_regset ptrace32_regsets [] = {
952
+ [REGSET_GENERAL ] = {
953
+ .n = 19 , .size = sizeof (u32 ), .get = getregs_get ,
954
+ },
955
+ [REGSET_FP ] = {
956
+ .n = 68 , .size = sizeof (u32 ), .get = getfpregs_get ,
957
+ },
958
+ };
959
+
960
+ static const struct user_regset_view ptrace32_view = {
961
+ .regsets = ptrace32_regsets , .n = ARRAY_SIZE (ptrace32_regsets )
962
+ };
963
+
843
964
static const struct user_regset_view user_sparc32_view = {
844
965
.name = "sparc" , .e_machine = EM_SPARC ,
845
966
.regsets = sparc32_regsets , .n = ARRAY_SIZE (sparc32_regsets )
@@ -889,15 +1010,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
889
1010
break ;
890
1011
891
1012
case PTRACE_GETREGS :
892
- ret = copy_regset_to_user (child , view , REGSET_GENERAL ,
893
- 32 * sizeof (u32 ),
894
- 4 * sizeof (u32 ),
895
- & pregs -> psr );
896
- if (!ret )
897
- ret = copy_regset_to_user (child , view , REGSET_GENERAL ,
898
- 1 * sizeof (u32 ),
899
- 15 * sizeof (u32 ),
900
- & pregs -> u_regs [0 ]);
1013
+ ret = copy_regset_to_user (child , & ptrace32_view ,
1014
+ REGSET_GENERAL , 0 ,
1015
+ 19 * sizeof (u32 ),
1016
+ pregs );
901
1017
break ;
902
1018
903
1019
case PTRACE_SETREGS :
@@ -913,22 +1029,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
913
1029
break ;
914
1030
915
1031
case PTRACE_GETFPREGS :
916
- ret = copy_regset_to_user (child , view , REGSET_FP ,
917
- 0 * sizeof (u32 ),
918
- 32 * sizeof (u32 ),
919
- & fps -> regs [0 ]);
920
- if (!ret )
921
- ret = copy_regset_to_user (child , view , REGSET_FP ,
922
- 33 * sizeof (u32 ),
923
- 1 * sizeof (u32 ),
924
- & fps -> fsr );
925
- if (!ret ) {
926
- if (__put_user (0 , & fps -> flags ) ||
927
- __put_user (0 , & fps -> extra ) ||
928
- __put_user (0 , & fps -> fpqd ) ||
929
- clear_user (& fps -> fpq [0 ], 32 * sizeof (unsigned int )))
930
- ret = - EFAULT ;
931
- }
1032
+ ret = copy_regset_to_user (child , & ptrace32_view ,
1033
+ REGSET_FP , 0 ,
1034
+ 68 * sizeof (u32 ),
1035
+ fps );
932
1036
break ;
933
1037
934
1038
case PTRACE_SETFPREGS :
@@ -999,17 +1103,10 @@ long arch_ptrace(struct task_struct *child, long request,
999
1103
break ;
1000
1104
1001
1105
case PTRACE_GETREGS64 :
1002
- ret = copy_regset_to_user (child , view , REGSET_GENERAL ,
1003
- 1 * sizeof (u64 ),
1004
- 15 * sizeof (u64 ),
1005
- & pregs -> u_regs [0 ]);
1006
- if (!ret ) {
1007
- /* XXX doesn't handle 'y' register correctly XXX */
1008
- ret = copy_regset_to_user (child , view , REGSET_GENERAL ,
1009
- 32 * sizeof (u64 ),
1010
- 4 * sizeof (u64 ),
1011
- & pregs -> tstate );
1012
- }
1106
+ ret = copy_regset_to_user (child , & ptrace64_view ,
1107
+ REGSET_GENERAL , 0 ,
1108
+ 19 * sizeof (u64 ),
1109
+ pregs );
1013
1110
break ;
1014
1111
1015
1112
case PTRACE_SETREGS64 :
0 commit comments