Skip to content

Commit a79ca8e

Browse files
author
Al Viro
committed
[ia64] regularize do_gpregs_[gs]et()
now access_elf_reg() does the right thing for everything other than r0, we can simplify do_grepgs_[gs]et() Signed-off-by: Al Viro <[email protected]>
1 parent e2115cf commit a79ca8e

File tree

1 file changed

+31
-124
lines changed

1 file changed

+31
-124
lines changed

arch/ia64/kernel/ptrace.c

Lines changed: 31 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,10 +1491,7 @@ access_elf_reg(struct task_struct *target, struct unw_frame_info *info,
14911491

14921492
void do_gpregs_get(struct unw_frame_info *info, void *arg)
14931493
{
1494-
struct pt_regs *pt;
14951494
struct regset_getset *dst = arg;
1496-
elf_greg_t tmp[16];
1497-
unsigned int i, index, min_copy;
14981495

14991496
if (unw_unwind_to_user(info) < 0)
15001497
return;
@@ -1517,160 +1514,70 @@ void do_gpregs_get(struct unw_frame_info *info, void *arg)
15171514
&dst->u.get.kbuf,
15181515
&dst->u.get.ubuf,
15191516
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)
15501518
return;
15511519
}
15521520

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) {
15621532
dst->ret = -EIO;
15631533
return;
15641534
}
1535+
}
15651536
dst->ret = user_regset_copyout(&dst->pos, &dst->count,
15661537
&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)
15691540
return;
15701541
}
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-
}
15901542
}
15911543

15921544
void do_gpregs_set(struct unw_frame_info *info, void *arg)
15931545
{
1594-
struct pt_regs *pt;
15951546
struct regset_getset *dst = arg;
1596-
elf_greg_t tmp[16];
1597-
unsigned int i, index;
15981547

15991548
if (unw_unwind_to_user(info) < 0)
16001549
return;
16011550

1551+
if (!dst->count)
1552+
return;
16021553
/* Skip r0 */
1603-
if (dst->count > 0 && dst->pos < ELF_GR_OFFSET(1)) {
1554+
if (dst->pos < ELF_GR_OFFSET(1)) {
16041555
dst->ret = user_regset_copyin_ignore(&dst->pos, &dst->count,
16051556
&dst->u.set.kbuf,
16061557
&dst->u.set.ubuf,
16071558
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));
16191559
if (dst->ret)
16201560
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;
16391561
}
16401562

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];
16591566

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 */
16661572
dst->ret = user_regset_copyin(&dst->pos, &dst->count,
16671573
&dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
1668-
ELF_CR_IIP_OFFSET, ELF_AR_END_OFFSET);
1574+
from, to);
16691575
if (dst->ret)
16701576
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) {
16741581
dst->ret = -EIO;
16751582
return;
16761583
}

0 commit comments

Comments
 (0)