kernel: Remove kernel profiling bits.
authorSascha Wildner <saw@online.de>
Sat, 5 Jan 2019 17:58:10 +0000 (18:58 +0100)
committerSascha Wildner <saw@online.de>
Sat, 5 Jan 2019 18:06:04 +0000 (19:06 +0100)
It was broken on i386, is even more broken on x86_64 and isn't
worth fixing.

Discussed-with: dillon

32 files changed:
Makefile_upgrade.inc
lib/libc/gen/sysctl.3
share/man/man7/clocks.7
share/man/man7/vkernel.7
sys/conf/files
sys/conf/kern.post.mk
sys/conf/kern.pre.mk
sys/cpu/x86_64/include/asm.h
sys/cpu/x86_64/include/asmacros.h
sys/cpu/x86_64/include/db_machdep.h
sys/cpu/x86_64/include/profile.h
sys/kern/kern_clock.c
sys/kern/subr_prof.c
sys/libkern/mcount.c [deleted file]
sys/platform/pc64/conf/files
sys/platform/pc64/isa/prof_machdep.c [deleted file]
sys/platform/pc64/x86_64/machdep.c
sys/platform/pc64/x86_64/mp_machdep.c
sys/platform/pc64/x86_64/mptable.c
sys/platform/vkernel64/conf/Makefile
sys/platform/vkernel64/conf/files
sys/sys/gmon.h
sys/sys/kernel.h
sys/sys/sysctl.h
usr.sbin/Makefile
usr.sbin/config/config.8
usr.sbin/config/config.h
usr.sbin/config/main.c
usr.sbin/config/mkmakefile.c
usr.sbin/kgmon/Makefile [deleted file]
usr.sbin/kgmon/kgmon.8 [deleted file]
usr.sbin/kgmon/kgmon.c [deleted file]

index 9f101e6..d8499b4 100644 (file)
@@ -3445,6 +3445,8 @@ TO_REMOVE+=/usr/share/man/man2/sigstack.2.gz
 TO_REMOVE+=/usr/include/sys/input.h
 TO_REMOVE+=/usr/include/sys/linux_types.h
 TO_REMOVE+=/etc/devd/uath.conf
+TO_REMOVE+=/usr/sbin/kgmon
+TO_REMOVE+=/usr/share/man/man8/kgmon.8.gz
 
 .if !defined(WANT_INSTALLER)
 TO_REMOVE+=/usr/sbin/dfuibe_installer
index 06e2a58..494b88c 100644 (file)
@@ -28,7 +28,7 @@
 .\"    @(#)sysctl.3    8.4 (Berkeley) 5/9/95
 .\" $FreeBSD: src/lib/libc/gen/sysctl.3,v 1.33.2.13 2002/04/07 04:57:14 dd Exp $
 .\"
-.Dd April 21, 2018
+.Dd January 5, 2019
 .Dt SYSCTL 3
 .Os
 .Sh NAME
@@ -374,7 +374,6 @@ information.
 .It Dv KERN_OSTYPE Ta "string" Ta "no"
 .It Dv KERN_POSIX1 Ta "integer" Ta "no"
 .It Dv KERN_PROC Ta "struct kinfo_proc" Ta "no"
-.It Dv KERN_PROF Ta "node" Ta "not applicable"
 .It Dv KERN_SAVED_IDS Ta "integer" Ta "no"
 .It Dv KERN_SECURELVL Ta "integer" Ta "raise only"
 .It Dv KERN_VERSION Ta "string" Ta "no"
@@ -488,46 +487,6 @@ A process ID of
 .Li \-1
 implies the current process.
 .El
-.It Dv KERN_PROF
-Return profiling information about the kernel.
-If the kernel is not compiled for profiling,
-attempts to retrieve any of the
-.Dv KERN_PROF
-values will
-fail with
-.Er ENOENT .
-The third level names for the string and integer profiling information
-is detailed below.
-The changeable column shows whether a process with appropriate
-privilege may change the value.
-.Bl -column "GPROFXGMONPARAMXXX" "struct gmonparamXXX" -offset indent
-.It Sy "Third level name" Ta Sy "Type" Ta Sy "Changeable"
-.It Dv GPROF_STATE Ta "integer" Ta "yes"
-.It Dv GPROF_COUNT Ta "u_short[]" Ta "yes"
-.It Dv GPROF_FROMS Ta "u_short[]" Ta "yes"
-.It Dv GPROF_TOS Ta "struct tostruct" Ta "yes"
-.It Dv GPROF_GMONPARAM Ta "struct gmonparam" Ta "no"
-.El
-.Pp
-The variables are as follows:
-.Bl -tag -width 6n
-.It Dv GPROF_STATE
-Returns
-.Dv GMON_PROF_ON
-or
-.Dv GMON_PROF_OFF
-to show that profiling is running or stopped.
-.It Dv GPROF_COUNT
-Array of statistical program counter counts.
-.It Dv GPROF_FROMS
-Array indexed by program counter of call-from points.
-.It Dv GPROF_TOS
-Array of
-.Vt struct tostruct
-describing destination of calls and their counts.
-.It Dv GPROF_GMONPARAM
-Structure giving the sizes of the above arrays.
-.El
 .It Dv KERN_SAVED_IDS
 Returns 1 if saved set-group and saved set-user ID is available.
 .It Dv KERN_SECURELVL
index 71968ea..af43c1a 100644 (file)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD: src/share/man/man7/clocks.7,v 1.9.2.5 2001/12/17 11:30:15 ru Exp $
 .\"
-.Dd May 2, 2009
+.Dd January 5, 2019
 .Dt CLOCKS 7
 .Os
 .Sh NAME
@@ -95,8 +95,7 @@ and throwing away information and resolution.
 .It
 The profiling clock.  This is a real clock with frequency 1024.
 It is used mainly by
-.Xr moncontrol 3 ,
-.Xr kgmon 8
+.Xr moncontrol 3
 and
 .Xr gprof 1 .
 Applications should determine its actual frequency using
index e3ca35a..2cc4cdf 100644 (file)
@@ -29,7 +29,7 @@
 .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd December 27, 2018
+.Dd January 5, 2019
 .Dt VKERNEL 7
 .Os
 .Sh NAME
@@ -370,17 +370,6 @@ It is recommended that you do a
 to ignore page faults processed by the virtual kernel itself and
 .Ql handle SIGUSR1 noprint
 to ignore signals used for simulating inter-processor interrupts.
-.Sh PROFILING
-To compile a vkernel with profiling support, the
-.Va CONFIGARGS
-variable needs to be used to pass
-.Fl p
-to
-.Xr config 8 .
-.Bd -literal
-cd /usr/src
-make -DNO_MODULES CONFIGARGS=-p buildkernel KERNCONF=VKERNEL64
-.Ed
 .Sh FILES
 .Bl -tag -width ".It Pa /sys/config/VKERNEL64" -compact
 .It Pa /dev/vcdX
index 3174b1c..387cd0f 100644 (file)
@@ -2156,7 +2156,6 @@ libkern/linux_idr.c                       standard
 libkern/index.c                                standard
 libkern/inet_ntoa.c                    standard
 libkern/inet_ntop.c                    standard
-libkern/mcount.c                       optional        profiling-routine
 libkern/memmove.c                      standard
 libkern/memcchr.c                      standard
 libkern/qsort.c                                standard
index 4c127d9..07042c6 100644 (file)
@@ -273,8 +273,6 @@ ioconf.o:
 vers.c: $S/conf/newvers.sh $S/sys/param.h ${SYSTEM_DEP}
        sh $S/conf/newvers.sh $S/..
 
-# XXX strictly, everything depends on Makefile because changes to ${PROF}
-# only appear there, but we don't handle that.
 vers.o:
        ${NORMAL_C} ${WERROR}
 
index 8213319..39a01f8 100644 (file)
@@ -66,15 +66,7 @@ CFLAGS=      ${COPTFLAGS} ${KCFLAGS} ${CWARNFLAGS} ${DEBUG} ${COPTS}
 # XXX LOCORE means "don't declare C stuff" not "for locore.s".
 ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${CFLAGS:N-flto}
 
-DEFINED_PROF=  ${PROF}
-.if defined(PROF)
-CFLAGS+=       -falign-functions=16
-.if ${PROFLEVEL} >= 2
-IDENT+=        -DGPROF4 -DGUPROF
-.endif
-.endif
-
-# Put configuration-specific C flags last (except for ${PROF}) so that they
+# Put configuration-specific C flags last so that they
 # can override the others.
 CFLAGS+=       ${CONF_CFLAGS}
 
@@ -83,13 +75,12 @@ CFLAGS+=    ${CONF_CFLAGS}
 CFLAGS+= -MD
 .endif
 
-NORMAL_C= ${CC} -c ${CFLAGS} ${PROF} ${.IMPSRC}
-NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${.IMPSRC}
+NORMAL_C= ${CC} -c ${CFLAGS} ${.IMPSRC}
+NORMAL_C_C= ${CC} -c ${CFLAGS} ${.IMPSRC}
 NORMAL_S= ${CC} -c ${ASM_CFLAGS} ${.IMPSRC}
-PROFILE_C= ${CC} -c ${CFLAGS} ${.IMPSRC}
 
 NORMAL_M= awk -f $S/tools/makeobjops.awk -- -c $<; \
-       ${CC} -c ${CFLAGS} ${PROF} ${.PREFIX}.c
+       ${CC} -c ${CFLAGS} ${.PREFIX}.c
 
 NORMAL_FW= uudecode -o ${.TARGET} ${.ALLSRC}
 NORMAL_FWO= ${LD} -b binary -d -warn-common -r -o ${.TARGET} ${.ALLSRC:M*.fw}
index 9dadeb4..73ba239 100644 (file)
 
 #define _ENTRY(x)      _START_ENTRY; \
                        .globl CNAME(x); .type CNAME(x),@function; CNAME(x):
