From ae37b288922ffc0f08f582ff88fbb106b0f11c4f7762595a945647b1a1907690 Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Sun, 18 Mar 2007 05:52:58 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/gdb?expand=0&rev=10 --- atomic-single-step.diff | 309 ++++++++++++++++------------------------ gdb.changes | 5 + gdb.spec | 4 +- 3 files changed, 134 insertions(+), 184 deletions(-) diff --git a/atomic-single-step.diff b/atomic-single-step.diff index f9bc193..399220b 100644 --- a/atomic-single-step.diff +++ b/atomic-single-step.diff @@ -30,10 +30,10 @@ breakpoints where inserted; false means they where not. Index: alpha-tdep.c -================================================================================ ---- alpha-tdep.c +=================================================================== +--- alpha-tdep.c.orig +++ alpha-tdep.c -@@ -1510,7 +1510,7 @@ +@@ -1510,7 +1510,7 @@ alpha_next_pc (CORE_ADDR pc) return (pc + 4); } @@ -42,7 +42,7 @@ Index: alpha-tdep.c alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p) { static CORE_ADDR next_pc; -@@ -1528,6 +1528,7 @@ +@@ -1528,6 +1528,7 @@ alpha_software_single_step (enum target_ remove_single_step_breakpoints (); write_pc (next_pc); } @@ -50,9 +50,11 @@ Index: alpha-tdep.c } ---- alpha-tdep.h +Index: alpha-tdep.h +=================================================================== +--- alpha-tdep.h.orig +++ alpha-tdep.h -@@ -107,7 +107,7 @@ +@@ -107,7 +107,7 @@ struct gdbarch_tdep }; extern unsigned int alpha_read_insn (CORE_ADDR pc); @@ -61,9 +63,11 @@ Index: alpha-tdep.c extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc); extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *); ---- arm-tdep.c +Index: arm-tdep.c +=================================================================== +--- arm-tdep.c.orig +++ arm-tdep.c -@@ -1840,7 +1840,7 @@ +@@ -1840,7 +1840,7 @@ arm_get_next_pc (CORE_ADDR pc) single_step() is also called just after the inferior stops. If we had set up a simulated single-step, we undo our damage. */ @@ -72,7 +76,7 @@ Index: alpha-tdep.c arm_software_single_step (enum target_signal sig, int insert_bpt) { /* NOTE: This may insert the wrong breakpoint instruction when -@@ -1855,6 +1855,8 @@ +@@ -1855,6 +1855,8 @@ arm_software_single_step (enum target_si } else remove_single_step_breakpoints (); @@ -81,9 +85,11 @@ Index: alpha-tdep.c } #include "bfd-in2.h" ---- cris-tdep.c +Index: cris-tdep.c +=================================================================== +--- cris-tdep.c.orig +++ cris-tdep.c -@@ -2117,7 +2117,7 @@ +@@ -2117,7 +2117,7 @@ find_step_target (inst_env_type *inst_en digs through the opcodes in order to find all possible targets. Either one ordinary target or two targets for branches may be found. */ @@ -92,7 +98,7 @@ Index: alpha-tdep.c cris_software_single_step (enum target_signal ignore, int insert_breakpoints) { inst_env_type inst_env; -@@ -2150,6 +2150,8 @@ +@@ -2150,6 +2150,8 @@ cris_software_single_step (enum target_s } else remove_single_step_breakpoints (); @@ -101,9 +107,11 @@ Index: alpha-tdep.c } /* Calculates the prefix value for quick offset addressing mode. */ ---- gdbarch.c +Index: gdbarch.c +=================================================================== +--- gdbarch.c.orig +++ gdbarch.c -@@ -3273,14 +3273,14 @@ +@@ -3273,14 +3273,14 @@ gdbarch_software_single_step_p (struct g return gdbarch->software_single_step != NULL; } @@ -120,9 +128,11 @@ Index: alpha-tdep.c } void ---- gdbarch.h +Index: gdbarch.h +=================================================================== +--- gdbarch.h.orig +++ gdbarch.h -@@ -1140,14 +1140,16 @@ +@@ -1140,14 +1140,16 @@ extern void set_gdbarch_smash_text_addre #define SMASH_TEXT_ADDRESS(addr) (gdbarch_smash_text_address (current_gdbarch, addr)) #endif @@ -145,7 +155,7 @@ Index: alpha-tdep.c #if defined (SOFTWARE_SINGLE_STEP) /* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */ -@@ -1164,8 +1166,8 @@ +@@ -1164,8 +1166,8 @@ extern int gdbarch_software_single_step_ #define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch)) #endif @@ -156,9 +166,11 @@ Index: alpha-tdep.c extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step); #if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP) #error "Non multi-arch definition of SOFTWARE_SINGLE_STEP" ---- gdbarch.sh +Index: gdbarch.sh +=================================================================== +--- gdbarch.sh.orig +++ gdbarch.sh -@@ -601,15 +601,19 @@ +@@ -601,15 +601,19 @@ f:=:CORE_ADDR:addr_bits_remove:CORE_ADDR # It is not at all clear why SMASH_TEXT_ADDRESS is not folded into # ADDR_BITS_REMOVE. f:=:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr::core_addr_identity::0 @@ -185,9 +197,11 @@ Index: alpha-tdep.c # Return non-zero if the processor is executing a delay slot and a # further single-step is needed before the instruction finishes. M::int:single_step_through_delay:struct frame_info *frame:frame ---- infrun.c +Index: infrun.c +=================================================================== +--- infrun.c.orig +++ infrun.c -@@ -557,13 +557,15 @@ +@@ -557,13 +557,15 @@ resume (int step, enum target_signal sig if (SOFTWARE_SINGLE_STEP_P () && step) { /* Do it the hard way, w/temp breakpoints */ @@ -210,7 +224,7 @@ Index: alpha-tdep.c } /* If there were any forks/vforks/execs that were caught and are -@@ -1382,7 +1384,7 @@ +@@ -1382,7 +1384,7 @@ handle_inferior_event (struct execution_ (LONGEST) ecs->ws.value.integer)); gdb_flush (gdb_stdout); target_mourn_inferior (); @@ -219,7 +233,7 @@ Index: alpha-tdep.c stop_print_frame = 0; stop_stepping (ecs); return; -@@ -1402,7 +1404,7 @@ +@@ -1402,7 +1404,7 @@ handle_inferior_event (struct execution_ target_mourn_inferior (); print_stop_reason (SIGNAL_EXITED, stop_signal); @@ -228,7 +242,7 @@ Index: alpha-tdep.c stop_stepping (ecs); return; -@@ -1576,7 +1578,7 @@ +@@ -1576,7 +1578,7 @@ handle_inferior_event (struct execution_ if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n"); /* Pull the single step breakpoints out of the target. */ @@ -237,7 +251,7 @@ Index: alpha-tdep.c singlestep_breakpoints_inserted_p = 0; ecs->random_signal = 0; -@@ -1640,7 +1642,7 @@ +@@ -1640,7 +1642,7 @@ handle_inferior_event (struct execution_ if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) { /* Pull the single step breakpoints out of the target. */ @@ -246,7 +260,7 @@ Index: alpha-tdep.c singlestep_breakpoints_inserted_p = 0; } -@@ -1713,7 +1715,7 @@ +@@ -1713,7 +1715,7 @@ handle_inferior_event (struct execution_ if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) { /* Pull the single step breakpoints out of the target. */ @@ -255,9 +269,11 @@ Index: alpha-tdep.c singlestep_breakpoints_inserted_p = 0; } ---- mips-tdep.c +Index: mips-tdep.c +=================================================================== +--- mips-tdep.c.orig +++ mips-tdep.c -@@ -2185,7 +2185,7 @@ +@@ -2185,7 +2185,7 @@ mips_addr_bits_remove (CORE_ADDR addr) single_step is also called just after the inferior stops. If we had set up a simulated single-step, we undo our damage. */ @@ -266,7 +282,7 @@ Index: alpha-tdep.c mips_software_single_step (enum target_signal sig, int insert_breakpoints_p) { CORE_ADDR pc, next_pc; -@@ -2199,6 +2199,8 @@ +@@ -2199,6 +2199,8 @@ mips_software_single_step (enum target_s } else remove_single_step_breakpoints (); @@ -275,9 +291,11 @@ Index: alpha-tdep.c } /* Test whether the PC points to the return instruction at the ---- mips-tdep.h +Index: mips-tdep.h +=================================================================== +--- mips-tdep.h.orig +++ mips-tdep.h -@@ -103,7 +103,7 @@ +@@ -103,7 +103,7 @@ enum }; /* Single step based on where the current instruction will take us. */ @@ -286,193 +304,100 @@ Index: alpha-tdep.c /* Tell if the program counter value in MEMADDR is in a MIPS16 function. */ ---- ppc-linux-tdep.c -+++ ppc-linux-tdep.c -@@ -931,6 +931,90 @@ - trad_frame_set_id (this_cache, frame_id_build (base, func)); - } - -+#define LWARX_MASK 0xfc0007fe -+#define LWARX_INSTRUCTION 0x7C000028 -+#define STWCX_MASK 0xfc0007ff -+#define STWCX_INSTRUCTION 0x7c00012d -+#define BC_MASK 0xfc000000 -+#define BC_INSTRUCTION 0x40000000 -+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16) -+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1)) -+ -+static int -+ppc_atomic_single_step (enum target_signal sig, int insert_breakpoints_p) -+{ -+ if (insert_breakpoints_p) -+ { -+ CORE_ADDR pc = read_pc (); -+ CORE_ADDR breaks[2] = {-1, -1}; -+ CORE_ADDR loc = pc; -+ int insn = read_insn (loc); -+ int last_break = 0; -+ int i; -+ -+ -+ /* Assume all atomic sequences start with an lwarx instruction. */ -+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION) -+ return 0; -+ -+ /* Assume that no atomic sequence is longer than 6 instructions. */ -+ for (i = 1; i < 5; ++i) -+ { -+ loc += PPC_INSN_SIZE; -+ insn = read_insn (loc); -+ -+ /* Assume at most one conditional branch instruction between -+ the lwarx and stwcx instructions.*/ -+ if ((insn & BC_MASK) == BC_INSTRUCTION) -+ { -+ last_break = 1; -+ breaks[1] = IMMEDIATE_PART (insn); -+ if (! ABSOLUTE_P (insn)) -+ breaks[1] += loc; -+ continue; -+ } -+ -+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION) -+ break; -+ } -+ -+ /* Assume that the atomic sequence ends with a stwcx instruction -+ followed by a conditional branch instruction. */ -+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION) -+ { -+ warning (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence.")); -+ return 0; -+ } -+ -+ loc += PPC_INSN_SIZE; -+ insn = read_insn (loc); -+ -+ if ((insn & BC_MASK) != BC_INSTRUCTION) -+ { -+ warning (_("Tried to step over an atomic sequence of instructions but it did not end as expected.")); -+ return 0; -+ } -+ -+ breaks[0] = loc; -+ -+ /* This should never happen, but make sure we don't but -+ two breakpoints on the same address. */ -+ if (last_break && breaks[1] == breaks[0]) -+ last_break = 0; -+ -+ for (i= 0; i <= last_break; ++i) -+ insert_single_step_breakpoint (breaks[i]); -+ -+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"), -+ core_addr_to_string (pc)); -+ gdb_flush (gdb_stdout); -+ } -+ else -+ remove_single_step_breakpoints (); -+ -+ return 1; -+} -+ - static void - ppc32_linux_sigaction_cache_init (const struct tramp_frame *self, - struct frame_info *next_frame, -@@ -1086,6 +1170,10 @@ - /* Enable TLS support. */ - set_gdbarch_fetch_tls_load_module_address (gdbarch, - svr4_fetch_objfile_link_map); -+ -+ /* Enable software_single_step in case someone tries to sngle step a -+ sequence of instructions that should be atomic. */ -+ set_gdbarch_software_single_step (gdbarch, ppc_atomic_single_step); - } - - void ---- rs6000-tdep.c +Index: rs6000-tdep.c +=================================================================== +--- rs6000-tdep.c.orig +++ rs6000-tdep.c -@@ -702,10 +702,89 @@ +@@ -702,10 +702,98 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp return little_breakpoint; } +#define LWARX_MASK 0xfc0007fe +#define LWARX_INSTRUCTION 0x7C000028 ++#define LDARX_INSTRUCTION 0x7C000108 +#define STWCX_MASK 0xfc0007ff +#define STWCX_INSTRUCTION 0x7c00012d ++#define STDCX_INSTRUCTION 0x7c0001ad +#define BC_MASK 0xfc000000 +#define BC_INSTRUCTION 0x40000000 +#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16) +#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1)) + +static int -+deal_with_atomic_sequence (enum target_signal sig) ++deal_with_atomic_sequence (enum target_signal sig, int insert_breakpoints_p) +{ + CORE_ADDR pc = read_pc (); + CORE_ADDR breaks[2] = {-1, -1}; + CORE_ADDR loc = pc; -+ int insn = read_memory_integer (loc, 4); ++ int insn = read_memory_integer (loc, PPC_INSN_SIZE); + int last_break = 0; + int i; -/* AIX does not support PT_STEP. Simulate it. */ - --void -+ /* Assume all atomic sequences start with an lwarx instruction. */ -+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION) ++ if (insert_breakpoints_p) ++ { ++ ++ /* Assume all atomic sequences start with an lwarx or ldarx instruction. */ ++ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION ++ && (insn & LWARX_MASK) != LDARX_INSTRUCTION) + return 0; + + /* Assume that no atomic sequence is longer than 6 instructions. */ + for (i = 1; i < 5; ++i) + { + loc += PPC_INSN_SIZE; -+ insn = read_memory_integer (loc, 4); ++ insn = read_memory_integer (loc, PPC_INSN_SIZE); + + /* Assume at most one conditional branch instruction between -+ the lwarx and stwcx instructions.*/ ++ the lwarx and stwcx instructions.*/ + if ((insn & BC_MASK) == BC_INSTRUCTION) -+ { -+ last_break = 1; -+ breaks[1] = IMMEDIATE_PART (insn); -+ if (! ABSOLUTE_P (insn)) -+ breaks[1] += loc; -+ continue; -+ } -+ -+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION) -+ break; ++ { ++ last_break = 1; ++ breaks[1] = IMMEDIATE_PART (insn); ++ if ( ! ABSOLUTE_P(insn)) ++ breaks[1] += loc; ++ continue; ++ } + +-void ++ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION ++ || (insn & STWCX_MASK) == STDCX_INSTRUCTION) ++ break; + } + + /* Assume that the atomic sequence ends with a stwcx instruction + followed by a conditional branch instruction. */ -+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION) -+ { -+ warning (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence.")); -+ return 0; -+ } ++ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION ++ && (insn & STWCX_MASK) != STDCX_INSTRUCTION) ++ warning (_("Tried to step over an atomic sequence of instructions at %s\n \ ++ but could not find the end of the sequence."), ++ core_addr_to_string(pc)); + + loc += PPC_INSN_SIZE; -+ insn = read_memory_integer (loc, 4); ++ insn = read_memory_integer (loc, PPC_INSN_SIZE); + + if ((insn & BC_MASK) != BC_INSTRUCTION) -+ { -+ warning (_("Tried to step over an atomic sequence of instructions but it did not end as expected.")); -+ return 0; -+ } ++ warning (_("Tried to step over an atomic sequence of instructions at %s\n \ ++ but the instruction sequence ended in an unexpected way."), ++ core_addr_to_string(pc)); + + breaks[0] = loc; + -+ /* This should never happen, but make sure we don't but ++ /* This should never happen, but make sure we don't put + two breakpoints on the same address. */ + if (last_break && breaks[1] == breaks[0]) + last_break = 0; + -+ for (i= 0; i <= last_break; ++i) ++ for (i = 0; i <= last_break; ++i) + insert_single_step_breakpoint (breaks[i]); + + printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"), + core_addr_to_string (pc)); ++ + gdb_flush (gdb_stdout); ++ } ++ else ++ remove_single_step_breakpoints(); + + return 1; +} @@ -484,17 +409,17 @@ Index: alpha-tdep.c rs6000_software_single_step (enum target_signal signal, int insert_breakpoints_p) { -@@ -723,6 +802,9 @@ +@@ -723,6 +811,9 @@ rs6000_software_single_step (enum target insn = read_memory_integer (loc, 4); -+ if (deal_with_atomic_sequence (signal)) ++ if (deal_with_atomic_sequence (signal, insert_breakpoints_p)) + return 1; + breaks[0] = loc + breakp_sz; opcode = insn >> 26; breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); -@@ -744,6 +826,8 @@ +@@ -744,6 +835,8 @@ rs6000_software_single_step (enum target errno = 0; /* FIXME, don't ignore errors! */ /* What errors? {read,write}_memory call error(). */ @@ -503,7 +428,19 @@ Index: alpha-tdep.c } ---- rs6000-tdep.h +@@ -3470,6 +3563,9 @@ rs6000_gdbarch_init (struct gdbarch_info + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc); + ++ /* Watch for locking instruction sequences during single stepping */ ++ set_gdbarch_software_single_step(gdbarch, deal_with_atomic_sequence); ++ + /* Handle the 64-bit SVR4 minimal-symbol convention of using "FN" + for the descriptor and ".FN" for the entry-point -- a user + specifying "break FN" will unexpectedly end up with a breakpoint +Index: rs6000-tdep.h +=================================================================== +--- rs6000-tdep.h.orig +++ rs6000-tdep.h @@ -21,6 +21,6 @@ @@ -514,9 +451,11 @@ Index: alpha-tdep.c +extern int rs6000_software_single_step (enum target_signal signal, + int insert_breakpoints_p); ---- sparc-tdep.c +Index: sparc-tdep.c +=================================================================== +--- sparc-tdep.c.orig +++ sparc-tdep.c -@@ -1131,7 +1131,7 @@ +@@ -1131,7 +1131,7 @@ sparc_step_trap (unsigned long insn) return 0; } @@ -525,7 +464,7 @@ Index: alpha-tdep.c sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p) { struct gdbarch *arch = current_gdbarch; -@@ -1161,6 +1161,8 @@ +@@ -1161,6 +1161,8 @@ sparc_software_single_step (enum target_ } else remove_single_step_breakpoints (); @@ -534,9 +473,11 @@ Index: alpha-tdep.c } static void ---- sparc-tdep.h +Index: sparc-tdep.h +=================================================================== +--- sparc-tdep.h.orig +++ sparc-tdep.h -@@ -167,8 +167,8 @@ +@@ -167,8 +167,8 @@ extern struct sparc_frame_cache * @@ -547,9 +488,11 @@ Index: alpha-tdep.c extern void sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum); ---- wince.c +Index: wince.c +=================================================================== +--- wince.c.orig +++ wince.c -@@ -838,7 +838,7 @@ +@@ -838,7 +838,7 @@ undoSStep (thread_info * th) } } @@ -558,7 +501,7 @@ Index: alpha-tdep.c wince_software_single_step (enum target_signal ignore, int insert_breakpoints_p) { -@@ -850,14 +850,15 @@ +@@ -850,14 +850,15 @@ wince_software_single_step (enum target_ if (!insert_breakpoints_p) { undoSStep (th); @@ -576,7 +519,7 @@ Index: alpha-tdep.c } #elif SHx /* Renesas SH architecture instruction encoding masks */ -@@ -979,7 +980,7 @@ +@@ -979,7 +980,7 @@ undoSStep (thread_info * th) instruction and setting a breakpoint on the "next" instruction which would be executed. This code hails from sh-stub.c. */ @@ -585,7 +528,7 @@ Index: alpha-tdep.c wince_software_single_step (enum target_signal ignore, int insert_breakpoints_p) { -@@ -989,13 +990,14 @@ +@@ -989,13 +990,14 @@ wince_software_single_step (enum target_ if (!insert_breakpoints_p) { undoSStep (th); @@ -602,7 +545,7 @@ Index: alpha-tdep.c } #elif defined (ARM) #undef check_for_step -@@ -1026,7 +1028,7 @@ +@@ -1026,7 +1028,7 @@ undoSStep (thread_info * th) } } @@ -611,7 +554,7 @@ Index: alpha-tdep.c wince_software_single_step (enum target_signal ignore, int insert_breakpoints_p) { -@@ -1038,14 +1040,15 @@ +@@ -1038,14 +1040,15 @@ wince_software_single_step (enum target_ if (!insert_breakpoints_p) { undoSStep (th); diff --git a/gdb.changes b/gdb.changes index 27932b2..3636170 100644 --- a/gdb.changes +++ b/gdb.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Fri Mar 16 13:39:50 CET 2007 - schwab@suse.de + +- Update single stepping patch [#154486]. + ------------------------------------------------------------------- Thu Mar 15 18:22:31 CET 2007 - schwab@suse.de diff --git a/gdb.spec b/gdb.spec index e2cc349..65d496f 100644 --- a/gdb.spec +++ b/gdb.spec @@ -21,7 +21,7 @@ Group: Development/Tools/Debuggers Autoreqprov: on PreReq: %{install_info_prereq} Version: 6.6 -Release: 20 +Release: 21 Summary: The GNU Debugger Source: gdb-%{version}.tar.bz2 Patch1: gdb-misc.patch @@ -149,6 +149,8 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Fri Mar 16 2007 - schwab@suse.de +- Update single stepping patch [#154486]. * Thu Mar 15 2007 - schwab@suse.de - Fix altivec vector return location [#250004]. * Mon Mar 12 2007 - schwab@suse.de