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, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 * Copyright (c) 2015, Joyent, Inc.
26 */
27
28/*
29 * libctf open/close interposition layer
30 *
31 * This interposition layer serves two purposes.  First, it allows the
32 * introduction of a kmdb-specific implementation of ctf_open().  The normal
33 * ctf_open() call open(2)s a file, and reads the CTF data directly from it.
34 * No such facility is available in kmdb, as kmdb does not run in userland.  We
35 * can, however, observe that kmdb uses this interface only to read CTF data
36 * from dmods.  dmods, as viewed by kmdb, do have CTF data, but they have it
37 * in a form that is best accessed by ctf_bufopen().  This interposition layer
38 * allows us to translate ctf_open() calls into ctf_bufopen() calls.
39 *
40 * The second purpose of the interposition layer is to reduce the work needed
41 * to call mdb_ctf_bufopen.
42 */
43
44#include <sys/types.h>
45#include <sys/kobj.h>
46#include <libctf.h>
47#include <ctf_impl.h>
48
49#include <kmdb/kmdb_module.h>
50#include <mdb/mdb_ctf.h>
51#include <mdb/mdb_string.h>
52#include <mdb/mdb_debug.h>
53#include <mdb/mdb_err.h>
54#include <mdb/mdb.h>
55
56static kmdb_modctl_t *
57mdb_ctf_name2ctl(const char *pathname)
58{
59	mdb_var_t *v;
60
61	if ((v = mdb_nv_lookup(&mdb.m_dmodctl, strbasename(pathname))) ==
62	    NULL)
63		return (NULL);
64
65	return ((kmdb_modctl_t *)MDB_NV_COOKIE(v));
66}
67
68ctf_file_t *
69mdb_ctf_open(const char *pathname, int *errp)
70{
71	struct module *mp;
72	kmdb_modctl_t *kmc;
73	ctf_file_t *ctfp;
74
75	if ((kmc = mdb_ctf_name2ctl(pathname)) == NULL) {
76		if (errp != NULL)
77			*errp = ENOENT;
78		return (NULL);
79	}
80
81	mp = kmc->kmc_modctl->mod_mp;
82	if (mp->ctfdata == NULL) {
83		if (errp != NULL)
84			*errp = ECTF_NOCTFDATA;
85		return (NULL);
86	}
87
88	if ((ctfp = mdb_ctf_bufopen(mp->ctfdata, mp->ctfsize, mp->symtbl,
89	    mp->symhdr, mp->strings, mp->strhdr, errp)) == NULL)
90		return (NULL);
91
92	mdb_dprintf(MDB_DBG_MODULE, "loaded %lu bytes of CTF data for %s\n",
93	    (ulong_t)mp->ctfsize, kmc->kmc_modname);
94
95	return (ctfp);
96}
97
98void
99mdb_ctf_close(ctf_file_t *fp)
100{
101	ctf_close(fp);
102}
103
104/*ARGSUSED*/
105int
106mdb_ctf_write(const char *file, ctf_file_t *fp)
107{
108	return (ENOTSUP);
109}
110