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

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

unix.superglobalmegacorp.com

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