-
-#ifdef PROF
-#if defined(__x86_64__)
-#define        ALTENTRY(x)     _ENTRY(x); \
-                       pushq %rbp; movq %rsp,%rbp; \
-                       call PIC_PLT(HIDENAME(mcount)); \
-                       popq %rbp; \
-                       jmp 9f
-#define        ENTRY(x)        _ENTRY(x); \
-                       pushq %rbp; movq %rsp,%rbp; \
-                       call PIC_PLT(HIDENAME(mcount)); \
-                       popq %rbp; \
-                       9:
-#else
-#define        ALTENTRY(x)     _ENTRY(x); \
-                       pushl %ebp; movl %esp,%ebp; \
-                       call PIC_PLT(HIDENAME(mcount)); \
-                       popl %ebp; \
-                       jmp 9f
-#define        ENTRY(x)        _ENTRY(x); \
-                       pushl %ebp; movl %esp,%ebp; \
-                       call PIC_PLT(HIDENAME(mcount)); \
-                       popl %ebp; \
-                       9:
-#endif
-#else
 #define        ALTENTRY(x)     _ENTRY(x)
 #define        ENTRY(x)        _ENTRY(x)
-#endif
 
 #define        END(x)          .size x, . - x
 
index 25965d5..ef8c8ab 100644 (file)
 #define CNAME(csym)            csym
 
 #define ALIGN_DATA     .p2align 3      /* 8 byte alignment, zero filled */
-#ifdef GPROF
 #define ALIGN_TEXT     .p2align 4,0x90 /* 16-byte alignment, nop filled */
-#else
-#define ALIGN_TEXT     .p2align 4,0x90 /* 16-byte alignment, nop filled */
-#endif
 #define SUPERALIGN_TEXT        .p2align 4,0x90 /* 16-byte alignment, nop filled */
 
 #define GEN_ENTRY(name)                ALIGN_TEXT; .globl CNAME(name); \
 
 #define        END(name)               .size name, . - name
 
-#ifdef GPROF
-/*
- * __mcount is like [.]mcount except that doesn't require its caller to set
- * up a frame pointer.  It must be called before pushing anything onto the
- * stack.  gcc should eventually generate code to call __mcount in most
- * cases.  This would make -pg in combination with -fomit-frame-pointer
- * useful.  gcc has a configuration variable PROFILE_BEFORE_PROLOGUE to
- * allow profiling before setting up the frame pointer, but this is
- * inadequate for good handling of special cases, e.g., -fpic works best
- * with profiling after the prologue.
- *
- * [.]mexitcount is a new function to support non-statistical profiling if an
- * accurate clock is available.  For C sources, calls to it are generated
- * by the FreeBSD extension `-mprofiler-epilogue' to gcc.  It is best to
- * call [.]mexitcount at the end of a function like the MEXITCOUNT macro does,
- * but gcc currently generates calls to it at the start of the epilogue to
- * avoid problems with -fpic.
- *
- * [.]mcount and __mcount may clobber the call-used registers and %ef.
- * [.]mexitcount may clobber %ecx and %ef.
- *
- * Cross-jumping makes non-statistical profiling timing more complicated.
- * It is handled in many cases by calling [.]mexitcount before jumping.  It
- * is handled for conditional jumps using CROSSJUMP() and CROSSJUMP_LABEL().
- * It is handled for some fault-handling jumps by not sharing the exit
- * routine.
- *
- * ALTENTRY() must be before a corresponding ENTRY() so that it can jump to
- * the main entry point.  Note that alt entries are counted twice.  They
- * have to be counted as ordinary entries for gprof to get the call times
- * right for the ordinary entries.
- *
- * High local labels are used in macros to avoid clashes with local labels
- * in functions.
- *
- * Ordinary `ret' is used instead of a macro `RET' because there are a lot
- * of `ret's.  0xc3 is the opcode for `ret' (`#define ret ... ret' can't
- * be used because this file is sometimes preprocessed in traditional mode).
- * `ret' clobbers eflags but this doesn't matter.
- */
-#define ALTENTRY(name)         GEN_ENTRY(name) ; MCOUNT ; MEXITCOUNT ; jmp 9f
-#define        CROSSJUMP(jtrue, label, jfalse) \
-       jfalse 8f; MEXITCOUNT; jmp __CONCAT(to,label); 8:
-#define CROSSJUMPTARGET(label) \
-       ALIGN_TEXT; __CONCAT(to,label): ; MCOUNT; jmp label
-#define ENTRY(name)            GEN_ENTRY(name) ; 9: ; MCOUNT
-#define FAKE_MCOUNT(caller)    pushq caller ; call __mcount ; popq %rcx
-#define MCOUNT                 call __mcount
-#define MCOUNT_LABEL(name)     GEN_ENTRY(name) ; nop ; ALIGN_TEXT
-#ifdef GUPROF
-#define MEXITCOUNT             call .mexitcount
-#define ret                    MEXITCOUNT ; NON_GPROF_RET
-#else
-#define MEXITCOUNT
-#endif
-
-#else /* !GPROF */
 /*
  * ALTENTRY() has to align because it is before a corresponding ENTRY().
  * ENTRY() has to align to because there may be no ALTENTRY() before it.
 #define MCOUNT
 #define MCOUNT_LABEL(name)
 #define MEXITCOUNT
-#endif /* GPROF */
 
 #ifdef LOCORE
 /*
index 875d8b1..8643079 100644 (file)
@@ -80,8 +80,7 @@ extern        db_addr_t       BP_REGS(db_regs_t *regs);
 #define inst_store(ins)                0
 
 /*
- * There no interesting addresses below _kstack = 0xefbfe000.  There
- * are small absolute values for GUPROF, but we don't want to see them.
+ * There no interesting addresses below _kstack = 0xefbfe000.
  * Treat "negative" addresses below _kstack as non-small to allow for
  * future reductions of _kstack and to avoid sign extension problems.
  *
index d2be59e..d1df5f7 100644 (file)
 #ifndef _CPU_PROFILE_H_
 #define        _CPU_PROFILE_H_
 
-#ifdef _KERNEL
-
-/*
- * Config generates something to tell the compiler to align functions on 16
- * byte boundaries.  A strict alignment is good for keeping the tables small.
- */
-#define        FUNCTION_ALIGNMENT      16
-
-/*
- * The kernel uses assembler stubs instead of unportable inlines.
- * This is mainly to save a little time when profiling is not enabled,
- * which is the usual case for the kernel.
- */
-#define        _MCOUNT_DECL void mcount
-#define        MCOUNT
-
-#ifdef GUPROF
-#define        CALIB_SCALE     1000
-#define        KCOUNT(p,index) ((p)->kcount[(index) \
-                        / (HISTFRACTION * sizeof(HISTCOUNTER))])
-#define        MCOUNT_DECL(s)
-#define        MCOUNT_ENTER(s)
-#define        MCOUNT_EXIT(s)
-#define        PC_TO_I(p, pc)  ((uintfptr_t)(pc) - (uintfptr_t)(p)->lowpc)
-#else
-#define        MCOUNT_DECL(s)  u_long s;
-extern int     mcount_lock;
-#define        MCOUNT_ENTER(s) { s = read_rflags(); disable_intr(); \
-                         while (!atomic_cmpset_acq_int(&mcount_lock, 0, 1)) \
-                               /* nothing */ ; }
-#define        MCOUNT_EXIT(s)  { atomic_store_rel_int(&mcount_lock, 0); \
-                         write_rflags(s); }
-#endif /* GUPROF */
-
-#else /* !_KERNEL */
+#include <sys/cdefs.h>
 
 #define        FUNCTION_ALIGNMENT      4
 
@@ -111,54 +77,16 @@ mcount()           \
 
 typedef        unsigned long   uintfptr_t;
 
-#endif /* _KERNEL */
-
 /*
  * An unsigned integral type that can hold non-negative difference between
  * function pointers.
  */
 typedef        unsigned long   fptrdiff_t;
 
-#ifdef _KERNEL
-
-void   mcount(uintfptr_t frompc, uintfptr_t selfpc);
-void   kmupetext(uintfptr_t nhighpc);
-
-#ifdef GUPROF
-struct gmonparam;
-
-void   nullfunc_loop_profiled(void);
-void   nullfunc_profiled(void);
-void   startguprof(struct gmonparam *p);
-void   stopguprof(struct gmonparam *p);
-#else
-#define        startguprof(p)
-#define        stopguprof(p)
-#endif /* GUPROF */
-
-#else /* !_KERNEL */
-
-#include <sys/cdefs.h>
-
 __BEGIN_DECLS
 #ifdef __GNUC__
 void   mcount(void) __asm(".mcount");
 #endif
 __END_DECLS
 
-#endif /* _KERNEL */
-
-#ifdef GUPROF
-/* XXX doesn't quite work outside kernel yet. */
-extern int     cputime_bias;
-
-__BEGIN_DECLS
-int    cputime(void);
-void   empty_loop(void);
-void   mexitcount(uintfptr_t selfpc);
-void   nullfunc(void);
-void   nullfunc_loop(void);
-__END_DECLS
-#endif
-
 #endif /* !_CPU_PROFILE_H_ */
index d1e5e0c..89f9b4c 100644 (file)
 #include <machine/specialreg.h>
 #include <machine/clock.h>
 
-#ifdef GPROF
-#include <sys/gmon.h>
-#endif
-
 #ifdef DEBUG_PCTRACK
 static void do_pctrack(struct intrframe *frame, int which);
 #endif
@@ -814,10 +810,6 @@ hardclock(systimer_t info, int in_ipi, struct intrframe *frame)
 static void
 statclock(systimer_t info, int in_ipi, struct intrframe *frame)
 {
-#ifdef GPROF
-       struct gmonparam *g;
-       int i;
-#endif
        globaldata_t gd = mycpu;
        thread_t td;
        struct proc *p;
@@ -892,19 +884,6 @@ statclock(systimer_t info, int in_ipi, struct intrframe *frame)
                         */
                        --intr_nest;
                }
-#ifdef GPROF
-               /*
-                * Kernel statistics are just like addupc_intr, only easier.
-                */
-               g = &_gmonparam;
-               if (g->state == GMON_PROF_ON && frame) {
-                       i = CLKF_PC(frame) - g->lowpc;
-                       if (i < g->textsize) {
-                               i /= HISTFRACTION * sizeof(*g->kcount);
-                               g->kcount[i]++;
-                       }
-               }
-#endif
 
 #define IS_INTR_RUNNING        ((frame && CLKF_INTR(intr_nest)) || CLKF_INTR_TD(td))
 
index 923eaaa..105a67d 100644 (file)
 
 #include <machine/cpu.h>
 
