Commit 3d029c25 authored by Keith Owens's avatar Keith Owens Committed by David Mosberger

[PATCH] ia64: fix unwinder to call get_scratch_regs() only when really needed

Only call get_scratch_regs() when pt is really needed.  The extraneous
calls to get_scratch_regs() can otherwise pick up the wrong address for pt.
For example, calling unw_access_ar(&info, UNW_AR_BSPSTORE,...) before pt_regs
had been reached could trigger this bug.
parent 75a559eb
...@@ -403,12 +403,11 @@ unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int ...@@ -403,12 +403,11 @@ unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int
unsigned long *addr; unsigned long *addr;
struct pt_regs *pt; struct pt_regs *pt;
pt = get_scratch_regs(info);
switch (regnum) { switch (regnum) {
/* scratch: */ /* scratch: */
case 0: addr = &pt->b0; break; case 0: pt = get_scratch_regs(info); addr = &pt->b0; break;
case 6: addr = &pt->b6; break; case 6: pt = get_scratch_regs(info); addr = &pt->b6; break;
case 7: addr = &pt->b7; break; case 7: pt = get_scratch_regs(info); addr = &pt->b7; break;
/* preserved: */ /* preserved: */
case 1: case 2: case 3: case 4: case 5: case 1: case 2: case 3: case 4: case 5:
...@@ -441,15 +440,15 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, ...@@ -441,15 +440,15 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val,
return -1; return -1;
} }
pt = get_scratch_regs(info);
if (regnum <= 5) { if (regnum <= 5) {
addr = *(&info->f2_loc + (regnum - 2)); addr = *(&info->f2_loc + (regnum - 2));
if (!addr) if (!addr)
addr = &info->sw->f2 + (regnum - 2); addr = &info->sw->f2 + (regnum - 2);
} else if (regnum <= 15) { } else if (regnum <= 15) {
if (regnum <= 11) if (regnum <= 11) {
pt = get_scratch_regs(info);
addr = &pt->f6 + (regnum - 6); addr = &pt->f6 + (regnum - 6);
}
else else
addr = &info->sw->f12 + (regnum - 12); addr = &info->sw->f12 + (regnum - 12);
} else if (regnum <= 31) { } else if (regnum <= 31) {
...@@ -479,7 +478,6 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int ...@@ -479,7 +478,6 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int
unsigned long *addr; unsigned long *addr;
struct pt_regs *pt; struct pt_regs *pt;
pt = get_scratch_regs(info);
switch (regnum) { switch (regnum) {
case UNW_AR_BSP: case UNW_AR_BSP:
addr = info->bsp_loc; addr = info->bsp_loc;
...@@ -534,18 +532,22 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int ...@@ -534,18 +532,22 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int
break; break;
case UNW_AR_RSC: case UNW_AR_RSC:
pt = get_scratch_regs(info);
addr = &pt->ar_rsc; addr = &pt->ar_rsc;
break; break;
case UNW_AR_CCV: case UNW_AR_CCV:
pt = get_scratch_regs(info);
addr = &pt->ar_ccv; addr = &pt->ar_ccv;
break; break;
case UNW_AR_CSD: case UNW_AR_CSD:
pt = get_scratch_regs(info);
addr = &pt->ar_csd; addr = &pt->ar_csd;
break; break;
case UNW_AR_SSD: case UNW_AR_SSD:
pt = get_scratch_regs(info);
addr = &pt->ar_ssd; addr = &pt->ar_ssd;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment