6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <assert.h>
28 #include <strings.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <errno.h>
32 #include <ctype.h>
33 #include <alloca.h>
34 #include <libgen.h>
35 #include <stddef.h>
36
37 #include <dt_impl.h>
38 #include <dt_program.h>
39 #include <dt_pid.h>
40 #include <dt_string.h>
41
42 typedef struct dt_pid_probe {
43 dtrace_hdl_t *dpp_dtp;
44 dt_pcb_t *dpp_pcb;
45 dt_proc_t *dpp_dpr;
46 struct ps_prochandle *dpp_pr;
47 const char *dpp_mod;
48 char *dpp_func;
49 const char *dpp_name;
50 const char *dpp_obj;
51 uintptr_t dpp_pc;
52 size_t dpp_size;
53 Lmid_t dpp_lmid;
54 uint_t dpp_nmatches;
55 uint64_t dpp_stret[4];
56 GElf_Sym dpp_last;
57 uint_t dpp_last_taken;
58 } dt_pid_probe_t;
59
60 /*
738 /*
739 * If it's not strictly a pid provider, we might match
740 * a USDT provider.
741 */
742 if (strcmp(provname, pdp->dtpd_provider) != 0 &&
743 dt_pid_create_usdt_probes(&pd, dtp, NULL, dpr) != 0)
744 ret = 1;
745 }
746 }
747
748 if (found) {
749 /*
750 * Give DTrace a shot to the ribs to get it to check
751 * out the newly created probes.
752 */
753 (void) dt_ioctl(dtp, DTRACEIOC_ENABLE, NULL);
754 }
755
756 return (ret);
757 }
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
28 */
29
30 #include <assert.h>
31 #include <strings.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <errno.h>
35 #include <ctype.h>
36 #include <alloca.h>
37 #include <libgen.h>
38 #include <stddef.h>
39 #include <sys/sysmacros.h>
40
41 #include <dt_impl.h>
42 #include <dt_program.h>
43 #include <dt_pid.h>
44 #include <dt_string.h>
45 #include <dt_module.h>
46
47 typedef struct dt_pid_probe {
48 dtrace_hdl_t *dpp_dtp;
49 dt_pcb_t *dpp_pcb;
50 dt_proc_t *dpp_dpr;
51 struct ps_prochandle *dpp_pr;
52 const char *dpp_mod;
53 char *dpp_func;
54 const char *dpp_name;
55 const char *dpp_obj;
56 uintptr_t dpp_pc;
57 size_t dpp_size;
58 Lmid_t dpp_lmid;
59 uint_t dpp_nmatches;
60 uint64_t dpp_stret[4];
61 GElf_Sym dpp_last;
62 uint_t dpp_last_taken;
63 } dt_pid_probe_t;
64
65 /*
743 /*
744 * If it's not strictly a pid provider, we might match
745 * a USDT provider.
746 */
747 if (strcmp(provname, pdp->dtpd_provider) != 0 &&
748 dt_pid_create_usdt_probes(&pd, dtp, NULL, dpr) != 0)
749 ret = 1;
750 }
751 }
752
753 if (found) {
754 /*
755 * Give DTrace a shot to the ribs to get it to check
756 * out the newly created probes.
757 */
758 (void) dt_ioctl(dtp, DTRACEIOC_ENABLE, NULL);
759 }
760
761 return (ret);
762 }
763
764 /*
765 * libdtrace has a backroom deal with us to ask us for type information on
766 * behalf of pid provider probes when fasttrap doesn't return any type
767 * information. Instead we'll look up the module and see if there is type
768 * information available. However, if there is no type information available due
769 * to a lack of CTF data, then we want to make sure that DTrace still carries on
770 * in face of that. As such we don't have a meaningful exit code about failure.
771 * We emit information about why we failed to the dtrace debug log so someone
772 * can figure it out by asking nicely for DTRACE_DEBUG.
773 */
774 void
775 dt_pid_get_types(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
776 dtrace_argdesc_t *adp, int *nargs)
777 {
778 dt_module_t *dmp;
779 ctf_file_t *fp;
780 ctf_funcinfo_t f;
781 ctf_id_t argv[32];
782 GElf_Sym sym;
783 prsyminfo_t si;
784 struct ps_prochandle *p;
785 int i, args;
786 char buf[DTRACE_ARGTYPELEN];
787 const char *mptr;
788 char *eptr;
789 int ret = 0;
790 int argc = sizeof (argv) / sizeof (ctf_id_t);
791 Lmid_t lmid;
792
793 /* Set up a potential outcome */
794 args = *nargs;
795 *nargs = 0;
796
797 /*
798 * If we don't have an entry or return probe then we can just stop right
799 * now as we don't have arguments for offset probes.
800 */
801 if (strcmp(pdp->dtpd_name, "entry") != 0 &&
802 strcmp(pdp->dtpd_name, "return") != 0)
803 return;
804
805 dmp = dt_module_create(dtp, pdp->dtpd_provider);
806 if (dmp == NULL) {
807 dt_dprintf("failed to find module for %s\n",
808 pdp->dtpd_provider);
809 return;
810 }
811 if (dt_module_load(dtp, dmp) != 0) {
812 dt_dprintf("failed to load module for %s\n",
813 pdp->dtpd_provider);
814 return;
815 }
816
817 /*
818 * We may be working with a module that doesn't have ctf. If that's the
819 * case then we just return now and move on with life.
820 */
821 fp = dt_module_getctflib(dtp, dmp, pdp->dtpd_mod);
822 if (fp == NULL) {
823 dt_dprintf("no ctf container for %s\n",
824 pdp->dtpd_mod);
825 return;
826 }
827 p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
828 if (p == NULL) {
829 dt_dprintf("failed to grab pid\n");
830 return;
831 }
832 dt_proc_lock(dtp, p);
833
834 /*
835 * Check to see if the D module has a link map ID and separate that out
836 * for properly interrogating libproc.
837 */
838 if ((mptr = strchr(pdp->dtpd_mod, '`')) != NULL) {
839 if (strlen(pdp->dtpd_mod) < 3) {
840 dt_dprintf("found weird modname with linkmap, "
841 "aborting: %s\n", pdp->dtpd_mod);
842 goto out;
843 }
844 if (pdp->dtpd_mod[0] != 'L' || pdp->dtpd_mod[1] != 'M') {
845 dt_dprintf("missing leading 'LM', "
846 "aborting: %s\n", pdp->dtpd_mod);
847 goto out;
848 }
849 errno = 0;
850 lmid = strtol(pdp->dtpd_mod + 2, &eptr, 16);
851 if (errno == ERANGE || eptr != mptr) {
852 dt_dprintf("failed to parse out lmid, aborting: %s\n",
853 pdp->dtpd_mod);
854 goto out;
855 }
856 mptr++;
857 } else {
858 mptr = pdp->dtpd_mod;
859 lmid = 0;
860 }
861
862 if (Pxlookup_by_name(p, lmid, mptr, pdp->dtpd_func,
863 &sym, &si) != 0) {
864 dt_dprintf("failed to find function %s in %s`%s\n",
865 pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
866 goto out;
867 }
868 if (ctf_func_info(fp, si.prs_id, &f) == CTF_ERR) {
869 dt_dprintf("failed to get ctf information for %s in %s`%s\n",
870 pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
871 goto out;
872 }
873
874 (void) snprintf(buf, sizeof (buf), "%s`%s", pdp->dtpd_provider,
875 pdp->dtpd_mod);
876
877 if (strcmp(pdp->dtpd_name, "return") == 0) {
878 if (args < 2)
879 goto out;
880
881 bzero(adp, sizeof (dtrace_argdesc_t));
882 adp->dtargd_ndx = 0;
883 adp->dtargd_id = pdp->dtpd_id;
884 adp->dtargd_mapping = adp->dtargd_ndx;
885 /*
886 * We explicitly leave out the library here, we only care that
887 * it is some int. We are assuming that there is no ctf
888 * container in here that is lying about what an int is.
889 */
890 (void) snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
891 "user %s`%s", pdp->dtpd_provider, "int");
892 adp++;
893 bzero(adp, sizeof (dtrace_argdesc_t));
894 adp->dtargd_ndx = 1;
895 adp->dtargd_id = pdp->dtpd_id;
896 adp->dtargd_mapping = adp->dtargd_ndx;
897 ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
898 "userland ");
899 (void) ctf_type_qname(fp, f.ctc_return, adp->dtargd_native +
900 ret, DTRACE_ARGTYPELEN - ret, buf);
901 *nargs = 2;
902 } else {
903 if (ctf_func_args(fp, si.prs_id, argc, argv) == CTF_ERR)
904 goto out;
905
906 *nargs = MIN(args, f.ctc_argc);
907 for (i = 0; i < *nargs; i++, adp++) {
908 bzero(adp, sizeof (dtrace_argdesc_t));
909 adp->dtargd_ndx = i;
910 adp->dtargd_id = pdp->dtpd_id;
911 adp->dtargd_mapping = adp->dtargd_ndx;
912 ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
913 "userland ");
914 (void) ctf_type_qname(fp, argv[i], adp->dtargd_native +
915 ret, DTRACE_ARGTYPELEN - ret, buf);
916 }
917 }
918 out:
919 dt_proc_unlock(dtp, p);
920 dt_proc_release(dtp, p);
921 }
|