1cd844e7aSJohn Birrell /*
2cd844e7aSJohn Birrell * CDDL HEADER START
3cd844e7aSJohn Birrell *
4cd844e7aSJohn Birrell * The contents of this file are subject to the terms of the
5cd844e7aSJohn Birrell * Common Development and Distribution License, Version 1.0 only
6cd844e7aSJohn Birrell * (the "License"). You may not use this file except in compliance
7cd844e7aSJohn Birrell * with the License.
8cd844e7aSJohn Birrell *
9cd844e7aSJohn Birrell * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10cd844e7aSJohn Birrell * or http://www.opensolaris.org/os/licensing.
11cd844e7aSJohn Birrell * See the License for the specific language governing permissions
12cd844e7aSJohn Birrell * and limitations under the License.
13cd844e7aSJohn Birrell *
14cd844e7aSJohn Birrell * When distributing Covered Code, include this CDDL HEADER in each
15cd844e7aSJohn Birrell * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16cd844e7aSJohn Birrell * If applicable, add the following below this CDDL HEADER, with the
17cd844e7aSJohn Birrell * fields enclosed by brackets "[]" replaced with your own identifying
18cd844e7aSJohn Birrell * information: Portions Copyright [yyyy] [name of copyright owner]
19cd844e7aSJohn Birrell *
20cd844e7aSJohn Birrell * CDDL HEADER END
21cd844e7aSJohn Birrell */
22cd844e7aSJohn Birrell /*
23cd844e7aSJohn Birrell * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24cd844e7aSJohn Birrell * Use is subject to license terms.
25cd844e7aSJohn Birrell */
26cd844e7aSJohn Birrell
27cd844e7aSJohn Birrell #pragma ident "%Z%%M% %I% %E% SMI"
28cd844e7aSJohn Birrell
29cd844e7aSJohn Birrell #include <sys/sysmacros.h>
30cd844e7aSJohn Birrell #include <sys/modctl.h>
31cd844e7aSJohn Birrell #include <sys/debug.h>
32cd844e7aSJohn Birrell #include <sys/mman.h>
33cd844e7aSJohn Birrell #include <sys/modctl.h>
34cd844e7aSJohn Birrell #include <sys/kobj.h>
35cd844e7aSJohn Birrell #include <ctf_impl.h>
36cd844e7aSJohn Birrell
37cd844e7aSJohn Birrell int ctf_leave_compressed = 0;
38cd844e7aSJohn Birrell
39cd844e7aSJohn Birrell static struct modlmisc modlmisc = {
40cd844e7aSJohn Birrell &mod_miscops, "Compact C Type Format routines"
41cd844e7aSJohn Birrell };
42cd844e7aSJohn Birrell
43cd844e7aSJohn Birrell static struct modlinkage modlinkage = {
44cd844e7aSJohn Birrell MODREV_1, &modlmisc, NULL
45cd844e7aSJohn Birrell };
46cd844e7aSJohn Birrell
47cd844e7aSJohn Birrell int
_init(void)48cd844e7aSJohn Birrell _init(void)
49cd844e7aSJohn Birrell {
50cd844e7aSJohn Birrell return (mod_install(&modlinkage));
51cd844e7aSJohn Birrell }
52cd844e7aSJohn Birrell
53cd844e7aSJohn Birrell int
_info(struct modinfo * mip)54cd844e7aSJohn Birrell _info(struct modinfo *mip)
55cd844e7aSJohn Birrell {
56cd844e7aSJohn Birrell return (mod_info(&modlinkage, mip));
57cd844e7aSJohn Birrell }
58cd844e7aSJohn Birrell
59cd844e7aSJohn Birrell int
_fini(void)60cd844e7aSJohn Birrell _fini(void)
61cd844e7aSJohn Birrell {
62cd844e7aSJohn Birrell return (mod_remove(&modlinkage));
63cd844e7aSJohn Birrell }
64cd844e7aSJohn Birrell
65cd844e7aSJohn Birrell /*ARGSUSED*/
66cd844e7aSJohn Birrell void *
ctf_zopen(int * errp)67cd844e7aSJohn Birrell ctf_zopen(int *errp)
68cd844e7aSJohn Birrell {
69cd844e7aSJohn Birrell return ((void *)1); /* zmod is always loaded because we depend on it */
70cd844e7aSJohn Birrell }
71cd844e7aSJohn Birrell
72cd844e7aSJohn Birrell /*ARGSUSED*/
73cd844e7aSJohn Birrell const void *
ctf_sect_mmap(ctf_sect_t * sp,int fd)74cd844e7aSJohn Birrell ctf_sect_mmap(ctf_sect_t *sp, int fd)
75cd844e7aSJohn Birrell {
76cd844e7aSJohn Birrell return (MAP_FAILED); /* we don't support this in the kernel */
77cd844e7aSJohn Birrell }
78cd844e7aSJohn Birrell
79cd844e7aSJohn Birrell /*ARGSUSED*/
80cd844e7aSJohn Birrell void
ctf_sect_munmap(const ctf_sect_t * sp)81cd844e7aSJohn Birrell ctf_sect_munmap(const ctf_sect_t *sp)
82cd844e7aSJohn Birrell {
83cd844e7aSJohn Birrell /* we don't support this in the kernel */
84cd844e7aSJohn Birrell }
85cd844e7aSJohn Birrell
86cd844e7aSJohn Birrell /*ARGSUSED*/
87cd844e7aSJohn Birrell ctf_file_t *
ctf_fdopen(int fd,int * errp)88cd844e7aSJohn Birrell ctf_fdopen(int fd, int *errp)
89cd844e7aSJohn Birrell {
90cd844e7aSJohn Birrell return (ctf_set_open_errno(errp, ENOTSUP));
91cd844e7aSJohn Birrell }
92cd844e7aSJohn Birrell
93cd844e7aSJohn Birrell /*ARGSUSED*/
94cd844e7aSJohn Birrell ctf_file_t *
ctf_open(const char * filename,int * errp)95cd844e7aSJohn Birrell ctf_open(const char *filename, int *errp)
96cd844e7aSJohn Birrell {
97cd844e7aSJohn Birrell return (ctf_set_open_errno(errp, ENOTSUP));
98cd844e7aSJohn Birrell }
99cd844e7aSJohn Birrell
100cd844e7aSJohn Birrell /*ARGSUSED*/
101cd844e7aSJohn Birrell int
ctf_write(ctf_file_t * fp,int fd)102cd844e7aSJohn Birrell ctf_write(ctf_file_t *fp, int fd)
103cd844e7aSJohn Birrell {
104cd844e7aSJohn Birrell return (ctf_set_errno(fp, ENOTSUP));
105cd844e7aSJohn Birrell }
106cd844e7aSJohn Birrell
107cd844e7aSJohn Birrell int
ctf_version(int version)108cd844e7aSJohn Birrell ctf_version(int version)
109cd844e7aSJohn Birrell {
110cd844e7aSJohn Birrell ASSERT(version > 0 && version <= CTF_VERSION);
111cd844e7aSJohn Birrell
112cd844e7aSJohn Birrell if (version > 0)
113cd844e7aSJohn Birrell _libctf_version = MIN(CTF_VERSION, version);
114cd844e7aSJohn Birrell
115cd844e7aSJohn Birrell return (_libctf_version);
116cd844e7aSJohn Birrell }
117cd844e7aSJohn Birrell
118cd844e7aSJohn Birrell /*ARGSUSED*/
119cd844e7aSJohn Birrell ctf_file_t *
ctf_modopen(struct module * mp,int * error)120cd844e7aSJohn Birrell ctf_modopen(struct module *mp, int *error)
121cd844e7aSJohn Birrell {
122cd844e7aSJohn Birrell ctf_sect_t ctfsect, symsect, strsect;
123cd844e7aSJohn Birrell ctf_file_t *fp = NULL;
124cd844e7aSJohn Birrell int err;
125cd844e7aSJohn Birrell
126cd844e7aSJohn Birrell if (error == NULL)
127cd844e7aSJohn Birrell error = &err;
128cd844e7aSJohn Birrell
129cd844e7aSJohn Birrell ctfsect.cts_name = ".SUNW_ctf";
130cd844e7aSJohn Birrell ctfsect.cts_type = SHT_PROGBITS;
131cd844e7aSJohn Birrell ctfsect.cts_flags = SHF_ALLOC;
132cd844e7aSJohn Birrell ctfsect.cts_data = mp->ctfdata;
133cd844e7aSJohn Birrell ctfsect.cts_size = mp->ctfsize;
134cd844e7aSJohn Birrell ctfsect.cts_entsize = 1;
135cd844e7aSJohn Birrell ctfsect.cts_offset = 0;
136cd844e7aSJohn Birrell
137cd844e7aSJohn Birrell symsect.cts_name = ".symtab";
138cd844e7aSJohn Birrell symsect.cts_type = SHT_SYMTAB;
139cd844e7aSJohn Birrell symsect.cts_flags = 0;
140cd844e7aSJohn Birrell symsect.cts_data = mp->symtbl;
141cd844e7aSJohn Birrell symsect.cts_size = mp->symhdr->sh_size;
142cd844e7aSJohn Birrell #ifdef _LP64
143cd844e7aSJohn Birrell symsect.cts_entsize = sizeof (Elf64_Sym);
144cd844e7aSJohn Birrell #else
145cd844e7aSJohn Birrell symsect.cts_entsize = sizeof (Elf32_Sym);
146cd844e7aSJohn Birrell #endif
147cd844e7aSJohn Birrell symsect.cts_offset = 0;
148cd844e7aSJohn Birrell
149cd844e7aSJohn Birrell strsect.cts_name = ".strtab";
150cd844e7aSJohn Birrell strsect.cts_type = SHT_STRTAB;
151cd844e7aSJohn Birrell strsect.cts_flags = 0;
152cd844e7aSJohn Birrell strsect.cts_data = mp->strings;
153cd844e7aSJohn Birrell strsect.cts_size = mp->strhdr->sh_size;
154cd844e7aSJohn Birrell strsect.cts_entsize = 1;
155cd844e7aSJohn Birrell strsect.cts_offset = 0;
156cd844e7aSJohn Birrell
157cd844e7aSJohn Birrell ASSERT(MUTEX_HELD(&mod_lock));
158cd844e7aSJohn Birrell
159cd844e7aSJohn Birrell if ((fp = ctf_bufopen(&ctfsect, &symsect, &strsect, error)) == NULL)
160cd844e7aSJohn Birrell return (NULL);
161cd844e7aSJohn Birrell
162cd844e7aSJohn Birrell if (!ctf_leave_compressed && (caddr_t)fp->ctf_base != mp->ctfdata) {
163cd844e7aSJohn Birrell /*
164cd844e7aSJohn Birrell * We must have just uncompressed the CTF data. To avoid
165cd844e7aSJohn Birrell * others having to pay the (substantial) cost of decompressing
166cd844e7aSJohn Birrell * the data, we're going to substitute the uncompressed version
167cd844e7aSJohn Birrell * for the compressed version. Note that this implies that the
168cd844e7aSJohn Birrell * first CTF consumer will induce memory impact on the system
169cd844e7aSJohn Birrell * (but in the name of performance of future CTF consumers).
170cd844e7aSJohn Birrell */
171cd844e7aSJohn Birrell kobj_set_ctf(mp, (caddr_t)fp->ctf_base, fp->ctf_size);
172cd844e7aSJohn Birrell fp->ctf_data.cts_data = fp->ctf_base;
173cd844e7aSJohn Birrell fp->ctf_data.cts_size = fp->ctf_size;
174cd844e7aSJohn Birrell }
175cd844e7aSJohn Birrell
176cd844e7aSJohn Birrell return (fp);
177cd844e7aSJohn Birrell }
178