Date: Thu, 13 Jul 2006 14:55:46 GMT From: Howard Su <howardsu@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 101472 for review Message-ID: <200607131455.k6DEtkHH030181@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=101472 Change 101472 by howardsu@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 */ - -
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607131455.k6DEtkHH030181>