Annotation of Net2/ddb/db_watch.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie the
                     24:  * rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  * HISTORY
                     28:  * $Log: db_watch.c,v $
                     29:  * Revision 1.1  1992/03/25  21:45:37  pace
                     30:  * Initial revision
                     31:  *
                     32:  * Revision 2.5  91/02/05  17:07:27  mrt
                     33:  *     Changed to new Mach copyright
                     34:  *     [91/01/31  16:20:02  mrt]
                     35:  * 
                     36:  * Revision 2.4  91/01/08  15:09:24  rpd
                     37:  *     Use db_map_equal, db_map_current, db_map_addr.
                     38:  *     [90/11/10            rpd]
                     39:  * 
                     40:  * Revision 2.3  90/11/05  14:26:39  rpd
                     41:  *     Initialize db_watchpoints_inserted to TRUE.
                     42:  *     [90/11/04            rpd]
                     43:  * 
                     44:  * Revision 2.2  90/10/25  14:44:16  rwd
                     45:  *     Made db_watchpoint_cmd parse a size argument.
                     46:  *     [90/10/17            rpd]
                     47:  *     Generalized the watchpoint support.
                     48:  *     [90/10/16            rwd]
                     49:  *     Created.
                     50:  *     [90/10/16            rpd]
                     51:  * 
                     52:  */
                     53: /*
                     54:  *     Author: Richard P. Draves, Carnegie Mellon University
                     55:  *     Date:   10/90
                     56:  */
                     57: 
                     58: #include "param.h"
                     59: #include "proc.h"
                     60: #include <machine/db_machdep.h>
                     61: 
                     62: #include <vm/vm_map.h>
                     63: #include <ddb/db_lex.h>
                     64: #include <ddb/db_watch.h>
                     65: #include <ddb/db_access.h>
                     66: #include <ddb/db_sym.h>
                     67: #include <machine/db_machdep.h>
                     68: 
                     69: /*
                     70:  * Watchpoints.
                     71:  */
                     72: 
                     73: extern boolean_t db_map_equal();
                     74: extern boolean_t db_map_current();
                     75: extern vm_map_t db_map_addr();
                     76: 
                     77: boolean_t      db_watchpoints_inserted = TRUE;
                     78: 
                     79: #define        NWATCHPOINTS    100
                     80: struct db_watchpoint   db_watch_table[NWATCHPOINTS];
                     81: db_watchpoint_t                db_next_free_watchpoint = &db_watch_table[0];
                     82: db_watchpoint_t                db_free_watchpoints = 0;
                     83: db_watchpoint_t                db_watchpoint_list = 0;
                     84: 
                     85: db_watchpoint_t
                     86: db_watchpoint_alloc()
                     87: {
                     88:        register db_watchpoint_t        watch;
                     89: 
                     90:        if ((watch = db_free_watchpoints) != 0) {
                     91:            db_free_watchpoints = watch->link;
                     92:            return (watch);
                     93:        }
                     94:        if (db_next_free_watchpoint == &db_watch_table[NWATCHPOINTS]) {
                     95:            db_printf("All watchpoints used.\n");
                     96:            return (0);
                     97:        }
                     98:        watch = db_next_free_watchpoint;
                     99:        db_next_free_watchpoint++;
                    100: 
                    101:        return (watch);
                    102: }
                    103: 
                    104: void
                    105: db_watchpoint_free(watch)
                    106:        register db_watchpoint_t        watch;
                    107: {
                    108:        watch->link = db_free_watchpoints;
                    109:        db_free_watchpoints = watch;
                    110: }
                    111: 
                    112: void
                    113: db_set_watchpoint(map, addr, size)
                    114:        vm_map_t        map;
                    115:        db_addr_t       addr;
                    116:        vm_size_t       size;
                    117: {
                    118:        register db_watchpoint_t        watch;
                    119: 
                    120:        if (map == NULL) {
                    121:            db_printf("No map.\n");
                    122:            return;
                    123:        }
                    124: 
                    125:        /*
                    126:         *      Should we do anything fancy with overlapping regions?
                    127:         */
                    128: 
                    129:        for (watch = db_watchpoint_list;
                    130:             watch != 0;
                    131:             watch = watch->link)
                    132:            if (db_map_equal(watch->map, map) &&
                    133:                (watch->loaddr == addr) &&
                    134:                (watch->hiaddr == addr+size)) {
                    135:                db_printf("Already set.\n");
                    136:                return;
                    137:            }
                    138: 
                    139:        watch = db_watchpoint_alloc();
                    140:        if (watch == 0) {
                    141:            db_printf("Too many watchpoints.\n");
                    142:            return;
                    143:        }
                    144: 
                    145:        watch->map = map;
                    146:        watch->loaddr = addr;
                    147:        watch->hiaddr = addr+size;
                    148: 
                    149:        watch->link = db_watchpoint_list;
                    150:        db_watchpoint_list = watch;
                    151: 
                    152:        db_watchpoints_inserted = FALSE;
                    153: }
                    154: 
                    155: void
                    156: db_delete_watchpoint(map, addr)
                    157:        vm_map_t        map;
                    158:        db_addr_t       addr;
                    159: {
                    160:        register db_watchpoint_t        watch;
                    161:        register db_watchpoint_t        *prev;
                    162: 
                    163:        for (prev = &db_watchpoint_list;
                    164:             (watch = *prev) != 0;
                    165:             prev = &watch->link)
                    166:            if (db_map_equal(watch->map, map) &&
                    167:                (watch->loaddr <= addr) &&
                    168:                (addr < watch->hiaddr)) {
                    169:                *prev = watch->link;
                    170:                db_watchpoint_free(watch);
                    171:                return;
                    172:            }
                    173: 
                    174:        db_printf("Not set.\n");
                    175: }
                    176: 
                    177: void
                    178: db_list_watchpoints()
                    179: {
                    180:        register db_watchpoint_t        watch;
                    181: 
                    182:        if (db_watchpoint_list == 0) {
                    183:            db_printf("No watchpoints set\n");
                    184:            return;
                    185:        }
                    186: 
                    187:        db_printf(" Map        Address  Size\n");
                    188:        for (watch = db_watchpoint_list;
                    189:             watch != 0;
                    190:             watch = watch->link)
                    191:            db_printf("%s%8x  %8x  %x\n",
                    192:                      db_map_current(watch->map) ? "*" : " ",
                    193:                      watch->map, watch->loaddr,
                    194:                      watch->hiaddr - watch->loaddr);
                    195: }
                    196: 
                    197: /* Delete watchpoint */
                    198: /*ARGSUSED*/
                    199: void
                    200: db_deletewatch_cmd(addr, have_addr, count, modif)
                    201:        db_expr_t       addr;
                    202:        int             have_addr;
                    203:        db_expr_t       count;
                    204:        char *          modif;
                    205: {
                    206:        db_delete_watchpoint(db_map_addr(addr), addr);
                    207: }
                    208: 
                    209: /* Set watchpoint */
                    210: /*ARGSUSED*/
                    211: void
                    212: db_watchpoint_cmd(addr, have_addr, count, modif)
                    213:        db_expr_t       addr;
                    214:        int             have_addr;
                    215:        db_expr_t       count;
                    216:        char *          modif;
                    217: {
                    218:        vm_size_t       size;
                    219:        db_expr_t       value;
                    220: 
                    221:        if (db_expression(&value))
                    222:            size = (vm_size_t) value;
                    223:        else
                    224:            size = 4;
                    225:        db_skip_to_eol();
                    226: 
                    227:        db_set_watchpoint(db_map_addr(addr), addr, size);
                    228: }
                    229: 
                    230: /* list watchpoints */
                    231: void
                    232: db_listwatch_cmd()
                    233: {
                    234:        db_list_watchpoints();
                    235: }
                    236: 
                    237: void
                    238: db_set_watchpoints()
                    239: {
                    240:        register db_watchpoint_t        watch;
                    241: 
                    242:        if (!db_watchpoints_inserted) {
                    243:            for (watch = db_watchpoint_list;
                    244:                 watch != 0;
                    245:                 watch = watch->link)
                    246:                pmap_protect(watch->map->pmap,
                    247:                             trunc_page(watch->loaddr),
                    248:                             round_page(watch->hiaddr),
                    249:                             VM_PROT_READ);
                    250: 
                    251:            db_watchpoints_inserted = TRUE;
                    252:        }
                    253: }
                    254: 
                    255: void
                    256: db_clear_watchpoints()
                    257: {
                    258:        db_watchpoints_inserted = FALSE;
                    259: }
                    260: 
                    261: boolean_t
                    262: db_find_watchpoint(map, addr, regs)
                    263:        vm_map_t        map;
                    264:        db_addr_t       addr;
                    265:        db_regs_t       *regs;
                    266: {
                    267:        register db_watchpoint_t watch;
                    268:        db_watchpoint_t found = 0;
                    269: 
                    270:        for (watch = db_watchpoint_list;
                    271:             watch != 0;
                    272:             watch = watch->link)
                    273:            if (db_map_equal(watch->map, map)) {
                    274:                if ((watch->loaddr <= addr) &&
                    275:                    (addr < watch->hiaddr))
                    276:                    return (TRUE);
                    277:                else if ((trunc_page(watch->loaddr) <= addr) &&
                    278:                         (addr < round_page(watch->hiaddr)))
                    279:                    found = watch;
                    280:            }
                    281: 
                    282:        /*
                    283:         *      We didn't hit exactly on a watchpoint, but we are
                    284:         *      in a protected region.  We want to single-step
                    285:         *      and then re-protect.
                    286:         */
                    287: 
                    288:        if (found) {
                    289:            db_watchpoints_inserted = FALSE;
                    290:            db_single_step(regs);
                    291:        }
                    292: 
                    293:        return (FALSE);
                    294: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.