PERFORCE change 101472 for review

Howard Su howardsu at FreeBSD.org
Thu Jul 13 14:55:47 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=101472

Change 101472 by howardsu at su_laptop on 2006/07/13 14:55:15

	Implement SDT in kernel module.
	Add proc:::exec sdt probe as a sample.
	
	I need help to implement other probes as in solaris.

Affected files ...

.. //depot/projects/dtrace/src/sys/cddl/dev/sdt/sdt.c#5 edit
.. //depot/projects/dtrace/src/sys/cddl/dev/sdt/sdt_subr.c#2 edit
.. //depot/projects/dtrace/src/sys/conf/kern.mk#6 edit
.. //depot/projects/dtrace/src/sys/i386/i386/elf_machdep.c#4 edit
.. //depot/projects/dtrace/src/sys/kern/kern_exec.c#5 edit
.. //depot/projects/dtrace/src/sys/kern/link_elf.c#6 edit
.. //depot/projects/dtrace/src/sys/sys/sdt.h#5 edit

Differences ...

==== //depot/projects/dtrace/src/sys/cddl/dev/sdt/sdt.c#5 (text+ko) ====

@@ -285,6 +285,7 @@
 			sdt_probetab[ndx] = sdt->sdp_hashnext;
 		}
 
+		free(sdt->sdp_name, M_SDT);
 		next = sdt->sdp_next;
 		free(sdt, M_SDT);
 

==== //depot/projects/dtrace/src/sys/cddl/dev/sdt/sdt_subr.c#2 (text+ko) ====

@@ -89,7 +89,7 @@
 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
 };
-
+*/
 static dtrace_pattr_t stab_attr = {
 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
@@ -97,7 +97,7 @@
 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
 };