-#ifdef GPROF
-#include <sys/malloc.h>
-#include <sys/gmon.h>
-#undef MCOUNT
-
-static MALLOC_DEFINE(M_GPROF, "gprof", "kernel profiling buffer");
-
-static void kmstartup (void *);
-SYSINIT(kmem, SI_SUB_KPROF, SI_ORDER_FIRST, kmstartup, NULL);
-
-struct gmonparam _gmonparam = { GMON_PROF_OFF };
-
-#ifdef GUPROF
-#include <machine/asmacros.h>
-
-void
-nullfunc_loop_profiled(void)
-{
-       int i;
-
-       for (i = 0; i < CALIB_SCALE; i++)
-               nullfunc_profiled();
-}
-
-#define        nullfunc_loop_profiled_end      nullfunc_profiled       /* XXX */
-
-void
-nullfunc_profiled(void)
-{
-}
-#endif /* GUPROF */
-
-static void
-kmstartup(void *dummy)
-{
-       char *cp;
-       struct gmonparam *p = &_gmonparam;
-#ifdef GUPROF
-       int cputime_overhead;
-       int empty_loop_time;
-       int i;
-       int mcount_overhead;
-       int mexitcount_overhead;
-       int nullfunc_loop_overhead;
-       int nullfunc_loop_profiled_time;
-       uintfptr_t tmp_addr;
-#endif
-
-       /*
-        * Round lowpc and highpc to multiples of the density we're using
-        * so the rest of the scaling (here and in gprof) stays in ints.
-        */
-       p->lowpc = ROUNDDOWN((u_long)btext, HISTFRACTION * sizeof(HISTCOUNTER));
-       p->highpc = ROUNDUP((u_long)etext, HISTFRACTION * sizeof(HISTCOUNTER));
-       p->textsize = p->highpc - p->lowpc;
-       kprintf("Profiling kernel, textsize=%lu [%jx..%jx]\n",
-           p->textsize, (uintmax_t)p->lowpc, (uintmax_t)p->highpc);
-       p->kcountsize = p->textsize / HISTFRACTION;
-       p->hashfraction = HASHFRACTION;
-       p->fromssize = p->textsize / HASHFRACTION;
-       p->tolimit = p->textsize * ARCDENSITY / 100;
-       if (p->tolimit < MINARCS)
-               p->tolimit = MINARCS;
-       else if (p->tolimit > MAXARCS)
-               p->tolimit = MAXARCS;
-       p->tossize = p->tolimit * sizeof(struct tostruct);
-       cp = (char *)kmalloc(p->kcountsize + p->fromssize + p->tossize,
-           M_GPROF, M_NOWAIT | M_ZERO);
-       if (cp == NULL) {
-               kprintf("No memory for profiling.\n");
-               return;
-       }
-       p->tos = (struct tostruct *)cp;
-       cp += p->tossize;
-       p->kcount = (HISTCOUNTER *)cp;
-       cp += p->kcountsize;
-       p->froms = (u_short *)cp;
-
-#ifdef GUPROF
-       /* Initialize pointers to overhead counters. */
-       p->cputime_count = &KCOUNT(p, PC_TO_I(p, cputime));
-       p->mcount_count = &KCOUNT(p, PC_TO_I(p, mcount));
-       p->mexitcount_count = &KCOUNT(p, PC_TO_I(p, mexitcount));
-
-       /*
-        * Disable interrupts to avoid interference while we calibrate
-        * things.
-        */
-       cpu_disable_intr();
-
-       /*
-        * Determine overheads.
-        * XXX this needs to be repeated for each useful timer/counter.
-        */
-       cputime_overhead = 0;
-       startguprof(p);
-       for (i = 0; i < CALIB_SCALE; i++)
-               cputime_overhead += cputime();
-
-       empty_loop();
-       startguprof(p);
-       empty_loop();
-       empty_loop_time = cputime();
-
-       nullfunc_loop_profiled();
-
-       /*
-        * Start profiling.  There won't be any normal function calls since
-        * interrupts are disabled, but we will call the profiling routines
-        * directly to determine their overheads.
-        */
-       p->state = GMON_PROF_HIRES;
-
-       startguprof(p);
-       nullfunc_loop_profiled();
-
-       startguprof(p);
-       for (i = 0; i < CALIB_SCALE; i++)
-#if defined(__i386__) && __GNUC__ >= 2
-               __asm("pushl %0; call __mcount; popl %%ecx"
-                     :
-                     : "i" (profil)
-                     : "ax", "bx", "cx", "dx", "memory");
-#else
-#error
-#endif
-       mcount_overhead = KCOUNT(p, PC_TO_I(p, profil));
-
-       startguprof(p);
-       for (i = 0; i < CALIB_SCALE; i++)
-#if defined(__i386__) && __GNUC__ >= 2
-                   __asm("call " __XSTRING(HIDENAME(mexitcount)) "; 1:"
-                         : : : "ax", "bx", "cx", "dx", "memory");
-       __asm("movl $1b,%0" : "=rm" (tmp_addr));
-#else
-#error
-#endif
-       mexitcount_overhead = KCOUNT(p, PC_TO_I(p, tmp_addr));
-
-       p->state = GMON_PROF_OFF;
-       stopguprof(p);
-
-       cpu_enable_intr();
-
-       nullfunc_loop_profiled_time = 0;
-       for (tmp_addr = (uintfptr_t)nullfunc_loop_profiled;
-            tmp_addr < (uintfptr_t)nullfunc_loop_profiled_end;
-            tmp_addr += HISTFRACTION * sizeof(HISTCOUNTER))
-               nullfunc_loop_profiled_time += KCOUNT(p, PC_TO_I(p, tmp_addr));
-#define CALIB_DOSCALE(count)   (((count) + CALIB_SCALE / 3) / CALIB_SCALE)
-#define        c2n(count, freq)        ((int)((count) * 1000000000LL / freq))
-       kprintf("cputime %d, empty_loop %d, nullfunc_loop_profiled %d, mcount %d, mexitcount %d\n",
-              CALIB_DOSCALE(c2n(cputime_overhead, p->profrate)),
-              CALIB_DOSCALE(c2n(empty_loop_time, p->profrate)),
-              CALIB_DOSCALE(c2n(nullfunc_loop_profiled_time, p->profrate)),
-              CALIB_DOSCALE(c2n(mcount_overhead, p->profrate)),
-              CALIB_DOSCALE(c2n(mexitcount_overhead, p->profrate)));
-       cputime_overhead -= empty_loop_time;
-       mcount_overhead -= empty_loop_time;
-       mexitcount_overhead -= empty_loop_time;
-
-       /*-
-        * Profiling overheads are determined by the times between the
-        * following events:
-        *      MC1: mcount() is called
-        *      MC2: cputime() (called from mcount()) latches the timer
-        *      MC3: mcount() completes
-        *      ME1: mexitcount() is called
-        *      ME2: cputime() (called from mexitcount()) latches the timer
-        *      ME3: mexitcount() completes.
-        * The times between the events vary slightly depending on instruction
-        * combination and cache misses, etc.  Attempt to determine the
-        * minimum times.  These can be subtracted from the profiling times
-        * without much risk of reducing the profiling times below what they
-        * would be when profiling is not configured.  Abbreviate:
-        *      ab = minimum time between MC1 and MC3
-        *      a  = minumum time between MC1 and MC2
-        *      b  = minimum time between MC2 and MC3
-        *      cd = minimum time between ME1 and ME3
-        *      c  = minimum time between ME1 and ME2
-        *      d  = minimum time between ME2 and ME3.
-        * These satisfy the relations:
-        *      ab            <= mcount_overhead                (just measured)
-        *      a + b         <= ab
-        *              cd    <= mexitcount_overhead            (just measured)
-        *              c + d <= cd
-        *      a         + d <= nullfunc_loop_profiled_time    (just measured)
-        *      a >= 0, b >= 0, c >= 0, d >= 0.
-        * Assume that ab and cd are equal to the minimums.
-        */
-       p->cputime_overhead = CALIB_DOSCALE(cputime_overhead);
-       p->mcount_overhead = CALIB_DOSCALE(mcount_overhead - cputime_overhead);
-       p->mexitcount_overhead = CALIB_DOSCALE(mexitcount_overhead
-                                              - cputime_overhead);
-       nullfunc_loop_overhead = nullfunc_loop_profiled_time - empty_loop_time;
-       p->mexitcount_post_overhead = CALIB_DOSCALE((mcount_overhead
-                                                    - nullfunc_loop_overhead)
-                                                   / 4);
-       p->mexitcount_pre_overhead = p->mexitcount_overhead
-                                    + p->cputime_overhead
-                                    - p->mexitcount_post_overhead;
-       p->mcount_pre_overhead = CALIB_DOSCALE(nullfunc_loop_overhead)
-                                - p->mexitcount_post_overhead;
-       p->mcount_post_overhead = p->mcount_overhead
-                                 + p->cputime_overhead
-                                 - p->mcount_pre_overhead;
-       kprintf(
-"Profiling overheads: mcount: %d+%d, %d+%d; mexitcount: %d+%d, %d+%d nsec\n",
-              c2n(p->cputime_overhead, p->profrate),
-              c2n(p->mcount_overhead, p->profrate),
-              c2n(p->mcount_pre_overhead, p->profrate),
-              c2n(p->mcount_post_overhead, p->profrate),
-              c2n(p->cputime_overhead, p->profrate),
-              c2n(p->mexitcount_overhead, p->profrate),
-              c2n(p->mexitcount_pre_overhead, p->profrate),
-              c2n(p->mexitcount_post_overhead, p->profrate));
-       kprintf(
-"Profiling overheads: mcount: %d+%d, %d+%d; mexitcount: %d+%d, %d+%d cycles\n",
-              p->cputime_overhead, p->mcount_overhead,
-              p->mcount_pre_overhead, p->mcount_post_overhead,
-              p->cputime_overhead, p->mexitcount_overhead,
-              p->mexitcount_pre_overhead, p->mexitcount_post_overhead);
-#endif /* GUPROF */
-}
-
-/*
- * Return kernel profiling information.
- */
-static int
-sysctl_kern_prof(SYSCTL_HANDLER_ARGS)
-{
-       int *name = (int *) arg1;
-       u_int namelen = arg2;
-       struct gmonparam *gp = &_gmonparam;
-       int error;
-       int state;
-
-       /* all sysctl names at this level are terminal */
-       if (namelen != 1)
-               return (ENOTDIR);               /* overloaded */
-
-       switch (name[0]) {
-       case GPROF_STATE:
-               state = gp->state;
-               error = sysctl_handle_int(oidp, &state, 0, req);
-               if (error)
-                       return (error);
-               if (!req->newptr)
-                       return (0);
-               lwkt_gettoken(&proc0.p_token);
-               if (state == GMON_PROF_OFF) {
-                       gp->state = state;
-                       stopprofclock(&proc0);
-                       stopguprof(gp);
-               } else if (state == GMON_PROF_ON) {
-                       gp->state = GMON_PROF_OFF;
-                       stopguprof(gp);
-                       gp->profrate = profhz;
-                       startprofclock(&proc0);
-                       gp->state = state;
-#ifdef GUPROF
-               } else if (state == GMON_PROF_HIRES) {
-                       gp->state = GMON_PROF_OFF;
-                       stopprofclock(&proc0);
-                       startguprof(gp);
-                       gp->state = state;
-#endif
-               } else if (state != gp->state) {
-                       error = EINVAL;
-               }
-               lwkt_reltoken(&proc0.p_token);
-               return (error);
-       case GPROF_COUNT:
-               return (sysctl_handle_opaque(oidp, 
-                       gp->kcount, gp->kcountsize, req));
-       case GPROF_FROMS:
-               return (sysctl_handle_opaque(oidp, 
-                       gp->froms, gp->fromssize, req));
-       case GPROF_TOS:
-               return (sysctl_handle_opaque(oidp, 
-                       gp->tos, gp->tossize, req));
-       case GPROF_GMONPARAM:
-               return (sysctl_handle_opaque(oidp, gp, sizeof *gp, req));
-       default:
-               return (EOPNOTSUPP);
-       }
-       /* NOTREACHED */
-}
-
-SYSCTL_NODE(_kern, KERN_PROF, prof, CTLFLAG_RW, sysctl_kern_prof, "");
-#endif /* GPROF */
-
 /*
  * Profiling system call.
  *
diff --git a/sys/libkern/mcount.c b/sys/libkern/mcount.c
deleted file mode 100644 (file)
index 0dd2cb5..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/*-
- * Copyright (c) 1983, 1992, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/libkern/mcount.c,v 1.16 1999/12/29 04:54:41 peter Exp $
- */
-
-#include <sys/param.h>
-#include <sys/gmon.h>
-#if defined(_KERNEL) && !defined(_KERNEL_VIRTUAL)
-#ifndef GUPROF
-#include <sys/systm.h>
-#endif
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-void   bintr(void);
-void   btrap(void);
-void   eintr(void);
-void   user(void);
-#endif
-
-/*
- * mcount is called on entry to each function compiled with the profiling
- * switch set.  _mcount(), which is declared in a machine-dependent way
- * with _MCOUNT_DECL, does the actual work and is either inlined into a
- * C routine or called by an assembly stub.  In any case, this magic is
- * taken care of by the MCOUNT definition in <machine/profile.h>.
- *
- * _mcount updates data structures that represent traversals of the
- * program's call graph edges.  frompc and selfpc are the return
- * address and function address that represents the given call graph edge.
- *
- * Note: the original BSD code used the same variable (frompcindex) for
- * both frompcindex and frompc.  Any reasonable, modern compiler will
- * perform this optimization.
- */
-/* _mcount; may be static, inline, etc */
-_MCOUNT_DECL(uintfptr_t frompc, uintfptr_t selfpc)
-{
-#ifdef GUPROF
-       int delta;
-#endif
-       fptrdiff_t frompci;
-       u_short *frompcindex;
-       struct tostruct *top, *prevtop;
-       struct gmonparam *p;
-       long toindex;
-#if defined(_KERNEL) && !defined(_KERNEL_VIRTUAL)
-       MCOUNT_DECL(s)
-#endif
-
-       p = &_gmonparam;
-#ifndef GUPROF                 /* XXX */
-       /*
-        * check that we are profiling
-        * and that we aren't recursively invoked.
-        */
-       if (p->state != GMON_PROF_ON)
-               return;
-#endif
-#if defined(_KERNEL) && !defined(_KERNEL_VIRTUAL)
-       MCOUNT_ENTER(s);
-#else
-       p->state = GMON_PROF_BUSY;
-#endif
-       frompci = frompc - p->lowpc;
-
-#if defined(_KERNEL) && !defined(_KERNEL_VIRTUAL)
-       /*
-        * When we are called from an exception handler, frompci may be
-        * for a user address.  Convert such frompci's to the index of
-        * user() to merge all user counts.
-        *
-        * XXX doesn't work properly with vkernel
-        */
-       if (frompci >= p->textsize) {
-               if (frompci + p->lowpc
-                   >= (uintfptr_t)(VM_MAX_USER_ADDRESS + UPAGES * PAGE_SIZE))
-                       goto done;
-               frompci = (uintfptr_t)user - p->lowpc;
-               if (frompci >= p->textsize)
-                   goto done;
-       }
-#endif
-
-#ifdef GUPROF
-       if (p->state == GMON_PROF_HIRES) {
-               /*
-                * Count the time since cputime() was previously called
-                * against `frompc'.  Compensate for overheads.
-                *
-                * cputime() sets its prev_count variable to the count when
-                * it is called.  This in effect starts a counter for
-                * the next period of execution (normally from now until 
-                * the next call to mcount() or mexitcount()).  We set
-                * cputime_bias to compensate for our own overhead.
-                *
-                * We use the usual sampling counters since they can be
-                * located efficiently.  4-byte counters are usually
-                * necessary.  gprof will add up the scattered counts
-                * just like it does for statistical profiling.  All
-                * counts are signed so that underflow in the subtractions
-                * doesn't matter much (negative counts are normally
-                * compensated for by larger counts elsewhere).  Underflow
-                * shouldn't occur, but may be caused by slightly wrong
-                * calibrations or from not clearing cputime_bias.
-                */
-               delta = cputime() - cputime_bias - p->mcount_pre_overhead;
-               cputime_bias = p->mcount_post_overhead;
-               KCOUNT(p, frompci) += delta;
-               *p->cputime_count += p->cputime_overhead;
-               *p->mcount_count += p->mcount_overhead;
-       }
-#endif /* GUPROF */
-
-#if defined(_KERNEL) && !defined(_KERNEL_VIRTUAL)
-       /*
-        * When we are called from an exception handler, frompc is faked
-        * to be for where the exception occurred.  We've just solidified
-        * the count for there.  Now convert frompci to the index of btrap()
-        * for trap handlers and bintr() for interrupt handlers to make
-        * exceptions appear in the call graph as calls from btrap() and
-        * bintr() instead of calls from all over.
-        */
-       if ((uintfptr_t)selfpc >= (uintfptr_t)btrap
-           && (uintfptr_t)selfpc < (uintfptr_t)eintr) {
-               if ((uintfptr_t)selfpc >= (uintfptr_t)bintr)
-                       frompci = (uintfptr_t)bintr - p->lowpc;
-               else
-                       frompci = (uintfptr_t)btrap - p->lowpc;
-       }
-#endif
-
-       /*
-        * check that frompc is a reasonable pc value.
-        * for example: signal catchers get called from the stack,
-        *              not from text space.  too bad.
-        */
-       if (frompci >= p->textsize)
-               goto done;
-
-       frompcindex = &p->froms[frompci / (p->hashfraction * sizeof(*p->froms))];
-       toindex = *frompcindex;
-       if (toindex == 0) {
-               /*
-                *      first time traversing this arc
-                */
-               toindex = ++p->tos[0].link;
-               if (toindex >= p->tolimit)
-                       /* halt further profiling */
-                       goto overflow;
-
-               *frompcindex = toindex;
-               top = &p->tos[toindex];
-               top->selfpc = selfpc;
-               top->count = 1;
-               top->link = 0;
-               goto done;
-       }
-       top = &p->tos[toindex];
-       if (top->selfpc == selfpc) {
-               /*
-                * arc at front of chain; usual case.
-                */
-               top->count++;
-               goto done;
-       }
-       /*
-        * have to go looking down chain for it.
-        * top points to what we are looking at,
-        * prevtop points to previous top.
-        * we know it is not at the head of the chain.
-        */
-       for (; /* goto done */; ) {
-               if (top->link == 0) {
-                       /*
-                        * top is end of the chain and none of the chain
-                        * had top->selfpc == selfpc.
-                        * so we allocate a new tostruct
-                        * and link it to the head of the chain.
-                        */
-                       toindex = ++p->tos[0].link;
-                       if (toindex >= p->tolimit)
-                               goto overflow;
-
-                       top = &p->tos[toindex];
-                       top->selfpc = selfpc;
-                       top->count = 1;
-                       top->link = *frompcindex;
-                       *frompcindex = toindex;
-                       goto done;
-               }
-               /*
-                * otherwise, check the next arc on the chain.
-                */
-               prevtop = top;
-               top = &p->tos[top->link];
-               if (top->selfpc == selfpc) {
-                       /*
-                        * there it is.
-                        * increment its count
-                        * move it to the head of the chain.
-                        */
-                       top->count++;
-                       toindex = prevtop->link;
-                       prevtop->link = top->link;
-                       top->link = *frompcindex;
-                       *frompcindex = toindex;
-                       goto done;
-               }
-
-       }
-done:
-#if defined(_KERNEL) && !defined(_KERNEL_VIRTUAL)
-       MCOUNT_EXIT(s);
-#else
-       p->state = GMON_PROF_ON;
-#endif
-       return;
-overflow:
-       p->state = GMON_PROF_ERROR;
-#if defined(_KERNEL) && !defined(_KERNEL_VIRTUAL)
-       MCOUNT_EXIT(s);
-#endif
-       return;
-}
-
-/*
- * Actual definition of mcount function.  Defined in <machine/profile.h>,
- * which is included by <sys/gmon.h>.
- */
-MCOUNT
-
-#ifdef GUPROF
-void
-mexitcount(uintfptr_t selfpc)
-{
-       struct gmonparam *p;
-       uintfptr_t selfpcdiff;
-
-       p = &_gmonparam;
-       selfpcdiff = selfpc - (uintfptr_t)p->lowpc;
-       if (selfpcdiff < p->textsize) {
-               int delta;
-
-               /*
-                * Count the time since cputime() was previously called
-                * against `selfpc'.  Compensate for overheads.
-                */
-               delta = cputime() - cputime_bias - p->mexitcount_pre_overhead;
-               cputime_bias = p->mexitcount_post_overhead;
-               KCOUNT(p, selfpcdiff) += delta;
-               *p->cputime_count += p->cputime_overhead;
-               *p->mexitcount_count += p->mexitcount_overhead;
-       }
-}
-
-void
-empty_loop(void)
-{
-       int i;
-
-       for (i = 0; i < CALIB_SCALE; i++)
-               ;
-}
-
-void
-nullfunc(void)
-{
-}
-
-void
-nullfunc_loop(void)
-{
-       int i;
-
-       for (i = 0; i < CALIB_SCALE; i++)
-               nullfunc();
-}
-#endif /* GUPROF */
index 6956929..3c1400a 100644 (file)
@@ -118,7 +118,7 @@ vfs/smbfs/smbfs_vfsops.c    optional        smbfs
 vfs/smbfs/smbfs_vnops.c                optional        smbfs
 
 cpu/x86_64/misc/atomic.c               standard                        \
