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