xref: /illumos-gate/usr/src/cmd/mdb/common/mdb/mdb_memio.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * Memory I/O backend.
30  *
31  * Simple backend that has main memory as its backing store.
32  */
33 
34 #include <mdb/mdb_io_impl.h>
35 #include <mdb/mdb.h>
36 
37 typedef struct mem_data {
38 	char *md_buf;
39 	size_t md_size;
40 	offset_t md_off;
41 } mem_data_t;
42 
43 static ssize_t
44 memio_read(mdb_io_t *io, void *buf, size_t nbytes)
45 {
46 	mem_data_t *mdp = io->io_data;
47 
48 	if (io->io_next == NULL) {
49 		if (mdp->md_off + nbytes > mdp->md_size)
50 			nbytes = (mdp->md_size - mdp->md_off);
51 		bcopy(mdp->md_buf + mdp->md_off, buf, nbytes);
52 		mdp->md_off += nbytes;
53 		return (nbytes);
54 	}
55 
56 	return (IOP_READ(io->io_next, buf, nbytes));
57 }
58 
59 static off64_t
60 memio_seek(mdb_io_t *io, off64_t offset, int whence)
61 {
62 	mem_data_t *mdp = io->io_data;
63 
64 	if (io->io_next == NULL) {
65 		switch (whence) {
66 		case SEEK_SET:
67 			mdp->md_off = offset;
68 			break;
69 		case SEEK_CUR:
70 			mdp->md_off += offset;
71 			break;
72 		case SEEK_END:
73 			mdp->md_off = mdp->md_size + offset;
74 			if (mdp->md_off > mdp->md_size)
75 				mdp->md_off = mdp->md_size;
76 			break;
77 		default:
78 			return (-1);
79 		}
80 
81 		return (mdp->md_off);
82 	}
83 
84 	return (IOP_SEEK(io->io_next, offset, whence));
85 }
86 
87 static const mdb_io_ops_t memio_ops = {
88 	memio_read,
89 	no_io_write,
90 	memio_seek,
91 	no_io_ctl,
92 	no_io_close,
93 	no_io_name,
94 	no_io_link,
95 	no_io_unlink,
96 	no_io_setattr,
97 	no_io_suspend,
98 	no_io_resume
99 };
100 
101 mdb_io_t *
102 mdb_memio_create(char *buf, size_t size)
103 {
104 	mdb_io_t *io = mdb_alloc(sizeof (mdb_io_t), UM_SLEEP);
105 	mem_data_t *mdp = mdb_alloc(sizeof (mem_data_t), UM_SLEEP);
106 
107 	mdp->md_buf = buf;
108 	mdp->md_size = size;
109 	mdp->md_off = 0;
110 
111 	io->io_ops = &memio_ops;
112 	io->io_data = mdp;
113 	io->io_next = NULL;
114 	io->io_refcnt = 0;
115 
116 	return (io);
117 }
118