This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ppc part commit] [patchv2 3/4] unwinder: ppc and ppc64


On Sun, 2013-12-15 at 18:57 +0100, Jan Kratochvil wrote:
> On Thu, 05 Dec 2013 22:25:34 +0100, Mark Wielaard wrote:
> > Yes, the patch seems OK, please just checkin the non-tests parts that
> > don't depend on the ppc64bidir stuff.
> 
> Checked in that part: 5cbf42aaf47195e2c41171786371d55b253a7667

PPC dwarf registering numbering is a pita :{
Found another issue with this part:

bool
ppc_dwarf_to_regno (Ebl *ebl __attribute__ ((unused)), unsigned *regno)
{
  switch (*regno)
  {
    case 108:
      // LR uses both 65 and 108 numbers, there is no consistency for it.
      *regno = 65;
      return true;

Unfortunately there seems to be code out there that actually uses and
restores both 65 and 108... sigh.

This is from /usr/lib64/libgcc_s-4.8.2-20131106.so.1
_Unwind_ForcedUnwind_ which we happen to use in our backtrace-dwarf
testcase:

 [   fc0] FDE length=220 cie=[    58]
   CIE_pointer:              3948
   initial_location:         +0x000000000000e600 <_Unwind_ForcedUnwind> (offset: 0xe600)
   address_range:            0x2d4 (end offset: 0xe8d4)

   Program:
     advance_loc 1 to 0xe604
     def_cfa_offset 3408
     advance_loc 43 to 0xe6b0
     offset_extended_sf r65 (fpscr) at cfa+16
     register r70 (r12) in r12 (r12)
     offset r46 (f14) at cfa-144
     offset r47 (f15) at cfa-136
     offset r48 (f16) at cfa-128
     offset r49 (f17) at cfa-120
     offset r50 (f18) at cfa-112
     offset r51 (f19) at cfa-104
     offset r52 (f20) at cfa-96
     offset r53 (f21) at cfa-88
     offset r54 (f22) at cfa-80
     offset r55 (f23) at cfa-72
     offset r56 (f24) at cfa-64
     offset r57 (f25) at cfa-56
     offset r58 (f26) at cfa-48
     offset r59 (f27) at cfa-40
     offset r60 (f28) at cfa-32
     offset r61 (f29) at cfa-24
     offset r62 (f30) at cfa-16
     offset r63 (f31) at cfa-8
     offset r14 (r14) at cfa-288
     offset r15 (r15) at cfa-280
     offset r16 (r16) at cfa-272
     offset r17 (r17) at cfa-264
     offset r18 (r18) at cfa-256
     offset r19 (r19) at cfa-248
     offset r20 (r20) at cfa-240
     offset r21 (r21) at cfa-232
     offset r22 (r22) at cfa-224
     offset r23 (r23) at cfa-216
     offset r24 (r24) at cfa-208
     offset r25 (r25) at cfa-200
     offset r26 (r26) at cfa-192
     offset r27 (r27) at cfa-184
     offset r28 (r28) at cfa-176
     offset r29 (r29) at cfa-168
     offset r30 (r30) at cfa-160
     offset r31 (r31) at cfa-152
     offset r3 (r3) at cfa-512
     offset r4 (r4) at cfa-504
     offset r5 (r5) at cfa-496
     offset r6 (r6) at cfa-488
     advance_loc 35 to 0xe73c
     offset_extended_sf r2 (r2) at cfa+40
     offset_extended_sf r70 (sr0) at cfa+8
     offset_extended r97 (??? 0x61) at cfa-480
     offset_extended r98 (??? 0x62) at cfa-464
     offset_extended r99 (??? 0x63) at cfa-448
     offset_extended r100 (spr0) at cfa-432
     offset_extended r101 (xer) at cfa-416
     offset_extended r102 (spr2) at cfa-400
     offset_extended r103 (spr3) at cfa-384
     offset_extended r104 (spr4) at cfa-368
     offset_extended r105 (spr5) at cfa-352
     offset_extended r106 (spr6) at cfa-336
     offset_extended r107 (spr7) at cfa-320
     offset_extended r108 (lr) at cfa-304
     advance_loc 23 to 0xe798
     remember_state
     restore_extended r70 (sr0)
     advance_loc 35 to 0xe824
     restore_extended r65 (fpscr)
     advance_loc 28 to 0xe894
     restore r63 (f31)
     restore r62 (f30)
     restore r61 (f29)
     restore r60 (f28)
     restore r59 (f27)
     restore r58 (f26)
     restore r57 (f25)
     restore r56 (f24)
     restore r55 (f23)
     restore r54 (f22)
     restore r53 (f21)
     restore r52 (f20)
     restore r51 (f19)
     restore r50 (f18)
     restore r49 (f17)
     restore r48 (f16)
     restore r47 (f15)
     restore r46 (f14)
     restore r31 (r31)
     restore r30 (r30)
     restore r29 (r29)
     restore r28 (r28)
     restore r27 (r27)
     restore r26 (r26)
     restore r25 (r25)
     restore r24 (r24)
     restore r23 (r23)
     restore r22 (r22)
     restore r21 (r21)
     restore r20 (r20)
     restore r19 (r19)
     restore r18 (r18)
     restore r17 (r17)
     restore r16 (r16)
     restore r15 (r15)
     restore r14 (r14)
     restore_extended r108 (lr)
     restore_extended r107 (spr7)
     restore_extended r106 (spr6)
     restore_extended r105 (spr5)
     restore_extended r104 (spr4)
     restore_extended r103 (spr3)
     restore_extended r102 (spr2)
     restore_extended r101 (xer)
     restore_extended r100 (spr0)
     restore_extended r99 (??? 0x63)
     restore_extended r98 (??? 0x62)
     restore_extended r97 (??? 0x61)
     def_cfa_offset 0
     advance_loc 2 to 0xe89c
     restore_state
     nop

I have not looked yet precisely which part of the program it gets while
unwinding. But as you can this is a somewhat special restore for
everything. Including both 65 and 108. Sadly 108 seems to evaluate to
zero in this particular case and gets set after 65 has been set, which
causes this part of the code to set DWFL_FRAME_STATE_PC_UNDEFINED
because it doesn't believe zero is a valid return register:

  if (unwound->pc_state == DWFL_FRAME_STATE_ERROR
      && __libdwfl_frame_reg_get (unwound,
                                  frame->fde->cie->return_address_register,
                                  &unwound->pc))
    {

      /* PPC32 __libc_start_main properly CFI-unwinds PC as zero.  Currently
         none of the archs supported for unwinding have zero as a valid PC.  */
      if (unwound->pc == 0)
        unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
      else
        unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
    }

But even if it wouldn't have triggered on zero, the unwind would go
wrongly because the value of reg65 which is the return address register,
would be overwritten.

If I just hard code ignoring 108 if 65 is already set things unwind
fine. But it needs a proper solution of course.

Cheers,

Mark


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]