-       compile-with    "${NORMAL_C} ${empty(DEFINED_PROF):?-fomit-frame-pointer:} ${WERROR}"
+       compile-with    "${NORMAL_C} -fomit-frame-pointer ${WERROR}"
 cpu/x86_64/misc/cputimer_tsc.c         standard
 platform/pc64/x86_64/autoconf.c        standard
 platform/pc64/x86_64/mpboot.S  standard
diff --git a/sys/platform/pc64/isa/prof_machdep.c b/sys/platform/pc64/isa/prof_machdep.c
deleted file mode 100644 (file)
index aad2509..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*-
- * Copyright (c) 1996 Bruce D. Evans.
- * Copyright (c) 2008 The DragonFly Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/i386/isa/prof_machdep.c,v 1.14.2.1 2000/08/03 00:09:30 ps Exp $
- */
-
-#ifdef GUPROF
-#include "opt_i586_guprof.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/gmon.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-
-#include <machine/clock.h>
-#include <machine/profile.h>
-#undef MCOUNT
-#endif
-
-#include <machine/asmacros.h>
-
-#include <bus/isa/isa.h>
-#include <machine_base/isa/timerreg.h>
-
-#ifdef GUPROF
-#define        CPUTIME_CLOCK_UNINITIALIZED     0
-#define        CPUTIME_CLOCK_I8254             1
-#define        CPUTIME_CLOCK_TSC               2
-#define        CPUTIME_CLOCK_I586_PMC          3
-#define        CPUTIME_CLOCK_I8254_SHIFT       7
-
-int    cputime_bias = 1;       /* initialize for locality of reference */
-
-static int     cputime_clock = CPUTIME_CLOCK_UNINITIALIZED;
-#endif /* GUPROF */
-
-#ifdef __GNUC__
-__asm("                                                                \n\
-GM_STATE       =       0                                       \n\
-GMON_PROF_OFF  =       3                                       \n\
-                                                               \n\
-       .text                                                   \n\
-       .p2align 4,0x90                                         \n\
-       .globl  __mcount                                        \n\
-       .type   __mcount,@function                              \n\
-__mcount:                                                      \n\
-       #                                                       \n\
-       # Check that we are profiling.  Do it early for speed.  \n\
-       #                                                       \n\
-       cmpl    $GMON_PROF_OFF," __XSTRING(CNAME(_gmonparam)) "+GM_STATE \n\
-       je      .mcount_exit                                    \n\
-       #                                                       \n\
-       # __mcount is the same as [.]mcount except the caller   \n\
-       # hasn't changed the stack except to call here, so the  \n\
-       # caller's raddr is above our raddr.                    \n\
-       #                                                       \n\
-       pushl   %eax                                            \n\
-       pushl   %ecx                                            \n\
-       pushl   %edx                                            \n\
-       movl    12+4(%esp),%edx                                 \n\
-       jmp     .got_frompc                                     \n\
-                                                               \n\
-       .p2align 4,0x90                                         \n\
-       .globl  " __XSTRING(HIDENAME(mcount)) "                 \n\
-" __XSTRING(HIDENAME(mcount)) ":                               \n\
-       cmpl    $GMON_PROF_OFF," __XSTRING(CNAME(_gmonparam)) "+GM_STATE \n\
-       je      .mcount_exit                                    \n\
-       #                                                       \n\
-       # The caller's stack frame has already been built, so   \n\
-       # %ebp is the caller's frame pointer.  The caller's     \n\
-       # raddr is in the caller's frame following the caller's \n\
-       # caller's frame pointer.                               \n\
-       #                                                       \n\
-       pushl   %eax                                            \n\
-       pushl   %ecx                                            \n\
-       pushl   %edx                                            \n\
-       movl    4(%ebp),%edx                                    \n\
-.got_frompc:                                                   \n\
-       #                                                       \n\
-       # Our raddr is the caller's pc.                         \n\
-       #                                                       \n\
-       movl    (%esp),%eax                                     \n\
-                                                               \n\
-       pushfl                                                  \n\
-       pushl   %eax                                            \n\
-       pushl   %edx                                            \n\
-       cli                                                     \n\
-       call    " __XSTRING(CNAME(mcount)) "                    \n\
-       addl    $8,%esp                                         \n\
-       popfl                                                   \n\
-       popl    %edx                                            \n\
-       popl    %ecx                                            \n\
-       popl    %eax                                            \n\
-.mcount_exit:                                                  \n\
-       ret                                                     \n\
-");
-#else /* !__GNUC__ */
-#error
-#endif /* __GNUC__ */
-
-#ifdef GUPROF
-/*
- * [.]mexitcount saves the return register(s), loads selfpc and calls
- * mexitcount(selfpc) to do the work.  Someday it should be in a machine
- * dependent file together with cputime(), __mcount and [.]mcount.  cputime()
- * can't just be put in machdep.c because it has to be compiled without -pg.
- */
-#ifdef __GNUC__
-__asm("                                                                \n\
-       .text                                                   \n\
-#                                                              \n\
-# Dummy label to be seen when gprof -u hides [.]mexitcount.    \n\
-#                                                              \n\
-       .p2align 4,0x90                                         \n\
-       .globl  __mexitcount                                    \n\
-       .type   __mexitcount,@function                          \n\
-__mexitcount:                                                  \n\
-       nop                                                     \n\
-                                                               \n\
-GMON_PROF_HIRES        =       4                                       \n\
-                                                               \n\
-       .p2align 4,0x90                                         \n\
-       .globl  " __XSTRING(HIDENAME(mexitcount)) "             \n\
-" __XSTRING(HIDENAME(mexitcount)) ":                           \n\
-       cmpl    $GMON_PROF_HIRES," __XSTRING(CNAME(_gmonparam)) "+GM_STATE \n\
-       jne     .mexitcount_exit                                \n\
-       pushl   %edx                                            \n\
-       pushl   %ecx                                            \n\
-       pushl   %eax                                            \n\
-       movl    12(%esp),%eax                                   \n\
-       pushfl                                                  \n\
-       pushl   %eax                                            \n\
-       cli                                                     \n\
-       call    " __XSTRING(CNAME(mexitcount)) "                \n\
-       addl    $4,%esp                                         \n\
-       popfl                                                   \n\
-       popl    %eax                                            \n\
-       popl    %ecx                                            \n\
-       popl    %edx                                            \n\
-.mexitcount_exit:                                              \n\
-       ret                                                     \n\
-");
-#else /* !__GNUC__ */
-#error
-#endif /* __GNUC__ */
-
-/*
- * Return the time elapsed since the last call.  The units are machine-
- * dependent.
- */
-int
-cputime(void)
-{
-       u_int count;
-       int delta;
-       u_char high, low;
-       static u_int prev_count;
-
-       /*
-        * Read the current value of the 8254 timer counter 0.
-        */
-       outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
-       low = inb(TIMER_CNTR0);
-       high = inb(TIMER_CNTR0);
-       count = ((high << 8) | low) << CPUTIME_CLOCK_I8254_SHIFT;
-
-       /*
-        * The timer counts down from TIMER_CNTR0_MAX to 0 and then resets.
-        * While profiling is enabled, this routine is called at least twice
-        * per timer reset (for mcounting and mexitcounting hardclock()),
-        * so at most one reset has occurred since the last call, and one
-        * has occurred iff the current count is larger than the previous
-        * count.  This allows counter underflow to be detected faster
-        * than in microtime().
-        */
-       delta = prev_count - count;
-       prev_count = count;
-       if (delta <= 0)
-               return (delta + (timer0_max_count << CPUTIME_CLOCK_I8254_SHIFT));
-       return (delta);
-}
-
-static int
-sysctl_machdep_cputime_clock(SYSCTL_HANDLER_ARGS)
-{
-       int clock;
-       int error;
-
-       clock = cputime_clock;
-       error = sysctl_handle_opaque(oidp, &clock, sizeof clock, req);
-       if (error == 0 && req->newptr != NULL) {
-               if (clock < 0 || clock >= CPUTIME_CLOCK_I586_PMC)
-                       return (EINVAL);
-               cputime_clock = clock;
-       }
-       return (error);
-}
-
-SYSCTL_PROC(_machdep, OID_AUTO, cputime_clock, CTLTYPE_INT | CTLFLAG_RW,
-           0, sizeof(u_int), sysctl_machdep_cputime_clock, "I", "");
-
-/*
- * The start and stop routines need not be here since we turn off profiling
- * before calling them.  They are here for convenience.
- */
-
-void
-startguprof(struct gmonparam *gp)
-{
-       if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED)
-               cputime_clock = CPUTIME_CLOCK_I8254;
-       gp->profrate = timer_freq << CPUTIME_CLOCK_I8254_SHIFT;
-       cputime_bias = 0;
-       cputime();
-}
-
-void
-stopguprof(struct gmonparam *gp)
-{
-}
-
-#else /* !GUPROF */
-#ifdef __GNUC__
-__asm("                                                                \n\
-       .text                                                   \n\
-       .p2align 4,0x90                                         \n\
-       .globl  " __XSTRING(HIDENAME(mexitcount)) "             \n\
-" __XSTRING(HIDENAME(mexitcount)) ":                           \n\
-       ret                                                     \n\
-");
-#else /* !__GNUC__ */
-#error
-#endif /* __GNUC__ */
-#endif /* GUPROF */
index f708d75..795dbe2 100644 (file)
@@ -3167,9 +3167,6 @@ outb(u_int port, u_char data)
 /* critical region when masking or unmasking interupts */
 struct spinlock_deprecated imen_spinlock;
 
