@@ -1491,10 +1491,7 @@ access_elf_reg(struct task_struct *target, struct unw_frame_info *info,
1491
1491
1492
1492
void do_gpregs_get (struct unw_frame_info * info , void * arg )
1493
1493
{
1494
- struct pt_regs * pt ;
1495
1494
struct regset_getset * dst = arg ;
1496
- elf_greg_t tmp [16 ];
1497
- unsigned int i , index , min_copy ;
1498
1495
1499
1496
if (unw_unwind_to_user (info ) < 0 )
1500
1497
return ;
@@ -1517,160 +1514,70 @@ void do_gpregs_get(struct unw_frame_info *info, void *arg)
1517
1514
& dst -> u .get .kbuf ,
1518
1515
& dst -> u .get .ubuf ,
1519
1516
0 , ELF_GR_OFFSET (1 ));
1520
- if (dst -> ret || dst -> count == 0 )
1521
- return ;
1522
- }
1523
-
1524
- /* gr1 - gr15 */
1525
- if (dst -> count > 0 && dst -> pos < ELF_GR_OFFSET (16 )) {
1526
- index = (dst -> pos - ELF_GR_OFFSET (1 )) / sizeof (elf_greg_t );
1527
- min_copy = ELF_GR_OFFSET (16 ) > (dst -> pos + dst -> count ) ?
1528
- (dst -> pos + dst -> count ) : ELF_GR_OFFSET (16 );
1529
- for (i = dst -> pos ; i < min_copy ; i += sizeof (elf_greg_t ),
1530
- index ++ )
1531
- if (access_elf_reg (dst -> target , info , i ,
1532
- & tmp [index ], 0 ) < 0 ) {
1533
- dst -> ret = - EIO ;
1534
- return ;
1535
- }
1536
- dst -> ret = user_regset_copyout (& dst -> pos , & dst -> count ,
1537
- & dst -> u .get .kbuf , & dst -> u .get .ubuf , tmp ,
1538
- ELF_GR_OFFSET (1 ), ELF_GR_OFFSET (16 ));
1539
- if (dst -> ret || dst -> count == 0 )
1540
- return ;
1541
- }
1542
-
1543
- /* r16-r31 */
1544
- if (dst -> count > 0 && dst -> pos < ELF_NAT_OFFSET ) {
1545
- pt = task_pt_regs (dst -> target );
1546
- dst -> ret = user_regset_copyout (& dst -> pos , & dst -> count ,
1547
- & dst -> u .get .kbuf , & dst -> u .get .ubuf , & pt -> r16 ,
1548
- ELF_GR_OFFSET (16 ), ELF_NAT_OFFSET );
1549
- if (dst -> ret || dst -> count == 0 )
1517
+ if (dst -> ret )
1550
1518
return ;
1551
1519
}
1552
1520
1553
- /* nat, pr, b0 - b7 */
1554
- if (dst -> count > 0 && dst -> pos < ELF_CR_IIP_OFFSET ) {
1555
- index = (dst -> pos - ELF_NAT_OFFSET ) / sizeof (elf_greg_t );
1556
- min_copy = ELF_CR_IIP_OFFSET > (dst -> pos + dst -> count ) ?
1557
- (dst -> pos + dst -> count ) : ELF_CR_IIP_OFFSET ;
1558
- for (i = dst -> pos ; i < min_copy ; i += sizeof (elf_greg_t ),
1559
- index ++ )
1560
- if (access_elf_reg (dst -> target , info , i ,
1561
- & tmp [index ], 0 ) < 0 ) {
1521
+ while (dst -> count && dst -> pos < ELF_AR_END_OFFSET ) {
1522
+ unsigned int n , from , to ;
1523
+ elf_greg_t tmp [16 ];
1524
+
1525
+ from = dst -> pos ;
1526
+ to = from + min (dst -> count , (unsigned )sizeof (tmp ));
1527
+ if (to > ELF_AR_END_OFFSET )
1528
+ to = ELF_AR_END_OFFSET ;
1529
+ for (n = 0 ; from < to ; from += sizeof (elf_greg_t ), n ++ ) {
1530
+ if (access_elf_reg (dst -> target , info , from ,
1531
+ & tmp [n ], 0 ) < 0 ) {
1562
1532
dst -> ret = - EIO ;
1563
1533
return ;
1564
1534
}
1535
+ }
1565
1536
dst -> ret = user_regset_copyout (& dst -> pos , & dst -> count ,
1566
1537
& dst -> u .get .kbuf , & dst -> u .get .ubuf , tmp ,
1567
- ELF_NAT_OFFSET , ELF_CR_IIP_OFFSET );
1568
- if (dst -> ret || dst -> count == 0 )
1538
+ dst -> pos , to );
1539
+ if (dst -> ret )
1569
1540
return ;
1570
1541
}
1571
-
1572
- /* ip cfm psr ar.rsc ar.bsp ar.bspstore ar.rnat
1573
- * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
1574
- */
1575
- if (dst -> count > 0 && dst -> pos < (ELF_AR_END_OFFSET )) {
1576
- index = (dst -> pos - ELF_CR_IIP_OFFSET ) / sizeof (elf_greg_t );
1577
- min_copy = ELF_AR_END_OFFSET > (dst -> pos + dst -> count ) ?
1578
- (dst -> pos + dst -> count ) : ELF_AR_END_OFFSET ;
1579
- for (i = dst -> pos ; i < min_copy ; i += sizeof (elf_greg_t ),
1580
- index ++ )
1581
- if (access_elf_reg (dst -> target , info , i ,
1582
- & tmp [index ], 0 ) < 0 ) {
1583
- dst -> ret = - EIO ;
1584
- return ;
1585
- }
1586
- dst -> ret = user_regset_copyout (& dst -> pos , & dst -> count ,
1587
- & dst -> u .get .kbuf , & dst -> u .get .ubuf , tmp ,
1588
- ELF_CR_IIP_OFFSET , ELF_AR_END_OFFSET );
1589
- }
1590
1542
}
1591
1543
1592
1544
void do_gpregs_set (struct unw_frame_info * info , void * arg )
1593
1545
{
1594
- struct pt_regs * pt ;
1595
1546
struct regset_getset * dst = arg ;
1596
- elf_greg_t tmp [16 ];
1597
- unsigned int i , index ;
1598
1547
1599
1548
if (unw_unwind_to_user (info ) < 0 )
1600
1549
return ;
1601
1550
1551
+ if (!dst -> count )
1552
+ return ;
1602
1553
/* Skip r0 */
1603
- if (dst -> count > 0 && dst -> pos < ELF_GR_OFFSET (1 )) {
1554
+ if (dst -> pos < ELF_GR_OFFSET (1 )) {
1604
1555
dst -> ret = user_regset_copyin_ignore (& dst -> pos , & dst -> count ,
1605
1556
& dst -> u .set .kbuf ,
1606
1557
& dst -> u .set .ubuf ,
1607
1558
0 , ELF_GR_OFFSET (1 ));
1608
- if (dst -> ret || dst -> count == 0 )
1609
- return ;
1610
- }
1611
-
1612
- /* gr1-gr15 */
1613
- if (dst -> count > 0 && dst -> pos < ELF_GR_OFFSET (16 )) {
1614
- i = dst -> pos ;
1615
- index = (dst -> pos - ELF_GR_OFFSET (1 )) / sizeof (elf_greg_t );
1616
- dst -> ret = user_regset_copyin (& dst -> pos , & dst -> count ,
1617
- & dst -> u .set .kbuf , & dst -> u .set .ubuf , tmp ,
1618
- ELF_GR_OFFSET (1 ), ELF_GR_OFFSET (16 ));
1619
1559
if (dst -> ret )
1620
1560
return ;
1621
- for ( ; i < dst -> pos ; i += sizeof (elf_greg_t ), index ++ )
1622
- if (access_elf_reg (dst -> target , info , i ,
1623
- & tmp [index ], 1 ) < 0 ) {
1624
- dst -> ret = - EIO ;
1625
- return ;
1626
- }
1627
- if (dst -> count == 0 )
1628
- return ;
1629
- }
1630
-
1631
- /* gr16-gr31 */
1632
- if (dst -> count > 0 && dst -> pos < ELF_NAT_OFFSET ) {
1633
- pt = task_pt_regs (dst -> target );
1634
- dst -> ret = user_regset_copyin (& dst -> pos , & dst -> count ,
1635
- & dst -> u .set .kbuf , & dst -> u .set .ubuf , & pt -> r16 ,
1636
- ELF_GR_OFFSET (16 ), ELF_NAT_OFFSET );
1637
- if (dst -> ret || dst -> count == 0 )
1638
- return ;
1639
1561
}
1640
1562
1641
- /* nat, pr, b0 - b7 */
1642
- if (dst -> count > 0 && dst -> pos < ELF_CR_IIP_OFFSET ) {
1643
- i = dst -> pos ;
1644
- index = (dst -> pos - ELF_NAT_OFFSET ) / sizeof (elf_greg_t );
1645
- dst -> ret = user_regset_copyin (& dst -> pos , & dst -> count ,
1646
- & dst -> u .set .kbuf , & dst -> u .set .ubuf , tmp ,
1647
- ELF_NAT_OFFSET , ELF_CR_IIP_OFFSET );
1648
- if (dst -> ret )
1649
- return ;
1650
- for (; i < dst -> pos ; i += sizeof (elf_greg_t ), index ++ )
1651
- if (access_elf_reg (dst -> target , info , i ,
1652
- & tmp [index ], 1 ) < 0 ) {
1653
- dst -> ret = - EIO ;
1654
- return ;
1655
- }
1656
- if (dst -> count == 0 )
1657
- return ;
1658
- }
1563
+ while (dst -> count && dst -> pos < ELF_AR_END_OFFSET ) {
1564
+ unsigned int n , from , to ;
1565
+ elf_greg_t tmp [16 ];
1659
1566
1660
- /* ip cfm psr ar.rsc ar.bsp ar.bspstore ar.rnat
1661
- * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
1662
- */
1663
- if (dst -> count > 0 && dst -> pos < (ELF_AR_END_OFFSET )) {
1664
- i = dst -> pos ;
1665
- index = (dst -> pos - ELF_CR_IIP_OFFSET ) / sizeof (elf_greg_t );
1567
+ from = dst -> pos ;
1568
+ to = from + sizeof (tmp );
1569
+ if (to > ELF_AR_END_OFFSET )
1570
+ to = ELF_AR_END_OFFSET ;
1571
+ /* get up to 16 values */
1666
1572
dst -> ret = user_regset_copyin (& dst -> pos , & dst -> count ,
1667
1573
& dst -> u .set .kbuf , & dst -> u .set .ubuf , tmp ,
1668
- ELF_CR_IIP_OFFSET , ELF_AR_END_OFFSET );
1574
+ from , to );
1669
1575
if (dst -> ret )
1670
1576
return ;
1671
- for ( ; i < dst -> pos ; i += sizeof (elf_greg_t ), index ++ )
1672
- if (access_elf_reg (dst -> target , info , i ,
1673
- & tmp [index ], 1 ) < 0 ) {
1577
+ /* now copy them into registers */
1578
+ for (n = 0 ; from < dst -> pos ; from += sizeof (elf_greg_t ), n ++ )
1579
+ if (access_elf_reg (dst -> target , info , from ,
1580
+ & tmp [n ], 1 ) < 0 ) {
1674
1581
dst -> ret = - EIO ;
1675
1582
return ;
1676
1583
}
0 commit comments