1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2017 Dell EMC 5 * Copyright (c) 2007 Sandvine Incorporated 6 * Copyright (c) 1998 John D. Polstra 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/endian.h> 35 #include <sys/param.h> 36 #include <sys/procfs.h> 37 #include <sys/ptrace.h> 38 #include <sys/queue.h> 39 #include <sys/linker_set.h> 40 #include <sys/sbuf.h> 41 #include <sys/sysctl.h> 42 #include <sys/user.h> 43 #include <sys/wait.h> 44 #include <machine/elf.h> 45 #include <vm/vm_param.h> 46 #include <vm/vm.h> 47 #include <assert.h> 48 #include <err.h> 49 #include <errno.h> 50 #include <fcntl.h> 51 #include <stdbool.h> 52 #include <stdint.h> 53 #include <stdio.h> 54 #include <stdlib.h> 55 #include <string.h> 56 #include <unistd.h> 57 #include <libutil.h> 58 59 #include "extern.h" 60 61 /* 62 * Code for generating ELF core dumps. 63 */ 64 65 struct map_entry { 66 struct map_entry *next; 67 vm_offset_t start; 68 vm_offset_t end; 69 vm_prot_t protection; 70 }; 71 72 typedef void (*segment_callback)(struct map_entry *, void *); 73 74 /* Closure for cb_put_phdr(). */ 75 struct phdr_closure { 76 Elf_Phdr *phdr; /* Program header to fill in */ 77 Elf_Off offset; /* Offset of segment in core file */ 78 }; 79 80 /* Closure for cb_size_segment(). */ 81 struct sseg_closure { 82 int count; /* Count of writable segments. */ 83 size_t size; /* Total size of all writable segments. */ 84 }; 85 86 #ifdef ELFCORE_COMPAT_32 87 typedef struct fpreg32 elfcore_fpregset_t; 88 typedef struct reg32 elfcore_gregset_t; 89 typedef struct prpsinfo32 elfcore_prpsinfo_t; 90 typedef struct prstatus32 elfcore_prstatus_t; 91 typedef struct ptrace_lwpinfo32 elfcore_lwpinfo_t; 92 static void elf_convert_lwpinfo(struct ptrace_lwpinfo32 *pld, 93 struct ptrace_lwpinfo *pls); 94 #else 95 typedef fpregset_t elfcore_fpregset_t; 96 typedef gregset_t elfcore_gregset_t; 97 typedef prpsinfo_t elfcore_prpsinfo_t; 98 typedef prstatus_t elfcore_prstatus_t; 99 typedef struct ptrace_lwpinfo elfcore_lwpinfo_t; 100 #define elf_convert_lwpinfo(d,s) *d = *s 101 #endif 102 103 typedef void* (*notefunc_t)(void *, size_t *); 104 105 static void cb_put_phdr(struct map_entry *, void *); 106 static void cb_size_segment(struct map_entry *, void *); 107 static void each_dumpable_segment(struct map_entry *, segment_callback, 108 void *closure); 109 static void elf_detach(void); /* atexit() handler. */ 110 static void *elf_note_prpsinfo(void *, size_t *); 111 static void *elf_note_thrmisc(void *, size_t *); 112 static void *elf_note_ptlwpinfo(void *, size_t *); 113 #if defined(__i386__) || defined(__amd64__) 114 static void *elf_note_x86_xstate(void *, size_t *); 115 #endif 116 #if defined(__powerpc__) 117 static void *elf_note_powerpc_vmx(void *, size_t *); 118 static void *elf_note_powerpc_vsx(void *, size_t *); 119 #endif 120 static void *elf_note_procstat_auxv(void *, size_t *); 121 static void *elf_note_procstat_files(void *, size_t *); 122 static void *elf_note_procstat_groups(void *, size_t *); 123 static void *elf_note_procstat_osrel(void *, size_t *); 124 static void *elf_note_procstat_proc(void *, size_t *); 125 static void *elf_note_procstat_psstrings(void *, size_t *); 126 static void *elf_note_procstat_rlimit(void *, size_t *); 127 static void *elf_note_procstat_umask(void *, size_t *); 128 static void *elf_note_procstat_vmmap(void *, size_t *); 129 static void elf_puthdr(int, pid_t, struct map_entry *, void *, size_t, size_t, 130 size_t, int); 131 static void elf_putnote(int, notefunc_t, void *, struct sbuf *); 132 static void elf_putnotes(pid_t, struct sbuf *, size_t *); 133 static void elf_putregnote(int, lwpid_t, struct sbuf *); 134 static void freemap(struct map_entry *); 135 static struct map_entry *readmap(pid_t); 136 static void *procstat_sysctl(void *, int, size_t, size_t *sizep); 137 138 static pid_t g_pid; /* Pid being dumped, global for elf_detach */ 139 static int g_status; /* proc status after ptrace attach */ 140 141 static int 142 elf_ident(int efd, pid_t pid __unused, char *binfile __unused) 143 { 144 Elf_Ehdr hdr; 145 int cnt; 146 uint16_t machine; 147 148 cnt = read(efd, &hdr, sizeof(hdr)); 149 if (cnt != sizeof(hdr)) 150 return (0); 151 if (!IS_ELF(hdr)) 152 return (0); 153 switch (hdr.e_ident[EI_DATA]) { 154 case ELFDATA2LSB: 155 machine = le16toh(hdr.e_machine); 156 break; 157 case ELFDATA2MSB: 158 machine = be16toh(hdr.e_machine); 159 break; 160 default: 161 return (0); 162 } 163 if (!ELF_MACHINE_OK(machine)) 164 return (0); 165 166 /* Looks good. */ 167 return (1); 168 } 169 170 static void 171 elf_detach(void) 172 { 173 int sig; 174 175 if (g_pid != 0) { 176 /* 177 * Forward any pending signals. SIGSTOP is generated by ptrace 178 * itself, so ignore it. 179 */ 180 sig = WIFSTOPPED(g_status) ? WSTOPSIG(g_status) : 0; 181 if (sig == SIGSTOP) 182 sig = 0; 183 ptrace(PT_DETACH, g_pid, (caddr_t)1, sig); 184 } 185 } 186 187 /* 188 * Write an ELF coredump for the given pid to the given fd. 189 */ 190 static void 191 elf_coredump(int efd, int fd, pid_t pid) 192 { 193 struct map_entry *map; 194 struct sseg_closure seginfo; 195 struct sbuf *sb; 196 void *hdr; 197 size_t hdrsize, notesz, segoff; 198 ssize_t n, old_len; 199 Elf_Phdr *php; 200 int i; 201 202 /* Attach to process to dump. */ 203 g_pid = pid; 204 if (atexit(elf_detach) != 0) 205 err(1, "atexit"); 206 errno = 0; 207 ptrace(PT_ATTACH, pid, NULL, 0); 208 if (errno) 209 err(1, "PT_ATTACH"); 210 if (waitpid(pid, &g_status, 0) == -1) 211 err(1, "waitpid"); 212 213 /* Get the program's memory map. */ 214 map = readmap(pid); 215 216 /* Size the program segments. */ 217 seginfo.count = 0; 218 seginfo.size = 0; 219 each_dumpable_segment(map, cb_size_segment, &seginfo); 220 221 /* 222 * Build the header and the notes using sbuf and write to the file. 223 */ 224 sb = sbuf_new_auto(); 225 hdrsize = sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * (1 + seginfo.count); 226 if (seginfo.count + 1 >= PN_XNUM) 227 hdrsize += sizeof(Elf_Shdr); 228 /* Start header + notes section. */ 229 sbuf_start_section(sb, NULL); 230 /* Make empty header subsection. */ 231 sbuf_start_section(sb, &old_len); 232 sbuf_putc(sb, 0); 233 sbuf_end_section(sb, old_len, hdrsize, 0); 234 /* Put notes. */ 235 elf_putnotes(pid, sb, ¬esz); 236 /* Align up to a page boundary for the program segments. */ 237 sbuf_end_section(sb, -1, getpagesize(), 0); 238 if (sbuf_finish(sb) != 0) 239 err(1, "sbuf_finish"); 240 hdr = sbuf_data(sb); 241 segoff = sbuf_len(sb); 242 /* Fill in the header. */ 243 elf_puthdr(efd, pid, map, hdr, hdrsize, notesz, segoff, seginfo.count); 244 245 n = write(fd, hdr, segoff); 246 if (n == -1) 247 err(1, "write"); 248 if (n < segoff) 249 errx(1, "short write"); 250 251 /* Write the contents of all of the writable segments. */ 252 php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1; 253 for (i = 0; i < seginfo.count; i++) { 254 struct ptrace_io_desc iorequest; 255 uintmax_t nleft = php->p_filesz; 256 257 iorequest.piod_op = PIOD_READ_D; 258 iorequest.piod_offs = (caddr_t)(uintptr_t)php->p_vaddr; 259 while (nleft > 0) { 260 char buf[8*1024]; 261 size_t nwant; 262 ssize_t ngot; 263 264 if (nleft > sizeof(buf)) 265 nwant = sizeof buf; 266 else 267 nwant = nleft; 268 iorequest.piod_addr = buf; 269 iorequest.piod_len = nwant; 270 ptrace(PT_IO, pid, (caddr_t)&iorequest, 0); 271 ngot = iorequest.piod_len; 272 if ((size_t)ngot < nwant) 273 errx(1, "short read wanted %zu, got %zd", 274 nwant, ngot); 275 ngot = write(fd, buf, nwant); 276 if (ngot == -1) 277 err(1, "write of segment %d failed", i); 278 if ((size_t)ngot != nwant) 279 errx(1, "short write"); 280 nleft -= nwant; 281 iorequest.piod_offs += ngot; 282 } 283 php++; 284 } 285 sbuf_delete(sb); 286 freemap(map); 287 } 288 289 /* 290 * A callback for each_dumpable_segment() to write out the segment's 291 * program header entry. 292 */ 293 static void 294 cb_put_phdr(struct map_entry *entry, void *closure) 295 { 296 struct phdr_closure *phc = (struct phdr_closure *)closure; 297 Elf_Phdr *phdr = phc->phdr; 298 size_t page_size; 299 300 page_size = getpagesize(); 301 phc->offset = roundup2(phc->offset, page_size); 302 303 phdr->p_type = PT_LOAD; 304 phdr->p_offset = phc->offset; 305 phdr->p_vaddr = entry->start; 306 phdr->p_paddr = 0; 307 phdr->p_filesz = phdr->p_memsz = entry->end - entry->start; 308 phdr->p_align = page_size; 309 phdr->p_flags = 0; 310 if (entry->protection & VM_PROT_READ) 311 phdr->p_flags |= PF_R; 312 if (entry->protection & VM_PROT_WRITE) 313 phdr->p_flags |= PF_W; 314 if (entry->protection & VM_PROT_EXECUTE) 315 phdr->p_flags |= PF_X; 316 317 phc->offset += phdr->p_filesz; 318 phc->phdr++; 319 } 320 321 /* 322 * A callback for each_dumpable_segment() to gather information about 323 * the number of segments and their total size. 324 */ 325 static void 326 cb_size_segment(struct map_entry *entry, void *closure) 327 { 328 struct sseg_closure *ssc = (struct sseg_closure *)closure; 329 330 ssc->count++; 331 ssc->size += entry->end - entry->start; 332 } 333 334 /* 335 * For each segment in the given memory map, call the given function 336 * with a pointer to the map entry and some arbitrary caller-supplied 337 * data. 338 */ 339 static void 340 each_dumpable_segment(struct map_entry *map, segment_callback func, 341 void *closure) 342 { 343 struct map_entry *entry; 344 345 for (entry = map; entry != NULL; entry = entry->next) 346 (*func)(entry, closure); 347 } 348 349 static void 350 elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep) 351 { 352 lwpid_t *tids; 353 size_t threads, old_len; 354 ssize_t size; 355 int i; 356 357 errno = 0; 358 threads = ptrace(PT_GETNUMLWPS, pid, NULL, 0); 359 if (errno) 360 err(1, "PT_GETNUMLWPS"); 361 tids = malloc(threads * sizeof(*tids)); 362 if (tids == NULL) 363 errx(1, "out of memory"); 364 errno = 0; 365 ptrace(PT_GETLWPLIST, pid, (void *)tids, threads); 366 if (errno) 367 err(1, "PT_GETLWPLIST"); 368 369 sbuf_start_section(sb, &old_len); 370 elf_putnote(NT_PRPSINFO, elf_note_prpsinfo, &pid, sb); 371 372 for (i = 0; i < threads; ++i) { 373 elf_putregnote(NT_PRSTATUS, tids[i], sb); 374 elf_putregnote(NT_FPREGSET, tids[i], sb); 375 elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb); 376 elf_putnote(NT_PTLWPINFO, elf_note_ptlwpinfo, tids + i, sb); 377 #if defined(__aarch64__) || defined(__arm__) 378 elf_putregnote(NT_ARM_TLS, tids[i], sb); 379 #endif 380 #if (defined(ELFCORE_COMPAT_32) && defined(__aarch64__)) || defined(__arm__) 381 elf_putregnote(NT_ARM_VFP, tids[i], sb); 382 #endif 383 #if defined(__i386__) || defined(__amd64__) 384 elf_putregnote(NT_X86_SEGBASES, tids[i], sb); 385 elf_putnote(NT_X86_XSTATE, elf_note_x86_xstate, tids + i, sb); 386 #endif 387 #if defined(__powerpc__) 388 elf_putnote(NT_PPC_VMX, elf_note_powerpc_vmx, tids + i, sb); 389 #ifndef __SPE__ 390 elf_putnote(NT_PPC_VSX, elf_note_powerpc_vsx, tids + i, sb); 391 #endif 392 #endif 393 } 394 395 #ifndef ELFCORE_COMPAT_32 396 elf_putnote(NT_PROCSTAT_PROC, elf_note_procstat_proc, &pid, sb); 397 elf_putnote(NT_PROCSTAT_FILES, elf_note_procstat_files, &pid, sb); 398 elf_putnote(NT_PROCSTAT_VMMAP, elf_note_procstat_vmmap, &pid, sb); 399 elf_putnote(NT_PROCSTAT_GROUPS, elf_note_procstat_groups, &pid, sb); 400 elf_putnote(NT_PROCSTAT_UMASK, elf_note_procstat_umask, &pid, sb); 401 elf_putnote(NT_PROCSTAT_RLIMIT, elf_note_procstat_rlimit, &pid, sb); 402 elf_putnote(NT_PROCSTAT_OSREL, elf_note_procstat_osrel, &pid, sb); 403 elf_putnote(NT_PROCSTAT_PSSTRINGS, elf_note_procstat_psstrings, &pid, 404 sb); 405 elf_putnote(NT_PROCSTAT_AUXV, elf_note_procstat_auxv, &pid, sb); 406 #endif 407 408 size = sbuf_end_section(sb, old_len, 1, 0); 409 if (size == -1) 410 err(1, "sbuf_end_section"); 411 free(tids); 412 *sizep = size; 413 } 414 415 /* 416 * Emit one register set note section to sbuf. 417 */ 418 static void 419 elf_putregnote(int type, lwpid_t tid, struct sbuf *sb) 420 { 421 Elf_Note note; 422 struct iovec iov; 423 ssize_t old_len; 424 425 iov.iov_base = NULL; 426 iov.iov_len = 0; 427 if (ptrace(PT_GETREGSET, tid, (void *)&iov, type) != 0) 428 return; 429 iov.iov_base = calloc(1, iov.iov_len); 430 if (iov.iov_base == NULL) 431 errx(1, "out of memory"); 432 if (ptrace(PT_GETREGSET, tid, (void *)&iov, type) != 0) 433 errx(1, "failed to fetch register set %d", type); 434 435 note.n_namesz = 8; /* strlen("FreeBSD") + 1 */ 436 note.n_descsz = iov.iov_len; 437 note.n_type = type; 438 439 sbuf_bcat(sb, ¬e, sizeof(note)); 440 sbuf_start_section(sb, &old_len); 441 sbuf_bcat(sb, "FreeBSD", note.n_namesz); 442 sbuf_end_section(sb, old_len, sizeof(Elf32_Size), 0); 443 sbuf_start_section(sb, &old_len); 444 sbuf_bcat(sb, iov.iov_base, iov.iov_len); 445 sbuf_end_section(sb, old_len, sizeof(Elf32_Size), 0); 446 free(iov.iov_base); 447 } 448 449 /* 450 * Emit one note section to sbuf. 451 */ 452 static void 453 elf_putnote(int type, notefunc_t notefunc, void *arg, struct sbuf *sb) 454 { 455 Elf_Note note; 456 size_t descsz; 457 ssize_t old_len; 458 void *desc; 459 460 desc = notefunc(arg, &descsz); 461 note.n_namesz = 8; /* strlen("FreeBSD") + 1 */ 462 note.n_descsz = descsz; 463 note.n_type = type; 464 465 sbuf_bcat(sb, ¬e, sizeof(note)); 466 sbuf_start_section(sb, &old_len); 467 sbuf_bcat(sb, "FreeBSD", note.n_namesz); 468 sbuf_end_section(sb, old_len, sizeof(Elf32_Size), 0); 469 if (descsz == 0) 470 return; 471 sbuf_start_section(sb, &old_len); 472 sbuf_bcat(sb, desc, descsz); 473 sbuf_end_section(sb, old_len, sizeof(Elf32_Size), 0); 474 free(desc); 475 } 476 477 /* 478 * Generate the ELF coredump header. 479 */ 480 static void 481 elf_puthdr(int efd, pid_t pid, struct map_entry *map, void *hdr, size_t hdrsize, 482 size_t notesz, size_t segoff, int numsegs) 483 { 484 Elf_Ehdr *ehdr, binhdr; 485 Elf_Phdr *phdr; 486 Elf_Shdr *shdr; 487 struct phdr_closure phc; 488 ssize_t cnt; 489 490 cnt = read(efd, &binhdr, sizeof(binhdr)); 491 if (cnt < 0) 492 err(1, "Failed to re-read ELF header"); 493 else if (cnt != sizeof(binhdr)) 494 errx(1, "Failed to re-read ELF header"); 495 496 ehdr = (Elf_Ehdr *)hdr; 497 498 ehdr->e_ident[EI_MAG0] = ELFMAG0; 499 ehdr->e_ident[EI_MAG1] = ELFMAG1; 500 ehdr->e_ident[EI_MAG2] = ELFMAG2; 501 ehdr->e_ident[EI_MAG3] = ELFMAG3; 502 ehdr->e_ident[EI_CLASS] = ELF_CLASS; 503 ehdr->e_ident[EI_DATA] = ELF_DATA; 504 ehdr->e_ident[EI_VERSION] = EV_CURRENT; 505 ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 506 ehdr->e_ident[EI_ABIVERSION] = 0; 507 ehdr->e_ident[EI_PAD] = 0; 508 ehdr->e_type = ET_CORE; 509 ehdr->e_machine = binhdr.e_machine; 510 ehdr->e_version = EV_CURRENT; 511 ehdr->e_entry = 0; 512 ehdr->e_phoff = sizeof(Elf_Ehdr); 513 ehdr->e_flags = binhdr.e_flags; 514 ehdr->e_ehsize = sizeof(Elf_Ehdr); 515 ehdr->e_phentsize = sizeof(Elf_Phdr); 516 ehdr->e_shentsize = sizeof(Elf_Shdr); 517 ehdr->e_shstrndx = SHN_UNDEF; 518 if (numsegs + 1 < PN_XNUM) { 519 ehdr->e_phnum = numsegs + 1; 520 ehdr->e_shnum = 0; 521 } else { 522 ehdr->e_phnum = PN_XNUM; 523 ehdr->e_shnum = 1; 524 525 ehdr->e_shoff = ehdr->e_phoff + 526 (numsegs + 1) * ehdr->e_phentsize; 527 528 shdr = (Elf_Shdr *)((char *)hdr + ehdr->e_shoff); 529 memset(shdr, 0, sizeof(*shdr)); 530 /* 531 * A special first section is used to hold large segment and 532 * section counts. This was proposed by Sun Microsystems in 533 * Solaris and has been adopted by Linux; the standard ELF 534 * tools are already familiar with the technique. 535 * 536 * See table 7-7 of the Solaris "Linker and Libraries Guide" 537 * (or 12-7 depending on the version of the document) for more 538 * details. 539 */ 540 shdr->sh_type = SHT_NULL; 541 shdr->sh_size = ehdr->e_shnum; 542 shdr->sh_link = ehdr->e_shstrndx; 543 shdr->sh_info = numsegs + 1; 544 } 545 546 /* 547 * Fill in the program header entries. 548 */ 549 phdr = (Elf_Phdr *)((char *)hdr + ehdr->e_phoff); 550 551 /* The note segment. */ 552 phdr->p_type = PT_NOTE; 553 phdr->p_offset = hdrsize; 554 phdr->p_vaddr = 0; 555 phdr->p_paddr = 0; 556 phdr->p_filesz = notesz; 557 phdr->p_memsz = 0; 558 phdr->p_flags = PF_R; 559 phdr->p_align = sizeof(Elf32_Size); 560 phdr++; 561 562 /* All the writable segments from the program. */ 563 phc.phdr = phdr; 564 phc.offset = segoff; 565 each_dumpable_segment(map, cb_put_phdr, &phc); 566 } 567 568 /* 569 * Free the memory map. 570 */ 571 static void 572 freemap(struct map_entry *map) 573 { 574 struct map_entry *next; 575 576 while (map != NULL) { 577 next = map->next; 578 free(map); 579 map = next; 580 } 581 } 582 583 /* 584 * Read the process's memory map using kinfo_getvmmap(), and return a list of 585 * VM map entries. Only the non-device read/writable segments are 586 * returned. The map entries in the list aren't fully filled in; only 587 * the items we need are present. 588 */ 589 static struct map_entry * 590 readmap(pid_t pid) 591 { 592 struct map_entry *ent, **linkp, *map; 593 struct kinfo_vmentry *vmentl, *kve; 594 int i, nitems; 595 596 vmentl = kinfo_getvmmap(pid, &nitems); 597 if (vmentl == NULL) 598 err(1, "cannot retrieve mappings for %u process", pid); 599 600 map = NULL; 601 linkp = ↦ 602 for (i = 0; i < nitems; i++) { 603 kve = &vmentl[i]; 604 605 /* 606 * Ignore 'malformed' segments or ones representing memory 607 * mapping with MAP_NOCORE on. 608 * If the 'full' support is disabled, just dump the most 609 * meaningful data segments. 610 */ 611 if ((kve->kve_protection & KVME_PROT_READ) == 0 || 612 (kve->kve_flags & KVME_FLAG_NOCOREDUMP) != 0 || 613 kve->kve_type == KVME_TYPE_DEAD || 614 kve->kve_type == KVME_TYPE_UNKNOWN || 615 ((pflags & PFLAGS_FULL) == 0 && 616 kve->kve_type != KVME_TYPE_DEFAULT && 617 kve->kve_type != KVME_TYPE_VNODE && 618 kve->kve_type != KVME_TYPE_SWAP && 619 kve->kve_type != KVME_TYPE_PHYS)) 620 continue; 621 622 ent = calloc(1, sizeof(*ent)); 623 if (ent == NULL) 624 errx(1, "out of memory"); 625 ent->start = (vm_offset_t)kve->kve_start; 626 ent->end = (vm_offset_t)kve->kve_end; 627 ent->protection = VM_PROT_READ; 628 if ((kve->kve_protection & KVME_PROT_WRITE) != 0) 629 ent->protection |= VM_PROT_WRITE; 630 if ((kve->kve_protection & KVME_PROT_EXEC) != 0) 631 ent->protection |= VM_PROT_EXECUTE; 632 633 *linkp = ent; 634 linkp = &ent->next; 635 } 636 free(vmentl); 637 return (map); 638 } 639 640 /* 641 * Miscellaneous note out functions. 642 */ 643 644 static void * 645 elf_note_prpsinfo(void *arg, size_t *sizep) 646 { 647 char *cp, *end; 648 pid_t pid; 649 elfcore_prpsinfo_t *psinfo; 650 struct kinfo_proc kip; 651 size_t len; 652 int name[4]; 653 654 pid = *(pid_t *)arg; 655 psinfo = calloc(1, sizeof(*psinfo)); 656 if (psinfo == NULL) 657 errx(1, "out of memory"); 658 psinfo->pr_version = PRPSINFO_VERSION; 659 psinfo->pr_psinfosz = sizeof(*psinfo); 660 661 name[0] = CTL_KERN; 662 name[1] = KERN_PROC; 663 name[2] = KERN_PROC_PID; 664 name[3] = pid; 665 len = sizeof(kip); 666 if (sysctl(name, 4, &kip, &len, NULL, 0) == -1) 667 err(1, "kern.proc.pid.%u", pid); 668 if (kip.ki_pid != pid) 669 err(1, "kern.proc.pid.%u", pid); 670 strlcpy(psinfo->pr_fname, kip.ki_comm, sizeof(psinfo->pr_fname)); 671 name[2] = KERN_PROC_ARGS; 672 len = sizeof(psinfo->pr_psargs) - 1; 673 if (sysctl(name, 4, psinfo->pr_psargs, &len, NULL, 0) == 0 && len > 0) { 674 cp = psinfo->pr_psargs; 675 end = cp + len - 1; 676 for (;;) { 677 cp = memchr(cp, '\0', end - cp); 678 if (cp == NULL) 679 break; 680 *cp = ' '; 681 } 682 } else 683 strlcpy(psinfo->pr_psargs, kip.ki_comm, 684 sizeof(psinfo->pr_psargs)); 685 psinfo->pr_pid = pid; 686 687 *sizep = sizeof(*psinfo); 688 return (psinfo); 689 } 690 691 static void * 692 elf_note_thrmisc(void *arg, size_t *sizep) 693 { 694 lwpid_t tid; 695 struct ptrace_lwpinfo lwpinfo; 696 thrmisc_t *thrmisc; 697 698 tid = *(lwpid_t *)arg; 699 thrmisc = calloc(1, sizeof(*thrmisc)); 700 if (thrmisc == NULL) 701 errx(1, "out of memory"); 702 ptrace(PT_LWPINFO, tid, (void *)&lwpinfo, 703 sizeof(lwpinfo)); 704 memset(&thrmisc->_pad, 0, sizeof(thrmisc->_pad)); 705 strcpy(thrmisc->pr_tname, lwpinfo.pl_tdname); 706 707 *sizep = sizeof(*thrmisc); 708 return (thrmisc); 709 } 710 711 static void * 712 elf_note_ptlwpinfo(void *arg, size_t *sizep) 713 { 714 lwpid_t tid; 715 elfcore_lwpinfo_t *elf_info; 716 struct ptrace_lwpinfo lwpinfo; 717 void *p; 718 719 tid = *(lwpid_t *)arg; 720 p = calloc(1, sizeof(int) + sizeof(elfcore_lwpinfo_t)); 721 if (p == NULL) 722 errx(1, "out of memory"); 723 *(int *)p = sizeof(elfcore_lwpinfo_t); 724 elf_info = (void *)((int *)p + 1); 725 ptrace(PT_LWPINFO, tid, (void *)&lwpinfo, sizeof(lwpinfo)); 726 elf_convert_lwpinfo(elf_info, &lwpinfo); 727 728 *sizep = sizeof(int) + sizeof(struct ptrace_lwpinfo); 729 return (p); 730 } 731 732 #if defined(__i386__) || defined(__amd64__) 733 static void * 734 elf_note_x86_xstate(void *arg, size_t *sizep) 735 { 736 lwpid_t tid; 737 char *xstate; 738 static bool xsave_checked = false; 739 static struct ptrace_xstate_info info; 740 741 tid = *(lwpid_t *)arg; 742 if (!xsave_checked) { 743 if (ptrace(PT_GETXSTATE_INFO, tid, (void *)&info, 744 sizeof(info)) != 0) 745 info.xsave_len = 0; 746 xsave_checked = true; 747 } 748 if (info.xsave_len == 0) { 749 *sizep = 0; 750 return (NULL); 751 } 752 xstate = calloc(1, info.xsave_len); 753 ptrace(PT_GETXSTATE, tid, xstate, 0); 754 *(uint64_t *)(xstate + X86_XSTATE_XCR0_OFFSET) = info.xsave_mask; 755 *sizep = info.xsave_len; 756 return (xstate); 757 } 758 #endif 759 760 #if defined(__powerpc__) 761 static void * 762 elf_note_powerpc_vmx(void *arg, size_t *sizep) 763 { 764 lwpid_t tid; 765 struct vmxreg *vmx; 766 static bool has_vmx = true; 767 struct vmxreg info; 768 769 tid = *(lwpid_t *)arg; 770 if (has_vmx) { 771 if (ptrace(PT_GETVRREGS, tid, (void *)&info, 772 sizeof(info)) != 0) 773 has_vmx = false; 774 } 775 if (!has_vmx) { 776 *sizep = 0; 777 return (NULL); 778 } 779 vmx = calloc(1, sizeof(*vmx)); 780 memcpy(vmx, &info, sizeof(*vmx)); 781 *sizep = sizeof(*vmx); 782 return (vmx); 783 } 784 785 static void * 786 elf_note_powerpc_vsx(void *arg, size_t *sizep) 787 { 788 lwpid_t tid; 789 char *vshr_data; 790 static bool has_vsx = true; 791 uint64_t vshr[32]; 792 793 tid = *(lwpid_t *)arg; 794 if (has_vsx) { 795 if (ptrace(PT_GETVSRREGS, tid, (void *)vshr, 796 sizeof(vshr)) != 0) 797 has_vsx = false; 798 } 799 if (!has_vsx) { 800 *sizep = 0; 801 return (NULL); 802 } 803 vshr_data = calloc(1, sizeof(vshr)); 804 memcpy(vshr_data, vshr, sizeof(vshr)); 805 *sizep = sizeof(vshr); 806 return (vshr_data); 807 } 808 #endif 809 810 static void * 811 procstat_sysctl(void *arg, int what, size_t structsz, size_t *sizep) 812 { 813 size_t len; 814 pid_t pid; 815 int name[4], structsize; 816 void *buf, *p; 817 818 pid = *(pid_t *)arg; 819 structsize = structsz; 820 name[0] = CTL_KERN; 821 name[1] = KERN_PROC; 822 name[2] = what; 823 name[3] = pid; 824 len = 0; 825 if (sysctl(name, 4, NULL, &len, NULL, 0) == -1) 826 err(1, "kern.proc.%d.%u", what, pid); 827 buf = calloc(1, sizeof(structsize) + len * 4 / 3); 828 if (buf == NULL) 829 errx(1, "out of memory"); 830 bcopy(&structsize, buf, sizeof(structsize)); 831 p = (char *)buf + sizeof(structsize); 832 if (sysctl(name, 4, p, &len, NULL, 0) == -1) 833 err(1, "kern.proc.%d.%u", what, pid); 834 835 *sizep = sizeof(structsize) + len; 836 return (buf); 837 } 838 839 static void * 840 elf_note_procstat_proc(void *arg, size_t *sizep) 841 { 842 843 return (procstat_sysctl(arg, KERN_PROC_PID | KERN_PROC_INC_THREAD, 844 sizeof(struct kinfo_proc), sizep)); 845 } 846 847 static void * 848 elf_note_procstat_files(void *arg, size_t *sizep) 849 { 850 851 return (procstat_sysctl(arg, KERN_PROC_FILEDESC, 852 sizeof(struct kinfo_file), sizep)); 853 } 854 855 static void * 856 elf_note_procstat_vmmap(void *arg, size_t *sizep) 857 { 858 859 return (procstat_sysctl(arg, KERN_PROC_VMMAP, 860 sizeof(struct kinfo_vmentry), sizep)); 861 } 862 863 static void * 864 elf_note_procstat_groups(void *arg, size_t *sizep) 865 { 866 867 return (procstat_sysctl(arg, KERN_PROC_GROUPS, sizeof(gid_t), sizep)); 868 } 869 870 static void * 871 elf_note_procstat_umask(void *arg, size_t *sizep) 872 { 873 874 return (procstat_sysctl(arg, KERN_PROC_UMASK, sizeof(u_short), sizep)); 875 } 876 877 static void * 878 elf_note_procstat_osrel(void *arg, size_t *sizep) 879 { 880 881 return (procstat_sysctl(arg, KERN_PROC_OSREL, sizeof(int), sizep)); 882 } 883 884 static void * 885 elf_note_procstat_psstrings(void *arg, size_t *sizep) 886 { 887 888 return (procstat_sysctl(arg, KERN_PROC_PS_STRINGS, 889 sizeof(vm_offset_t), sizep)); 890 } 891 892 static void * 893 elf_note_procstat_auxv(void *arg, size_t *sizep) 894 { 895 896 return (procstat_sysctl(arg, KERN_PROC_AUXV, 897 sizeof(Elf_Auxinfo), sizep)); 898 } 899 900 static void * 901 elf_note_procstat_rlimit(void *arg, size_t *sizep) 902 { 903 pid_t pid; 904 size_t len; 905 int i, name[5], structsize; 906 void *buf, *p; 907 908 pid = *(pid_t *)arg; 909 structsize = sizeof(struct rlimit) * RLIM_NLIMITS; 910 buf = calloc(1, sizeof(structsize) + structsize); 911 if (buf == NULL) 912 errx(1, "out of memory"); 913 bcopy(&structsize, buf, sizeof(structsize)); 914 p = (char *)buf + sizeof(structsize); 915 name[0] = CTL_KERN; 916 name[1] = KERN_PROC; 917 name[2] = KERN_PROC_RLIMIT; 918 name[3] = pid; 919 len = sizeof(struct rlimit); 920 for (i = 0; i < RLIM_NLIMITS; i++) { 921 name[4] = i; 922 if (sysctl(name, 5, p, &len, NULL, 0) == -1) 923 err(1, "kern.proc.rlimit.%u", pid); 924 if (len != sizeof(struct rlimit)) 925 errx(1, "kern.proc.rlimit.%u: short read", pid); 926 p += len; 927 } 928 929 *sizep = sizeof(structsize) + structsize; 930 return (buf); 931 } 932 933 struct dumpers __elfN(dump) = { elf_ident, elf_coredump }; 934 TEXT_SET(dumpset, __elfN(dump)); 935