-/* lock region used by kernel profiling */
-struct spinlock_deprecated mcount_spinlock;
-
 /* locks com (tty) data/hardware accesses: a FASTINTR() */
 struct spinlock_deprecated com_spinlock;
 
@@ -3185,7 +3182,6 @@ init_locks(void)
         */
        cpu_get_initial_mplock();
        /* DEPRECATED */
-       spin_init_deprecated(&mcount_spinlock);
        spin_init_deprecated(&imen_spinlock);
        spin_init_deprecated(&com_spinlock);
        spin_init_deprecated(&clock_spinlock);
index 1382b5a..6eef776 100644 (file)
@@ -47,9 +47,6 @@
 #include <sys/lock.h>
 #include <vm/vm_map.h>
 #include <sys/user.h>
-#ifdef GPROF 
-#include <sys/gmon.h>
-#endif
 
 #include <machine/smp.h>
 #include <machine_base/apic/apicreg.h>
index e995d9f..141a1d7 100644 (file)
@@ -46,9 +46,6 @@
 #include <sys/lock.h>
 #include <vm/vm_map.h>
 #include <sys/user.h>
-#ifdef GPROF 
-#include <sys/gmon.h>
-#endif
 
 #include <machine/smp.h>
 #include <machine_base/isa/isa_intr.h>
