The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_watch.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: db_watch.c,v 1.20 2003/11/09 20:52:18 scw Exp $        */
    2 
    3 /*
    4  * Mach Operating System
    5  * Copyright (c) 1991,1990 Carnegie Mellon University
    6  * All Rights Reserved.
    7  *
    8  * Permission to use, copy, modify and distribute this software and its
    9  * documentation is hereby granted, provided that both the copyright
   10  * notice and this permission notice appear in all copies of the
   11  * software, derivative works or modified versions, and any portions
   12  * thereof, and that both notices appear in supporting documentation.
   13  *
   14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   17  *
   18  * Carnegie Mellon requests users of this software to return to
   19  *
   20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   21  *  School of Computer Science
   22  *  Carnegie Mellon University
   23  *  Pittsburgh PA 15213-3890
   24  *
   25  * any improvements or extensions that they make and grant Carnegie the
   26  * rights to redistribute these changes.
   27  *
   28  *      Author: Richard P. Draves, Carnegie Mellon University
   29  *      Date:   10/90
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: db_watch.c,v 1.20 2003/11/09 20:52:18 scw Exp $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/proc.h>
   37 
   38 #include <machine/db_machdep.h>
   39 
   40 #include <ddb/db_break.h>
   41 #include <ddb/db_watch.h>
   42 #include <ddb/db_lex.h>
   43 #include <ddb/db_access.h>
   44 #include <ddb/db_run.h>
   45 #include <ddb/db_sym.h>
   46 #include <ddb/db_output.h>
   47 #include <ddb/db_command.h>
   48 #include <ddb/db_extern.h>
   49 
   50 /*
   51  * Watchpoints.
   52  */
   53 
   54 static boolean_t                db_watchpoints_inserted = TRUE;
   55 
   56 #define NWATCHPOINTS    100
   57 static struct db_watchpoint     db_watch_table[NWATCHPOINTS];
   58 static db_watchpoint_t          db_next_free_watchpoint = &db_watch_table[0];
   59 static db_watchpoint_t          db_free_watchpoints = 0;
   60 static db_watchpoint_t          db_watchpoint_list = 0;
   61 
   62 static void             db_delete_watchpoint(struct vm_map *, db_addr_t);
   63 static void             db_list_watchpoints(void);
   64 static void             db_set_watchpoint(struct vm_map *, db_addr_t, vsize_t);
   65 static db_watchpoint_t  db_watchpoint_alloc(void);
   66 static void             db_watchpoint_free(db_watchpoint_t);
   67 
   68 db_watchpoint_t
   69 db_watchpoint_alloc(void)
   70 {
   71         db_watchpoint_t watch;
   72 
   73         if ((watch = db_free_watchpoints) != 0) {
   74                 db_free_watchpoints = watch->link;
   75                 return (watch);
   76         }
   77         if (db_next_free_watchpoint == &db_watch_table[NWATCHPOINTS]) {
   78                 db_printf("All watchpoints used.\n");
   79                 return (0);
   80         }
   81         watch = db_next_free_watchpoint;
   82         db_next_free_watchpoint++;
   83 
   84         return (watch);
   85 }
   86 
   87 void
   88 db_watchpoint_free(db_watchpoint_t watch)
   89 {
   90         watch->link = db_free_watchpoints;
   91         db_free_watchpoints = watch;
   92 }
   93 
   94 void
   95 db_set_watchpoint(struct vm_map *map, db_addr_t addr, vsize_t size)
   96 {
   97         db_watchpoint_t watch;
   98 
   99         if (map == NULL) {
  100                 db_printf("No map.\n");
  101                 return;
  102         }
  103 
  104         /*
  105          *      Should we do anything fancy with overlapping regions?
  106          */
  107 
  108         for (watch = db_watchpoint_list; watch != 0; watch = watch->link)
  109                 if (db_map_equal(watch->map, map) &&
  110                     (watch->loaddr == addr) &&
  111                     (watch->hiaddr == addr+size)) {
  112                         db_printf("Already set.\n");
  113                         return;
  114                 }
  115 
  116         watch = db_watchpoint_alloc();
  117         if (watch == 0) {
  118                 db_printf("Too many watchpoints.\n");
  119                 return;
  120         }
  121 
  122         watch->map = map;
  123         watch->loaddr = addr;
  124         watch->hiaddr = addr+size;
  125 
  126         watch->link = db_watchpoint_list;
  127         db_watchpoint_list = watch;
  128 
  129         db_watchpoints_inserted = FALSE;
  130 }
  131 
  132 static void
  133 db_delete_watchpoint(struct vm_map *map, db_addr_t addr)
  134 {
  135         db_watchpoint_t watch;
  136         db_watchpoint_t *prev;
  137 
  138         for (prev = &db_watchpoint_list;
  139              (watch = *prev) != 0;
  140              prev = &watch->link)
  141                 if (db_map_equal(watch->map, map) &&
  142                     (watch->loaddr <= addr) &&
  143                     (addr < watch->hiaddr)) {
  144                         *prev = watch->link;
  145                         db_watchpoint_free(watch);
  146                         return;
  147                 }
  148 
  149         db_printf("Not set.\n");
  150 }
  151 
  152 void
  153 db_list_watchpoints(void)
  154 {
  155         db_watchpoint_t watch;
  156 
  157         if (db_watchpoint_list == 0) {
  158                 db_printf("No watchpoints set\n");
  159                 return;
  160         }
  161 
  162         db_printf(" Map        Address  Size\n");
  163         for (watch = db_watchpoint_list; watch != 0; watch = watch->link)
  164                 db_printf("%s%p  %8lx  %lx\n",
  165                     db_map_current(watch->map) ? "*" : " ",
  166                     watch->map, (long)watch->loaddr,
  167                     (long)(watch->hiaddr - watch->loaddr));
  168 }
  169 
  170 /* Delete watchpoint */
  171 /*ARGSUSED*/
  172 void
  173 db_deletewatch_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  174 {
  175 
  176         db_delete_watchpoint(db_map_addr(addr), addr);
  177 }
  178 
  179 /* Set watchpoint */
  180 /*ARGSUSED*/
  181 void
  182 db_watchpoint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  183 {
  184         vsize_t size;
  185         db_expr_t value;
  186 
  187         if (db_expression(&value))
  188                 size = (vsize_t) value;
  189         else
  190                 size = 4;
  191         db_skip_to_eol();
  192 
  193         db_set_watchpoint(db_map_addr(addr), addr, size);
  194 }
  195 
  196 /* list watchpoints */
  197 /*ARGSUSED*/
  198 void
  199 db_listwatch_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  200 {
  201 
  202         db_list_watchpoints();
  203 }
  204 
  205 void
  206 db_set_watchpoints(void)
  207 {
  208         db_watchpoint_t watch;
  209 
  210         if (!db_watchpoints_inserted) {
  211                 for (watch = db_watchpoint_list;
  212                      watch != 0;
  213                      watch = watch->link) {
  214                         pmap_protect(watch->map->pmap,
  215                             trunc_page(watch->loaddr),
  216                             round_page(watch->hiaddr),
  217                             VM_PROT_READ);
  218                         pmap_update(watch->map->pmap);
  219                 }
  220 
  221                 db_watchpoints_inserted = TRUE;
  222         }
  223 }
  224 
  225 void
  226 db_clear_watchpoints(void)
  227 {
  228 
  229         db_watchpoints_inserted = FALSE;
  230 }

Cache object: 62d305662819bbaf5c3916d525f56bed


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.