Home | History | Annotate | Line # | Download | only in gdb
mem-break.c revision 1.1.1.8
      1      1.1  christos /* Simulate breakpoints by patching locations in the target system, for GDB.
      2      1.1  christos 
      3  1.1.1.8  christos    Copyright (C) 1990-2023 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    Contributed by Cygnus Support.  Written by John Gilmore.
      6      1.1  christos 
      7      1.1  christos    This file is part of GDB.
      8      1.1  christos 
      9      1.1  christos    This program is free software; you can redistribute it and/or modify
     10      1.1  christos    it under the terms of the GNU General Public License as published by
     11      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12      1.1  christos    (at your option) any later version.
     13      1.1  christos 
     14      1.1  christos    This program is distributed in the hope that it will be useful,
     15      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17      1.1  christos    GNU General Public License for more details.
     18      1.1  christos 
     19      1.1  christos    You should have received a copy of the GNU General Public License
     20      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21      1.1  christos 
     22      1.1  christos #include "defs.h"
     23      1.1  christos #include "symtab.h"
     24      1.1  christos #include "breakpoint.h"
     25      1.1  christos #include "inferior.h"
     26      1.1  christos #include "target.h"
     27  1.1.1.7  christos #include "gdbarch.h"
     28  1.1.1.7  christos 
     29      1.1  christos /* Insert a breakpoint on targets that don't have any better
     30      1.1  christos    breakpoint support.  We read the contents of the target location
     31      1.1  christos    and stash it, then overwrite it with a breakpoint instruction.
     32      1.1  christos    BP_TGT->placed_address is the target location in the target
     33      1.1  christos    machine.  BP_TGT->shadow_contents is some memory allocated for
     34      1.1  christos    saving the target contents.  It is guaranteed by the caller to be
     35      1.1  christos    long enough to save BREAKPOINT_LEN bytes (this is accomplished via
     36      1.1  christos    BREAKPOINT_MAX).  */
     37      1.1  christos 
     38      1.1  christos int
     39      1.1  christos default_memory_insert_breakpoint (struct gdbarch *gdbarch,
     40      1.1  christos 				  struct bp_target_info *bp_tgt)
     41      1.1  christos {
     42  1.1.1.5  christos   CORE_ADDR addr = bp_tgt->placed_address;
     43      1.1  christos   const unsigned char *bp;
     44      1.1  christos   gdb_byte *readbuf;
     45  1.1.1.2  christos   int bplen;
     46  1.1.1.2  christos   int val;
     47      1.1  christos 
     48      1.1  christos   /* Determine appropriate breakpoint contents and size for this address.  */
     49  1.1.1.5  christos   bp = gdbarch_sw_breakpoint_from_kind (gdbarch, bp_tgt->kind, &bplen);
     50  1.1.1.2  christos 
     51      1.1  christos   /* Save the memory contents in the shadow_contents buffer and then
     52      1.1  christos      write the breakpoint instruction.  */
     53  1.1.1.4  christos   readbuf = (gdb_byte *) alloca (bplen);
     54  1.1.1.2  christos   val = target_read_memory (addr, readbuf, bplen);
     55      1.1  christos   if (val == 0)
     56      1.1  christos     {
     57  1.1.1.3  christos       /* These must be set together, either before or after the shadow
     58  1.1.1.3  christos 	 read, so that if we're "reinserting" a breakpoint that
     59  1.1.1.3  christos 	 doesn't have a shadow yet, the breakpoint masking code inside
     60  1.1.1.3  christos 	 target_read_memory doesn't mask out this breakpoint using an
     61  1.1.1.3  christos 	 unfilled shadow buffer.  The core may be trying to reinsert a
     62  1.1.1.3  christos 	 permanent breakpoint, for targets that support breakpoint
     63  1.1.1.3  christos 	 conditions/commands on the target side for some types of
     64  1.1.1.3  christos 	 breakpoints, such as target remote.  */
     65  1.1.1.3  christos       bp_tgt->shadow_len = bplen;
     66  1.1.1.2  christos       memcpy (bp_tgt->shadow_contents, readbuf, bplen);
     67  1.1.1.3  christos 
     68  1.1.1.2  christos       val = target_write_raw_memory (addr, bp, bplen);
     69      1.1  christos     }
     70      1.1  christos 
     71      1.1  christos   return val;
     72      1.1  christos }
     73      1.1  christos 
     74      1.1  christos 
     75      1.1  christos int
     76      1.1  christos default_memory_remove_breakpoint (struct gdbarch *gdbarch,
     77      1.1  christos 				  struct bp_target_info *bp_tgt)
     78      1.1  christos {
     79  1.1.1.5  christos   int bplen;
     80  1.1.1.5  christos 
     81  1.1.1.5  christos   gdbarch_sw_breakpoint_from_kind (gdbarch, bp_tgt->kind, &bplen);
     82  1.1.1.5  christos 
     83      1.1  christos   return target_write_raw_memory (bp_tgt->placed_address, bp_tgt->shadow_contents,
     84  1.1.1.5  christos 				  bplen);
     85      1.1  christos }
     86      1.1  christos 
     87      1.1  christos 
     88      1.1  christos int
     89  1.1.1.2  christos memory_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
     90      1.1  christos 			  struct bp_target_info *bp_tgt)
     91      1.1  christos {
     92      1.1  christos   return gdbarch_memory_insert_breakpoint (gdbarch, bp_tgt);
     93      1.1  christos }
     94      1.1  christos 
     95      1.1  christos int
     96  1.1.1.2  christos memory_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
     97  1.1.1.4  christos 			  struct bp_target_info *bp_tgt,
     98  1.1.1.4  christos 			  enum remove_bp_reason reason)
     99      1.1  christos {
    100      1.1  christos   return gdbarch_memory_remove_breakpoint (gdbarch, bp_tgt);
    101      1.1  christos }
    102  1.1.1.2  christos 
    103  1.1.1.2  christos int
    104  1.1.1.2  christos memory_validate_breakpoint (struct gdbarch *gdbarch,
    105  1.1.1.2  christos 			    struct bp_target_info *bp_tgt)
    106  1.1.1.2  christos {
    107  1.1.1.2  christos   CORE_ADDR addr = bp_tgt->placed_address;
    108  1.1.1.2  christos   const gdb_byte *bp;
    109  1.1.1.2  christos   int val;
    110  1.1.1.2  christos   int bplen;
    111  1.1.1.2  christos   gdb_byte cur_contents[BREAKPOINT_MAX];
    112  1.1.1.2  christos 
    113  1.1.1.2  christos   /* Determine appropriate breakpoint contents and size for this
    114  1.1.1.2  christos      address.  */
    115  1.1.1.2  christos   bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
    116  1.1.1.2  christos 
    117  1.1.1.5  christos   if (bp == NULL)
    118  1.1.1.2  christos     return 0;
    119  1.1.1.2  christos 
    120  1.1.1.2  christos   /* Make sure we see the memory breakpoints.  */
    121  1.1.1.6  christos   scoped_restore restore_memory
    122  1.1.1.6  christos     = make_scoped_restore_show_memory_breakpoints (1);
    123  1.1.1.2  christos   val = target_read_memory (addr, cur_contents, bplen);
    124  1.1.1.2  christos 
    125  1.1.1.2  christos   /* If our breakpoint is no longer at the address, this means that
    126  1.1.1.2  christos      the program modified the code on us, so it is wrong to put back
    127  1.1.1.2  christos      the old value.  */
    128  1.1.1.6  christos   return (val == 0 && memcmp (bp, cur_contents, bplen) == 0);
    129  1.1.1.2  christos }
    130