Print this page
9210 remove KMDB branch debugging support
9211 ::crregs could do with cr2/cr3 support
9209 ::ttrace should be able to filter by thread
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/mdb/mdb_rawfile.c
+++ new/usr/src/cmd/mdb/common/mdb/mdb_rawfile.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + *
25 + * Copyright 2018 Joyent, Inc.
24 26 */
25 27
26 -#pragma ident "%Z%%M% %I% %E% SMI"
27 -
28 28 /*
29 29 * Raw File Target
30 30 *
31 31 * The raw file target is invoked whenever a file of unrecognizable type is
32 32 * specified on the command line, or when raw file examination is forced using
33 33 * the -f option. If one file is specified, that file will be opened as the
34 34 * "object" file. If two files are specified, the second one will be opened
35 35 * as the "core" file. Each file is opened using the fdio backend, which
36 36 * internally supports both byte-oriented i/o and block-oriented i/o as needed.
37 37 */
38 38
39 39 #include <mdb/mdb_modapi.h>
40 40 #include <mdb/mdb_target_impl.h>
41 41 #include <mdb/mdb_io_impl.h>
42 42 #include <mdb/mdb_conf.h>
43 43 #include <mdb/mdb_err.h>
44 44 #include <mdb/mdb.h>
45 45
46 46 #include <sys/dtrace.h>
47 47 #include <fcntl.h>
48 48
49 49 typedef struct rf_data {
50 50 mdb_io_t *r_object_fio;
51 51 mdb_io_t *r_core_fio;
52 52 } rf_data_t;
53 53
54 54 #define RF_OBJECT(p) (((rf_data_t *)(p))->r_object_fio)
55 55 #define RF_CORE(p) (((rf_data_t *)(p))->r_core_fio)
56 56
57 57 static void
58 58 rf_data_destroy(rf_data_t *rf)
59 59 {
60 60 if (rf->r_object_fio != NULL)
61 61 mdb_io_destroy(rf->r_object_fio);
62 62
63 63 if (rf->r_core_fio != NULL)
64 64 mdb_io_destroy(rf->r_core_fio);
65 65
66 66 mdb_free(rf, sizeof (rf_data_t));
67 67 }
68 68
69 69 static int
70 70 rf_setflags(mdb_tgt_t *t, int flags)
71 71 {
72 72 if ((flags ^ t->t_flags) & MDB_TGT_F_RDWR) {
73 73 uint_t otflags = t->t_flags;
74 74 rf_data_t *orf = t->t_data;
75 75 const char *argv[2];
76 76 int argc = 0;
77 77
78 78 if (orf->r_object_fio != NULL)
79 79 argv[argc++] = IOP_NAME(orf->r_object_fio);
80 80 if (orf->r_core_fio != NULL)
81 81 argv[argc++] = IOP_NAME(orf->r_core_fio);
82 82
83 83 t->t_flags = (t->t_flags & ~MDB_TGT_F_RDWR) |
84 84 (flags & MDB_TGT_F_RDWR);
85 85
86 86 if (mdb_rawfile_tgt_create(t, argc, argv) == -1) {
87 87 t->t_flags = otflags;
88 88 t->t_data = orf;
89 89 return (-1);
90 90 }
91 91
92 92 rf_data_destroy(orf);
93 93 }
94 94
95 95 return (0);
96 96 }
97 97
98 98 static void
99 99 rf_destroy(mdb_tgt_t *t)
100 100 {
101 101 rf_data_destroy(t->t_data);
102 102 }
103 103
104 104 /*ARGSUSED*/
105 105 static const char *
106 106 rf_name(mdb_tgt_t *t)
107 107 {
108 108 return ("raw");
109 109 }
110 110
111 111 static ssize_t
112 112 rf_read(mdb_io_t *io, void *buf, size_t nbytes, uint64_t addr)
113 113 {
114 114 ssize_t rbytes;
115 115
116 116 if (io == NULL)
117 117 return (set_errno(EMDB_NOMAP));
118 118
119 119 if (IOP_SEEK(io, addr, SEEK_SET) == -1)
120 120 return (-1); /* errno is set for us */
121 121
122 122 if ((rbytes = IOP_READ(io, buf, nbytes)) == 0)
123 123 (void) set_errno(EMDB_EOF);
124 124
125 125 return (rbytes);
126 126 }
127 127
128 128 static ssize_t
129 129 rf_write(mdb_io_t *io, const void *buf, size_t nbytes, uint64_t addr)
130 130 {
131 131 if (io == NULL)
132 132 return (set_errno(EMDB_NOMAP));
133 133
134 134 if (IOP_SEEK(io, addr, SEEK_SET) == -1)
135 135 return (-1); /* errno is set for us */
136 136
137 137 return (IOP_WRITE(io, buf, nbytes));
138 138 }
139 139
140 140 static ssize_t
141 141 rf_aread(mdb_tgt_t *t, mdb_tgt_as_t as, void *buf,
142 142 size_t len, mdb_tgt_addr_t addr)
143 143 {
144 144 switch ((uintptr_t)as) {
145 145 case (uintptr_t)MDB_TGT_AS_VIRT:
146 146 case (uintptr_t)MDB_TGT_AS_PHYS:
147 147 if (RF_CORE(t->t_data) != NULL)
148 148 return (rf_read(RF_CORE(t->t_data), buf, len, addr));
149 149 /*FALLTHRU*/
150 150 case (uintptr_t)MDB_TGT_AS_FILE:
151 151 return (rf_read(RF_OBJECT(t->t_data), buf, len, addr));
152 152 default:
153 153 return (set_errno(EMDB_NOMAP));
154 154 }
155 155 }
156 156
157 157 static ssize_t
158 158 rf_awrite(mdb_tgt_t *t, mdb_tgt_as_t as, const void *buf,
159 159 size_t len, mdb_tgt_addr_t addr)
160 160 {
161 161 switch ((uintptr_t)as) {
162 162 case (uintptr_t)MDB_TGT_AS_VIRT:
163 163 case (uintptr_t)MDB_TGT_AS_PHYS:
164 164 if (RF_CORE(t->t_data) != NULL)
165 165 return (rf_write(RF_CORE(t->t_data), buf, len, addr));
166 166 /*FALLTHRU*/
167 167 case (uintptr_t)MDB_TGT_AS_FILE:
168 168 return (rf_write(RF_OBJECT(t->t_data), buf, len, addr));
169 169 default:
170 170 return (set_errno(EMDB_NOMAP));
171 171 }
172 172 }
173 173
174 174 static ssize_t
175 175 rf_vread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr)
176 176 {
177 177 if (RF_CORE(t->t_data) != NULL)
178 178 return (rf_read(RF_CORE(t->t_data), buf, nbytes, addr));
179 179
180 180 return (rf_read(RF_OBJECT(t->t_data), buf, nbytes, addr));
181 181 }
182 182
183 183 static ssize_t
184 184 rf_vwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
185 185 {
186 186 if (RF_CORE(t->t_data) != NULL)
187 187 return (rf_write(RF_CORE(t->t_data), buf, nbytes, addr));
188 188
189 189 return (rf_write(RF_OBJECT(t->t_data), buf, nbytes, addr));
190 190 }
191 191
192 192 static ssize_t
193 193 rf_pread(mdb_tgt_t *t, void *buf, size_t nbytes, physaddr_t addr)
194 194 {
195 195 if (RF_CORE(t->t_data) != NULL)
196 196 return (rf_read(RF_CORE(t->t_data), buf, nbytes, addr));
197 197
198 198 return (rf_read(RF_OBJECT(t->t_data), buf, nbytes, addr));
199 199 }
200 200
201 201 static ssize_t
202 202 rf_pwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, physaddr_t addr)
203 203 {
204 204 if (RF_CORE(t->t_data) != NULL)
205 205 return (rf_write(RF_CORE(t->t_data), buf, nbytes, addr));
206 206
207 207 return (rf_write(RF_OBJECT(t->t_data), buf, nbytes, addr));
208 208 }
209 209
210 210 static ssize_t
211 211 rf_fread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr)
212 212 {
213 213 return (rf_read(RF_OBJECT(t->t_data), buf, nbytes, addr));
214 214 }
215 215
216 216 static ssize_t
217 217 rf_fwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
218 218 {
219 219 return (rf_write(RF_OBJECT(t->t_data), buf, nbytes, addr));
220 220 }
221 221
222 222
223 223 static int
224 224 rf_print_map(mdb_io_t *io, const char *type, int tflags,
225 225 mdb_tgt_map_f *func, void *private)
226 226 {
227 227 mdb_map_t map;
228 228
229 229 (void) mdb_iob_snprintf(map.map_name, MDB_TGT_MAPSZ,
230 230 "%s (%s)", IOP_NAME(io), type);
231 231
232 232 map.map_base = 0;
233 233 map.map_size = IOP_SEEK(io, 0, SEEK_END);
234 234 map.map_flags = MDB_TGT_MAP_R;
235 235
236 236 if (tflags & MDB_TGT_F_RDWR)
237 237 map.map_flags |= MDB_TGT_MAP_W;
238 238
239 239 return (func(private, &map, map.map_name));
240 240 }
241 241
242 242 static int
243 243 rf_mapping_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private)
244 244 {
245 245 rf_data_t *rf = t->t_data;
246 246
247 247 if (rf->r_object_fio != NULL && rf_print_map(rf->r_object_fio,
248 248 "object file", t->t_flags, func, private) != 0)
249 249 return (0);
250 250
251 251 if (rf->r_core_fio != NULL && rf_print_map(rf->r_core_fio,
252 252 "core file", t->t_flags, func, private) != 0)
253 253 return (0);
254 254
255 255 return (0);
256 256 }
257 257
258 258 /*ARGSUSED*/
259 259 static int
260 260 rf_status(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
261 261 {
262 262 bzero(tsp, sizeof (mdb_tgt_status_t));
263 263
264 264 if (RF_CORE(t->t_data) != NULL)
265 265 tsp->st_state = MDB_TGT_DEAD;
266 266 else
267 267 tsp->st_state = MDB_TGT_IDLE;
268 268
269 269 return (0);
270 270 }
271 271
272 272 /*ARGSUSED*/
273 273 static int
274 274 rf_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
275 275 {
276 276 rf_data_t *rf = mdb.m_target->t_data;
277 277
278 278 if (rf->r_object_fio != NULL) {
279 279 mdb_printf("debugging file '%s' (object file)",
280 280 IOP_NAME(rf->r_object_fio));
281 281
282 282 if (rf->r_core_fio != NULL) {
283 283 mdb_printf(" and file '%s' (core file)",
284 284 IOP_NAME(rf->r_core_fio));
285 285 }
286 286
287 287 mdb_printf("\n");
288 288 } else {
289 289 mdb_printf("debugging empty target\n");
290 290 }
291 291
292 292 return (DCMD_OK);
293 293 }
294 294
295 295 static const mdb_dcmd_t rf_dcmds[] = {
296 296 { "status", NULL, "print summary of current target", rf_status_dcmd },
297 297 { NULL }
298 298 };
299 299
300 300 static const struct rf_magic {
301 301 const char *rfm_str;
302 302 size_t rfm_len;
303 303 const char *rfm_mod;
304 304 } rf_magic[] = {
305 305 { DOF_MAG_STRING, DOF_MAG_STRLEN, "dof" },
306 306 { NULL, 0, NULL }
307 307 };
308 308
309 309 static void
310 310 rf_activate(mdb_tgt_t *t)
311 311 {
312 312 rf_data_t *rf = t->t_data;
313 313 const struct rf_magic *m;
314 314 mdb_var_t *v;
315 315 off64_t size;
316 316
317 317 (void) mdb_tgt_register_dcmds(t, &rf_dcmds[0], MDB_MOD_FORCE);
318 318
319 319 /*
320 320 * We set the legacy adb variable 'd' to be the size of the file (data
321 321 * segment). To get this value, we call seek() on the underlying fdio.
322 322 */
323 323 if (rf->r_object_fio != NULL) {
324 324 size = IOP_SEEK(rf->r_object_fio, 0, SEEK_END);
325 325 if ((v = mdb_nv_lookup(&mdb.m_nv, "d")) != NULL)
326 326 mdb_nv_set_value(v, size);
327 327 }
328 328
329 329 /*
330 330 * Load any debugging support modules that match the file type, as
331 331 * determined by our poor man's /etc/magic. If many clients need
332 332 * to use this feature, rf_magic[] should be computed dynamically.
333 333 */
334 334 for (m = rf_magic; m->rfm_str != NULL; m++) {
335 335 char *buf = mdb_alloc(m->rfm_len, UM_SLEEP);
336 336
337 337 if (mdb_tgt_vread(t, buf, m->rfm_len, 0) == m->rfm_len &&
338 338 bcmp(buf, m->rfm_str, m->rfm_len) == 0) {
339 339 (void) mdb_module_load(m->rfm_mod,
340 340 MDB_MOD_LOCAL | MDB_MOD_SILENT);
341 341 }
342 342
343 343 mdb_free(buf, m->rfm_len);
344 344 }
345 345 }
346 346
347 347 static void
348 348 rf_deactivate(mdb_tgt_t *t)
349 349 {
350 350 const mdb_dcmd_t *dcp;
351 351
352 352 for (dcp = &rf_dcmds[0]; dcp->dc_name != NULL; dcp++) {
353 353 if (mdb_module_remove_dcmd(t->t_module, dcp->dc_name) == -1)
354 354 warn("failed to remove dcmd %s", dcp->dc_name);
355 355 }
356 356 }
357 357
358 358 static const mdb_tgt_ops_t rawfile_ops = {
359 359 rf_setflags, /* t_setflags */
360 360 (int (*)()) mdb_tgt_notsup, /* t_setcontext */
361 361 rf_activate, /* t_activate */
362 362 rf_deactivate, /* t_deactivate */
363 363 (void (*)()) mdb_tgt_nop, /* t_periodic */
364 364 rf_destroy, /* t_destroy */
365 365 rf_name, /* t_name */
366 366 (const char *(*)()) mdb_conf_isa, /* t_isa */
367 367 (const char *(*)()) mdb_conf_platform, /* t_platform */
368 368 (int (*)()) mdb_tgt_notsup, /* t_uname */
369 369 (int (*)()) mdb_tgt_notsup, /* t_dmodel */
370 370 rf_aread, /* t_aread */
371 371 rf_awrite, /* t_awrite */
372 372 rf_vread, /* t_vread */
373 373 rf_vwrite, /* t_vwrite */
374 374 rf_pread, /* t_pread */
375 375 rf_pwrite, /* t_pwrite */
376 376 rf_fread, /* t_fread */
377 377 rf_fwrite, /* t_fwrite */
378 378 (ssize_t (*)()) mdb_tgt_notsup, /* t_ioread */
379 379 (ssize_t (*)()) mdb_tgt_notsup, /* t_iowrite */
380 380 (int (*)()) mdb_tgt_notsup, /* t_vtop */
381 381 (int (*)()) mdb_tgt_notsup, /* t_lookup_by_name */
382 382 (int (*)()) mdb_tgt_notsup, /* t_lookup_by_addr */
383 383 (int (*)()) mdb_tgt_notsup, /* t_symbol_iter */
↓ open down ↓ |
346 lines elided |
↑ open up ↑ |
384 384 rf_mapping_iter, /* t_mapping_iter */
385 385 rf_mapping_iter, /* t_object_iter */
386 386 (const mdb_map_t *(*)()) mdb_tgt_null, /* t_addr_to_map */
387 387 (const mdb_map_t *(*)()) mdb_tgt_null, /* t_name_to_map */
388 388 (struct ctf_file *(*)()) mdb_tgt_null, /* t_addr_to_ctf */
389 389 (struct ctf_file *(*)()) mdb_tgt_null, /* t_name_to_ctf */
390 390 rf_status, /* t_status */
391 391 (int (*)()) mdb_tgt_notsup, /* t_run */
392 392 (int (*)()) mdb_tgt_notsup, /* t_step */
393 393 (int (*)()) mdb_tgt_notsup, /* t_step_out */
394 - (int (*)()) mdb_tgt_notsup, /* t_step_branch */
395 394 (int (*)()) mdb_tgt_notsup, /* t_next */
396 395 (int (*)()) mdb_tgt_notsup, /* t_cont */
397 396 (int (*)()) mdb_tgt_notsup, /* t_signal */
398 397 (int (*)()) mdb_tgt_null, /* t_add_vbrkpt */
399 398 (int (*)()) mdb_tgt_null, /* t_add_sbrkpt */
400 399 (int (*)()) mdb_tgt_null, /* t_add_pwapt */
401 400 (int (*)()) mdb_tgt_null, /* t_add_vwapt */
402 401 (int (*)()) mdb_tgt_null, /* t_add_iowapt */
403 402 (int (*)()) mdb_tgt_null, /* t_add_sysenter */
404 403 (int (*)()) mdb_tgt_null, /* t_add_sysexit */
405 404 (int (*)()) mdb_tgt_null, /* t_add_signal */
406 405 (int (*)()) mdb_tgt_null, /* t_add_fault */
407 406 (int (*)()) mdb_tgt_notsup, /* t_getareg */
408 407 (int (*)()) mdb_tgt_notsup, /* t_putareg */
409 408 (int (*)()) mdb_tgt_notsup, /* t_stack_iter */
410 409 (int (*)()) mdb_tgt_notsup /* t_auxv */
411 410 };
412 411
413 412 int
414 413 mdb_rawfile_tgt_create(mdb_tgt_t *t, int argc, const char *argv[])
415 414 {
416 415 mdb_io_t *io[2] = { NULL, NULL };
417 416 rf_data_t *rf;
418 417 int oflags, i;
419 418
420 419 if (argc > 2)
421 420 return (set_errno(EINVAL));
422 421
423 422 rf = mdb_zalloc(sizeof (rf_data_t), UM_SLEEP);
424 423 t->t_ops = &rawfile_ops;
425 424 t->t_data = rf;
426 425
427 426 if (t->t_flags & MDB_TGT_F_RDWR)
428 427 oflags = O_RDWR;
429 428 else
430 429 oflags = O_RDONLY;
431 430
432 431 for (i = 0; i < argc; i++) {
433 432 io[i] = mdb_fdio_create_path(NULL, argv[i], oflags, 0);
434 433 if (io[i] == NULL) {
435 434 warn("failed to open %s", argv[i]);
436 435 goto err;
437 436 }
438 437 }
439 438
440 439 rf->r_object_fio = io[0]; /* first file is the "object" */
441 440 rf->r_core_fio = io[1]; /* second file is the "core" */
442 441 t->t_flags |= MDB_TGT_F_ASIO; /* do i/o using aread and awrite */
443 442
444 443 return (0);
445 444
446 445 err:
447 446 for (i = 0; i < argc; i++) {
448 447 if (io[i] != NULL)
449 448 mdb_io_destroy(io[i]);
450 449 }
451 450
452 451
453 452 mdb_free(rf, sizeof (rf_data_t));
454 453 return (set_errno(EMDB_TGT));
455 454 }
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX