1 /* $OpenBSD: fxproc0.c,v 1.2 2021/12/13 16:56:49 deraadt Exp $ */ 2 /* 3 * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/types.h> 19 #include <sys/signal.h> 20 #include <sys/proc.h> 21 #include <sys/user.h> 22 #include <machine/fpu.h> 23 #include <machine/pcb.h> 24 25 #include <err.h> 26 #include <fcntl.h> 27 #include <kvm.h> 28 #include <limits.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 33 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 34 35 void __dead usage(void); 36 void fenv_proc(kvm_t *, unsigned long); 37 38 void __dead 39 usage(void) 40 { 41 fprintf(stderr, "usage: %s [-M core] [-N system]\n", getprogname()); 42 exit(1); 43 } 44 45 int 46 main(int argc, char *argv[]) 47 { 48 char errbuf[_POSIX2_LINE_MAX]; 49 char *memf, *nlistf; 50 kvm_t *kd; 51 int ch; 52 struct nlist nl[] = { { .n_name = "_proc0" }, { .n_name = NULL } }; 53 54 memf = nlistf = NULL; 55 while ((ch = getopt(argc, argv, "M:N:")) != -1) { 56 switch(ch) { 57 case 'M': 58 memf = optarg; 59 break; 60 case 'N': 61 nlistf = optarg; 62 break; 63 default: 64 usage(); 65 } 66 } 67 argc -= optind; 68 argv += optind; 69 if (argc) 70 usage(); 71 72 kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); 73 if (kd == NULL) 74 errx(1, "kvm_openfiles: %s", errbuf); 75 if (kvm_nlist(kd, nl) == -1) 76 errx(1, "kvm_nlist: %s", kvm_geterr(kd)); 77 if (nl[0].n_type == 0) 78 errx(1, "name '%s' has type %d", nl[0].n_name, nl[0].n_type); 79 fenv_proc(kd, nl[0].n_value); 80 81 if (kvm_close(kd) == -1) 82 errx(1, "kvm_close: %s", kvm_geterr(kd)); 83 return 0; 84 } 85 86 void 87 fenv_proc(kvm_t *kd, unsigned long p) 88 { 89 struct proc proc; 90 struct user user; 91 struct fxsave64 *fxs = &user.u_pcb.pcb_savefpu.fp_fxsave; 92 size_t i; 93 94 if (kvm_read(kd, p, &proc, sizeof(proc)) == -1) 95 errx(1, "kvm_read proc: %s", kvm_geterr(kd)); 96 if (kvm_read(kd, (u_long)proc.p_addr, &user, sizeof(user)) == -1) 97 errx(1, "kvm_read user: %s", kvm_geterr(kd)); 98 99 if (fxs != &fxs->fx_fcw) 100 errx(1, "fxsave start %p, fx_fcw start %p", 101 &fxs, &fxs->fx_fcw); 102 printf("fcw\t%04x\n", fxs->fx_fcw); 103 printf("fsw\t%04x\n", fxs->fx_fsw); 104 printf("ftw\t%02x\n", fxs->fx_ftw); 105 printf("unused1\t%02x\n", fxs->fx_unused1); 106 printf("fop\t%04x\n", fxs->fx_fop); 107 printf("rip\t%016llx\n", fxs->fx_rip); 108 printf("rdp\t%016llx\n", fxs->fx_rdp); 109 printf("mxcsr\t%08x\n", fxs->fx_mxcsr); 110 printf("mxcsr_mask\t%08x\n", fxs->fx_mxcsr_mask); 111 if (&fxs->fx_mxcsr_mask + 1 != fxs->fx_st) 112 errx(1, "fx_mxcsr_mask end %p, fx_st start %p", 113 &fxs->fx_mxcsr_mask + 1, fxs->fx_st); 114 for (i = 0; i < nitems(fxs->fx_st); i++) 115 printf("st[%zu]\t%016llx:%016llx\n", i, 116 fxs->fx_st[i][1], fxs->fx_st[i][0]); 117 if (&fxs->fx_st[i] != fxs->fx_xmm) 118 errx(1, "fx_st end %p, fx_xmm start %p", 119 &fxs->fx_st[i], fxs->fx_xmm); 120 for (i = 0; i < nitems(fxs->fx_xmm); i++) 121 printf("xmm[%zu]\t%016llx:%016llx\n", i, 122 fxs->fx_xmm[i][1], fxs->fx_xmm[i][0]); 123 if (&fxs->fx_xmm[i] != fxs->fx_unused3) 124 errx(1, "fx_xmm end %p, fx_unused3 start %p", 125 &fxs->fx_xmm[i], fxs->fx_unused3); 126 for (i = 0; i < nitems(fxs->fx_unused3); i++) 127 printf("unused3[%zu]\t%02x\n", i, fxs->fx_unused3[i]); 128 if (&fxs->fx_unused3[i] != fxs + 1) 129 errx(1, "fx_unused3 end %p, fxsave end %p", 130 &fxs->fx_unused3[i], fxs + 1); 131 } 132