1179193Sjb/* 2179193Sjb * CDDL HEADER START 3179193Sjb * 4179193Sjb * The contents of this file are subject to the terms of the 5179193Sjb * Common Development and Distribution License, Version 1.0 only 6179193Sjb * (the "License"). You may not use this file except in compliance 7179193Sjb * with the License. 8179193Sjb * 9179193Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10179193Sjb * or http://www.opensolaris.org/os/licensing. 11179193Sjb * See the License for the specific language governing permissions 12179193Sjb * and limitations under the License. 13179193Sjb * 14179193Sjb * When distributing Covered Code, include this CDDL HEADER in each 15179193Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16179193Sjb * If applicable, add the following below this CDDL HEADER, with the 17179193Sjb * fields enclosed by brackets "[]" replaced with your own identifying 18179193Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 19179193Sjb * 20179193Sjb * CDDL HEADER END 21179193Sjb */ 22179193Sjb/* 23179193Sjb * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24179193Sjb * Use is subject to license terms. 25179193Sjb */ 26179193Sjb 27179193Sjb#pragma ident "%Z%%M% %I% %E% SMI" 28179193Sjb 29179193Sjb#include <sys/sysmacros.h> 30179193Sjb#include <sys/modctl.h> 31179193Sjb#include <sys/debug.h> 32179193Sjb#include <sys/mman.h> 33179193Sjb#include <sys/modctl.h> 34179193Sjb#include <sys/kobj.h> 35179193Sjb#include <ctf_impl.h> 36179193Sjb 37179193Sjbint ctf_leave_compressed = 0; 38179193Sjb 39179193Sjbstatic struct modlmisc modlmisc = { 40179193Sjb &mod_miscops, "Compact C Type Format routines" 41179193Sjb}; 42179193Sjb 43179193Sjbstatic struct modlinkage modlinkage = { 44179193Sjb MODREV_1, &modlmisc, NULL 45179193Sjb}; 46179193Sjb 47179193Sjbint 48179193Sjb_init(void) 49179193Sjb{ 50179193Sjb return (mod_install(&modlinkage)); 51179193Sjb} 52179193Sjb 53179193Sjbint 54179193Sjb_info(struct modinfo *mip) 55179193Sjb{ 56179193Sjb return (mod_info(&modlinkage, mip)); 57179193Sjb} 58179193Sjb 59179193Sjbint 60179193Sjb_fini(void) 61179193Sjb{ 62179193Sjb return (mod_remove(&modlinkage)); 63179193Sjb} 64179193Sjb 65179193Sjb/*ARGSUSED*/ 66179193Sjbvoid * 67179193Sjbctf_zopen(int *errp) 68179193Sjb{ 69179193Sjb return ((void *)1); /* zmod is always loaded because we depend on it */ 70179193Sjb} 71179193Sjb 72179193Sjb/*ARGSUSED*/ 73179193Sjbconst void * 74179193Sjbctf_sect_mmap(ctf_sect_t *sp, int fd) 75179193Sjb{ 76179193Sjb return (MAP_FAILED); /* we don't support this in the kernel */ 77179193Sjb} 78179193Sjb 79179193Sjb/*ARGSUSED*/ 80179193Sjbvoid 81179193Sjbctf_sect_munmap(const ctf_sect_t *sp) 82179193Sjb{ 83179193Sjb /* we don't support this in the kernel */ 84179193Sjb} 85179193Sjb 86179193Sjb/*ARGSUSED*/ 87179193Sjbctf_file_t * 88179193Sjbctf_fdopen(int fd, int *errp) 89179193Sjb{ 90179193Sjb return (ctf_set_open_errno(errp, ENOTSUP)); 91179193Sjb} 92179193Sjb 93179193Sjb/*ARGSUSED*/ 94179193Sjbctf_file_t * 95179193Sjbctf_open(const char *filename, int *errp) 96179193Sjb{ 97179193Sjb return (ctf_set_open_errno(errp, ENOTSUP)); 98179193Sjb} 99179193Sjb 100179193Sjb/*ARGSUSED*/ 101179193Sjbint 102179193Sjbctf_write(ctf_file_t *fp, int fd) 103179193Sjb{ 104179193Sjb return (ctf_set_errno(fp, ENOTSUP)); 105179193Sjb} 106179193Sjb 107179193Sjbint 108179193Sjbctf_version(int version) 109179193Sjb{ 110179193Sjb ASSERT(version > 0 && version <= CTF_VERSION); 111179193Sjb 112179193Sjb if (version > 0) 113179193Sjb _libctf_version = MIN(CTF_VERSION, version); 114179193Sjb 115179193Sjb return (_libctf_version); 116179193Sjb} 117179193Sjb 118179193Sjb/*ARGSUSED*/ 119179193Sjbctf_file_t * 120179193Sjbctf_modopen(struct module *mp, int *error) 121179193Sjb{ 122179193Sjb ctf_sect_t ctfsect, symsect, strsect; 123179193Sjb ctf_file_t *fp = NULL; 124179193Sjb int err; 125179193Sjb 126179193Sjb if (error == NULL) 127179193Sjb error = &err; 128179193Sjb 129179193Sjb ctfsect.cts_name = ".SUNW_ctf"; 130179193Sjb ctfsect.cts_type = SHT_PROGBITS; 131179193Sjb ctfsect.cts_flags = SHF_ALLOC; 132179193Sjb ctfsect.cts_data = mp->ctfdata; 133179193Sjb ctfsect.cts_size = mp->ctfsize; 134179193Sjb ctfsect.cts_entsize = 1; 135179193Sjb ctfsect.cts_offset = 0; 136179193Sjb 137179193Sjb symsect.cts_name = ".symtab"; 138179193Sjb symsect.cts_type = SHT_SYMTAB; 139179193Sjb symsect.cts_flags = 0; 140179193Sjb symsect.cts_data = mp->symtbl; 141179193Sjb symsect.cts_size = mp->symhdr->sh_size; 142179193Sjb#ifdef _LP64 143179193Sjb symsect.cts_entsize = sizeof (Elf64_Sym); 144179193Sjb#else 145179193Sjb symsect.cts_entsize = sizeof (Elf32_Sym); 146179193Sjb#endif 147179193Sjb symsect.cts_offset = 0; 148179193Sjb 149179193Sjb strsect.cts_name = ".strtab"; 150179193Sjb strsect.cts_type = SHT_STRTAB; 151179193Sjb strsect.cts_flags = 0; 152179193Sjb strsect.cts_data = mp->strings; 153179193Sjb strsect.cts_size = mp->strhdr->sh_size; 154179193Sjb strsect.cts_entsize = 1; 155179193Sjb strsect.cts_offset = 0; 156179193Sjb 157179193Sjb ASSERT(MUTEX_HELD(&mod_lock)); 158179193Sjb 159179193Sjb if ((fp = ctf_bufopen(&ctfsect, &symsect, &strsect, error)) == NULL) 160179193Sjb return (NULL); 161179193Sjb 162179193Sjb if (!ctf_leave_compressed && (caddr_t)fp->ctf_base != mp->ctfdata) { 163179193Sjb /* 164179193Sjb * We must have just uncompressed the CTF data. To avoid 165179193Sjb * others having to pay the (substantial) cost of decompressing 166179193Sjb * the data, we're going to substitute the uncompressed version 167179193Sjb * for the compressed version. Note that this implies that the 168179193Sjb * first CTF consumer will induce memory impact on the system 169179193Sjb * (but in the name of performance of future CTF consumers). 170179193Sjb */ 171179193Sjb kobj_set_ctf(mp, (caddr_t)fp->ctf_base, fp->ctf_size); 172179193Sjb fp->ctf_data.cts_data = fp->ctf_base; 173179193Sjb fp->ctf_data.cts_size = fp->ctf_size; 174179193Sjb } 175179193Sjb 176179193Sjb return (fp); 177179193Sjb} 178