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

Cache object: ad52ed82ae92fddd0c1bdbb5e579a6d1


[ 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.