kern_ctf.c revision 241896
1179224Sjb/*- 2179224Sjb * Copyright (c) 2008 John Birrell <jb@freebsd.org> 3179224Sjb * All rights reserved. 4179224Sjb * 5179224Sjb * Redistribution and use in source and binary forms, with or without 6179224Sjb * modification, are permitted provided that the following conditions 7179224Sjb * are met: 8179224Sjb * 1. Redistributions of source code must retain the above copyright 9179224Sjb * notice, this list of conditions and the following disclaimer. 10179224Sjb * 2. Redistributions in binary form must reproduce the above copyright 11179224Sjb * notice, this list of conditions and the following disclaimer in the 12179224Sjb * documentation and/or other materials provided with the distribution. 13179224Sjb * 14179224Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15179224Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16179224Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17179224Sjb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18179224Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19179224Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20179224Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21179224Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22179224Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23179224Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24179224Sjb * SUCH DAMAGE. 25179224Sjb * 26179224Sjb * $FreeBSD: head/sys/kern/kern_ctf.c 241896 2012-10-22 17:50:54Z kib $ 27179224Sjb */ 28179224Sjb 29179224Sjb/* 30179224Sjb * Note this file is included by both link_elf.c and link_elf_obj.c. 31179224Sjb * 32179224Sjb * The CTF header structure definition can't be used here because it's 33179224Sjb * (annoyingly) covered by the CDDL. We will just use a few bytes from 34179224Sjb * it as an integer array where we 'know' what they mean. 35179224Sjb */ 36179224Sjb#define CTF_HDR_SIZE 36 37179224Sjb#define CTF_HDR_STRTAB_U32 7 38179224Sjb#define CTF_HDR_STRLEN_U32 8 39179224Sjb 40179224Sjb#ifdef DDB_CTF 41179224Sjbstatic void * 42179224Sjbz_alloc(void *nil, u_int items, u_int size) 43179224Sjb{ 44179224Sjb void *ptr; 45179224Sjb 46179224Sjb ptr = malloc(items * size, M_TEMP, M_NOWAIT); 47179224Sjb return ptr; 48179224Sjb} 49179224Sjb 50179224Sjbstatic void 51179224Sjbz_free(void *nil, void *ptr) 52179224Sjb{ 53179224Sjb free(ptr, M_TEMP); 54179224Sjb} 55179224Sjb 56179224Sjb#endif 57179224Sjb 58179224Sjbstatic int 59179224Sjblink_elf_ctf_get(linker_file_t lf, linker_ctf_t *lc) 60179224Sjb{ 61179224Sjb#ifdef DDB_CTF 62179224Sjb Elf_Ehdr *hdr = NULL; 63179224Sjb Elf_Shdr *shdr = NULL; 64179224Sjb caddr_t ctftab = NULL; 65179224Sjb caddr_t raw = NULL; 66179224Sjb caddr_t shstrtab = NULL; 67179224Sjb elf_file_t ef = (elf_file_t) lf; 68179224Sjb int flags; 69179224Sjb int i; 70179224Sjb int nbytes; 71231949Skib ssize_t resid; 72179224Sjb size_t sz; 73179224Sjb struct nameidata nd; 74179224Sjb struct thread *td = curthread; 75179224Sjb uint8_t ctf_hdr[CTF_HDR_SIZE]; 76179224Sjb#endif 77179224Sjb int error = 0; 78179224Sjb 79179224Sjb if (lf == NULL || lc == NULL) 80179224Sjb return (EINVAL); 81179224Sjb 82179224Sjb /* Set the defaults for no CTF present. That's not a crime! */ 83179224Sjb bzero(lc, sizeof(*lc)); 84179224Sjb 85179224Sjb#ifdef DDB_CTF 86179224Sjb /* 87179224Sjb * First check if we've tried to load CTF data previously and the 88179224Sjb * CTF ELF section wasn't found. We flag that condition by setting 89179224Sjb * ctfcnt to -1. See below. 90179224Sjb */ 91179224Sjb if (ef->ctfcnt < 0) 92227342Srstone return (EFTYPE); 93179224Sjb 94179224Sjb /* Now check if we've already loaded the CTF data.. */ 95179224Sjb if (ef->ctfcnt > 0) { 96179224Sjb /* We only need to load once. */ 97179224Sjb lc->ctftab = ef->ctftab; 98179224Sjb lc->ctfcnt = ef->ctfcnt; 99179224Sjb lc->symtab = ef->ddbsymtab; 100179224Sjb lc->strtab = ef->ddbstrtab; 101179224Sjb lc->strcnt = ef->ddbstrcnt; 102179224Sjb lc->nsym = ef->ddbsymcnt; 103179224Sjb lc->ctfoffp = (uint32_t **) &ef->ctfoff; 104179224Sjb lc->typoffp = (uint32_t **) &ef->typoff; 105179224Sjb lc->typlenp = &ef->typlen; 106179224Sjb return (0); 107179224Sjb } 108179224Sjb 109179224Sjb /* 110179224Sjb * We need to try reading the CTF data. Flag no CTF data present 111179224Sjb * by default and if we actually succeed in reading it, we'll 112179224Sjb * update ctfcnt to the number of bytes read. 113179224Sjb */ 114179224Sjb ef->ctfcnt = -1; 115179224Sjb 116241896Skib NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, lf->pathname, td); 117179224Sjb flags = FREAD; 118179224Sjb error = vn_open(&nd, &flags, 0, NULL); 119179224Sjb if (error) 120179224Sjb return (error); 121179224Sjb NDFREE(&nd, NDF_ONLY_PNBUF); 122179224Sjb 123179224Sjb /* Allocate memory for the FLF header. */ 124179224Sjb if ((hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK)) == NULL) { 125179224Sjb error = ENOMEM; 126179224Sjb goto out; 127179224Sjb } 128179224Sjb 129179224Sjb /* Read the ELF header. */ 130179224Sjb if ((error = vn_rdwr(UIO_READ, nd.ni_vp, hdr, sizeof(*hdr), 131179224Sjb 0, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, 132179224Sjb td)) != 0) 133179224Sjb goto out; 134179224Sjb 135179224Sjb /* Sanity check. */ 136179224Sjb if (!IS_ELF(*hdr)) { 137179224Sjb error = ENOEXEC; 138179224Sjb goto out; 139179224Sjb } 140179224Sjb 141179224Sjb nbytes = hdr->e_shnum * hdr->e_shentsize; 142179224Sjb if (nbytes == 0 || hdr->e_shoff == 0 || 143179224Sjb hdr->e_shentsize != sizeof(Elf_Shdr)) { 144179224Sjb error = ENOEXEC; 145179224Sjb goto out; 146179224Sjb } 147179224Sjb 148179224Sjb /* Allocate memory for all the section headers */ 149179224Sjb if ((shdr = malloc(nbytes, M_LINKER, M_WAITOK)) == NULL) { 150179224Sjb error = ENOMEM; 151179224Sjb goto out; 152179224Sjb } 153179224Sjb 154179224Sjb /* Read all the section headers */ 155179224Sjb if ((error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes, 156179224Sjb hdr->e_shoff, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 157179224Sjb &resid, td)) != 0) 158179224Sjb goto out; 159179224Sjb 160179224Sjb /* 161179224Sjb * We need to search for the CTF section by name, so if the 162179224Sjb * section names aren't present, then we can't locate the 163179224Sjb * .SUNW_ctf section containing the CTF data. 164179224Sjb */ 165226082Sdelphij if (hdr->e_shstrndx == 0 || shdr[hdr->e_shstrndx].sh_type != SHT_STRTAB) { 166226082Sdelphij printf("%s(%d): module %s e_shstrndx is %d, sh_type is %d\n", 167226082Sdelphij __func__, __LINE__, lf->pathname, hdr->e_shstrndx, 168226082Sdelphij shdr[hdr->e_shstrndx].sh_type); 169226082Sdelphij error = EFTYPE; 170179224Sjb goto out; 171226082Sdelphij } 172179224Sjb 173179224Sjb /* Allocate memory to buffer the section header strings. */ 174179224Sjb if ((shstrtab = malloc(shdr[hdr->e_shstrndx].sh_size, M_LINKER, 175179224Sjb M_WAITOK)) == NULL) { 176179224Sjb error = ENOMEM; 177179224Sjb goto out; 178179224Sjb } 179179224Sjb 180179224Sjb /* Read the section header strings. */ 181179224Sjb if ((error = vn_rdwr(UIO_READ, nd.ni_vp, shstrtab, 182179224Sjb shdr[hdr->e_shstrndx].sh_size, shdr[hdr->e_shstrndx].sh_offset, 183179224Sjb UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, 184179224Sjb td)) != 0) 185179224Sjb goto out; 186179224Sjb 187179224Sjb /* Search for the section containing the CTF data. */ 188179224Sjb for (i = 0; i < hdr->e_shnum; i++) 189179224Sjb if (strcmp(".SUNW_ctf", shstrtab + shdr[i].sh_name) == 0) 190179224Sjb break; 191179224Sjb 192179224Sjb /* Check if the CTF section wasn't found. */ 193226082Sdelphij if (i >= hdr->e_shnum) { 194226082Sdelphij printf("%s(%d): module %s has no .SUNW_ctf section\n", 195226082Sdelphij __func__, __LINE__, lf->pathname); 196226082Sdelphij error = EFTYPE; 197179224Sjb goto out; 198226082Sdelphij } 199179224Sjb 200179224Sjb /* Read the CTF header. */ 201179224Sjb if ((error = vn_rdwr(UIO_READ, nd.ni_vp, ctf_hdr, sizeof(ctf_hdr), 202179224Sjb shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, 203179224Sjb NOCRED, &resid, td)) != 0) 204179224Sjb goto out; 205179224Sjb 206179224Sjb /* Check the CTF magic number. (XXX check for big endian!) */ 207226082Sdelphij if (ctf_hdr[0] != 0xf1 || ctf_hdr[1] != 0xcf) { 208226082Sdelphij printf("%s(%d): module %s has invalid format\n", 209226082Sdelphij __func__, __LINE__, lf->pathname); 210226082Sdelphij error = EFTYPE; 211179224Sjb goto out; 212226082Sdelphij } 213179224Sjb 214179224Sjb /* Check if version 2. */ 215226082Sdelphij if (ctf_hdr[2] != 2) { 216226082Sdelphij printf("%s(%d): module %s CTF format version is %d " 217226082Sdelphij "(2 expected)\n", 218226082Sdelphij __func__, __LINE__, lf->pathname, ctf_hdr[2]); 219226082Sdelphij error = EFTYPE; 220179224Sjb goto out; 221226082Sdelphij } 222179224Sjb 223179224Sjb /* Check if the data is compressed. */ 224179224Sjb if ((ctf_hdr[3] & 0x1) != 0) { 225179224Sjb uint32_t *u32 = (uint32_t *) ctf_hdr; 226179224Sjb 227179224Sjb /* 228179224Sjb * The last two fields in the CTF header are the offset 229179224Sjb * from the end of the header to the start of the string 230179224Sjb * data and the length of that string data. se this 231179224Sjb * information to determine the decompressed CTF data 232179224Sjb * buffer required. 233179224Sjb */ 234179224Sjb sz = u32[CTF_HDR_STRTAB_U32] + u32[CTF_HDR_STRLEN_U32] + 235179224Sjb sizeof(ctf_hdr); 236179224Sjb 237179224Sjb /* 238179224Sjb * Allocate memory for the compressed CTF data, including 239179224Sjb * the header (which isn't compressed). 240179224Sjb */ 241179224Sjb if ((raw = malloc(shdr[i].sh_size, M_LINKER, M_WAITOK)) == NULL) { 242179224Sjb error = ENOMEM; 243179224Sjb goto out; 244179224Sjb } 245179224Sjb } else { 246179224Sjb /* 247179224Sjb * The CTF data is not compressed, so the ELF section 248179224Sjb * size is the same as the buffer size required. 249179224Sjb */ 250179224Sjb sz = shdr[i].sh_size; 251179224Sjb } 252179224Sjb 253179224Sjb /* 254179224Sjb * Allocate memory to buffer the CTF data in it's decompressed 255179224Sjb * form. 256179224Sjb */ 257179224Sjb if ((ctftab = malloc(sz, M_LINKER, M_WAITOK)) == NULL) { 258179224Sjb error = ENOMEM; 259179224Sjb goto out; 260179224Sjb } 261179224Sjb 262179224Sjb /* 263179224Sjb * Read the CTF data into the raw buffer if compressed, or 264179224Sjb * directly into the CTF buffer otherwise. 265179224Sjb */ 266179224Sjb if ((error = vn_rdwr(UIO_READ, nd.ni_vp, raw == NULL ? ctftab : raw, 267179224Sjb shdr[i].sh_size, shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED, 268179224Sjb td->td_ucred, NOCRED, &resid, td)) != 0) 269179224Sjb goto out; 270179224Sjb 271179224Sjb /* Check if decompression is required. */ 272179224Sjb if (raw != NULL) { 273179224Sjb z_stream zs; 274179224Sjb int ret; 275179224Sjb 276179224Sjb /* 277179224Sjb * The header isn't compressed, so copy that into the 278179224Sjb * CTF buffer first. 279179224Sjb */ 280179224Sjb bcopy(ctf_hdr, ctftab, sizeof(ctf_hdr)); 281179224Sjb 282179224Sjb /* Initialise the zlib structure. */ 283179224Sjb bzero(&zs, sizeof(zs)); 284179224Sjb zs.zalloc = z_alloc; 285179224Sjb zs.zfree = z_free; 286179224Sjb 287179224Sjb if (inflateInit(&zs) != Z_OK) { 288179224Sjb error = EIO; 289179224Sjb goto out; 290179224Sjb } 291179224Sjb 292179224Sjb zs.avail_in = shdr[i].sh_size - sizeof(ctf_hdr); 293179224Sjb zs.next_in = ((uint8_t *) raw) + sizeof(ctf_hdr); 294179224Sjb zs.avail_out = sz - sizeof(ctf_hdr); 295179224Sjb zs.next_out = ((uint8_t *) ctftab) + sizeof(ctf_hdr); 296179224Sjb if ((ret = inflate(&zs, Z_FINISH)) != Z_STREAM_END) { 297179224Sjb printf("%s(%d): zlib inflate returned %d\n", __func__, __LINE__, ret); 298179224Sjb error = EIO; 299179224Sjb goto out; 300179224Sjb } 301179224Sjb } 302179224Sjb 303179224Sjb /* Got the CTF data! */ 304179224Sjb ef->ctftab = ctftab; 305179224Sjb ef->ctfcnt = shdr[i].sh_size; 306179224Sjb 307179224Sjb /* We'll retain the memory allocated for the CTF data. */ 308179224Sjb ctftab = NULL; 309179224Sjb 310179224Sjb /* Let the caller use the CTF data read. */ 311179224Sjb lc->ctftab = ef->ctftab; 312179224Sjb lc->ctfcnt = ef->ctfcnt; 313179224Sjb lc->symtab = ef->ddbsymtab; 314179224Sjb lc->strtab = ef->ddbstrtab; 315179224Sjb lc->strcnt = ef->ddbstrcnt; 316179224Sjb lc->nsym = ef->ddbsymcnt; 317179224Sjb lc->ctfoffp = (uint32_t **) &ef->ctfoff; 318179224Sjb lc->typoffp = (uint32_t **) &ef->typoff; 319179224Sjb lc->typlenp = &ef->typlen; 320179224Sjb 321179224Sjbout: 322179224Sjb VOP_UNLOCK(nd.ni_vp, 0); 323179224Sjb vn_close(nd.ni_vp, FREAD, td->td_ucred, td); 324179224Sjb 325179224Sjb if (hdr != NULL) 326179224Sjb free(hdr, M_LINKER); 327179224Sjb if (shdr != NULL) 328179224Sjb free(shdr, M_LINKER); 329179224Sjb if (shstrtab != NULL) 330179224Sjb free(shstrtab, M_LINKER); 331179224Sjb if (ctftab != NULL) 332179224Sjb free(ctftab, M_LINKER); 333179224Sjb if (raw != NULL) 334179224Sjb free(raw, M_LINKER); 335179224Sjb#else 336179224Sjb error = EOPNOTSUPP; 337179224Sjb#endif 338179224Sjb 339179224Sjb return (error); 340179224Sjb} 341