This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: [ppc part commit] [patchv2 3/4] unwinder: ppc and ppc64
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Thu, 19 Dec 2013 00:05:34 +0100
- Subject: 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