Re: [PATCH] fix backtrace on PA-RISC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


On Tue, 28 Jun 2011, John David Anglin wrote:

> > @@ -305,18 +310,16 @@ static void unwind_frame_regs(struct unw
> >  
> >  			insn = *(unsigned int *)npc;
> >  
> > -			if ((insn & 0xffffc000) == 0x37de0000 ||
> > -			    (insn & 0xffe00000) == 0x6fc00000) {
> > +			if ((insn & 0xffffc001) == 0x37de0000 ||
> > +			    (insn & 0xffe00001) == 0x6fc00000) {
> >  				/* ldo X(sp), sp, or stwm X,D(sp) */
> > -				frame_size += (insn & 0x1 ? -1 << 13 : 0) | 
> > -					((insn & 0x3fff) >> 1);
> > +				frame_size += (insn & 0x3fff) >> 1;
> 
> This doesn't look correct to me.  Look at the disassembly code
> in binutils.  In wide mode, an extract_16 operation needs to be
> used for ldo.  In non wide mode and for stwm, extract_14 needs
> to be used.  extract_14 is a simple 14-bit extraction followed 
> low sign extension.
> 
> I believe the problem with the original code is that it doesn't
> handle wide mode (64-bit kernels) for ldo.

Here are the sign extension routines from binutils:

static inline int
sign_extend (int x, int len)
{
  int signbit = (1 << (len - 1));
  int mask = (signbit << 1) - 1;
  return ((x & mask) ^ signbit) - signbit;
}

static inline int
low_sign_extend (int x, int len)
{
  return (x >> 1) - ((x & 1) << (len - 1));
}

It probably doesn't matter too much but they are written in a manner
to avoid conditional tests.

Dave
-- 
J. David Anglin                                  dave.anglin@xxxxxxxxxxxxxx
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)
--
To unsubscribe from this list: send the line "unsubscribe linux-parisc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Free Online Dating]     [Linux Kernel]     [Linux SCSI]     [XFree86]

Add to Google Powered by Linux