[Crash-utility] How do I get IA64 register R32 and above?

Seymour, Shane M shane.seymour at hp.com
Mon Apr 29 00:28:07 UTC 2013


Hi Dave,

> I would presume that even if they were modified in sys_select() that
> rse_function_params() would still reflect the arguments as they were
> passed in to the function.  Otherwise, what's the point of the function?

They will only be the contents of the input registers in a local function after they were rotated during a function call at the point in time where they were saved/spilt to the RSE. What they may contain is really determined by the ABI/compiler/calling convention and I don't know if Linux or the compiler options used to compile the kernel dictate that the input registers can be reused or not. 

When a function starts usually the first instruction is an alloc instruction which allocates input, local, output registers in the RSE (input and local are really combined). When use the call instruction the RSE automatically renumbers the rotating registers so the output registers start from r32 and the caller uses alloc to formalize its RSE usage (defining the callers outputs as inputs to the callee). 

Although r32 is the first argument register if the callee wants to reuse the register it could, for example it only needs the argument initially and after that it can be reused as a general register (if the compiler is willing to do it). If they were reused you'd need to look at where they came from in in the caller or saved somewhere (onto the memory stack, into another register, or used in a calculation that you can undo, etc). To be really safe you'd really need to disassemble the function they're used in and verify that what you are about to rely on hasn't been modified or replaced by a different value.

Thanks
Shane

-----Original Message-----
From: crash-utility-bounces at redhat.com [mailto:crash-utility-bounces at redhat.com] On Behalf Of Dave Anderson
Sent: Wednesday, April 24, 2013 6:29 AM
To: Montgomery, Bob; Discussion list for crash utility usage, maintenance and development
Subject: Re: [Crash-utility] How do I get IA64 register R32 and above?



----- Original Message -----
> On Mon, 2013-04-22 at 16:38 -0700, Jay Lan wrote:
> > Hi,
> > 
> > I got an IA64 vmcore. The stack backtrace only printed registers up 
> > to R31. How do I get the contents of R32 and above?
> > 
> > Thanks,
> > Jay
> 
> Jay, here's an excerpt from an email I answered in 2006.  It's not clear
> that I remember anything about this now :-)   Hope it helps.
> 
> Bob Montgomery
> 
> --------------------------------
> 
> 
> >  #8 [BSP:e00000404ae490e8] mdc_replay_open at a00000020122f490
> >     (e0000040ffcd1f10)
> >     ...mdc/mdc_request.c: 332
> >  #9 [BSP:e00000404ae49078] ptlrpc_replay_interpret at a0000002013ed930
> >     (e0000040ff86f300)
> >     ...ptlrpc/client.c: 1636
> > #10 [BSP:e00000404ae48fe8] ptlrpc_check_set at a0000002013e14c0
> >     (e0000000015eda80)
> >     
> 
> There are three big secrets:
> 
> 1) The saved values of the stack frame registers (r32, r33, ... up to 
> the limit set by the alloc statement at the beginning of the function 
> for that frame) are located at the Backing Store Pointer (BSP) shown 
> for the frame.  If you want to see r32, r33, r34, r35 for frame #8, do
>         crash> x/4xg 0xe00000404ae490e8
> 
> 2) The saved values of the stack frame registers are their current 
> values, not necessarily the values passed in to the function (for 
> those registers that were used as input registers, for example).  In 
> other words, the first parameter is passed as r32, but r32 might be 
> modified by that function before the point in the code represented by 
> the stack trace.  Check for this by disassembling:
>         crash> dis mdc_replay_open | grep r32 and looking to see where 
> (if ever) r32 is modified (appears on the left hand side of an "=") in 
> that function.
> 
> 3)  Every 64th word in the backing store is a NaT register store, not 
> a regular register.  So when you're counting words from the BSP 
> pointer for that frame to match up with registers, skip any word whose 
> address ends in 0x1f8, 0x3f8, 0x5f8, ...
> 
> crash is trying to show you the passed parameters.  If that's working, 
> those values in parentheses at each level should correspond to r32,
> r33 ... for as many as shown.  If I remember right, crash doesn't do 
> that very well for functions in modules.
> ---------------------------------------------------------------