-*/
+
 static dtrace_pattr_t sdt_attr = {
 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
@@ -107,6 +107,7 @@
 };
 
 sdt_provider_t sdt_providers[] = {
+    { "proc", "__proc_", &stab_attr, 0 },
   /*	{ "vtrace", "__vtrace_", &vtrace_attr, 0 },
 	{ "sysinfo", "__cpu_sysinfo_", &info_attr, 0 },
 	{ "vminfo", "__cpu_vminfo_", &info_attr, 0 },

==== //depot/projects/dtrace/src/sys/conf/kern.mk#6 (text+ko) ====

@@ -10,7 +10,7 @@
 #CWARNFLAGS=	-w2	# use this if you are terribly bored
 CWARNFLAGS=
 .else
-CWARNFLAGS?=	-Wall -Wredundant-decls -Wstrict-prototypes \
+CWARNFLAGS?=	-Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes \
 		-Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual \
 		${_wundef} -fformat-extensions
 .if !defined(NO_UNDEF)

==== //depot/projects/dtrace/src/sys/i386/i386/elf_machdep.c#4 (text+ko) ====

@@ -34,6 +34,7 @@
 #include <sys/linker.h>
 #include <sys/sysent.h>
 #include <sys/imgact_elf.h>
+#include <sys/sdt.h>
 #include <sys/syscall.h>
 #include <sys/signalvar.h>
 #include <sys/vnode.h>
@@ -222,7 +223,6 @@
 int
 elf_cpu_load_file(linker_file_t lf __unused)
 {
-
 	return (0);
 }
 
@@ -235,16 +235,18 @@
 
 #define SDT_NOP 0x90
 #define SDT_NOPS 5
+#define SDT_SIZEOF_CALL 5
 
 int
 sdt_reloc_resolve(uint8_t *instr, sdt_probedesc_t *sdp)
 {
-  int i;
-  sdp->sdpd_offset = (uintptr_t)instr;
- 
-  for(i = 0; i < SDT_NOPS; i++) {
-	instr[i - 1] = SDT_NOP;
-  }
+  	int i;
+	instr -= SDT_SIZEOF_CALL;
+	sdp->sdpd_offset = (uintptr_t)instr;
+ 	
+	for(i = 0; i < SDT_NOPS; i++) {
+		instr[i] = SDT_NOP;
+  	}
 
-  return (1);
+	return (1);
 }

==== //depot/projects/dtrace/src/sys/kern/kern_exec.c#5 (text+ko) ====

@@ -54,6 +54,7 @@
 #include <sys/namei.h>
 #include <sys/resourcevar.h>
 #include <sys/sf_buf.h>
+#include <sys/sdt.h>
 #include <sys/syscallsubr.h>
 #include <sys/sysent.h>
 #include <sys/shm.h>
@@ -345,6 +346,7 @@
 	if (error)
 		goto exec_fail;
 #endif
+	DTRACE_PROBE1(__proc_exec, char *, imgp->interpreter_name);
 
 	imgp->image_header = NULL;
 

==== //depot/projects/dtrace/src/sys/kern/link_elf.c#6 (text+ko) ====

@@ -225,6 +225,40 @@
     printf("kldload: %s\n", s);
 }
 
+static void
+elf_sdt_hook_sweep(linker_file_t lf)
+{
+	sdt_probedesc_t *sdp;
+	elf_file_t ef = (elf_file_t)lf;
+	const Elf_Sym* symp;
+	linker_symval_t symval;
+	int i;
+	uint8_t *instr;
+	const char *symname;
+
+	for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
+		if (symp->st_value != 0 && 
+			ELF_ST_TYPE(symp->st_info) == STT_NOTYPE) {
+				link_elf_symbol_values(lf, (c_linker_sym_t)symp, &symval);
+				if (strncmp(symval.name, sdt_prefix, strlen(sdt_prefix)) == 0) {
+					instr = (uint8_t *)symval.value;
+					symname = symval.name;
+					symname += strlen(sdt_prefix);
+					sdp = malloc(sizeof(sdt_probedesc_t), M_LINKER, M_WAITOK);
+					sdp->sdpd_name = malloc(strlen(symname) + 1, M_LINKER, M_WAITOK);
+					strcpy(sdp->sdpd_name, symname);
+					if (sdt_reloc_resolve(instr, sdp)) {
+						sdp->sdpd_next = lf->sdt_probes;
+						lf->sdt_probes = sdp;
+					}else{
+						free(sdp->sdpd_name, M_LINKER);
+						free(sdp, M_LINKER);
+					}
+				}
+			}
+	}
+}
+
 /*
  * Actions performed after linking/loading both the preloaded kernel and any
  * modules; whether preloaded or dynamicly loaded.
@@ -238,10 +272,11 @@
 #endif
     int error;
 
+	elf_sdt_hook_sweep(lf);
     /* Notify MD code that a module is being loaded. */
     error = elf_cpu_load_file(lf);
     if (error)
-	return (error);
+		return (error);
 
 #ifdef GDB
     GDB_STATE(RT_ADD);
@@ -931,29 +966,6 @@
 }
 
 static int
-sdt_reloc_check(linker_file_t lf, const char *symname, uint8_t * instr)
-{
-    sdt_probedesc_t *sdp;
-    if (strncmp(symname, sdt_prefix, strlen(sdt_prefix)) != 0)
-        return (0);
-
-    symname += strlen(sdt_prefix);
-    sdp = malloc(sizeof(sdt_probedesc_t), M_LINKER, M_WAITOK);
-    sdp->sdpd_name = malloc(strlen(symname) + 1, M_LINKER, M_WAITOK);
-    strcpy(sdp->sdpd_name, symname);
-
-    if (sdt_reloc_resolve(instr, sdp)) {
-        sdp->sdpd_next = lf->sdt_probes;
-        lf->sdt_probes = sdp;
-        return (1);
-    } else {
-        free(sdp->sdpd_name, M_LINKER);
-        free(sdp, M_LINKER);
-        return (0);
-    }
-}
-
-static int
 relocate_file(elf_file_t ef)
 {
     const Elf_Rel *rellim;
@@ -969,12 +981,9 @@
 	while (rel < rellim) {
 	    if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL,
 			  elf_lookup)) {
-		symname = symbol_name(ef, rel->r_info);
-		if (!sdt_reloc_check(&ef->lf, symname,
-                  (uint8_t *) (ef->address + rel->r_offset))) {
+			symname = symbol_name(ef, rel->r_info);
 			printf("link_elf: symbol %s undefined\n", symname);
 			return ENOENT;
-		}
 	    }
 	    rel++;
 	}
@@ -1388,3 +1397,30 @@
 	}
     }
 }
+
+void
+dtrace_sdt_stub0(void)
+{
+}
+
+void
+dtrace_sdt_stub1(uintptr_t arg1 __unused)
+{
+}
+
+void
+dtrace_sdt_stub2(uintptr_t arg1 __unused, uintptr_t arg2 __unused)
+{
+}
+
+void
+dtrace_sdt_stub3(uintptr_t arg1 __unused, uintptr_t arg2 __unused, uintptr_t arg3 __unused)
+{
+}
+
+void
+dtrace_sdt_stub4(uintptr_t arg1 __unused, uintptr_t arg2 __unused, uintptr_t arg3 __unused,
+                    uintptr_t arg4 __unused)
+{
+}
+

==== //depot/projects/dtrace/src/sys/sys/sdt.h#5 (text+ko) ====

@@ -71,33 +71,42 @@
 
 #else /* _KERNEL */
 
+#define __SDT_LABEL(name) \
+	__asm__(".globl __dtrace_probe_" #name); \
+	__asm__("__dtrace_probe_"#name ":")
+
+extern void dtrace_sdt_stub0(void);
+extern void dtrace_sdt_stub1(uintptr_t);
+extern void dtrace_sdt_stub2(uintptr_t, uintptr_t);
+extern void dtrace_sdt_stub3(uintptr_t, uintptr_t, uintptr_t);
+extern void dtrace_sdt_stub4(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+
 #define	DTRACE_PROBE(name)	{					\
-	extern void __dtrace_probe_##name(void);			\
-	__dtrace_probe_##name();					\
+	dtrace_sdt_stub0();					\
+	__SDT_LABEL(name);							\
 }
 
 #define	DTRACE_PROBE1(name, type1, arg1) {				\
-	extern void __dtrace_probe_##name(uintptr_t);			\
-	__dtrace_probe_##name((uintptr_t)(arg1));			\
+	dtrace_sdt_stub1((uintptr_t)(arg1));			\
+	__SDT_LABEL(name);									\
 }
 
 #define	DTRACE_PROBE2(name, type1, arg1, type2, arg2) {			\
-	extern void __dtrace_probe_##name(uintptr_t, uintptr_t);	\
-	__dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2));	\
+	dtrace_sdt_stub2((uintptr_t)(arg1), (uintptr_t)(arg2));	\
+	__SDT_LABEL(name);											\
 }
 
 #define	DTRACE_PROBE3(name, type1, arg1, type2, arg2, type3, arg3) {	\
-	extern void __dtrace_probe_##name(uintptr_t, uintptr_t, uintptr_t); \
-	__dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2),	\
+	dtrace_sdt_stub3((uintptr_t)(arg1), (uintptr_t)(arg2),	\
 	    (uintptr_t)(arg3));						\
+	__SDT_LABEL(name);											\
 }
 
 #define	DTRACE_PROBE4(name, type1, arg1, type2, arg2, 			\
     type3, arg3, type4, arg4) {						\
-	extern void __dtrace_probe_##name(uintptr_t, uintptr_t,		\
-	    uintptr_t, uintptr_t);					\
-	__dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2),	\
+	dtrace_sdt_stub4((uintptr_t)(arg1), (uintptr_t)(arg2),	\
 	    (uintptr_t)(arg3), (uintptr_t)(arg4));			\
+	__SDT_LABEL(name);								\
 }
 
 #endif /* _KERNEL */
@@ -115,5 +124,3 @@
 #endif
 
 #endif	/* _SYS_SDT_H */
-
-


More information about the p4-projects mailing list