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 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/sysmacros.h> 28 #include <sys/modctl.h> 29 #include <sys/debug.h> 30 #include <sys/mman.h> 31 #include <sys/modctl.h> 32 #include <sys/kobj.h> 33 #include <ctf_impl.h> 34 35 int ctf_leave_compressed = 0; 36 37 static struct modlmisc modlmisc = { 38 &mod_miscops, "Compact C Type Format routines" 39 }; 40 41 static struct modlinkage modlinkage = { 42 MODREV_1, &modlmisc, NULL 43 }; 44 45 int 46 _init(void) 47 { 48 return (mod_install(&modlinkage)); 49 } 50 51 int 52 _info(struct modinfo *mip) 53 { 54 return (mod_info(&modlinkage, mip)); 55 } 56 57 int 58 _fini(void) 59 { 60 return (mod_remove(&modlinkage)); 61 } 62 63 /*ARGSUSED*/ 64 void * 65 ctf_zopen(int *errp) 66 { 67 return ((void *)1); /* zmod is always loaded because we depend on it */ 68 } 69 70 /*ARGSUSED*/ 71 const void * 72 ctf_sect_mmap(ctf_sect_t *sp, int fd) 73 { 74 return (MAP_FAILED); /* we don't support this in the kernel */ 75 } 76 77 /*ARGSUSED*/ 78 void 79 ctf_sect_munmap(const ctf_sect_t *sp) 80 { 81 /* we don't support this in the kernel */ 82 } 83 84 /*ARGSUSED*/ 85 ctf_file_t * 86 ctf_fdopen(int fd, int *errp) 87 { 88 return (ctf_set_open_errno(errp, ENOTSUP)); 89 } 90 91 /*ARGSUSED*/ 92 ctf_file_t * 93 ctf_open(const char *filename, int *errp) 94 { 95 return (ctf_set_open_errno(errp, ENOTSUP)); 96 } 97 98 /*ARGSUSED*/ 99 int 100 ctf_write(ctf_file_t *fp, int fd) 101 { 102 return (ctf_set_errno(fp, ENOTSUP)); 103 } 104 105 int 106 ctf_version(int version) 107 { 108 ASSERT(version > 0 && version <= CTF_VERSION); 109 110 if (version > 0) 111 _libctf_version = MIN(CTF_VERSION, version); 112 113 return (_libctf_version); 114 } 115 116 /*ARGSUSED*/ 117 ctf_file_t * 118 ctf_fdcreate_int(int fd, int *errp, ctf_sect_t *ctfp) 119 { 120 if (errp != NULL) 121 *errp = ENOTSUP; 122 return (NULL); 123 } 124 125 /*ARGSUSED*/ 126 ctf_file_t * 127 ctf_modopen(struct module *mp, int *error) 128 { 129 ctf_sect_t ctfsect, symsect, strsect; 130 ctf_file_t *fp = NULL; 131 int err; 132 133 if (error == NULL) 134 error = &err; 135 136 ctfsect.cts_name = ".SUNW_ctf"; 137 ctfsect.cts_type = SHT_PROGBITS; 138 ctfsect.cts_flags = SHF_ALLOC; 139 ctfsect.cts_data = mp->ctfdata; 140 ctfsect.cts_size = mp->ctfsize; 141 ctfsect.cts_entsize = 1; 142 ctfsect.cts_offset = 0; 143 144 symsect.cts_name = ".symtab"; 145 symsect.cts_type = SHT_SYMTAB; 146 symsect.cts_flags = 0; 147 symsect.cts_data = mp->symtbl; 148 symsect.cts_size = mp->symhdr->sh_size; 149 #ifdef _LP64 150 symsect.cts_entsize = sizeof (Elf64_Sym); 151 #else 152 symsect.cts_entsize = sizeof (Elf32_Sym); 153 #endif 154 symsect.cts_offset = 0; 155 156 strsect.cts_name = ".strtab"; 157 strsect.cts_type = SHT_STRTAB; 158 strsect.cts_flags = 0; 159 strsect.cts_data = mp->strings; 160 strsect.cts_size = mp->strhdr->sh_size; 161 strsect.cts_entsize = 1; 162 strsect.cts_offset = 0; 163 164 ASSERT(MUTEX_HELD(&mod_lock)); 165 166 if ((fp = ctf_bufopen(&ctfsect, &symsect, &strsect, error)) == NULL) 167 return (NULL); 168 169 if (!ctf_leave_compressed && (caddr_t)fp->ctf_base != mp->ctfdata) { 170 /* 171 * We must have just uncompressed the CTF data. To avoid 172 * others having to pay the (substantial) cost of decompressing 173 * the data, we're going to substitute the uncompressed version 174 * for the compressed version. Note that this implies that the 175 * first CTF consumer will induce memory impact on the system 176 * (but in the name of performance of future CTF consumers). 177 */ 178 kobj_set_ctf(mp, (caddr_t)fp->ctf_base, fp->ctf_size); 179 fp->ctf_data.cts_data = fp->ctf_base; 180 fp->ctf_data.cts_size = fp->ctf_size; 181 } 182 183 return (fp); 184 } 185