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 /*
23 * Copyright 2006 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 <libdisasm.h>
30 #include <stdlib.h>
31 #ifdef DIS_STANDALONE
32 #include <mdb/mdb_modapi.h>
33 #endif
34
35 static int _dis_errno;
36
37 /*
38 * For the standalone library, we need to link against mdb's malloc/free.
39 * Otherwise, use the standard malloc/free.
40 */
41 #ifdef DIS_STANDALONE
42 void *
43 dis_zalloc(size_t bytes)
44 {
45 return (mdb_zalloc(bytes, UM_SLEEP));
46 }
47
48 void
49 dis_free(void *ptr, size_t bytes)
50 {
51 mdb_free(ptr, bytes);
52 }
53 #else
54 void *
55 dis_zalloc(size_t bytes)
56 {
57 return (calloc(1, bytes));
69 dis_seterrno(int error)
70 {
71 _dis_errno = error;
72 return (-1);
73 }
74
75 int
76 dis_errno(void)
77 {
78 return (_dis_errno);
79 }
80
81 const char *
82 dis_strerror(int error)
83 {
84 switch (error) {
85 case E_DIS_NOMEM:
86 return ("out of memory");
87 case E_DIS_INVALFLAG:
88 return ("invalid flags for this architecture");
89 default:
90 return ("unknown error");
91 }
92 }
|
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 /*
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
26 */
27
28 #include <libdisasm.h>
29 #include <stdlib.h>
30 #ifdef DIS_STANDALONE
31 #include <mdb/mdb_modapi.h>
32 #endif
33
34 #include "libdisasm_impl.h"
35
36 static int _dis_errno;
37
38 /*
39 * If we're building the standalone library, then we only want to
40 * include support for disassembly of the native architecture.
41 * The regular shared library should include support for all
42 * architectures.
43 */
44 #if !defined(DIS_STANDALONE) || defined(__i386) || defined(__amd64)
45 extern dis_arch_t dis_arch_i386;
46 #endif
47 #if !defined(DIS_STANDALONE) || defined(__sparc)
48 extern dis_arch_t dis_arch_sparc;
49 #endif
50
51 static dis_arch_t *dis_archs[] = {
52 #if !defined(DIS_STANDALONE) || defined(__i386) || defined(__amd64)
53 &dis_arch_i386,
54 #endif
55 #if !defined(DIS_STANDALONE) || defined(__sparc)
56 &dis_arch_sparc,
57 #endif
58 NULL
59 };
60
61 /*
62 * For the standalone library, we need to link against mdb's malloc/free.
63 * Otherwise, use the standard malloc/free.
64 */
65 #ifdef DIS_STANDALONE
66 void *
67 dis_zalloc(size_t bytes)
68 {
69 return (mdb_zalloc(bytes, UM_SLEEP));
70 }
71
72 void
73 dis_free(void *ptr, size_t bytes)
74 {
75 mdb_free(ptr, bytes);
76 }
77 #else
78 void *
79 dis_zalloc(size_t bytes)
80 {
81 return (calloc(1, bytes));
93 dis_seterrno(int error)
94 {
95 _dis_errno = error;
96 return (-1);
97 }
98
99 int
100 dis_errno(void)
101 {
102 return (_dis_errno);
103 }
104
105 const char *
106 dis_strerror(int error)
107 {
108 switch (error) {
109 case E_DIS_NOMEM:
110 return ("out of memory");
111 case E_DIS_INVALFLAG:
112 return ("invalid flags for this architecture");
113 case E_DIS_UNSUPARCH:
114 return ("unsupported machine architecture");
115 default:
116 return ("unknown error");
117 }
118 }
119
120 void
121 dis_set_data(dis_handle_t *dhp, void *data)
122 {
123 dhp->dh_data = data;
124 }
125
126 void
127 dis_flags_set(dis_handle_t *dhp, int f)
128 {
129 dhp->dh_flags |= f;
130 }
131
132 void
133 dis_flags_clear(dis_handle_t *dhp, int f)
134 {
135 dhp->dh_flags &= ~f;
136 }
137
138 void
139 dis_handle_destroy(dis_handle_t *dhp)
140 {
141 dhp->dh_arch->da_handle_detach(dhp);
142 dis_free(dhp, sizeof (dis_handle_t));
143 }
144
145 dis_handle_t *
146 dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
147 dis_read_f read_func)
148 {
149 dis_handle_t *dhp;
150 dis_arch_t *arch = NULL;
151 int i;
152
153 /* Select an architecture based on flags */
154 for (i = 0; dis_archs[i] != NULL; i++) {
155 if (dis_archs[i]->da_supports_flags(flags)) {
156 arch = dis_archs[i];
157 break;
158 }
159 }
160 if (arch == NULL) {
161 (void) dis_seterrno(E_DIS_UNSUPARCH);
162 return (NULL);
163 }
164
165 if ((dhp = dis_zalloc(sizeof (dis_handle_t))) == NULL) {
166 (void) dis_seterrno(E_DIS_NOMEM);
167 return (NULL);
168 }
169 dhp->dh_arch = arch;
170 dhp->dh_lookup = lookup_func;
171 dhp->dh_read = read_func;
172 dhp->dh_flags = flags;
173 dhp->dh_data = data;
174
175 /*
176 * Allow the architecture-specific code to allocate
177 * its private data.
178 */
179 if (arch->da_handle_attach(dhp) != 0) {
180 dis_free(dhp, sizeof (dis_handle_t));
181 /* dis errno already set */
182 return (NULL);
183 }
184
185 return (dhp);
186 }
187
188 int
189 dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
190 {
191 return (dhp->dh_arch->da_disassemble(dhp, addr, buf, buflen));
192 }
193
194 uint64_t
195 dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
196 {
197 return (dhp->dh_arch->da_previnstr(dhp, pc, n));
198 }
199
200 int
201 dis_min_instrlen(dis_handle_t *dhp)
202 {
203 return (dhp->dh_arch->da_min_instrlen(dhp));
204 }
205
206 int
207 dis_max_instrlen(dis_handle_t *dhp)
208 {
209 return (dhp->dh_arch->da_max_instrlen(dhp));
210 }
|