index f61f3fc..979c70a 100644 (file)
@@ -20,7 +20,7 @@ S=    ../..
 # Additionally, the max-page-size is set to 0x200000 regardless of the ld
 # default setting.
 #
-SYSTEM_LD= @${CC} ${DEBUG} ${PROF} -Wl,--export-dynamic -o ${.TARGET} ${SYSTEM_OBJS} vers.o -pthread
+SYSTEM_LD= @${CC} ${DEBUG} -Wl,--export-dynamic -o ${.TARGET} ${SYSTEM_OBJS} vers.o -pthread
 SYSTEM_LD+= -Wl,--hash-style=sysv
 SYSTEM_LD+= -Wl,-z,max-page-size=0x200000
 
index 5732122..c02b143 100644 (file)
@@ -13,7 +13,7 @@ vfs/smbfs/smbfs_subr.c                optional        smbfs
 vfs/smbfs/smbfs_vfsops.c       optional        smbfs
 vfs/smbfs/smbfs_vnops.c                optional        smbfs
 cpu/x86_64/misc/atomic.c       standard                                \
-       compile-with    "${NORMAL_C} ${empty(DEFINED_PROF):?-fomit-frame-pointer:} ${WERROR}"
+       compile-with    "${NORMAL_C} -fomit-frame-pointer ${WERROR}"
 cpu/x86_64/misc/cputimer_tsc.c standard
 platform/vkernel64/x86_64/autoconf.c   standard
 platform/vkernel64/x86_64/mp.c         standard                        \
index 9341fb1..c240d0f 100644 (file)
@@ -33,6 +33,8 @@
 #ifndef _SYS_GMON_H_
 #define _SYS_GMON_H_
 
+#include <sys/cdefs.h>
+
 #include <machine/profile.h>
 
 /*
@@ -49,14 +51,7 @@ struct gmonhdr {
 };
 #define GMONVERSION    0x00051879
 
-/*
- * Type of histogram counters used in the kernel.
- */
-#ifdef GPROF4
-#define        HISTCOUNTER     int64_t
-#else
 #define        HISTCOUNTER     unsigned short
-#endif
 
 /*
  * Fraction of text space to allocate for histogram counters.
@@ -188,24 +183,9 @@ extern struct gmonparam _gmonparam;
 #define        GMON_PROF_OFF   3
 #define        GMON_PROF_HIRES 4
 
-/*
- * Sysctl definitions for extracting profiling information from the kernel.
- */
-#define        GPROF_STATE     0       /* int: profiling enabling variable */
-#define        GPROF_COUNT     1       /* struct: profile tick count buffer */
-#define        GPROF_FROMS     2       /* struct: from location hash bucket */
-#define        GPROF_TOS       3       /* struct: destination/count structure */
-#define        GPROF_GMONPARAM 4       /* struct: profiling parameters (see above) */
-
-#ifndef _KERNEL
-
-#include <sys/cdefs.h>
-
 __BEGIN_DECLS
 void   moncontrol(int);
 void   monstartup(u_long, u_long);
 __END_DECLS
 
-#endif /* !_KERNEL */
-
 #endif /* !_SYS_GMON_H_ */
