#ifdef __cplusplus
extern "C" {
#endif
#ifndef H_SCCSID
#include <sccs.h>
#endif /* ! H_SCCSID*/
H_SCCSID(@(#)mon.h	1.20	AIX);	/* Modified 9/17/89 00:49:06 */
/* 
 * (C) Copyright IBM Corp. 1989 
 * All Rights Reserved 
 * Licensed Materials - Property of IBM 
 */

#include	<sys/types.h>

#define MON_OUT	"mon.out"	/* Default data file name. */
#define	MON_SUM	"mon.sum"	/* Default summary file name. */
#define MPROGS0	600		/* Default (mcrt0) number of functions. */
#define MSCALE0	4		/* Default scaling. */
#define MRANGE0	11		/* Max number of PC ranges per mon.out file */

/*
**	Gathering of profile information (roughly) each clock tick is
**	implemented by having the kernel increment various timers in
**	the user data space based on the user text address at the time
**	of the clock tick.
*/
typedef unsigned short WORD;

/*
**	There is one monrange_t per profiling range. In the data file, these
**	structures immediately follow the header structure described below.
**	The timer offset entry is the offset relative to the start of the
**	data file of the compressed list of entries, while the timer address
**	entry is the address of the uncompressed list of entries in memory.
*/
typedef	struct	monrange_struct {
	ulong	r_low;		/* Low address. */
	ulong	r_high;		/* High address. */
	ulong	r_scale;	/* Scale used for this region. */
	ulong	r_ctimer;	/* Number of timer entries (compressed). */
	ulong	r_ntimer;	/* Number of timer entries (uncompressed). */
	ulong	r_otimer;	/* Offset to timer entries. */
	WORD	*r_atimer;	/* Address of timer entries. */
	ulong	r_ftimer;	/* Number of entries in first occurrence. */
	WORD	*r_stimer;	/* Address of summed timer entries. */
}	monrange_t;

/*
**	There is one monfunc_t structure for each routine. The f_fnpc entry
**	contains the address of where mcount returns, and therefore is
**	not the exact address of the start of the routine.
*/
typedef	struct	monfunc_struct	{
	ulong	f_fnpc;		/* Address of function (sort of). */
	ulong	f_mcnt;		/* Call count for function. */
#define	fnpc	f_fnpc
#define	mcnt	f_mcnt
}	monfunc_t;

/*	
**	To allow portability proper interpretation of the data file on
**	different architectures, it is necessary for the data file to
**	carry with it some information about the architecture of the
**	machine on which it was created. One approach would be to include
**	a data representation word (as defined in the datarep.h header)
**	but this has some drawbacks:
**
**	---	since it is defined as a word, the individual bytes
**		are subject to byte-ordering issues and therefore
**		not portable (as a word)
**	---	no information regarding bit-field order is provided
**
**	Therefore data representation information is passed through
**	a series of fields of different types that, by accessing as ulong,
**	allow determination of cross/native compatibility between
**	the system running prof and the system on which the data file
**	was generated:
**	---	chars: set to 0x12, 0x34, 0x56, and 0x78
**			(ulong 0x12345678 or 0x78563412)
**	---	high_bit: set to 1
**			(ulong 0x80000000 or 0x0000001)
**	---	data_float:	set to 1.0
**			(native IEEE 0x3f800000, native 370 0x41100000)
**	---	lc_a:	set to 'a'
**			(ox61 in ASCII, 0x81 in EBCDIC)
**
**	Full blown portability information, such as size/alignment
**	for basic types, is not attempted since this version of prof
**	is for AIX machines, which are similar in those respects.
**
**	WARNING: The size of monordet_t is different for various versions
**	of the AIX family compilers. Therefore the data in the file is
**	defined as ulong, and filled in by setting the appropriate field
**	in a monorder_t structure and then copying the field contents
**	as "data_32".
*/
typedef	union	monorder_union	{
	char	chars[4];
	ulong	data_32;
	ushort	data_16;
	int	high_bit:1;
	float	data_float;
	char	lc_a;
}	monorder_t;

/*
**	The monitor output file begins with a pmon_t structure.
**
**	Note: The idea behind the version stamp is that the stamp will allow
**	differentiation between "new"/"old" mon.out files. Since old files
**	started with the lowpc, it is (hopefully) unlikely that a mon.out
**	file will exist with MON_VERSION as the lowpc. Similarily, the
**	shared library support in some versions of prof/monitor flagged
**	there existence with a lowpc address of 0xfffffff. Therefore, in
**	choosing a value for MON_VERSION try to make it large, but not
**	all ones. Additionally, the definition should not be machine
**	specific with respect to byte order, therefore it is best to
**	select a byte value as the version, and replicate the value
**	in all bytes of the version entry.
*/
#define	MON_VERSION	0xfefefefe
#define	MON_ORDER	0x12345678
typedef	struct	pmon	{
	ulong	p_version;	/* Monitor() version information. */
	ulong	p_order;	/* Byte order information. */
	ulong	p_bitorder;	/* "High" bit set. */
	ulong	p_float1;	/* Floating point "1.0" (high order word) */
	ulong	p_minsize;	/* Size of monitored empty routine. */
	ulong	p_monitor;	/* Address of monitor(). */
	ulong	p_ihz;		/* Internal tick rate. */
	ulong	p_drw;		/* Data Representation Word. */

	ulong	p_nrange;	/* Number of ranges. */
	ulong	p_orange;	/* Offset to first range. */

	ulong	p_cfunc;	/* Number of compressed function entries. */
	ulong	p_nfunc;	/* Number of function entries. */
	ulong	p_ofunc;	/* Offset to first function entry. */

	monrange_t	*p_arange;	/* Address of ranges. */
	monfunc_t	*p_afunc;	/* Address of function call list. */
}	pmon_t;

/*
**	Copy of old definitions for prof/hdr structures.
**	Included here for compatibility.
*/
typedef	struct	prof	{
	daddr_t	p_low;		/* low sampling address */
	daddr_t	p_high;		/* high sampling address */
	WORD	*p_buff;	/* address of sampling buffer */
	int	p_bufsize;	/* size in bytes of buffer */
	int	p_scale;	/* scale factor */
}	prof_t;

typedef	struct hdr {
	char	*lpc;
	char	*hpc;
	int	nfns;
}	hdr_t;

#ifdef __cplusplus
}
#endif
