1 1.1 chs /* 2 1.1 chs * CDDL HEADER START 3 1.1 chs * 4 1.1 chs * The contents of this file are subject to the terms of the 5 1.1 chs * Common Development and Distribution License, Version 1.0 only 6 1.1 chs * (the "License"). You may not use this file except in compliance 7 1.1 chs * with the License. 8 1.1 chs * 9 1.1 chs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 1.1 chs * or http://www.opensolaris.org/os/licensing. 11 1.1 chs * See the License for the specific language governing permissions 12 1.1 chs * and limitations under the License. 13 1.1 chs * 14 1.1 chs * When distributing Covered Code, include this CDDL HEADER in each 15 1.1 chs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 1.1 chs * If applicable, add the following below this CDDL HEADER, with the 17 1.1 chs * fields enclosed by brackets "[]" replaced with your own identifying 18 1.1 chs * information: Portions Copyright [yyyy] [name of copyright owner] 19 1.1 chs * 20 1.1 chs * CDDL HEADER END 21 1.1 chs */ 22 1.1 chs /* 23 1.1 chs * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 1.1 chs * Use is subject to license terms. 25 1.1 chs * Copyright 2014 Howard Su 26 1.1 chs * Copyright 2015 George V. Neville-Neil 27 1.1 chs * Copyright 2015 Ruslan Bukin <br (at) bsdpad.com> 28 1.1 chs */ 29 1.1 chs 30 1.1 chs #pragma ident "%Z%%M% %I% %E% SMI" 31 1.1 chs 32 1.2 jmcneill #include <sys/ioctl.h> 33 1.2 jmcneill 34 1.1 chs #include <stdlib.h> 35 1.1 chs #include <assert.h> 36 1.1 chs #include <errno.h> 37 1.1 chs #include <string.h> 38 1.1 chs #include <libgen.h> 39 1.1 chs 40 1.1 chs #include <dt_impl.h> 41 1.1 chs #include <dt_pid.h> 42 1.1 chs 43 1.1 chs #if !defined(sun) 44 1.1 chs #include <libproc_compat.h> 45 1.1 chs #endif 46 1.1 chs 47 1.1 chs /*ARGSUSED*/ 48 1.1 chs int 49 1.1 chs dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, 50 1.1 chs fasttrap_probe_spec_t *ftp, const GElf_Sym *symp) 51 1.1 chs { 52 1.1 chs 53 1.1 chs ftp->ftps_type = DTFTP_ENTRY; 54 1.1 chs ftp->ftps_pc = (uintptr_t)symp->st_value; 55 1.1 chs ftp->ftps_size = (size_t)symp->st_size; 56 1.1 chs ftp->ftps_noffs = 1; 57 1.1 chs ftp->ftps_offs[0] = 0; 58 1.1 chs 59 1.1 chs if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { 60 1.1 chs dt_dprintf("fasttrap probe creation ioctl failed: %s\n", 61 1.1 chs strerror(errno)); 62 1.1 chs return (dt_set_errno(dtp, errno)); 63 1.1 chs } 64 1.1 chs 65 1.1 chs return (1); 66 1.1 chs } 67 1.1 chs 68 1.1 chs int 69 1.1 chs dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, 70 1.1 chs fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret) 71 1.1 chs { 72 1.1 chs 73 1.1 chs dt_dprintf("%s: unimplemented\n", __func__); 74 1.1 chs 75 1.1 chs return (DT_PROC_ERR); 76 1.1 chs } 77 1.1 chs 78 1.1 chs /*ARGSUSED*/ 79 1.1 chs int 80 1.1 chs dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, 81 1.1 chs fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off) 82 1.1 chs { 83 1.1 chs 84 1.1 chs if (!ALIGNED_POINTER(off, 4)) 85 1.1 chs return (DT_PROC_ALIGN); 86 1.1 chs 87 1.1 chs ftp->ftps_type = DTFTP_OFFSETS; 88 1.1 chs ftp->ftps_pc = (uintptr_t)symp->st_value; 89 1.1 chs ftp->ftps_size = (size_t)symp->st_size; 90 1.1 chs ftp->ftps_noffs = 1; 91 1.1 chs ftp->ftps_offs[0] = off; 92 1.1 chs 93 1.1 chs if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { 94 1.1 chs dt_dprintf("fasttrap probe creation ioctl failed: %s\n", 95 1.1 chs strerror(errno)); 96 1.1 chs return (dt_set_errno(dtp, errno)); 97 1.1 chs } 98 1.1 chs 99 1.1 chs return (1); 100 1.1 chs } 101 1.1 chs 102 1.1 chs /*ARGSUSED*/ 103 1.1 chs int 104 1.1 chs dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp, 105 1.1 chs fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern) 106 1.1 chs { 107 1.1 chs ulong_t i; 108 1.1 chs 109 1.1 chs ftp->ftps_type = DTFTP_OFFSETS; 110 1.1 chs ftp->ftps_pc = (uintptr_t)symp->st_value; 111 1.1 chs ftp->ftps_size = (size_t)symp->st_size; 112 1.1 chs ftp->ftps_noffs = 0; 113 1.1 chs 114 1.1 chs /* 115 1.1 chs * If we're matching against everything, just iterate through each 116 1.1 chs * instruction in the function, otherwise look for matching offset 117 1.1 chs * names by constructing the string and comparing it against the 118 1.1 chs * pattern. 119 1.1 chs */ 120 1.1 chs if (strcmp("*", pattern) == 0) { 121 1.1 chs for (i = 0; i < symp->st_size; i += 4) { 122 1.1 chs ftp->ftps_offs[ftp->ftps_noffs++] = i; 123 1.1 chs } 124 1.1 chs } else { 125 1.1 chs char name[sizeof (i) * 2 + 1]; 126 1.1 chs 127 1.1 chs for (i = 0; i < symp->st_size; i += 4) { 128 1.1 chs (void) sprintf(name, "%lx", i); 129 1.1 chs if (gmatch(name, pattern)) 130 1.1 chs ftp->ftps_offs[ftp->ftps_noffs++] = i; 131 1.1 chs } 132 1.1 chs } 133 1.1 chs 134 1.1 chs if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { 135 1.1 chs dt_dprintf("fasttrap probe creation ioctl failed: %s\n", 136 1.1 chs strerror(errno)); 137 1.1 chs return (dt_set_errno(dtp, errno)); 138 1.1 chs } 139 1.1 chs 140 1.1 chs return (ftp->ftps_noffs); 141 1.1 chs } 142