126 dis_set_data(dis_handle_t *dhp, void *data)
127 {
128 dhp->dh_data = data;
129 }
130
131 void
132 dis_flags_set(dis_handle_t *dhp, int f)
133 {
134 dhp->dh_flags |= f;
135 }
136
137 void
138 dis_flags_clear(dis_handle_t *dhp, int f)
139 {
140 dhp->dh_flags &= ~f;
141 }
142
143 void
144 dis_handle_destroy(dis_handle_t *dhp)
145 {
146 dhp->dh_arch->da_handle_detach(dhp);
147 dis_free(dhp, sizeof (dis_handle_t));
148 }
149
150 dis_handle_t *
151 dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
152 dis_read_f read_func)
153 {
154 dis_handle_t *dhp;
155 dis_arch_t *arch = NULL;
156 int i;
157
158 /* Select an architecture based on flags */
159 for (i = 0; dis_archs[i] != NULL; i++) {
160 if (dis_archs[i]->da_supports_flags(flags)) {
161 arch = dis_archs[i];
162 break;
163 }
164 }
165 if (arch == NULL) {
166 (void) dis_seterrno(E_DIS_UNSUPARCH);
167 return (NULL);
168 }
169
170 if ((dhp = dis_zalloc(sizeof (dis_handle_t))) == NULL) {
171 (void) dis_seterrno(E_DIS_NOMEM);
172 return (NULL);
173 }
174 dhp->dh_arch = arch;
175 dhp->dh_lookup = lookup_func;
176 dhp->dh_read = read_func;
177 dhp->dh_flags = flags;
178 dhp->dh_data = data;
179
180 /*
181 * Allow the architecture-specific code to allocate
182 * its private data.
183 */
184 if (arch->da_handle_attach(dhp) != 0) {
185 dis_free(dhp, sizeof (dis_handle_t));
186 /* dis errno already set */
187 return (NULL);
188 }
189
190 return (dhp);
191 }
192
193 int
194 dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
195 {
196 return (dhp->dh_arch->da_disassemble(dhp, addr, buf, buflen));
197 }
198
199 /*
200 * On some instruction sets (e.g., x86), we have no choice except to
201 * disassemble everything from the start of the symbol, and stop when we
202 * have reached our instruction address. If we're not in the middle of a
203 * known symbol, then we return the same address to indicate failure.
204 */
|
126 dis_set_data(dis_handle_t *dhp, void *data)
127 {
128 dhp->dh_data = data;
129 }
130
131 void
132 dis_flags_set(dis_handle_t *dhp, int f)
133 {
134 dhp->dh_flags |= f;
135 }
136
137 void
138 dis_flags_clear(dis_handle_t *dhp, int f)
139 {
140 dhp->dh_flags &= ~f;
141 }
142
143 void
144 dis_handle_destroy(dis_handle_t *dhp)
145 {
146 if (dhp->dh_arch->da_handle_detach != NULL)
147 dhp->dh_arch->da_handle_detach(dhp);
148
149 dis_free(dhp, sizeof (dis_handle_t));
150 }
151
152 dis_handle_t *
153 dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
154 dis_read_f read_func)
155 {
156 dis_handle_t *dhp;
157 dis_arch_t *arch = NULL;
158 int i;
159
160 /* Select an architecture based on flags */
161 for (i = 0; dis_archs[i] != NULL; i++) {
162 if (dis_archs[i]->da_supports_flags(flags)) {
163 arch = dis_archs[i];
164 break;
165 }
166 }
167 if (arch == NULL) {
168 (void) dis_seterrno(E_DIS_UNSUPARCH);
169 return (NULL);
170 }
171
172 if ((dhp = dis_zalloc(sizeof (dis_handle_t))) == NULL) {
173 (void) dis_seterrno(E_DIS_NOMEM);
174 return (NULL);
175 }
176 dhp->dh_arch = arch;
177 dhp->dh_lookup = lookup_func;
178 dhp->dh_read = read_func;
179 dhp->dh_flags = flags;
180 dhp->dh_data = data;
181
182 /*
183 * Allow the architecture-specific code to allocate
184 * its private data.
185 */
186 if (arch->da_handle_attach != NULL &&
187 arch->da_handle_attach(dhp) != 0) {
188 dis_free(dhp, sizeof (dis_handle_t));
189 /* dis errno already set */
190 return (NULL);
191 }
192
193 return (dhp);
194 }
195
196 int
197 dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
198 {
199 return (dhp->dh_arch->da_disassemble(dhp, addr, buf, buflen));
200 }
201
202 /*
203 * On some instruction sets (e.g., x86), we have no choice except to
204 * disassemble everything from the start of the symbol, and stop when we
205 * have reached our instruction address. If we're not in the middle of a
206 * known symbol, then we return the same address to indicate failure.
207 */
|