index 6718461..eda6762 100644 (file)
@@ -200,7 +200,6 @@ enum sysinit_sub_id {
        SI_SUB_PROTO_IFATTACHDOMAIN     
                                = 0x8800001,    /* domain dependent data init */
        SI_SUB_PROTO_END        = 0x8ffffff,    /* network protocol post-init */
-       SI_SUB_KPROF            = 0x9000000,    /* kernel profiling*/
        SI_SUB_KICK_SCHEDULER   = 0xa000000,    /* start the timeout events*/
        SI_SUB_INT_CONFIG_HOOKS = 0xa800000,    /* Interrupts enabled config */
 
index 87a182e..e82ded3 100644 (file)
@@ -479,7 +479,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
 #define        KERN_VNODE              13      /* struct: vnode structures */
 #define        KERN_PROC               14      /* struct: process entries */
 #define        KERN_FILE               15      /* struct: file entries */
-#define        KERN_PROF               16      /* node: kernel profiling info */
+#define        KERN_UNUSED16           16      /* was: node: kernel profiling info */
 #define        KERN_POSIX1             17      /* int: POSIX.1 version */
 #define        KERN_NGROUPS            18      /* int: # of supplemental group ids */
 #define        KERN_JOB_CONTROL        19      /* int: is job control available */
index 8c72d84..4d88a54 100644 (file)
@@ -157,7 +157,6 @@ SUBDIR+=nscd
 
 .if ${MACHINE_ARCH} == "x86_64"
 SUBDIR+= \
-       kgmon \
        lptcontrol \
        mptable \
        rndcontrol
index 59b9659..e97b8f1 100644 (file)
@@ -28,7 +28,7 @@
 .\"     @(#)config.8   8.2 (Berkeley) 4/19/94
 .\" $FreeBSD: src/usr.sbin/config/config.8,v 1.21.2.7 2003/04/23 07:32:39 brueffer Exp $
 .\"
-.Dd May 8, 2018
+.Dd January 5, 2019
 .Dt CONFIG 8
 .Os
 .Sh NAME
@@ -36,7 +36,7 @@
 .Nd build system configuration files
 .Sh SYNOPSIS
 .Nm
-.Op Fl gpr
+.Op Fl gr
 .Op Fl d Ar destdir
 .Ar SYSTEM_NAME
 .Sh DESCRIPTION
@@ -69,16 +69,6 @@ does not append
 to the directory given.
 .It Fl g
 Configure a system for debugging.
-.It Fl p
-Configure a system for profiling; for example,
-.Xr kgmon 8
-and
-.Xr gprof 1 .
-If two or more
-.Fl p
-options are supplied,
-.Nm
-configures a system for high resolution profiling.
 .It Fl r
 Remove the old compile directory (see below).
 .It Ar SYSTEM_NAME
@@ -219,8 +209,7 @@ specific files
 .Xr make 1 ,
 .Xr kernconf 5 ,
 .Xr build 7 ,
-.Xr vkernel 7 ,
-.Xr kgmon 8
+.Xr vkernel 7
 .Pp
 The
 .Sx SYNOPSIS
index d474d8c..89d4a73 100644 (file)
@@ -54,9 +54,8 @@ struct file_list {
  */
 #define NORMAL         1
 #define        INVISIBLE       2
-#define        PROFILING       3
-#define NODEPEND       4
-#define LOCAL          5
+#define NODEPEND       3
+#define LOCAL          4
 #define DEVDONE                0x80000000
 #define TYPEMASK       0x7fffffff
 
@@ -157,7 +156,6 @@ extern int  yyline;
 
 extern struct  file_list *ftab;
 
-extern int     profiling;
 extern int     debugging;
 
 extern int     maxusers;
index 1e30df0..1e9bbda 100644 (file)
@@ -61,7 +61,6 @@ char  srcdir[MAXPATHLEN - 32];
 
 static int no_config_clobber = TRUE;
 int    debugging;
-int    profiling;
 
 extern int yyparse(void);
 static void configfile(void);
@@ -85,7 +84,7 @@ main(int argc, char *argv[])
        static const char *emus[] = { "linux" };
 #endif
 
-       while ((ch = getopt(argc, argv, "d:gpr")) != -1)
+       while ((ch = getopt(argc, argv, "d:gr")) != -1)
                switch (ch) {
                case 'd':
                        if (*destdir == '\0')
@@ -96,9 +95,6 @@ main(int argc, char *argv[])
                case 'g':
                        debugging++;
                        break;
-               case 'p':
-                       profiling++;
-                       break;
                case 'r':
                        no_config_clobber = FALSE;
                        break;
index 2cc38c1..cc8b05b 100644 (file)
@@ -159,11 +159,6 @@ makefile(void)
        fprintf(ofp, ".export MACHINE\n");
        fprintf(ofp, ".export MACHINE_ARCH\n");
        fprintf(ofp, "IDENT=");
-       if (profiling) {
-               /* Don't compile kernel profiling code for vkernel */
-               if (strncmp(platformname, "vkernel", 6) != 0)
-                       fprintf(ofp, " -DGPROF");
-       }
 
        if (cputype == 0) {
                printf("cpu type must be specified\n");
@@ -174,10 +169,6 @@ makefile(void)
                fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
        if (debugging)
                fprintf(ofp, "DEBUG=-g\n");
-       if (profiling) {
-               fprintf(ofp, "PROF=-pg\n");
-               fprintf(ofp, "PROFLEVEL=%d\n", profiling);
-       }
        if (*srcdir != '\0')
                fprintf(ofp,"S=%s\n", srcdir);
        while (fgets(line, BUFSIZ, ifp) != 0) {
@@ -256,7 +247,7 @@ openit:
 next:
        /*
         * filename    [ standard | mandatory | optional ] [ config-dependent ]
-        *      [ dev* | profiling-routine ] [ no-obj ]
+        *      [ dev* ] [ no-obj ]
         *      [ compile-with "compile rule" [no-implicit-rule] ]
         *      [ dependency "dependency-list"] [ before-depend ]
         *      [ clean "file-list"] [ warning "text warning" ]
@@ -430,10 +421,6 @@ nextparam:
                printf("%s: `device-driver' flag obsolete.\n", fname);
                exit(1);
        }
-       if (strcmp(wd, "profiling-routine") == 0) {
-               filetype = PROFILING;
-               goto nextparam;
-       }
        if (needs == NULL && nreqs == 1)
                needs = strdup(wd);
        if (isdup)
@@ -501,8 +488,6 @@ doneparam:
                    fname, this);
                exit(1);
        }
-       if (filetype == PROFILING && profiling == 0)
-               goto next;
        if (tp == NULL)
                tp = new_fent();
        tp->f_fn = this;
@@ -742,12 +727,6 @@ do_rules(FILE *f)
                                ftype = "NORMAL";
                                break;
 
-                       case PROFILING:
-                               if (!profiling)
-                                       continue;
-                               ftype = "PROFILE";
-                               break;
-
                        default:
                                printf("config: don't know rules for %s\n", np);
                                break;
diff --git a/usr.sbin/kgmon/Makefile b/usr.sbin/kgmon/Makefile
deleted file mode 100644 (file)
index 5d50f3b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#      @(#)Makefile    8.1 (Berkeley) 6/6/93
-# $FreeBSD: src/usr.sbin/kgmon/Makefile,v 1.2.14.1 2001/04/25 12:09:51 ru Exp $
-# $DragonFly: src/usr.sbin/kgmon/Makefile,v 1.2 2003/06/17 04:29:55 dillon Exp $
-
-PROG=  kgmon
-MAN=   kgmon.8
-DPADD= ${LIBKVM}
-LDADD= -lkvm
-WARNS?=        2
-
-#
-# This program may safely be run setuid-root to allow non-root
-# users to start, stop, and reset profiling buffers.
-#
-#BINOWN=root
-#BINMODE=4555
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/kgmon/kgmon.8 b/usr.sbin/kgmon/kgmon.8
deleted file mode 100644 (file)
index 4008563..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-.\" Copyright (c) 1983, 1991, 1993
-.\"    The Regents of the University of California.  All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the University nor the names of its contributors
-.\"    may be used to endorse or promote products derived from this software
-.\"    without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\"     @(#)kgmon.8    8.1 (Berkeley) 6/6/93
-.\" $FreeBSD: src/usr.sbin/kgmon/kgmon.8,v 1.7.2.4 2003/03/11 21:13:50 trhodes Exp $
-.\" $DragonFly: src/usr.sbin/kgmon/kgmon.8,v 1.4 2008/09/02 11:50:46 matthias Exp $
-.\"
-.Dd September 2, 2008
-.Dt KGMON 8
-.Os
-.Sh NAME
-.Nm kgmon
-.Nd generate a dump of the operating system's profile buffers
-.Sh SYNOPSIS
-.Nm
-.Op Fl Bbhpr
-.Op Fl M core
-.Op Fl N system
-.Sh DESCRIPTION
-The
-.Nm
-utility is used when profiling the operating system.
-When no arguments are supplied,
-.Nm
-indicates the state of operating system profiling as running,
-off, or not configured.
-(see
-.Xr config 8 )
-If the
-.Fl p
-flag is specified,
-.Nm
-extracts profile data from the operating system and produces a
-.Pa gmon.out
-file suitable for later analysis by
-.Xr gprof 1 .
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl B
-Resume the collection of high resolution profile data.
-.It Fl b
-Resume the collection of low resolution profile data.
-.It Fl h
-Stop the collection of profile data.
-.It Fl p
-Dump the contents of the profile buffers into a
-.Pa gmon.out
-file.
-.It Fl r
-Reset all the profile buffers.
-If the
-.Fl p
-flag is also specified, the
-.Pa gmon.out
-file is generated before the buffers are reset.
-.It Fl M
-Extract values associated with the name list from the specified core
-instead of the default
-.Pa /dev/kmem .
-.It Fl N
-Extract the name list from the specified system instead of the
-default
-.Pa /boot/kernel .
-.El
-.Pp
-If neither
-.Fl B
-nor
-.Fl b
-nor
-.Fl h
-is specified, the state of profiling collection remains unchanged.
-For example, if the
-.Fl p
-flag is specified and profile data is being collected,
-profiling will be momentarily suspended,
-the operating system profile buffers will be dumped,
-and profiling will be immediately resumed.
-.Pp
-The profile buffers should be reset when the resolution
-of the profile data is changed.
-.Sh FILES
-.Bl -tag -width /dev/kmemx -compact
-.It Pa /boot/kernel
-the default system
-.It Pa /dev/kmem
-the default memory
-.El
-.Sh DIAGNOSTICS
-Users with only read permission on
-.Pa /dev/kmem
-cannot change the state
-of profiling collection.
-They can get a
-.Pa gmon.out
-file with the warning that the data may be
-inconsistent if profiling is in progress.
-.Sh SEE ALSO
-.Xr gprof 1 ,
-.Xr config 8
-.Sh HISTORY
-The
-.Nm
-utility appeared in
-.Bx 4.2 .
diff --git a/usr.sbin/kgmon/kgmon.c b/usr.sbin/kgmon/kgmon.c
deleted file mode 100644 (file)
index 03eacec..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright (c) 1983, 1992, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) Copyright (c) 1983, 1992, 1993 The Regents of the University of California.  All rights reserved.
- * @(#)kgmon.c 8.1 (Berkeley) 6/6/93
- * $FreeBSD: src/usr.sbin/kgmon/kgmon.c,v 1.9 1999/08/28 01:16:42 peter Exp $
- */
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <sys/sysctl.h>
-#include <sys/gmon.h>
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <kvm.h>
-#include <limits.h>
-#include <nlist.h>
-#include <paths.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-struct nlist nl[] = {
-#define        N_GMONPARAM     0
-       { "__gmonparam" },
-       { NULL },
-};
-
-struct kvmvars {
-       kvm_t   *kd;
-       struct gmonparam gpm;
-};
-
-int    Bflag, bflag, hflag, kflag, rflag, pflag;
-int    debug = 0;
-int    getprof(struct kvmvars *);
-void   kern_readonly(int);
-int    openfiles(char *, char *, struct kvmvars *);
-void   setprof(struct kvmvars *kvp, int state);
-void   dumpstate(struct kvmvars *kvp);
-void   reset(struct kvmvars *kvp);
-static void usage(void);
-
-int
-main(int argc, char **argv)
-{
-       int ch, mode, disp, accessmode;
-       struct kvmvars kvmvars;
-       char *system, *kmemf;
-
-       seteuid(getuid());
-       kmemf = NULL;
-       system = NULL;
-       while ((ch = getopt(argc, argv, "M:N:Bbhpr")) != -1) {
-               switch((char)ch) {
-
-               case 'M':
-                       kmemf = optarg;
-                       kflag = 1;
-                       break;
-
-               case 'N':
-                       system = optarg;
-                       break;
-
-               case 'B':
-                       Bflag = 1;
-                       break;
-
-               case 'b':
-                       bflag = 1;
-                       break;
-
-               case 'h':
-                       hflag = 1;
-                       break;
-
-               case 'p':
-                       pflag = 1;
-                       break;
-
-               case 'r':
-                       rflag = 1;
-                       break;
-
-               default:
-                       usage();
-               }
-       }
-       argc -= optind;
-       argv += optind;
-
-#define BACKWARD_COMPATIBILITY
-#ifdef BACKWARD_COMPATIBILITY
-       if (*argv) {
-               system = *argv;
-               if (*++argv) {
-                       kmemf = *argv;
-                       ++kflag;
-               }
-       }
-#endif
-       if (system == NULL)
-               system = (char *)getbootfile();
-       accessmode = openfiles(system, kmemf, &kvmvars);
-       mode = getprof(&kvmvars);
-       if (hflag)
-               disp = GMON_PROF_OFF;
-       else if (Bflag)
-               disp = GMON_PROF_HIRES;
-       else if (bflag)
-               disp = GMON_PROF_ON;
-       else
-               disp = mode;
-       if (pflag)
-               dumpstate(&kvmvars);
-       if (rflag)
-               reset(&kvmvars);
-       if (accessmode == O_RDWR)
-               setprof(&kvmvars, disp);
-       fprintf(stdout, "kgmon: kernel profiling is %s.\n",
-                     disp == GMON_PROF_OFF ? "off" :
-                     disp == GMON_PROF_HIRES ? "running (high resolution)" :
-                     disp == GMON_PROF_ON ? "running" :
-                     disp == GMON_PROF_BUSY ? "busy" :
-                     disp == GMON_PROF_ERROR ? "off (error)" :
-                     "in an unknown state");
-       return (0);
-}
-
-static void
-usage(void)
-{
-       fprintf(stderr, "usage: kgmon [-Bbhrp] [-M core] [-N system]\n");
-       exit(1);
-}
-
-/*
- * Check that profiling is enabled and open any ncessary files.
- */
-int
-openfiles(char *system, char *kmemf, struct kvmvars *kvp)
-{
-       int mib[3], state, openmode;
-       size_t size;
-       char errbuf[_POSIX2_LINE_MAX];
-
-       if (!kflag) {
-               mib[0] = CTL_KERN;
-               mib[1] = KERN_PROF;
-               mib[2] = GPROF_STATE;
-               size = sizeof state;
-               if (sysctl(mib, 3, &state, &size, NULL, 0) < 0)
-                       errx(20, "profiling not defined in kernel");
-               if (!(Bflag || bflag || hflag || rflag ||
-                   (pflag &&
-                    (state == GMON_PROF_HIRES || state == GMON_PROF_ON))))
-                       return (O_RDONLY);
-               seteuid(0);
-               if (sysctl(mib, 3, NULL, NULL, &state, size) >= 0)
-                       return (O_RDWR);
-               seteuid(getuid());
-               kern_readonly(state);
-               return (O_RDONLY);
-       }
-       openmode = (Bflag || bflag || hflag || pflag || rflag)
-                  ? O_RDWR : O_RDONLY;
-       kvp->kd = kvm_openfiles(system, kmemf, NULL, openmode, errbuf);
-       if (kvp->kd == NULL) {
-               if (openmode == O_RDWR) {
-                       openmode = O_RDONLY;
-                       kvp->kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY,
-                           errbuf);
-               }
-               if (kvp->kd == NULL)
-                       errx(2, "kvm_openfiles: %s", errbuf);
-               kern_readonly(GMON_PROF_ON);
-       }
-       if (kvm_nlist(kvp->kd, nl) < 0)
-               errx(3, "%s: no namelist", system);
-       if (!nl[N_GMONPARAM].n_value)
-               errx(20, "profiling not defined in kernel");
-       return (openmode);
-}
-
-/*
- * Suppress options that require a writable kernel.
- */
-void
-kern_readonly(int mode)
-{
-       fprintf(stderr, "kgmon: kernel read-only: ");
-       if (pflag && (mode == GMON_PROF_HIRES || mode == GMON_PROF_ON))
-               fprintf(stderr, "data may be inconsistent\n");
-       if (rflag)
-               fprintf(stderr, "-r suppressed\n");
-       if (Bflag)
-               fprintf(stderr, "-B suppressed\n");
-       if (bflag)
-               fprintf(stderr, "-b suppressed\n");
-       if (hflag)
-               fprintf(stderr, "-h suppressed\n");
-       rflag = Bflag = bflag = hflag = 0;
-}
-
-/*
- * Get the state of kernel profiling.
- */
-int
-getprof(struct kvmvars *kvp)
-{
-       int mib[3];
-       size_t size;
-
-       if (kflag) {
-               size = kvm_read(kvp->kd, nl[N_GMONPARAM].n_value, &kvp->gpm,
-                   sizeof kvp->gpm);
-       } else {
-               mib[0] = CTL_KERN;
-               mib[1] = KERN_PROF;
-               mib[2] = GPROF_GMONPARAM;
-               size = sizeof kvp->gpm;
-               if (sysctl(mib, 3, &kvp->gpm, &size, NULL, 0) < 0)
-                       size = 0;
-       }
-       if (size != sizeof kvp->gpm)
-               errx(4, "cannot get gmonparam: %s",
-                   kflag ? kvm_geterr(kvp->kd) : strerror(errno));
-       return (kvp->gpm.state);
-}
-
-/*
- * Enable or disable kernel profiling according to the state variable.
- */
-void
-setprof(struct kvmvars *kvp, int state)
-{
-       struct gmonparam *p = (struct gmonparam *)nl[N_GMONPARAM].n_value;
-       int mib[3], oldstate;
-       size_t size;
-
-       size = sizeof(state);
-       if (!kflag) {
-               mib[0] = CTL_KERN;
-               mib[1] = KERN_PROF;
-               mib[2] = GPROF_STATE;
-               if (sysctl(mib, 3, &oldstate, &size, NULL, 0) < 0)
-                       goto bad;
-               if (oldstate == state)
-                       return;
-               seteuid(0);
-               if (sysctl(mib, 3, NULL, NULL, &state, size) >= 0) {
-                       seteuid(getuid());
-                       return;
-               }
-               seteuid(getuid());
-       } else if (kvm_write(kvp->kd, (u_long)&p->state, (void *)&state, size)
-                   == size) {
-               return;
-       }
-bad:
-       warnx("warning: cannot turn profiling %s",
-           state == GMON_PROF_OFF ? "off" : "on");
-}
-
-/*
- * Build the gmon.out file.
- */
-void
-dumpstate(struct kvmvars *kvp)
-{
-       FILE *fp;
-       struct rawarc rawarc;
-       struct tostruct *tos;
-       u_long frompc;
-       u_short *froms, *tickbuf;
-       int mib[3];
-       size_t i;
-       struct gmonhdr h;
-       int fromindex, endfrom, toindex;
-
-       setprof(kvp, GMON_PROF_OFF);
-       fp = fopen("gmon.out", "w");
-       if (fp == NULL) {
-               warn("gmon.out");
-               return;
-       }
-
-       /*
-        * Build the gmon header and write it to a file.
-        */
-       bzero(&h, sizeof(h));
-       h.lpc = kvp->gpm.lowpc;
-       h.hpc = kvp->gpm.highpc;
-       h.ncnt = kvp->gpm.kcountsize + sizeof(h);
-       h.version = GMONVERSION;
-       h.profrate = kvp->gpm.profrate;
-       fwrite((char *)&h, sizeof(h), 1, fp);
-
-       /*
-        * Write out the tick buffer.
-        */
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_PROF;
-       if ((tickbuf = (u_short *)malloc(kvp->gpm.kcountsize)) == NULL)
-               errx(5, "cannot allocate kcount space");
-       if (kflag) {
-               i = kvm_read(kvp->kd, (u_long)kvp->gpm.kcount, (void *)tickbuf,
-                   kvp->gpm.kcountsize);
-       } else {
-               mib[2] = GPROF_COUNT;
-               i = kvp->gpm.kcountsize;
-               if (sysctl(mib, 3, tickbuf, &i, NULL, 0) < 0)
-                       i = 0;
-       }
-       if (i != kvp->gpm.kcountsize)
-               errx(6, "read ticks: read %lu, got %zd: %s",
-                   kvp->gpm.kcountsize, i,
-                   kflag ? kvm_geterr(kvp->kd) : strerror(errno));
-       if ((fwrite(tickbuf, kvp->gpm.kcountsize, 1, fp)) != 1)
-               err(7, "writing tocks to gmon.out");
-       free(tickbuf);
-
-       /*
-        * Write out the arc info.
-        */
-       if ((froms = (u_short *)malloc(kvp->gpm.fromssize)) == NULL)
-               errx(8, "cannot allocate froms space");
-       if (kflag) {
-               i = kvm_read(kvp->kd, (u_long)kvp->gpm.froms, (void *)froms,
-                   kvp->gpm.fromssize);
-       } else {
-               mib[2] = GPROF_FROMS;
-               i = kvp->gpm.fromssize;
-               if (sysctl(mib, 3, froms, &i, NULL, 0) < 0)
-                       i = 0;
-       }
-       if (i != kvp->gpm.fromssize)
-               errx(9, "read froms: read %lu, got %zd: %s",
-                   kvp->gpm.fromssize, i,
-                   kflag ? kvm_geterr(kvp->kd) : strerror(errno));
-       if ((tos = (struct tostruct *)malloc(kvp->gpm.tossize)) == NULL)
-               errx(10, "cannot allocate tos space");
-       if (kflag) {
-               i = kvm_read(kvp->kd, (u_long)kvp->gpm.tos, (void *)tos,
-                   kvp->gpm.tossize);
-       } else {
-               mib[2] = GPROF_TOS;
-               i = kvp->gpm.tossize;
-               if (sysctl(mib, 3, tos, &i, NULL, 0) < 0)
-                       i = 0;
-       }
-       if (i != kvp->gpm.tossize)
-               errx(11, "read tos: read %lu, got %zd: %s",
-                   kvp->gpm.tossize, i,
-                   kflag ? kvm_geterr(kvp->kd) : strerror(errno));
-       if (debug)
-               warnx("lowpc 0x%tx, textsize 0x%lx",
-                             kvp->gpm.lowpc, kvp->gpm.textsize);
-       endfrom = kvp->gpm.fromssize / sizeof(*froms);
-       for (fromindex = 0; fromindex < endfrom; ++fromindex) {
-               if (froms[fromindex] == 0)
-                       continue;
-               frompc = (u_long)kvp->gpm.lowpc +
-                   (fromindex * kvp->gpm.hashfraction * sizeof(*froms));
-               for (toindex = froms[fromindex]; toindex != 0;
-                  toindex = tos[toindex].link) {
-                       if (debug)
-                           warnx("[mcleanup] frompc 0x%lx selfpc 0x%lx count %ld",
-                           frompc, tos[toindex].selfpc,
-                           tos[toindex].count);
-                       rawarc.raw_frompc = frompc;
-                       rawarc.raw_selfpc = (u_long)tos[toindex].selfpc;
-                       rawarc.raw_count = tos[toindex].count;
-                       fwrite((char *)&rawarc, sizeof(rawarc), 1, fp);
-               }
-       }
-       fclose(fp);
-}
-
-/*
- * Reset the kernel profiling date structures.
- */
-void
-reset(struct kvmvars *kvp)
-{
-       char *zbuf;
-       u_long biggest;
-       int mib[3];
-
-       setprof(kvp, GMON_PROF_OFF);
-
-       biggest = kvp->gpm.kcountsize;
-       if (kvp->gpm.fromssize > biggest)
-               biggest = kvp->gpm.fromssize;
-       if (kvp->gpm.tossize > biggest)
-               biggest = kvp->gpm.tossize;
-       if ((zbuf = (char *)malloc(biggest)) == NULL)
-               errx(12, "cannot allocate zbuf space");
-       bzero(zbuf, biggest);
-       if (kflag) {
-               if (kvm_write(kvp->kd, (u_long)kvp->gpm.kcount, zbuf,
-                   kvp->gpm.kcountsize) != kvp->gpm.kcountsize)
-                       errx(13, "tickbuf zero: %s", kvm_geterr(kvp->kd));
-               if (kvm_write(kvp->kd, (u_long)kvp->gpm.froms, zbuf,
-                   kvp->gpm.fromssize) != kvp->gpm.fromssize)
-                       errx(14, "froms zero: %s", kvm_geterr(kvp->kd));
-               if (kvm_write(kvp->kd, (u_long)kvp->gpm.tos, zbuf,
-                   kvp->gpm.tossize) != kvp->gpm.tossize)
-                       errx(15, "tos zero: %s", kvm_geterr(kvp->kd));
-               return;
-       }
-       seteuid(0);
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_PROF;
-       mib[2] = GPROF_COUNT;
-       if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.kcountsize) < 0)
-               err(13, "tickbuf zero");
-       mib[2] = GPROF_FROMS;
-       if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.fromssize) < 0)
-               err(14, "froms zero");
-       mib[2] = GPROF_TOS;
-       if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.tossize) < 0)
-               err(15, "tos zero");
-       seteuid(getuid());
-       free(zbuf);
-}