Re: a question about rs6k's prologue analysis

Wu Zhou
2006-10-13T04:13:53Z

I applied the following patch to latest cvs:

*** rs6000-tdep.c.orig 2006-10-14 00:02:47.000000000 +0800
--- rs6000-tdep.c 2006-10-14 00:08:10.000000000 +0800
*************** store_param_on_stack_p (unsigned long op
*** 902,907 ****
--- 902,931 ----
return 0;
}

+ /* Assuming that INSN is a "bl" instruction located at PC, return
+ nonzero if the destination of the branch is a "blrl" instruction.
+
+ This sequence is sometimes found in certain function prologues.
+ It allows the function to load the LR register with a value that
+ they can use to access PIC data using PC-relative offsets. */
+
+ static int
+ bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
+ {
+ const int opcode = 18;
+ const CORE_ADDR dest = branch_dest (opcode, insn, pc, -1);
+ int dest_insn;
+
+ if (dest == -1)
+ return 0; /* Should never happen, but just return zero to be safe. */
+
+ dest_insn = read_memory_integer (dest, 4);
+ if ((dest_insn & 0xfc00ffff) == 0x4c000021) /* blrl */
+ return 1;
+
+ return 0;
+ }
+
static CORE_ADDR
skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
{
*************** skip_prologue (CORE_ADDR pc, CORE_ADDR l
*** 1133,1138 ****
--- 1157,1166 ----
to save fprs??? */

fdata->frameless = 0;
+
+ if (bl_to_blrl_insn_p (pc, op))
+ continue;
+
/* Don't skip over the subroutine call if it is not within
the first three instructions of the prologue and either
we have no line table information or the line info tells

It works ok for my scenario. but it also brings some changes to the test result of gdb testsuite.
Here is the difference of file gdb.sum:

< ERROR: internal buffer is full.
< UNRESOLVED: gdb.base/checkpoint.exp: info checkpoints with at least 600 checkpoints
---
> PASS: gdb.base/checkpoint.exp: info checkpoints with at least 600 checkpoints

*** Patched gdb have an internal buffer full error, which make checkpoint.exp have a unresolved case.

11453a11453
> PASS: gdb.threads/schedlock.exp: other thread 0 didn't run
11455d11454
< PASS: gdb.threads/schedlock.exp: other thread 1 didn't run
11472a11472
> PASS: gdb.threads/schedlock.exp: other thread 0 didn't run (stepping)
11474d11473
< PASS: gdb.threads/schedlock.exp: other thread 1 didn't run (stepping)

*** patched gdb has two PASSes which occur at different thread.

11560c11559
< PASS: gdb.threads/tls.exp: backtrace of thread number 2 in spin
---
> PASS: gdb.threads/tls.exp: backtrace of thread number 2 not relevant
11562c11561
< PASS: gdb.threads/tls.exp: backtrace of thread number 3 in spin
---
> PASS: gdb.threads/tls.exp: backtrace of thread number 3 not relevant
11564,11585c11563,11564
< PASS: gdb.threads/tls.exp: backtrace of thread number 4 in spin
< PASS: gdb.threads/tls.exp: selected thread: 4
< PASS: gdb.threads/tls.exp: thread 4 up
< PASS: gdb.threads/tls.exp: 4 thread print me
< FAIL: gdb.threads/tls.exp: 4 thread local storage
< FAIL: gdb.threads/tls.exp: 4 another thread local storage
< PASS: gdb.threads/tls.exp: 4 info address a_thread_local
< PASS: gdb.threads/tls.exp: 4 info address another_thread_local
< PASS: gdb.threads/tls.exp: selected thread: 2
< PASS: gdb.threads/tls.exp: thread 2 up
< PASS: gdb.threads/tls.exp: 2 thread print me
< FAIL: gdb.threads/tls.exp: 2 thread local storage
< FAIL: gdb.threads/tls.exp: 2 another thread local storage
< PASS: gdb.threads/tls.exp: 2 info address a_thread_local
< PASS: gdb.threads/tls.exp: 2 info address another_thread_local
< PASS: gdb.threads/tls.exp: selected thread: 3
< PASS: gdb.threads/tls.exp: thread 3 up
< PASS: gdb.threads/tls.exp: 3 thread print me
< FAIL: gdb.threads/tls.exp: 3 thread local storage
< FAIL: gdb.threads/tls.exp: 3 another thread local storage
< PASS: gdb.threads/tls.exp: 3 info address a_thread_local
< PASS: gdb.threads/tls.exp: 3 info address another_thread_local
---
> PASS: gdb.threads/tls.exp: backtrace of thread number 4 not relevant
> FAIL: gdb.threads/tls.exp: No thread backtrace reported spin (vsyscall kernel problem?)

*** patched gdb has 15 more PASSes, and 4 more FAILs in gdb.threads/tls.exp

11741,11742c11720,11721
< # of expected passes 11140
< # of unexpected failures 114
---
> # of expected passes 11126
> # of unexpected failures 109
11745d11723
< # of unresolved testcases 1

*** Could we claim that this is a progress? :-)

I don't have any clue as to why the above patch makes these changes, any idea? Thanks.

Regards
- Wu Zhou

Wu Zhou wrote:
> Joel Brobecker wrote:
> >> I knew this sounded familiar. Here it is:
> >
> > Yes, me too! :-)
> >
> >> http://sourceware.org/ml/gdb-patches/2004-12/msg00234.html
> >> http://sourceware.org/ml/gdb-patches/2005-06/msg00242.html
> >>
> >> Joel, things have changed a lot since then - if you have a chance to
> >> respond to my last message there, I'll take another look at it.
> >
> > For the record:
> >
> > http://www.sourceware.org/ml/gdb-patches/2006-10/msg00119.html
> >
>
> I had a test with your patch, changing the blrl test to be additional.
> It works ok in my scenario.
>
> But I don't do any regression test yet (will do that later, having other
> things for rush). Also that I am now applying your patch to RHEL4's gdb
> sources (It seems that community gdb has some problems on ppc64, which
> hinders our scenario.). I will apply that patch to community source
> later to see if there are any regression.
>
> BTW, adapting the first three instructions to be four don't work in some
> cases. I see some cases where bl_to_blrl occurs at about the 6th or
> even 8th instruction of the prologue.
>
> Thanks a lot for all your help. I will return back to regression test a
> while later.
>
> Regards
> - Wu Zhou
>
>