diff options
author | Carl Love <cel@us.ibm.com> | 2023-01-13 17:59:33 -0500 |
---|---|---|
committer | Carl Love <cel@us.ibm.com> | 2023-01-17 11:39:42 -0500 |
commit | 92e07580db6a5572573d5177ca23933064158f89 (patch) | |
tree | 3b6e814c5360a226f3f57d0a0f4fa23f69f0b197 /gdb/infcmd.c | |
parent | b22548ddb30bfb167708e82d3bb932461c1b703a (diff) | |
download | gdb-92e07580db6a5572573d5177ca23933064158f89.zip gdb-92e07580db6a5572573d5177ca23933064158f89.tar.gz gdb-92e07580db6a5572573d5177ca23933064158f89.tar.bz2 |
PowerPC: fix for gdb.reverse/finish-precsave.exp and gdb.reverse/finish-reverse.exp
PR record/29927 - reverse-finish requires two reverse next instructions to
reach previous source line
PowerPC uses two entry points called the local entry point (LEP) and the
global entry point (GEP). Normally the LEP is used when calling a
function. However, if the table of contents (TOC) value in register 2 is
not valid the GEP is called to setup the TOC before execution continues at
the LEP. When executing in reverse, the function finish_backward sets the
break point at the alternate entry point (GEP). However if the forward
execution enters via the normal entry point (LEP), the reverse execution
never sees the break point at the GEP of the function. Reverse execution
continues until the next break point is encountered or the end of the
recorded log is reached causing gdb to stop at the wrong place.
This patch adds a new address to struct execution_control_state to hold the
address of the alternate function start address, known as the GEP on
PowerPC. The finish_backwards function is updated. If the stopping point
is between the two entry points (the LEP and GEP on PowerPC), the stepping
range is set to execute back to the alternate entry point (GEP on PowerPC).
Otherwise, a breakpoint is inserted at the normal entry point (LEP on
PowerPC).
Function process_event_stop_test checks uses a stepping range to stop
execution in the caller at the first instruction of the source code line.
Note, on systems that only support one entry point, the address of the two
entry points are the same.
Test finish-reverse-next.exp is updated to include tests for the
reverse-finish command when the function is entered via the normal entry
point (i.e. the LEP) and the alternate entry point (i.e. the GEP).
The patch has been tested on X86 and PowerPC with no regressions.
Diffstat (limited to 'gdb/infcmd.c')
-rw-r--r-- | gdb/infcmd.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 5fcd2ab..978c07f 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1720,22 +1720,25 @@ finish_backward (struct finish_command_fsm *sm) sal = find_pc_line (func_addr, 0); frame_info_ptr frame = get_selected_frame (nullptr); + struct gdbarch *gdbarch = get_frame_arch (frame); + CORE_ADDR alt_entry_point = sal.pc; + CORE_ADDR entry_point = alt_entry_point; - if (sal.pc != pc) + if (gdbarch_skip_entrypoint_p (gdbarch)) { - struct gdbarch *gdbarch = get_frame_arch (frame); - - /* Set a step-resume at the function's entry point. Once that's - hit, we'll do one more step backwards. */ - symtab_and_line sr_sal; - sr_sal.pc = sal.pc; - sr_sal.pspace = get_frame_program_space (frame); - insert_step_resume_breakpoint_at_sal (gdbarch, - sr_sal, null_frame_id); + /* Some architectures, like PowerPC use local and global entry points. + There is only one Entry Point (GEP = LEP) for other architectures. + The GEP is an alternate entry point. The LEP is the normal entry + point. The value of entry_point was initialized to the alternate + entry point (GEP). It will be adjusted if the normal entry point + (LEP) was used. */ + entry_point = gdbarch_skip_entrypoint (gdbarch, entry_point); } - else + + if (alt_entry_point <= pc && pc <= entry_point) { - /* We are exactly at the function entry point. Note that this + /* We are exactly at the function entry point, or between the entry + point on platforms that have two (like PowerPC). Note that this can only happen at frame #0. When setting a step range, need to call set_step_info @@ -1744,8 +1747,17 @@ finish_backward (struct finish_command_fsm *sm) /* Return using a step range so we will keep stepping back to the first instruction in the source code line. */ - tp->control.step_range_start = sal.pc; - tp->control.step_range_end = sal.pc; + tp->control.step_range_start = alt_entry_point; + tp->control.step_range_end = entry_point; + } + else + { + symtab_and_line sr_sal; + /* Set a step-resume at the function's entry point. */ + sr_sal.pc = entry_point; + sr_sal.pspace = get_frame_program_space (frame); + insert_step_resume_breakpoint_at_sal (gdbarch, + sr_sal, null_frame_id); } proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); } |