xref: /freebsd/sys/cddl/contrib/opensolaris/uts/common/ctf/ctf_mod.c (revision cd844e7a7df72952bb1135fea0a4c6ee372a7027)
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