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

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: /*
1.1.1.3 ! root       27:  * db_watch.c,v 1.2 1993/05/20 03:39:38 cgd Exp
        !            28:  *
1.1       root       29:  * HISTORY
1.1.1.3 ! root       30:  * db_watch.c,v
        !            31:  * Revision 1.2  1993/05/20  03:39:38  cgd
        !            32:  * add explicit rcs id
        !            33:  *
        !            34:  * Revision 1.1.1.1  1993/03/21  09:46:27  cgd
1.1.1.2   root       35:  * initial import of 386bsd-0.1 sources
                     36:  *
1.1       root       37:  * Revision 1.1  1992/03/25  21:45:37  pace
                     38:  * Initial revision
                     39:  *
                     40:  * Revision 2.5  91/02/05  17:07:27  mrt
                     41:  *     Changed to new Mach copyright
                     42:  *     [91/01/31  16:20:02  mrt]
                     43:  * 
                     44:  * Revision 2.4  91/01/08  15:09:24  rpd
                     45:  *     Use db_map_equal, db_map_current, db_map_addr.
                     46:  *     [90/11/10            rpd]
                     47:  * 
                     48:  * Revision 2.3  90/11/05  14:26:39  rpd
                     49:  *     Initialize db_watchpoints_inserted to TRUE.
                     50:  *     [90/11/04            rpd]
                     51:  * 
                     52:  * Revision 2.2  90/10/25  14:44:16  rwd
                     53:  *     Made db_watchpoint_cmd parse a size argument.
                     54:  *     [90/10/17            rpd]
                     55:  *     Generalized the watchpoint support.
                     56:  *     [90/10/16            rwd]
                     57:  *     Created.
                     58:  *     [90/10/16            rpd]
                     59:  * 
                     60:  */
                     61: /*
                     62:  *     Author: Richard P. Draves, Carnegie Mellon University
                     63:  *     Date:   10/90
                     64:  */
                     65: 
                     66: #include "param.h"
                     67: #include "proc.h"
                     68: #include <machine/db_machdep.h>
                     69: 
                     70: #include <vm/vm_map.h>
                     71: #include <ddb/db_lex.h>
                     72: #include <ddb/db_watch.h>
                     73: #include <ddb/db_access.h>
                     74: #include <ddb/db_sym.h>
                     75: #include <machine/db_machdep.h>
                     76: 
                     77: /*
                     78:  * Watchpoints.
                     79:  */
                     80: 
                     81: extern boolean_t db_map_equal();
                     82: extern boolean_t db_map_current();
                     83: extern vm_map_t db_map_addr();
                     84: 
                     85: boolean_t      db_watchpoints_inserted = TRUE;
                     86: 
                     87: #define        NWATCHPOINTS    100
                     88: struct db_watchpoint   db_watch_table[NWATCHPOINTS];
                     89: db_watchpoint_t                db_next_free_watchpoint = &db_watch_table[0];
                     90: db_watchpoint_t                db_free_watchpoints = 0;
                     91: db_watchpoint_t                db_watchpoint_list = 0;
                     92: 
                     93: db_watchpoint_t
                     94: db_watchpoint_alloc()
                     95: {
                     96:        register db_watchpoint_t        watch;
                     97: 
                     98:        if ((watch = db_free_watchpoints) != 0) {
                     99:            db_free_watchpoints = watch->link;
                    100:            return (watch);
                    101:        }
                    102:        if (db_next_free_watchpoint == &db_watch_table[NWATCHPOINTS]) {
                    103:            db_printf("All watchpoints used.\n");
                    104:            return (0);
                    105:        }
                    106:        watch = db_next_free_watchpoint;
                    107:        db_next_free_watchpoint++;
                    108: 
                    109:        return (watch);
                    110: }
                    111: 
                    112: void
                    113: db_watchpoint_free(watch)
                    114:        register db_watchpoint_t        watch;
                    115: {
                    116:        watch->link = db_free_watchpoints;
                    117:        db_free_watchpoints = watch;
                    118: }
                    119: 
                    120: void
                    121: db_set_watchpoint(map, addr, size)
                    122:        vm_map_t        map;
                    123:        db_addr_t       addr;
                    124:        vm_size_t       size;
                    125: {
                    126:        register db_watchpoint_t        watch;
                    127: 
                    128:        if (map == NULL) {
                    129:            db_printf("No map.\n");
                    130:            return;
                    131:        }
                    132: 
                    133:        /*
                    134:         *      Should we do anything fancy with overlapping regions?
                    135:         */
                    136: 
                    137:        for (watch = db_watchpoint_list;
                    138:             watch != 0;
                    139:             watch = watch->link)
                    140:            if (db_map_equal(watch->map, map) &&
                    141:                (watch->loaddr == addr) &&
                    142:                (watch->hiaddr == addr+size)) {
                    143:                db_printf("Already set.\n");
                    144:                return;
                    145:            }
                    146: 
                    147:        watch = db_watchpoint_alloc();
                    148:        if (watch == 0) {
                    149:            db_printf("Too many watchpoints.\n");
                    150:            return;
                    151:        }
                    152: 
                    153:        watch->map = map;
                    154:        watch->loaddr = addr;
                    155:        watch->hiaddr = addr+size;
                    156: 
                    157:        watch->link = db_watchpoint_list;
                    158:        db_watchpoint_list = watch;
                    159: 
                    160:        db_watchpoints_inserted = FALSE;
                    161: }
                    162: 
                    163: void
                    164: db_delete_watchpoint(map, addr)
                    165:        vm_map_t        map;
                    166:        db_addr_t       addr;
                    167: {
                    168:        register db_watchpoint_t        watch;
                    169:        register db_watchpoint_t        *prev;
                    170: 
                    171:        for (prev = &db_watchpoint_list;
                    172:             (watch = *prev) != 0;
                    173:             prev = &watch->link)
                    174:            if (db_map_equal(watch->map, map) &&
                    175:                (watch->loaddr <= addr) &&
                    176:                (addr < watch->hiaddr)) {
                    177:                *prev = watch->link;
                    178:                db_watchpoint_free(watch);
                    179:                return;
                    180:            }
                    181: 
                    182:        db_printf("Not set.\n");
                    183: }
                    184: 
                    185: void
                    186: db_list_watchpoints()
                    187: {
                    188:        register db_watchpoint_t        watch;
                    189: 
                    190:        if (db_watchpoint_list == 0) {
                    191:            db_printf("No watchpoints set\n");
                    192:            return;
                    193:        }
                    194: 
                    195:        db_printf(" Map        Address  Size\n");
                    196:        for (watch = db_watchpoint_list;
                    197:             watch != 0;
                    198:             watch = watch->link)
                    199:            db_printf("%s%8x  %8x  %x\n",
                    200:                      db_map_current(watch->map) ? "*" : " ",
                    201:                      watch->map, watch->loaddr,
                    202:                      watch->hiaddr - watch->loaddr);
                    203: }
                    204: 
                    205: /* Delete watchpoint */
                    206: /*ARGSUSED*/
                    207: void
                    208: db_deletewatch_cmd(addr, have_addr, count, modif)
                    209:        db_expr_t       addr;
                    210:        int             have_addr;
                    211:        db_expr_t       count;
                    212:        char *          modif;
                    213: {
                    214:        db_delete_watchpoint(db_map_addr(addr), addr);
                    215: }
                    216: 
                    217: /* Set watchpoint */
                    218: /*ARGSUSED*/
                    219: void
                    220: db_watchpoint_cmd(addr, have_addr, count, modif)
                    221:        db_expr_t       addr;
                    222:        int             have_addr;
                    223:        db_expr_t       count;
                    224:        char *          modif;
                    225: {
                    226:        vm_size_t       size;
                    227:        db_expr_t       value;
                    228: 
                    229:        if (db_expression(&value))
                    230:            size = (vm_size_t) value;
                    231:        else
                    232:            size = 4;
                    233:        db_skip_to_eol();
                    234: 
                    235:        db_set_watchpoint(db_map_addr(addr), addr, size);
                    236: }
                    237: 
                    238: /* list watchpoints */
                    239: void
                    240: db_listwatch_cmd()
                    241: {
                    242:        db_list_watchpoints();
                    243: }
                    244: 
                    245: void
                    246: db_set_watchpoints()
                    247: {
                    248:        register db_watchpoint_t        watch;
                    249: 
                    250:        if (!db_watchpoints_inserted) {
                    251:            for (watch = db_watchpoint_list;
                    252:                 watch != 0;
                    253:                 watch = watch->link)
                    254:                pmap_protect(watch->map->pmap,
                    255:                             trunc_page(watch->loaddr),
                    256:                             round_page(watch->hiaddr),
                    257:                             VM_PROT_READ);
                    258: 
                    259:            db_watchpoints_inserted = TRUE;
                    260:        }
                    261: }
                    262: 
                    263: void
                    264: db_clear_watchpoints()
                    265: {
                    266:        db_watchpoints_inserted = FALSE;
                    267: }
                    268: 
                    269: boolean_t
                    270: db_find_watchpoint(map, addr, regs)
                    271:        vm_map_t        map;
                    272:        db_addr_t       addr;
                    273:        db_regs_t       *regs;
                    274: {
                    275:        register db_watchpoint_t watch;
                    276:        db_watchpoint_t found = 0;
                    277: 
                    278:        for (watch = db_watchpoint_list;
                    279:             watch != 0;
                    280:             watch = watch->link)
                    281:            if (db_map_equal(watch->map, map)) {
                    282:                if ((watch->loaddr <= addr) &&
                    283:                    (addr < watch->hiaddr))
                    284:                    return (TRUE);
                    285:                else if ((trunc_page(watch->loaddr) <= addr) &&
                    286:                         (addr < round_page(watch->hiaddr)))
                    287:                    found = watch;
                    288:            }
                    289: 
                    290:        /*
                    291:         *      We didn't hit exactly on a watchpoint, but we are
                    292:         *      in a protected region.  We want to single-step
                    293:         *      and then re-protect.
                    294:         */
                    295: 
                    296:        if (found) {
                    297:            db_watchpoints_inserted = FALSE;
                    298:            db_single_step(regs);
                    299:        }
                    300: 
                    301:        return (FALSE);
                    302: }

unix.superglobalmegacorp.com

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