1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2008 John Birrell <jb@freebsd.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #include <sys/ctf.h> 32 33 /* 34 * Note this file is included by both link_elf.c and link_elf_obj.c. 35 */ 36 37 #ifdef DDB_CTF 38 #include <contrib/zlib/zlib.h> 39 #endif 40 41 static int 42 link_elf_ctf_get(linker_file_t lf, linker_ctf_t *lc) 43 { 44 #ifdef DDB_CTF 45 Elf_Ehdr *hdr = NULL; 46 Elf_Shdr *shdr = NULL; 47 caddr_t ctftab = NULL; 48 caddr_t raw = NULL; 49 caddr_t shstrtab = NULL; 50 elf_file_t ef = (elf_file_t) lf; 51 int flags; 52 int i; 53 int nbytes; 54 size_t sz; 55 struct nameidata nd; 56 struct thread *td = curthread; 57 struct ctf_header cth; 58 #endif 59 int error = 0; 60 61 if (lf == NULL || lc == NULL) 62 return (EINVAL); 63 64 /* Set the defaults for no CTF present. That's not a crime! */ 65 bzero(lc, sizeof(*lc)); 66 67 #ifdef DDB_CTF 68 /* 69 * First check if we've tried to load CTF data previously and the 70 * CTF ELF section wasn't found. We flag that condition by setting 71 * ctfcnt to -1. See below. 72 */ 73 if (ef->ctfcnt < 0) 74 return (EFTYPE); 75 76 /* Now check if we've already loaded the CTF data.. */ 77 if (ef->ctfcnt > 0) { 78 /* We only need to load once. */ 79 lc->ctftab = ef->ctftab; 80 lc->ctfcnt = ef->ctfcnt; 81 lc->symtab = ef->ddbsymtab; 82 lc->strtab = ef->ddbstrtab; 83 lc->strcnt = ef->ddbstrcnt; 84 lc->nsym = ef->ddbsymcnt; 85 lc->ctfoffp = (uint32_t **) &ef->ctfoff; 86 lc->typoffp = (uint32_t **) &ef->typoff; 87 lc->typlenp = &ef->typlen; 88 return (0); 89 } 90 91 /* 92 * We need to try reading the CTF data. Flag no CTF data present 93 * by default and if we actually succeed in reading it, we'll 94 * update ctfcnt to the number of bytes read. 95 */ 96 ef->ctfcnt = -1; 97 98 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, lf->pathname); 99 flags = FREAD; 100 error = vn_open(&nd, &flags, 0, NULL); 101 if (error) 102 return (error); 103 NDFREE_PNBUF(&nd); 104 105 /* Allocate memory for the FLF header. */ 106 hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK); 107 108 /* Read the ELF header. */ 109 if ((error = vn_rdwr(UIO_READ, nd.ni_vp, hdr, sizeof(*hdr), 110 0, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, NULL, 111 td)) != 0) 112 goto out; 113 114 /* Sanity check. */ 115 if (!IS_ELF(*hdr)) { 116 error = ENOEXEC; 117 goto out; 118 } 119 120 nbytes = hdr->e_shnum * hdr->e_shentsize; 121 if (nbytes == 0 || hdr->e_shoff == 0 || 122 hdr->e_shentsize != sizeof(Elf_Shdr)) { 123 error = ENOEXEC; 124 goto out; 125 } 126 127 /* Allocate memory for all the section headers */ 128 shdr = malloc(nbytes, M_LINKER, M_WAITOK); 129 130 /* Read all the section headers */ 131 if ((error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes, 132 hdr->e_shoff, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 133 NULL, td)) != 0) 134 goto out; 135 136 /* 137 * We need to search for the CTF section by name, so if the 138 * section names aren't present, then we can't locate the 139 * .SUNW_ctf section containing the CTF data. 140 */ 141 if (hdr->e_shstrndx == 0 || shdr[hdr->e_shstrndx].sh_type != SHT_STRTAB) { 142 printf("%s(%d): module %s e_shstrndx is %d, sh_type is %d\n", 143 __func__, __LINE__, lf->pathname, hdr->e_shstrndx, 144 shdr[hdr->e_shstrndx].sh_type); 145 error = EFTYPE; 146 goto out; 147 } 148 149 /* Allocate memory to buffer the section header strings. */ 150 shstrtab = malloc(shdr[hdr->e_shstrndx].sh_size, M_LINKER, M_WAITOK); 151 152 /* Read the section header strings. */ 153 if ((error = vn_rdwr(UIO_READ, nd.ni_vp, shstrtab, 154 shdr[hdr->e_shstrndx].sh_size, shdr[hdr->e_shstrndx].sh_offset, 155 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, NULL, td)) != 0) 156 goto out; 157 158 /* Search for the section containing the CTF data. */ 159 for (i = 0; i < hdr->e_shnum; i++) 160 if (strcmp(".SUNW_ctf", shstrtab + shdr[i].sh_name) == 0) 161 break; 162 163 /* Check if the CTF section wasn't found. */ 164 if (i >= hdr->e_shnum) { 165 printf("%s(%d): module %s has no .SUNW_ctf section\n", 166 __func__, __LINE__, lf->pathname); 167 error = EFTYPE; 168 goto out; 169 } 170 171 /* Read the CTF header. */ 172 if ((error = vn_rdwr(UIO_READ, nd.ni_vp, &cth, sizeof(cth), 173 shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, 174 NOCRED, NULL, td)) != 0) 175 goto out; 176 177 /* Check the CTF magic number. */ 178 if (cth.cth_magic != CTF_MAGIC) { 179 printf("%s(%d): module %s has invalid format\n", 180 __func__, __LINE__, lf->pathname); 181 error = EFTYPE; 182 goto out; 183 } 184 185 if (cth.cth_version != CTF_VERSION_2 && 186 cth.cth_version != CTF_VERSION_3) { 187 printf( 188 "%s(%d): module %s CTF format has unsupported version %d\n", 189 __func__, __LINE__, lf->pathname, cth.cth_version); 190 error = EFTYPE; 191 goto out; 192 } 193 194 /* Check if the data is compressed. */ 195 if ((cth.cth_flags & CTF_F_COMPRESS) != 0) { 196 /* 197 * The last two fields in the CTF header are the offset 198 * from the end of the header to the start of the string 199 * data and the length of that string data. Use this 200 * information to determine the decompressed CTF data 201 * buffer required. 202 */ 203 sz = cth.cth_stroff + cth.cth_strlen + sizeof(cth); 204 205 /* 206 * Allocate memory for the compressed CTF data, including 207 * the header (which isn't compressed). 208 */ 209 raw = malloc(shdr[i].sh_size, M_LINKER, M_WAITOK); 210 } else { 211 /* 212 * The CTF data is not compressed, so the ELF section 213 * size is the same as the buffer size required. 214 */ 215 sz = shdr[i].sh_size; 216 } 217 218 /* 219 * Allocate memory to buffer the CTF data in its decompressed 220 * form. 221 */ 222 ctftab = malloc(sz, M_LINKER, M_WAITOK); 223 224 /* 225 * Read the CTF data into the raw buffer if compressed, or 226 * directly into the CTF buffer otherwise. 227 */ 228 if ((error = vn_rdwr(UIO_READ, nd.ni_vp, raw == NULL ? ctftab : raw, 229 shdr[i].sh_size, shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED, 230 td->td_ucred, NOCRED, NULL, td)) != 0) 231 goto out; 232 233 /* Check if decompression is required. */ 234 if (raw != NULL) { 235 uLongf destlen; 236 int ret; 237 238 /* 239 * The header isn't compressed, so copy that into the 240 * CTF buffer first. 241 */ 242 bcopy(&cth, ctftab, sizeof(cth)); 243 244 destlen = sz - sizeof(cth); 245 ret = uncompress(ctftab + sizeof(cth), &destlen, 246 raw + sizeof(cth), shdr[i].sh_size - sizeof(cth)); 247 if (ret != Z_OK) { 248 printf("%s(%d): zlib uncompress returned %d\n", 249 __func__, __LINE__, ret); 250 error = EIO; 251 goto out; 252 } 253 } 254 255 /* Got the CTF data! */ 256 ef->ctftab = ctftab; 257 ef->ctfcnt = shdr[i].sh_size; 258 259 /* We'll retain the memory allocated for the CTF data. */ 260 ctftab = NULL; 261 262 /* Let the caller use the CTF data read. */ 263 lc->ctftab = ef->ctftab; 264 lc->ctfcnt = ef->ctfcnt; 265 lc->symtab = ef->ddbsymtab; 266 lc->strtab = ef->ddbstrtab; 267 lc->strcnt = ef->ddbstrcnt; 268 lc->nsym = ef->ddbsymcnt; 269 lc->ctfoffp = (uint32_t **) &ef->ctfoff; 270 lc->typoffp = (uint32_t **) &ef->typoff; 271 lc->typlenp = &ef->typlen; 272 273 out: 274 VOP_UNLOCK(nd.ni_vp); 275 vn_close(nd.ni_vp, FREAD, td->td_ucred, td); 276 277 if (hdr != NULL) 278 free(hdr, M_LINKER); 279 if (shdr != NULL) 280 free(shdr, M_LINKER); 281 if (shstrtab != NULL) 282 free(shstrtab, M_LINKER); 283 if (ctftab != NULL) 284 free(ctftab, M_LINKER); 285 if (raw != NULL) 286 free(raw, M_LINKER); 287 #else 288 error = EOPNOTSUPP; 289 #endif 290 291 return (error); 292 } 293