diff options
author | Andrew Cagney <cagney@redhat.com> | 2002-04-26 03:37:42 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2002-04-26 03:37:42 +0000 |
commit | 6096c27ac0ed55998d2c8d887254c75a19afca0d (patch) | |
tree | d431257effc3773805733fe0f21ba5598e061a2f /gdb | |
parent | eba91044963246c0246346b7ccd1242a49bd6737 (diff) | |
download | gdb-6096c27ac0ed55998d2c8d887254c75a19afca0d.zip gdb-6096c27ac0ed55998d2c8d887254c75a19afca0d.tar.gz gdb-6096c27ac0ed55998d2c8d887254c75a19afca0d.tar.bz2 |
* valops.c (hand_function_call): Call
generic_save_call_dummy_addr.
* frame.h (generic_save_call_dummy_addr): Declare.
* blockframe.c (struct dummy_frame): Add fields call_lo and
call_hi.
(generic_find_dummy_frame): Check for PC in range call_lo to
call_hi instead of entry_point_address.
(generic_pc_in_call_dummy): Search the dummy frames for a PC in
the call_lo to call_hi range. Allow for DECR_PC_AFTER_BREAK.
(generic_save_call_dummy_addr): New function.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 13 | ||||
-rw-r--r-- | gdb/blockframe.c | 52 | ||||
-rw-r--r-- | gdb/frame.h | 2 | ||||
-rw-r--r-- | gdb/valops.c | 11 |
4 files changed, 65 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8dd3fdd..e91880f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2002-04-25 Andrew Cagney <ac131313@redhat.com> + + * valops.c (hand_function_call): Call + generic_save_call_dummy_addr. + * frame.h (generic_save_call_dummy_addr): Declare. + * blockframe.c (struct dummy_frame): Add fields call_lo and + call_hi. + (generic_find_dummy_frame): Check for PC in range call_lo to + call_hi instead of entry_point_address. + (generic_pc_in_call_dummy): Search the dummy frames for a PC in + the call_lo to call_hi range. Allow for DECR_PC_AFTER_BREAK. + (generic_save_call_dummy_addr): New function. + 2002-04-24 David S. Miller <davem@redhat.com> * sparc-tdep.c (sparc_gdbarch_skip_prologue): Kill, duplicates diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 3150f88..6f2a796 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -1070,42 +1070,59 @@ struct dummy_frame CORE_ADDR sp; CORE_ADDR top; char *registers; + + /* Address range of the call dummy code. Look for PC in the range + [LO..HI) (after allowing for DECR_PC_AFTER_BREAK). */ + CORE_ADDR call_lo; + CORE_ADDR call_hi; }; static struct dummy_frame *dummy_frame_stack = NULL; /* Function: find_dummy_frame(pc, fp, sp) - Search the stack of dummy frames for one matching the given PC, FP and SP. - This is the work-horse for pc_in_call_dummy and read_register_dummy */ + + Search the stack of dummy frames for one matching the given PC, FP + and SP. Unlike PC_IN_CALL_DUMMY, this function doesn't need to + adjust for DECR_PC_AFTER_BREAK. This is because it is only legal + to call this function after the PC has been adjusted. */ char * generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp) { struct dummy_frame *dummyframe; - if (pc != entry_point_address ()) - return 0; - for (dummyframe = dummy_frame_stack; dummyframe != NULL; dummyframe = dummyframe->next) - if (fp == dummyframe->fp - || fp == dummyframe->sp - || fp == dummyframe->top) + if ((pc >= dummyframe->call_lo && pc < dummyframe->call_hi) + && (fp == dummyframe->fp + || fp == dummyframe->sp + || fp == dummyframe->top)) /* The frame in question lies between the saved fp and sp, inclusive */ return dummyframe->registers; return 0; } -/* Function: pc_in_call_dummy (pc, fp) - Return true if this is a dummy frame created by gdb for an inferior call */ +/* Function: pc_in_call_dummy (pc, sp, fp) + + Return true if the PC falls in a dummy frame created by gdb for an + inferior call. The code below which allows DECR_PC_AFTER_BREAK is + for infrun.c, which may give the function a PC without that + subtracted out. */ int generic_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp) { - /* if find_dummy_frame succeeds, then PC is in a call dummy */ - /* Note: SP and not FP is passed on. */ - return (generic_find_dummy_frame (pc, sp) != 0); + struct dummy_frame *dummyframe; + for (dummyframe = dummy_frame_stack; + dummyframe != NULL; + dummyframe = dummyframe->next) + { + if ((pc >= dummyframe->call_lo) + && (pc < dummyframe->call_hi + DECR_PC_AFTER_BREAK)) + return 1; + } + return 0; } /* Function: read_register_dummy @@ -1170,6 +1187,15 @@ generic_save_dummy_frame_tos (CORE_ADDR sp) dummy_frame_stack->top = sp; } +/* Record the upper/lower bounds on the address of the call dummy. */ + +void +generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi) +{ + dummy_frame_stack->call_lo = lo; + dummy_frame_stack->call_hi = hi; +} + /* Restore the machine state from either the saved dummy stack or a real stack frame. */ diff --git a/gdb/frame.h b/gdb/frame.h index 2b7bf41..aca2e25 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -285,6 +285,8 @@ extern void generic_get_saved_register (char *, int *, CORE_ADDR *, struct frame_info *, int, enum lval_type *); +extern void generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi); + extern void get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR * addrp, struct frame_info *frame, diff --git a/gdb/valops.c b/gdb/valops.c index 16d3c8c..86c3112 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1385,6 +1385,8 @@ hand_function_call (struct value *function, int nargs, struct value **args) if (CALL_DUMMY_LOCATION == ON_STACK) { write_memory (start_sp, (char *) dummy1, sizeof_dummy1); + if (USE_GENERIC_DUMMY_FRAMES) + generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1); } if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END) @@ -1401,6 +1403,8 @@ hand_function_call (struct value *function, int nargs, struct value **args) sp = old_sp; real_pc = text_end - sizeof_dummy1; write_memory (real_pc, (char *) dummy1, sizeof_dummy1); + if (USE_GENERIC_DUMMY_FRAMES) + generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1); } if (CALL_DUMMY_LOCATION == AFTER_TEXT_END) @@ -1412,11 +1416,18 @@ hand_function_call (struct value *function, int nargs, struct value **args) errcode = target_write_memory (real_pc, (char *) dummy1, sizeof_dummy1); if (errcode != 0) error ("Cannot write text segment -- call_function failed"); + if (USE_GENERIC_DUMMY_FRAMES) + generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1); } if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) { real_pc = funaddr; + if (USE_GENERIC_DUMMY_FRAMES) + /* NOTE: cagney/2002-04-13: The entry point is going to be + modified with a single breakpoint. */ + generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (), + CALL_DUMMY_ADDRESS () + 1); } #ifdef lint |