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_break.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_break.c,v 1.22 2020/10/15 03:13:59 deraadt Exp $   */
    2 /*      $NetBSD: db_break.c,v 1.7 1996/03/30 22:30:03 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: David B. Golub, Carnegie Mellon University
   30  *      Date:   7/90
   31  */
   32 
   33 /*
   34  * Breakpoints.
   35  */
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 
   39 #include <machine/db_machdep.h>         /* type definitions */
   40 
   41 #include <ddb/db_access.h>
   42 #include <ddb/db_sym.h>
   43 #include <ddb/db_break.h>
   44 #include <ddb/db_output.h>
   45 
   46 #define NBREAKPOINTS    100
   47 struct db_breakpoint    db_break_table[NBREAKPOINTS];
   48 db_breakpoint_t         db_next_free_breakpoint = &db_break_table[0];
   49 db_breakpoint_t         db_free_breakpoints = 0;
   50 db_breakpoint_t         db_breakpoint_list = 0;
   51 
   52 db_breakpoint_t db_breakpoint_alloc(void);
   53 void db_breakpoint_free(db_breakpoint_t);
   54 void db_set_breakpoint(vaddr_t, int);
   55 void db_delete_breakpoint(vaddr_t);
   56 void db_list_breakpoints(void);
   57 
   58 db_breakpoint_t
   59 db_breakpoint_alloc(void)
   60 {
   61         db_breakpoint_t bkpt;
   62 
   63         if ((bkpt = db_free_breakpoints) != 0) {
   64                 db_free_breakpoints = bkpt->link;
   65                 return (bkpt);
   66         }
   67         if (db_next_free_breakpoint == &db_break_table[NBREAKPOINTS]) {
   68                 db_printf("All breakpoints used.\n");
   69                 return (0);
   70         }
   71         bkpt = db_next_free_breakpoint;
   72         db_next_free_breakpoint++;
   73 
   74         return (bkpt);
   75 }
   76 
   77 void
   78 db_breakpoint_free(db_breakpoint_t bkpt)
   79 {
   80         bkpt->link = db_free_breakpoints;
   81         db_free_breakpoints = bkpt;
   82 }
   83 
   84 void
   85 db_set_breakpoint(vaddr_t addr, int count)
   86 {
   87         db_breakpoint_t bkpt;
   88 
   89         if (db_find_breakpoint(addr)) {
   90                 db_printf("Already set.\n");
   91                 return;
   92         }
   93 
   94 #ifdef DB_VALID_BREAKPOINT
   95         if (!DB_VALID_BREAKPOINT(addr)) {
   96                 db_printf("Not a valid address for a breakpoint.\n");
   97                 return;
   98         }
   99 #endif
  100 
  101         bkpt = db_breakpoint_alloc();
  102         if (bkpt == 0) {
  103                 db_printf("Too many breakpoints.\n");
  104                 return;
  105         }
  106 
  107         bkpt->address = addr;
  108         bkpt->flags = 0;
  109         bkpt->init_count = count;
  110         bkpt->count = count;
  111 
  112         bkpt->link = db_breakpoint_list;
  113         db_breakpoint_list = bkpt;
  114 }
  115 
  116 void
  117 db_delete_breakpoint(vaddr_t addr)
  118 {
  119         db_breakpoint_t bkpt;
  120         db_breakpoint_t *prev;
  121 
  122         for (prev = &db_breakpoint_list; (bkpt = *prev) != 0;
  123             prev = &bkpt->link) {
  124                 if (bkpt->address == addr) {
  125                         *prev = bkpt->link;
  126                         break;
  127                 }
  128         }
  129         if (bkpt == 0) {
  130                 db_printf("Not set.\n");
  131                 return;
  132         }
  133 
  134         db_breakpoint_free(bkpt);
  135 }
  136 
  137 db_breakpoint_t
  138 db_find_breakpoint(vaddr_t addr)
  139 {
  140         db_breakpoint_t bkpt;
  141 
  142         for (bkpt = db_breakpoint_list; bkpt != 0; bkpt = bkpt->link)
  143                 if (bkpt->address == addr)
  144                         return (bkpt);
  145 
  146         return (0);
  147 }
  148 
  149 int db_breakpoints_inserted = 1;
  150 
  151 void
  152 db_set_breakpoints(void)
  153 {
  154         db_breakpoint_t bkpt;
  155 
  156         if (!db_breakpoints_inserted) {
  157                 for (bkpt = db_breakpoint_list; bkpt != 0; bkpt = bkpt->link) {
  158                         bkpt->bkpt_inst =
  159                             db_get_value(bkpt->address, BKPT_SIZE, 0);
  160                         db_put_value(bkpt->address, BKPT_SIZE,
  161                             BKPT_SET(bkpt->bkpt_inst));
  162                 }
  163                 db_breakpoints_inserted = 1;
  164         }
  165 }
  166 
  167 void
  168 db_clear_breakpoints(void)
  169 {
  170         db_breakpoint_t bkpt;
  171 
  172         if (db_breakpoints_inserted) {
  173                 for (bkpt = db_breakpoint_list; bkpt != 0; bkpt = bkpt->link)
  174                         db_put_value(bkpt->address, BKPT_SIZE, bkpt->bkpt_inst);
  175                 db_breakpoints_inserted = 0;
  176         }
  177 }
  178 
  179 /*
  180  * Set a temporary breakpoint.
  181  * The instruction is changed immediately,
  182  * so the breakpoint does not have to be on the breakpoint list.
  183  */
  184 db_breakpoint_t
  185 db_set_temp_breakpoint(vaddr_t addr)
  186 {
  187         db_breakpoint_t bkpt;
  188 
  189 #ifdef DB_VALID_BREAKPOINT
  190         if (!DB_VALID_BREAKPOINT(addr)) {
  191                 db_printf("Not a valid address for a breakpoint.\n");
  192                 return (0);
  193         }
  194 #endif
  195 
  196         bkpt = db_breakpoint_alloc();
  197         if (bkpt == 0) {
  198                 db_printf("Too many breakpoints.\n");
  199                 return (0);
  200         }
  201 
  202         bkpt->address = addr;
  203         bkpt->flags = BKPT_TEMP;
  204         bkpt->init_count = 1;
  205         bkpt->count = 1;
  206 
  207         bkpt->bkpt_inst = db_get_value(bkpt->address, BKPT_SIZE, 0);
  208         db_put_value(bkpt->address, BKPT_SIZE, BKPT_SET(bkpt->bkpt_inst));
  209         return bkpt;
  210 }
  211 
  212 void
  213 db_delete_temp_breakpoint(db_breakpoint_t bkpt)
  214 {
  215         db_put_value(bkpt->address, BKPT_SIZE, bkpt->bkpt_inst);
  216         db_breakpoint_free(bkpt);
  217 }
  218 
  219 /*
  220  * List breakpoints.
  221  */
  222 void
  223 db_list_breakpoints(void)
  224 {
  225         db_breakpoint_t bkpt;
  226 
  227         if (db_breakpoint_list == NULL) {
  228                 db_printf("No breakpoints set\n");
  229                 return;
  230         }
  231 
  232         db_printf(" Count    Address\n");
  233         for (bkpt = db_breakpoint_list; bkpt != 0; bkpt = bkpt->link) {
  234                 db_printf(" %5d    ", bkpt->init_count);
  235                 db_printsym(bkpt->address, DB_STGY_PROC, db_printf);
  236                 db_printf("\n");
  237         }
  238 }
  239 
  240 /* Delete breakpoint */
  241 /*ARGSUSED*/
  242 void
  243 db_delete_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  244 {
  245         db_delete_breakpoint((vaddr_t)addr);
  246 }
  247 
  248 /* Set breakpoint with skip count */
  249 /*ARGSUSED*/
  250 void
  251 db_breakpoint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  252 {
  253         if (count == -1)
  254                 count = 1;
  255 
  256         db_set_breakpoint((vaddr_t)addr, count);
  257 }
  258 
  259 /* list breakpoints */
  260 /*ARGSUSED*/
  261 void
  262 db_listbreak_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  263 {
  264         db_list_breakpoints();
  265 }

Cache object: 3ba133c414fb3b6e154af53679a1c2b0


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