This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
PATCH: S/390: prologue analysis refinement
- To: gdb-patches at sources dot redhat dot com
- Subject: PATCH: S/390: prologue analysis refinement
- From: Jim Blandy <jimb at zwingli dot cygnus dot com>
- Date: Thu, 8 Nov 2001 18:22:25 -0500 (EST)
2001-11-06 Jim Blandy <jimb@redhat.com>
* s390-tdep.c (s390_get_frame_info): If the prologue loads r12
from the constant pool, but doesn't add in the constant pool's
address to it, then this function probably isn't using r12 as a
GOT pointer, and that load probably wasn't part of the prologue.
Index: gdb/s390-tdep.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/s390-tdep.c,v
retrieving revision 2.3
diff -c -r2.3 s390-tdep.c
*** gdb/s390-tdep.c 2001/11/01 21:05:46 2.3
--- gdb/s390-tdep.c 2001/11/06 23:27:27
***************
*** 209,221 ****
int fprs_saved[S390_NUM_FPRS];
int regidx, instrlen;
int save_link_regidx, subtract_sp_regidx;
! int const_pool_state, save_link_state, got_state;
int frame_pointer_found, varargs_state;
int loop_cnt, gdb_gpr_store, gdb_fpr_store;
int frame_pointer_regidx = 0xf;
int offset, expected_offset;
int err = 0;
disassemble_info info;
const_pool_state = save_link_state = got_state = varargs_state = 0;
frame_pointer_found = 0;
memset (gprs_saved, 0, sizeof (gprs_saved));
--- 209,236 ----
int fprs_saved[S390_NUM_FPRS];
int regidx, instrlen;
int save_link_regidx, subtract_sp_regidx;
! int const_pool_state, save_link_state;
int frame_pointer_found, varargs_state;
int loop_cnt, gdb_gpr_store, gdb_fpr_store;
int frame_pointer_regidx = 0xf;
int offset, expected_offset;
int err = 0;
disassemble_info info;
+
+ /* What we've seen so far regarding r12 --- the GOT (Global Offset
+ Table) pointer. We expect to see `l %r12, N(%r13)', which loads
+ r12 with the offset from the constant pool to the GOT, and then
+ an `ar %r12, %r13', which adds the constant pool address,
+ yielding the GOT's address. Here's what got_state means:
+ 0 -- seen nothing
+ 1 -- seen `l %r12, N(%r13)', but no `ar'
+ 2 -- seen load and add, so GOT pointer is totally initialized
+ When got_state is 1, then got_load_addr is the address of the
+ load instruction, and got_load_len is the length of that
+ instruction. */
+ int got_state;
+ CORE_ADDR got_load_addr, got_load_len;
+
const_pool_state = save_link_state = got_state = varargs_state = 0;
frame_pointer_found = 0;
memset (gprs_saved, 0, sizeof (gprs_saved));
***************
*** 539,545 ****
&& (instr[2] == (CONST_POOL_REGIDX << 4))
&& ((instr[1] >> 4) == GOT_REGIDX))
{
! got_state == 1;
valid_prologue = 1;
continue;
}
--- 554,562 ----
&& (instr[2] == (CONST_POOL_REGIDX << 4))
&& ((instr[1] >> 4) == GOT_REGIDX))
{
! got_state = 1;
! got_load_addr = test_pc;
! got_load_len = instrlen;
valid_prologue = 1;
continue;
}
***************
*** 556,563 ****
while (valid_prologue && good_prologue);
if (good_prologue)
{
! good_prologue = (((got_state == 0) || (got_state == 2)) &&
! ((const_pool_state == 0) || (const_pool_state == 2)) &&
((save_link_state == 0) || (save_link_state == 4)) &&
((varargs_state == 0) || (varargs_state == 2)));
}
--- 573,592 ----
while (valid_prologue && good_prologue);
if (good_prologue)
{
! /* If this function doesn't reference the global offset table,
! then the compiler may use r12 for other things. If the last
! instruction we saw was a load of r12 from the constant pool,
! with no subsequent add to make the address PC-relative, then
! the load was probably a genuine body instruction; don't treat
! it as part of the prologue. */
! if (got_state == 1
! && got_load_addr + got_load_len == test_pc)
! {
! test_pc = got_load_addr;
! instrlen = got_load_len;
! }
!
! good_prologue = (((const_pool_state == 0) || (const_pool_state == 2)) &&
((save_link_state == 0) || (save_link_state == 4)) &&
((varargs_state == 0) || (varargs_state == 2)));
}