1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <mdb/mdb_modapi.h> 30 #include <sys/list.h> 31 32 typedef struct list_walk_data { 33 uintptr_t lw_start; 34 size_t lw_size; 35 size_t lw_offset; 36 void *lw_obj; 37 } list_walk_data_t; 38 39 int 40 list_walk_init(mdb_walk_state_t *wsp) 41 { 42 list_walk_data_t *lwd; 43 list_t list; 44 45 lwd = mdb_alloc(sizeof (list_walk_data_t), UM_SLEEP); 46 if (mdb_vread(&list, sizeof (list_t), wsp->walk_addr) == -1) { 47 mdb_warn("failed to read list_t at %#lx", wsp->walk_addr); 48 mdb_free(lwd, sizeof (list_walk_data_t)); 49 return (WALK_ERR); 50 } 51 52 lwd->lw_size = list.list_size; 53 lwd->lw_offset = list.list_offset; 54 lwd->lw_obj = mdb_alloc(list.list_size, UM_SLEEP); 55 lwd->lw_start = (uintptr_t)&((list_t *)wsp->walk_addr)->list_head; 56 57 wsp->walk_addr = (uintptr_t)list.list_head.list_next; 58 wsp->walk_data = lwd; 59 60 return (WALK_NEXT); 61 } 62 63 int 64 list_walk_step(mdb_walk_state_t *wsp) 65 { 66 list_walk_data_t *lwd = wsp->walk_data; 67 uintptr_t addr = wsp->walk_addr - lwd->lw_offset; 68 list_node_t *node; 69 int status; 70 71 if (wsp->walk_addr == lwd->lw_start) 72 return (WALK_DONE); 73 74 if (mdb_vread(lwd->lw_obj, lwd->lw_size, addr) == -1) { 75 mdb_warn("failed to read list element at %#lx", addr); 76 return (WALK_ERR); 77 } 78 79 status = wsp->walk_callback(addr, lwd->lw_obj, wsp->walk_cbdata); 80 node = (list_node_t *)((uintptr_t)lwd->lw_obj + lwd->lw_offset); 81 wsp->walk_addr = (uintptr_t)node->list_next; 82 83 return (status); 84 } 85 86 void 87 list_walk_fini(mdb_walk_state_t *wsp) 88 { 89 list_walk_data_t *lwd = wsp->walk_data; 90 91 mdb_free(lwd->lw_obj, lwd->lw_size); 92 mdb_free(lwd, sizeof (list_walk_data_t)); 93 } 94