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
memio_read(mdb_io_t * io,void * buf,size_t nbytes)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
memio_seek(mdb_io_t * io,off64_t offset,int whence)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 *
mdb_memio_create(char * buf,size_t size)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