home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 4 / hacker04 / 04_HACK04.ISO / darwin / darwinx86.iso / usr / include / profile / i386 / profile-md.h < prev   
Encoding:
C/C++ Source or Header  |  2001-09-30  |  13.5 KB  |  391 lines

  1. /*
  2.  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
  3.  *
  4.  * @APPLE_LICENSE_HEADER_START@
  5.  * 
  6.  * The contents of this file constitute Original Code as defined in and
  7.  * are subject to the Apple Public Source License Version 1.1 (the
  8.  * "License").  You may not use this file except in compliance with the
  9.  * License.  Please obtain a copy of the License at
  10.  * http://www.apple.com/publicsource and read it before using this file.
  11.  * 
  12.  * This Original Code and all software distributed under the License are
  13.  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  14.  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
  17.  * License for the specific language governing rights and limitations
  18.  * under the License.
  19.  * 
  20.  * @APPLE_LICENSE_HEADER_END@
  21.  */
  22. /*
  23.  * @OSF_COPYRIGHT@
  24.  */
  25. /*
  26.  * HISTORY
  27.  * 
  28.  * Revision 1.1.1.1  1998/09/22 21:05:49  wsanchez
  29.  * Import of Mac OS X kernel (~semeria)
  30.  *
  31.  * Revision 1.1.1.1  1998/03/07 02:26:08  wsanchez
  32.  * Import of OSF Mach kernel (~mburg)
  33.  *
  34.  * Revision 1.1.5.2  1996/07/31  09:57:36  paire
  35.  *     Added some more constraints to __asm__ functions for compilation
  36.  *     under gcc2.7.1 for PROF_CNT_[L]{ADD|SUB} macros
  37.  *     [96/06/14            paire]
  38.  *
  39.  * Revision 1.1.5.1  1995/01/06  19:53:52  devrcs
  40.  *     mk6 CR668 - 1.3b26 merge
  41.  *     new file for mk6
  42.  *     [1994/10/12  22:25:27  dwm]
  43.  * 
  44.  * Revision 1.1.2.2  1994/05/16  19:19:26  meissner
  45.  *     Add {,L}PROF_CNT_{SUB,LSUB,OVERFLOW} macros for gprof command.
  46.  *     [1994/05/10  10:36:06  meissner]
  47.  * 
  48.  *     Correct 64-bit integer asms to specify result values as inputs, and use =g instead of =m.
  49.  *     Cast the integer argument to PROF_CNT_ADD to unsigned long, so a short register is widened.
  50.  *     Add more support for writing the gprof command.
  51.  *     PROF_CNT_{EQ,NE} should not use ^=, it just uses ^.
  52.  *     Round PROF_CNT_DIGITS up to 24 bytes so it is word aligned.
  53.  *     _profile_cnt_to_decimal now takes the low/high values as separate arguments.
  54.  *     Delete _profile_cnt_to_hex.
  55.  *     [1994/04/28  21:45:07  meissner]
  56.  * 
  57.  *     Add more 64 bit arithmetic macros to support writing gprof.
  58.  *     [1994/04/20  15:47:05  meissner]
  59.  * 
  60.  * Revision 1.1.2.1  1994/04/08  17:51:56  meissner
  61.  *     Correct spelling on LPROF_CNT_TO_LDOUBLE macro.
  62.  *     [1994/04/08  16:18:06  meissner]
  63.  * 
  64.  *     Make LHISTCOUNTER be 64 bits.
  65.  *     Define LPROF_CNT_INC to increment LHISTCOUNTER.
  66.  *     [1994/04/08  12:40:32  meissner]
  67.  * 
  68.  *     Make most stats 64 bits, except for things like memory allocation.
  69.  *     [1994/04/02  14:58:34  meissner]
  70.  * 
  71.  *     Add overflow support for {gprof,prof,old,dummy}_mcount counters.
  72.  *     [1994/03/17  20:13:37  meissner]
  73.  * 
  74.  *     Add gprof/prof overflow support
  75.  *     [1994/03/17  14:56:56  meissner]
  76.  * 
  77.  *     Define LHISTCOUNTER.
  78.  *     [1994/02/28  12:05:16  meissner]
  79.  * 
  80.  *     Set HISTFRACTION to 4, so new lprofil call takes the same space.
  81.  *     [1994/02/24  16:15:34  meissner]
  82.  * 
  83.  *     Add too_low/too_high to profile_stats.
  84.  *     [1994/02/16  22:38:23  meissner]
  85.  * 
  86.  *     Make prof_cnt_t unsigned long.
  87.  *     [1994/02/11  16:52:09  meissner]
  88.  * 
  89.  *     Remember function unique ptr in gfuncs structure to reset profiling.
  90.  *     Add support for range checking gprof arc {from,self}pc addresses.
  91.  *     Add counter for # times acontext was locked.
  92.  *     Expand copyright.
  93.  *     [1994/02/07  12:41:08  meissner]
  94.  * 
  95.  *     Keep track of the number of times the kernel overflows the HISTCOUNTER counter.
  96.  *     [1994/02/03  20:13:31  meissner]
  97.  * 
  98.  *     Add stats for {user,kernel,idle} mode in the kernel.
  99.  *     [1994/02/03  15:17:36  meissner]
  100.  * 
  101.  *     No change.
  102.  *     [1994/02/03  00:58:59  meissner]
  103.  * 
  104.  *     Combine _profile_{vars,stats,md}; Allow more than one _profile_vars.
  105.  *     [1994/02/01  12:04:04  meissner]
  106.  * 
  107.  *     Split # records to # gprof and # prof records.
  108.  *     Add my_cpu/max_cpu fields.
  109.  *     [1994/01/28  23:33:30  meissner]
  110.  * 
  111.  *     Eliminate hash_{size,mask} from gfuncs structure.
  112.  *     [1994/01/26  20:23:41  meissner]
  113.  * 
  114.  *     Add structure size fields to _profile_{vars,stats,md}.
  115.  *     Add major/minor version number to _profile_md.
  116.  *     Move allocation context block pointer to main structure.
  117.  *     Delete shift count for allocation contexts.
  118.  *     [1994/01/25  01:46:08  meissner]
  119.  * 
  120.  *     Add HASHFRACTION
  121.  *     [1994/01/22  01:14:02  meissner]
  122.  * 
  123.  *     Split profile-md.h into profile-internal.h and profile-md.
  124.  *     [1994/01/20  20:57:18  meissner]
  125.  * 
  126.  *     Fixup copyright.
  127.  *     [1994/01/18  23:08:14  meissner]
  128.  * 
  129.  *     Make flags byte-sized.
  130.  *     Add have_bb flag.
  131.  *     Add init_format flag.
  132.  *     [1994/01/18  21:57:18  meissner]
  133.  * 
  134.  *     CR 10198 - Initial version.
  135.  *     [1994/01/18  19:44:59  meissner]
  136.  * 
  137.  * $EndLog$
  138.  */
  139.  
  140. #ifndef _PROFILE_MD_H
  141. #define _PROFILE_MD_H
  142.  
  143. /*
  144.  * Define the interfaces between the assembly language profiling support
  145.  * that is common between the kernel, mach servers, and user space library.
  146.  */
  147.  
  148. /*
  149.  * Integer types used.
  150.  */
  151.  
  152. typedef    long        prof_ptrint_t;    /* hold either pointer or signed int */
  153. typedef    unsigned long    prof_uptrint_t;    /* hold either pointer or unsigned int */
  154. typedef    long        prof_lock_t;    /* lock word type */
  155. typedef unsigned char    prof_flag_t;    /* type for boolean flags */
  156.  
  157. /*
  158.  * Double precision counter.
  159.  */
  160.  
  161. typedef struct prof_cnt_t {
  162.     prof_uptrint_t    low;        /* low 32 bits of counter */
  163.     prof_uptrint_t    high;        /* high 32 bits of counter */
  164. } prof_cnt_t;
  165.  
  166. #if defined(__GNUC__) && !defined(lint)
  167. #define PROF_CNT_INC(cnt)                    \
  168.     __asm__("addl $1,%0; adcl $0,%1"            \
  169.         : "=g" ((cnt).low), "=g" ((cnt).high)        \
  170.         : "0" ((cnt).low), "1" ((cnt).high))
  171.  
  172. #define PROF_CNT_ADD(cnt,val)                    \
  173.     __asm__("addl %2,%0; adcl $0,%1"            \
  174.         : "=g,r" ((cnt).low), "=g,r" ((cnt).high)    \
  175.         : "r,g" ((unsigned long)(val)),            \
  176.         "0,0" ((cnt).low), "1,1" ((cnt).high))
  177.  
  178. #define PROF_CNT_LADD(cnt,val)                    \
  179.     __asm__("addl %2,%0; adcl %3,%1"            \
  180.         : "=g,r" ((cnt).low), "=g,r" ((cnt).high)    \
  181.         : "r,g" ((val).low), "r,g" ((val).high),    \
  182.         "0,0" ((cnt).low), "1,1" ((cnt).high))
  183.  
  184. #define PROF_CNT_SUB(cnt,val)                    \
  185.     __asm__("subl %2,%0; sbbl $0,%1"            \
  186.         : "=g,r" ((cnt).low), "=g,r" ((cnt).high)    \
  187.         : "r,g" ((unsigned long)(val)),            \
  188.         "0,0" ((cnt).low), "1,1" ((cnt).high))
  189.  
  190. #define PROF_CNT_LSUB(cnt,val)                    \
  191.     __asm__("subl %2,%0; sbbl %3,%1"            \
  192.         : "=g,r" ((cnt).low), "=g,r" ((cnt).high)    \
  193.         : "r,g" ((val).low), "r,g" ((val).high),    \
  194.         "0,0" ((cnt).low), "1,1" ((cnt).high))
  195.  
  196. #else
  197. #define PROF_CNT_INC(cnt)    ((++((cnt).low) == 0) ? ++((cnt).high) : 0)
  198. #define PROF_CNT_ADD(cnt,val)    (((((cnt).low + (val)) < (val)) ? ((cnt).high++) : 0), ((cnt).low += (val)))
  199. #define PROF_CNT_LADD(cnt,val)    (PROF_CNT_ADD(cnt,(val).low), (cnt).high += (val).high)
  200. #define PROF_CNT_SUB(cnt,val)    (((((cnt).low - (val)) > (cnt).low) ? ((cnt).high--) : 0), ((cnt).low -= (val)))
  201. #define PROF_CNT_LSUB(cnt,val)    (PROF_CNT_SUB(cnt,(val).low), (cnt).high -= (val).high)
  202. #endif
  203.  
  204. #define PROF_ULONG_TO_CNT(cnt,val)    (((cnt).high = 0), ((cnt).low = val))
  205. #define    PROF_CNT_OVERFLOW(cnt,high,low)    (((high) = (cnt).high), ((low) = (cnt).low))
  206. #define PROF_CNT_TO_ULONG(cnt)        (((cnt).high == 0) ? (cnt).low : 0xffffffffu)
  207. #define PROF_CNT_TO_LDOUBLE(cnt)    ((((long double)(cnt).high) * 4294967296.0L) + (long double)(cnt).low)
  208. #define PROF_CNT_TO_DECIMAL(buf,cnt)    _profile_cnt_to_decimal(buf, (cnt).low, (cnt).high)
  209. #define PROF_CNT_EQ_0(cnt)        (((cnt).high | (cnt).low) == 0)
  210. #define PROF_CNT_NE_0(cnt)        (((cnt).high | (cnt).low) != 0)
  211. #define PROF_CNT_EQ(cnt1,cnt2)        ((((cnt1).high ^ (cnt2).high) | ((cnt1).low ^ (cnt2).low)) == 0)
  212. #define PROF_CNT_NE(cnt1,cnt2)        ((((cnt1).high ^ (cnt2).high) | ((cnt1).low ^ (cnt2).low)) != 0)
  213. #define PROF_CNT_GT(cnt1,cnt2)        (((cnt1).high > (cnt2).high) || ((cnt1).low > (cnt2).low))
  214. #define PROF_CNT_LT(cnt1,cnt2)        (((cnt1).high < (cnt2).high) || ((cnt1).low < (cnt2).low))
  215.  
  216. /* max # digits + null to hold prof_cnt_t values (round up to multiple of 4) */
  217. #define PROF_CNT_DIGITS            24
  218.  
  219. /*
  220.  * Types of the profil counter.
  221.  */
  222.  
  223. typedef unsigned short    HISTCOUNTER;        /* profil */
  224. typedef prof_cnt_t    LHISTCOUNTER;        /* lprofil */
  225.  
  226. #define LPROF_ULONG_TO_CNT(cnt,val)    PROF_ULONG_TO_CNT(cnt,val)
  227. #define LPROF_CNT_INC(lp)        PROF_CNT_INC(lp)
  228. #define LPROF_CNT_ADD(lp,val)        PROF_CNT_ADD(lp,val)
  229. #define LPROF_CNT_LADD(lp,val)        PROF_CNT_LADD(lp,val)
  230. #define LPROF_CNT_SUB(lp,val)        PROF_CNT_SUB(lp,val)
  231. #define LPROF_CNT_LSUB(lp,val)        PROF_CNT_LSUB(lp,val)
  232. #define    LPROF_CNT_OVERFLOW(lp,high,low)    PROF_CNT_OVERFLOW(lp,high,low)
  233. #define LPROF_CNT_TO_ULONG(lp)        PROF_CNT_TO_ULONG(lp)
  234. #define LPROF_CNT_TO_LDOUBLE(lp)    PROF_CNT_TO_LDOUBLE(lp)
  235. #define LPROF_CNT_TO_DECIMAL(buf,cnt)    PROF_CNT_TO_DECIMAL(buf,cnt)
  236. #define LPROF_CNT_EQ_0(cnt)        PROF_CNT_EQ_0(cnt)
  237. #define LPROF_CNT_NE_0(cnt)        PROF_CNT_NE_0(cnt)
  238. #define LPROF_CNT_EQ(cnt1,cnt2)        PROF_CNT_EQ(cnt1,cnt2)
  239. #define LPROF_CNT_NE(cnt1,cnt2)        PROF_CNT_NE(cnt1,cnt2)
  240. #define LPROF_CNT_GT(cnt1,cnt2)        PROF_CNT_GT(cnt1,cnt2)
  241. #define LPROF_CNT_LT(cnt1,cnt2)        PROF_CNT_LT(cnt1,cnt2)
  242. #define LPROF_CNT_DIGITS        PROF_CNT_DIGITS
  243.  
  244. /*
  245.  *  fraction of text space to allocate for histogram counters
  246.  */
  247.  
  248. #define HISTFRACTION    4
  249.  
  250. /*
  251.  * Fraction of text space to allocate for from hash buckets.
  252.  */
  253.  
  254. #define HASHFRACTION    HISTFRACTION
  255.  
  256. /*
  257.  * Prof call count, external format.
  258.  */
  259.  
  260. struct prof_ext {
  261.     prof_uptrint_t    cvalue;        /* caller address */
  262.     prof_uptrint_t    cncall;        /* # of calls */
  263. };
  264.  
  265. /*
  266.  * Prof call count, internal format.
  267.  */
  268.  
  269. struct prof_int {
  270.     struct prof_ext    prof;        /* external prof struct */
  271.     prof_uptrint_t    overflow;    /* # times prof counter overflowed */
  272. };
  273.  
  274. /*
  275.  * Gprof arc, external format.
  276.  */
  277.  
  278. struct gprof_arc {
  279.     prof_uptrint_t     frompc;    /* caller's caller */
  280.     prof_uptrint_t     selfpc;    /* caller's address */
  281.     prof_uptrint_t     count;        /* # times arc traversed */
  282. };
  283.  
  284. /*
  285.  * Gprof arc, internal format.
  286.  */
  287.  
  288. struct hasharc {
  289.     struct hasharc    *next;        /* next gprof record */
  290.     struct gprof_arc arc;        /* gprof record */
  291.     prof_uptrint_t     overflow;    /* # times counter overflowed */
  292. };
  293.  
  294. /*
  295.  * Linked list of all function profile blocks.
  296.  */
  297.  
  298. #define MAX_CACHE    3        /* # cache table entries */
  299.  
  300. struct gfuncs {
  301.     struct hasharc **hash_ptr;        /* gprof hash table */
  302.     struct hasharc **unique_ptr;         /* function unique pointer */
  303.     struct prof_int prof;            /* -p stats for elf */
  304.     struct hasharc *cache_ptr[MAX_CACHE];    /* cache element pointers */
  305. };
  306.  
  307. /*
  308.  * Profile information which might be written out in ELF {,g}mon.out files.
  309.  */
  310.  
  311. #define MAX_BUCKETS 9            /* max bucket chain to print out */
  312.  
  313. struct profile_stats {            /* Debugging counters */
  314.     prof_uptrint_t major_version;    /* major version number */
  315.     prof_uptrint_t minor_version;    /* minor version number */
  316.     prof_uptrint_t stats_size;    /* size of profile_vars structure */
  317.     prof_uptrint_t profil_buckets;     /* # profil buckets */
  318.     prof_uptrint_t my_cpu;        /* identify current cpu/thread */
  319.     prof_uptrint_t max_cpu;        /* identify max cpu/thread */
  320.     prof_uptrint_t prof_records;    /* # of functions profiled */
  321.     prof_uptrint_t gprof_records;    /* # of gprof arcs */
  322.     prof_uptrint_t hash_buckets;    /* # gprof hash buckets */
  323.     prof_uptrint_t bogus_count;    /* # of bogus functions found in gprof */
  324.  
  325.     prof_cnt_t cnt;            /* # of calls to _{,g}prof_mcount */
  326.     prof_cnt_t dummy;        /* # of calls to _dummy_mcount */
  327.     prof_cnt_t old_mcount;        /* # of calls to old mcount */
  328.     prof_cnt_t hash_search;        /* # hash buckets searched */
  329.     prof_cnt_t hash_num;        /* # times hash table searched */
  330.     prof_cnt_t user_ticks;        /* # ticks in user space */
  331.     prof_cnt_t kernel_ticks;    /* # ticks in kernel space */
  332.     prof_cnt_t idle_ticks;        /* # ticks in idle mode */
  333.     prof_cnt_t overflow_ticks;    /* # ticks where HISTCOUNTER overflowed */
  334.     prof_cnt_t acontext_locked;    /* # times an acontext was locked */
  335.     prof_cnt_t too_low;        /* # times a histogram tick was too low */
  336.     prof_cnt_t too_high;        /* # times a histogram tick was too high */
  337.     prof_cnt_t prof_overflow;    /* # times a prof count field overflowed */
  338.     prof_cnt_t gprof_overflow;    /* # times a gprof count field overflowed */
  339.  
  340.                     /* allocation statistics */
  341.     prof_uptrint_t num_alloc  [(int)ACONTEXT_MAX];    /* # allocations */
  342.     prof_uptrint_t bytes_alloc[(int)ACONTEXT_MAX];    /* bytes allocated */
  343.     prof_uptrint_t num_context[(int)ACONTEXT_MAX];    /* # contexts */
  344.     prof_uptrint_t wasted     [(int)ACONTEXT_MAX];    /* wasted bytes */
  345.     prof_uptrint_t overhead   [(int)ACONTEXT_MAX];    /* overhead bytes */
  346.  
  347.     prof_uptrint_t buckets[MAX_BUCKETS+1]; /* # hash indexes that have n buckets */
  348.     prof_cnt_t     cache_hits[MAX_CACHE];  /* # times nth cache entry matched */
  349.  
  350.     prof_cnt_t stats_unused[64];    /* reserved for future use */
  351. };
  352.  
  353. #define PROFILE_MAJOR_VERSION 1
  354. #define PROFILE_MINOR_VERSION 1
  355.  
  356. /*
  357.  * Machine dependent fields.
  358.  */
  359.  
  360. struct profile_md {
  361.     int major_version;        /* major version number */
  362.     int minor_version;        /* minor version number */
  363.     size_t md_size;            /* size of profile_md structure */
  364.     struct hasharc **hash_ptr;    /* gprof hash table */
  365.     size_t hash_size;        /* size of hash table */
  366.     prof_uptrint_t num_cache;    /* # of cache entries */
  367.     void (*save_mcount_ptr)(void);    /* save for _mcount_ptr */
  368.     void (**mcount_ptr_ptr)(void);    /* pointer to _mcount_ptr */
  369.     struct hasharc *dummy_ptr;    /* pointer to dummy gprof record */
  370.     void *(*alloc_pages)(size_t);    /* pointer to _profile_alloc_pages */
  371.     char num_buffer[PROF_CNT_DIGITS]; /* convert 64 bit ints to string */
  372.     long md_unused[58];        /* add unused fields */
  373. };
  374.  
  375. /*
  376.  * Record information about each function call.  Specify
  377.  * caller, caller's caller, and a unique label for use by
  378.  * the profiling routines.
  379.  */
  380. extern void _prof_mcount(void);
  381. extern void _gprof_mcount(void);
  382. extern void _dummy_mcount(void);
  383. extern void (*_mcount_ptr)(void);
  384.  
  385. /*
  386.  * Function in profile-md.c to convert prof_cnt_t to string format (decimal & hex).
  387.  */
  388. extern char *_profile_cnt_to_decimal(char *, prof_uptrint_t, prof_uptrint_t);
  389.  
  390. #endif /* _PROFILE_MD_H */
  391.