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