The "bt -f" option uses the rse_function_params() function backported from the kernel's ia64 unwind facility.  And they do appear to be as you described, i.e., at the BSP address location.  For example:

 crash> bt -f
  PID: 1      TASK: e0000100ff118000  CPU: 0   COMMAND: "init"
   #0 [BSP:e0000100ff119358] schedule at a000000100678b90
      (void)
   #1 [BSP:e0000100ff119328] schedule_timeout at a00000010067a1b0
      (1388)
   #2 [BSP:e0000100ff119250] do_select at a0000001001b0090
      (e0000100fe518180, e0000100ff11fce0, e0000100ff11fe10)
   #3 [BSP:e0000100ff1191f0] core_sys_select at a0000001001b0990
      (b, 60000fffffdf77a8, 0, 0, e0000100ff11fe10)
   #4 [BSP:e0000100ff119160] sys_select at a0000001001b18b0
      (b, 60000fffffdf77a8, 0, 0, 60000fffffdf7828)
   #5 [BSP:e0000100ff119160] ia64_ret_from_syscall at a00000010000be40
    EFRAME: e0000100ff11fe40
        B0: 400000000000aee0      CR_IIP: a000000000010620
   CR_IPSR: 00001213085a6010      CR_IFS: 0000000000000005
    AR_PFS: c000000000000005      AR_RSC: 000000000000000f
   AR_UNAT: 0000000000000000     AR_RNAT: 0000000000000000
    AR_CCV: 0000000000000000     AR_FPSR: 0009804c8a70033f
    LOADRS: 0000000000c00000 AR_BSPSTORE: 600007ffffdfc138
        B6: 20000000002cb1a0          B7: a00000010000fc20
        PR: 0000000000026241          R1: 2000000000328238
        R2: a000000000010640          R3: e0000100ff11fef8
        R8: 0000000000000001          R9: 0000000051763204
       R10: 0000000000000000         R11: c000000000000611
       R12: 60000fffffdf7670         R13: 20000000003b55f0
       R14: a000000100707f18         R15: 0000000000000441
       R16: e0000100ff118000         R17: 000000000000003f
       R18: a00000010000fc20         R19: 000000000000011d
       R20: 0009804c8a70033f         R21: 0009804c8a70033f
       R22: 0000000000000000         R23: 600007ffffdfc138
       R24: 0000000000000000         R25: 0000000000000000
       R26: c000000000000002         R27: 000000000000000f
       R28: a000000000010620         R29: 00000010085a2010
       R30: 0000000000000005         R31: 0000000000026241
        F6: 000000000000000000000     F7: 000000000000000000000
        F8: 000000000000000000000     F9: 000000000000000000000
       F10: 000000000000000000000    F11: 000000000000000000000
   #6 [BSP:e0000100ff119160] __kernel_syscall_via_break at a000000000010620
  crash> 
  
So if I look at the BSP location for the sys_select() frame #4: 

   #4 [BSP:e0000100ff119160] sys_select at a0000001001b18b0
      (b, 60000fffffdf77a8, 0, 0, 60000fffffdf7828)

the arguments match up:
  
  crash> rd e0000100ff119160 5
  e0000100ff119160:  000000000000000b 60000fffffdf77a8   .........w.....`
  e0000100ff119170:  0000000000000000 0000000000000000   ................
  e0000100ff119180:  60000fffffdf7828                    (x.....`
  crash> 

I would presume that even if they were modified in sys_select() that
rse_function_params() would still reflect the arguments as they were passed in to the function.  Otherwise, what's the point of the function?
  
And I don't know why it would behave any differently for a module function?

Dave


--
Crash-utility mailing list
Crash-utility at redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility




More information about the Crash-utility mailing list