/*static char *SCCSID = "@(#)dynlocal.h	6.1 90/11/17";*/
/***	SCCSID = @(#)dynlocal.h	   13.5 90/01/27
 *
 *	Definitions for 32 bit private structures used by DosDynamicTrace.
 *
 *
 *	IBM/Microsoft Confidential
 *
 *	Copyright (c) IBM Corporation 1987, 1989
 *	Copyright (c) Microsoft Corporation 1987, 1989
 *
 *	All Rights Reserved
 */

/***ED+ dtl - DynamicTrace Locator Structure
 *
 *	This defines the DynamicTrace Locator structure.  There is
 *	one of these structures per segment in the traced module.
 *	This is used to keep information on a per-object basis.
 *
 *	An array of locator structures (one per object, 1-based index)
 *	is allocated from the kernel resident heap, and is referenced by
 *	dti_padtl. The number of locator structures is given by dti_cdtl.
 *
 */

struct	dtl_s	{
	ushort_t	dtl_fs;		// flags bit vector - per object info
	ushort_t	dtl_sel;	// Object's selector.  Zero = Invalid
	ulong_t		dtl_pBase;	// Object's Base linear address.
	ulong_t		dtl_cb;		// Size (in bytes) of object.
};

typedef struct	dtl_s  dtl_t;

/*end*/

extern	int	LDRGetDYNMteInfo(VMHOB hobmte, dtl_t **ppadtl, ulong_t *plcdtl,
			ulong_t *pModType);


/***EK+ DTL_ - Locator Structure flags definitions.
 *
 *	This defines the DynamicTrace Locator structure flags, as
 *	stored in dtl_fs.
 *
 *	DTL_CODE	- This object is executable
 *	DTL_RESOURCE	- This is a resource object
 *	DTL_TRACED	- This (code) object contains a tracepoint.
 *
 */

#define DTL_CODE	0x0001
#define DTL_RESOURCE	0x0002
#define DTL_TRACED	0x0100

/*end*/


/***LD+ dti_s - DynamicTrace Kernel Information Structure
 *
 *	The dti_s structure is a kernel header placed at the start
 *	of each DynamicTrace Object in the kernel.  This information
 *	is subject to change for future kernel implementations.
 *
 */

#define DTRHASHSIZE	256

struct	dti_s	{
	struct dto_s   *dti_pDTOScan;
	struct dto_s   *dti_pDTONext;
	ulong_t		dti_lfState;
	ulong_t		dti_cbDTO;
	ulong_t		dti_lAddrMin;
	ulong_t		dti_lAddrMax;
	ulong_t		dti_cdtl;
	dtl_t	       *dti_padtl;
	VMHOB		dti_hDTO;
	ushort_t	dti_cchLibName;
	uchar_t	       *dti_pchLibName;
	dtr_t	       *dti_apDTRHash[DTRHASHSIZE];
};

typedef struct	dti_s	dti_t;

/*end*/


/***EP+ Dynamic Trace Hash pointer folllowing
 *
 *	dtr_Offset is passed in from the user relative to dtr_Object.
 *	dtr_Offset is converted to a flat linear address by the kernel,
 *	when setting up the hash table.  At that point, dtr_Object
 *	becomes replaced with the hash table link, which is a flat pointer.
 *
 *	See dynapi.h for the dtr_s structure definition.
 *
 */

// XLATOFF
#define pdtrNextHash(pdtr)	((dtr_t *) pdtr-> dtr_Object)
#define pdtrNextSeq(pdtr)	((dtr_t *) ((ulong_t) pdtr + sizeof(dtr_t) + \
				(ulong_t) pdtr->dtr_cbDTCODE))
#define dynHashCalc(offset)	((unsigned char) (offset>>2))
// XLATON

/*end*/


/***LD+ dtb_s - DynamicTrace Kernel Buffer
 *
 *	When a tracepoint is taken, the data is collected in the
 *	following dtb_s structure.
 *
 *	There is exactly one of these structures available, which
 *	is one of the reasons why DynTrc is not reentrant.
 *
 *	This structure is always resident and locked when in use.
 *	Currently, it is stored in Dgroup.
 *
 */

#define CLRPNSTACKMAX	 16
#define CBLOGMAX	512

struct	dtb_s	{
	ulong_t		dtb_RPNStack[CLRPNSTACKMAX];

	ushort_t	dtb_MajCode;
	ushort_t	dtb_bfRas;
	ushort_t	dtb_MinCode;

	ushort_t	dtb_fAbort;
	ulong_t		dtb_cbLog;

	// dtb_Log MUST be the last element of the DTB structure.
	// Its actual length varies between 1 and CBLOGMAX.

	char		dtb_Log[CBLOGMAX];
};

typedef struct	dtb_s	dtb_t;

/*end*/

/***EP+ Dynamic Trace Kernel Object
 *
 *	The entire Dynamic Trace Kernel Object is made up of 4 sections :
 *
 *    - dto_dti : DynamicTrace Kernel Information Structure
 *		Contains kernel variables not defined by the user.
 *
 *    - dto_dth : DynamicTrace Header (32-bit)
 *		Contains per-object information passed in by the user.
 *
 *    - Variable length reserved Data section, currently holding no
 *	reserved data.  This starts at the end of dto_dth, and
 *	progresses to dth_pDTRHead.
 *
 *    - DynamicTrace records section.  This progresses from dth_pDTRHead
 *	to the end of the object.   The records are variable in number,
 *	length, and starting location, and therefore cannot be represented
 *	by a C structure.
 *
 */

struct	dto_s	{
	dti_t	dto_dti;
	dth_t	dto_dth;
	/* Variable length data area */
	/* List of tracepoint records. */
};

typedef struct	dto_s	dto_t;

/*end*/


/***LK+ Dynamic Trace object state (dti_lfState)
 *
 *	DTO_LALL	: Tracepoints listed in pdtoHeadAll
 *	DTO_LSCAN	: Tracepoints listed in pdtoHeadScan
 *	DTO_DETACHED	: Tracepoints are detached - no tracepoints are set.
 *	DTO_LOADING	: Tracepoints will be loaded again soon.
 *	DTO_CANSWAP	: Tracepoint object can be made swappable.
 *	DTO_SWAPPABLE	: Tracepoint object has been made swappable.
 *	DTO_TRUSTED	: All DTR linkages will stay within the dto object
 *	DTO_FIXEDUP	: All tracepoints are fixed up.
 *	DTO_SOMESET	: Some tracepoints may be set - hash table is valid.
 *	DTO_ALLSET	: All tracepoints valid and set.
 *	DTO_REATTACH	: Tracepoint object (re)attachement required
 *	DTO_PROGRAM	: Tracepoint object for program module (private arena)
 *	DTO_DLL		: Tracepoint object for library module (shared arena)
 *
 */

#define DTO_LALL	0x00000001
#define DTO_LSCAN	0x00000002
#define DTO_DETACHED	0x00000004
#define DTO_LOADING	0x00000008
#define DTO_CANSWAP	0x00000010
#define DTO_SWAPPABLE	0x00000020
#define DTO_TRUSTED	0x00000100
#define DTO_FIXEDUP	0x00000200
#define DTO_SOMESET	0x00000400
#define DTO_ALLSET	0x00000800
#define DTO_REATTACH	0x00001000
#define DTO_PROGRAM	0x00002000
#define DTO_DLL		0x00004000


/***LK+ Dynamic Trace record state (dtr_Reserved is a flags byte)
 *
 *	Note: We only have one byte to work with, and this is difficult
 *	to expand any more than it is, so be careful.
 *
 *	DTR_FIXEDUP	: This tracepoint is fixed up.  Hash table valid.
 *	DTR_COMPILED	: This tracepoint is compiled.
 *	DTR_VALID	: This tracepoint has been verified.
 *	DTR_SET		: This tracepoint is set.  (INT 3 set in code)
 *	DTR_NOCODE	: The code for this tracepoint is free
 *	DTR_REMOVED	: The tracepoint has been removed from the code
 *	DTR_PURGED	: The tracepoint has been purged from a debug alias
 *
 */

#define DTR_FIXEDUP	0x01
#define DTR_COMPILED	0x02
#define DTR_VALID	0x04
#define DTR_SET		0x08
#define DTR_NOCODE	0x10
#define DTR_REMOVED	0x20
#define DTR_PURGED	0x40

// XLATOFF
//	Internal Interfaces
//	API-control

extern	ulong_t dynAPIInsert	(dth_t *pdthUser);
extern	ulong_t dynAPIRemove	(VMHOB *phmteUser);
extern	ulong_t dynAPIClearAll	(void);
extern	ulong_t dynAPIGetVar	(dtgh_t *pdtghUser, dtgp_t *pdtgpUser);
extern	ulong_t dynAPIQuery	(dtqi_t *pdtqiUser, dtqo_t *pdtqoUser);

//	Internal interfaces
//	List Control

extern	ulong_t dynDTOLink	(dto_t *pdto);
extern	ulong_t dynDTOUnLink	(dto_t *pdto);

//	API assistants

extern	ulong_t dynDTORead11	(dto_t **ppdto, dth_t *pdthUser);
extern	ulong_t dynDTORead20	(dto_t **ppdto, dth_t *pdthUser);
extern	ulong_t dynAPIVerify	(dto_t *pdto);
extern	ulong_t dynInitialize	(void);
extern	void	dynShutdown	(void);

// XLATON

//	DynTrc Scan Routines
//	Standard DynTrc scan variables, passed down to workers as needed.

struct	dtlv_s	{
	dto_t	**dtlv_ppdtoHead;	// dto list head
	VMHOB	dtlv_hmte;		// MTE handle
	VMHOB	dtlv_hptda;		// Context handle
	VMHOB	dtlv_hobAlias;		// Handle to aliased object
	ushort_t dtlv_cchLibName;	// LibName length (strlen)
	char	*dtlv_pchLibName;	// LibName pointer
	ulong_t dtlv_pAlias;		// Linear address of alias
	ulong_t dtlv_cbAlias;		// Size of alias
	ulong_t dtlv_pAliasedPoint;	// Aliased address (target base)
	ulong_t dtlv_lAddrMin;		// minimum address of a range
	ulong_t dtlv_lAddrMax;		// max address of a range
	dtl_t	*dtlv_padtlOld;		// Old dtl array for DTRMove
	dtl_t	*dtlv_padtlNew;		// New dtl array for DTRMove
	ushort_t *dtlv_pasTargets;	// Compiler workspace address
	char	*dtlv_pResultUser;	// User result packet pointer
	ulong_t dtlv_cbResult;		// Actual size of result packet
	ulong_t dtlv_cbAllocRes;	// Allocated size for result packet
	ulong_t dtlv_ulCmd;		// Command
	dtgp_t	*dtlv_pdtgp;		// Pointer to a dtgp (parameter) struct
	ushort_t dtlv_ID;		// Identifier
};

typedef struct	dtlv_s	dtlv_t;

#define DYN_MAXTARGETS	256		// Max number of Compiler jump targets,
					// (space alloc'ed from heap)
					// See dtlv_pasTargets.

//	dynDTOScan Option Flags

#define DYN_DTOS_SHOULDEXIST	0x00000001	// Error if DTO not found
#define DYN_DTOS_MUSTEXIST	0x00000002	// Panic if DTO not found
#define DYN_DTOS_MATCHMTE	0x00000004	// Match hmte field in DTO
#define DYN_DTOS_REATTACH	0x00000008	// Scan only reattching modules
#define DYN_DTOS_ERRORPROP	0x00000010	// Propogate DTO worker errors
#define DYN_DTOS_ERROREXIT	0x00000020	// Exit if DTO worker error
#define DYN_DTOS_MATCHID	0x00000040	// Match ID field in DTO

//	dynDTRScan Option Flags

#define DYN_DTRS_ALIAS		0x00000100	// Create R/W page alias

#define DYN_DTRS_ERRORPROP	0x00001000	// Propogate DTR worker errors
#define DYN_DTRS_ERROREXIT	0x00002000	// Exit if DTR worker error
#define DYN_DTRS_IFSET		0x00004000	// Scan only if DTR bits set
#define DYN_DTRS_IFCLEAR	0x00008000	// Scan only if DTR bits clear
#define DYN_DTRS_IFSETMASK	0x00FF0000	// DTR_ bits (DYN_DTRS_IFSET)
#define DYN_DTRS_IFCLEARMASK	0xFF000000	// DTR_ bits (DYN_DTRS_IFCLEAR)
#define DYN_DTRS_IFSETSHIFT	16		// DTR_ mask (DYN_DTRS_IFSET)
#define DYN_DTRS_IFCLEARSHIFT	24		// DTR_ mask (DYN_DTRS_IFCLEAR)

// XLATOFF

extern	ulong_t dynDTOScan	(dto_t **ppdtoHead,	// dto list to traverse
				ulong_t flCmd,		// option flags
				ulong_t lAddrMin,	// inclusive range
				ulong_t lAddrMax,	// inclusive range
				ulong_t (*pfnWorker)
					(dto_t *, dtlv_t *),
				dtlv_t *pdtlv);

extern	ulong_t dynDTRScan     (dto_t *pdto,		// dto to traverse
				ulong_t flCmd,		// option flags
				ulong_t lAddrMin,	// inclusive range
				ulong_t lAddrMax,	// inclusive range
				ulong_t (*pfnWorker)
					(dto_t *, dtr_t *, dtlv_t *),
				dtlv_t *pdtlv);

//	DTO Workers

extern	ulong_t dynDTOVerify		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOFixup		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOSet		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOUnSet		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTODestroy		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOFree		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTODetach		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOMove		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOAttachCheck	(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOAttach		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOAttachError	(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTONullProc		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOMakeSwappable	(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOMakeResident	(dto_t *pdto, dtlv_t *pdtlv);

extern	ulong_t dynDTOPurgeRange	(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOReAttachRange	(dto_t *pdto, dtlv_t *pdtlv);

extern	ulong_t dynDTOGetVar		(dto_t *pdto, dtlv_t *pdtlv);
extern	ulong_t dynDTOQuery		(dto_t *pdto, dtlv_t *pdtlv);

//	DTR Workers

extern	ulong_t dynDTRFixup	(dto_t *pdto, dtr_t *pdtr, dtlv_t *pdtlv);
extern	ulong_t dynDTRCompile	(dto_t *pdto, dtr_t *pdtr, dtlv_t *pdtlv);
extern	ulong_t dynDTRValidate	(dto_t *pdto, dtr_t *pdtr, dtlv_t *pdtlv);
extern	ulong_t dynDTRSet	(dto_t *pdto, dtr_t *pdtr, dtlv_t *pdtlv);
extern	ulong_t dynDTRUnSet	(dto_t *pdto, dtr_t *pdtr, dtlv_t *pdtlv);
extern	ulong_t dynDTRDetach	(dto_t *pdto, dtr_t *pdtr, dtlv_t *pdtlv);
extern	ulong_t dynDTRMove	(dto_t *pdto, dtr_t *pdtr, dtlv_t *pdtlv);
extern	ulong_t dynDTRPurge	(dto_t *pdto, dtr_t *pdtr, dtlv_t *pdtlv);


/***LD+ DynamicTrace Tracepoint Object Lists
 *
 *	Each of the following point to a list of Tracepoint Objects.
 *	Each list is initially empty.
 *
 *	pdtoHeadAll
 *		Linked by dti_pDTONext, this is the list of all
 *		tracepoint objects.  (Overlayed with fDYNActive)
 *
 *	pdtoHeadScan
 *		Linked by dti_pDTOScan, this is the list of all
 *		tracepoint objects which have active tracepoints.
 *
 *	cdtoDetached
 *		Count of DTOs in the DTO_DETACHED state.  (pdtoHeadAll subset)
 *
 *	cdtoLoading
 *		Count of DTOs in the DTO_LOADING state.  (pdtoHeadAll subset)
 *
 *	fdynCodeLocked
 *		True if lockable DynTrc code is locked.
 */

#define pdtoHeadAll	((dto_t *) fDYNActive)

extern	dto_t  *pdtoHeadScan;
extern	ulong_t cdtoDetached;
extern	ulong_t cdtoLoading;
extern	ulong_t fdynCodeLocked;

/***LD+ DynamicTrace Global Data
 *
 *	This dtb is used to keep logging information for DynTrc.
 *
 */

extern	dtb_t	dynDTB;


/***LD	RASselSTDA - STDA selector for RAS logging.
 *
 *	If RASselSTDA is 0, RAS is disabled.
 *
 */

extern	ushort_t RASselSTDA;

// XLATON
/* ASM

;***	Stack frame for _dynInterpreter, setup by _DYNTrap3
;
;	All except dt_ESP and dt_pLog must be set up by _DYNTrap3
;	before calling _dynInterpreter.

dtci_frame	struc
	dt_ESP		dd	?	; Interpreter's ESP
	dt_FaultKind	dd	?	; GP Fault Kind. (see tci_GPFault)
	dt_pLog		dd	?	; Log pointer (16-bit offset)
	dt_pdto		dd	?	; pointer to DTO for interpreter
	dt_pdtr		dd	?	; pointer to DTR for interpreter
	dt_gs		dd	?	; gs register
	dt_fs		dd	?	; fs register
	dt_es		dd	?	; es register
	dt_pad		db	size pushad_s dup(?)	; pushad structure
	dt_ds		dd	?	; ds register
	dt_ret		dd	?	; FLAT return address
	dt_tnum		dd	?	; trap number (not used)
	dt_err		dd	?	; error code  (not used)
	dt_iret		db	size pltiret32_s dup(?) ; 32-bit iret frame
					; Note: PI32_SSESP will not exist
					; if pltiret32_cs is ring 0.
dtci_frame	ends

;	Memory Log Flags definition (see dtml_tokenid)

DYN_LF_VALIDMEMORY	equ	0		; valid memory log
DYN_LF_VALIDASCIIZ	equ	1		; valid asciiz log

DYN_LF_INVALIDSEL	equ	-1		; invalid selector
DYN_LF_NOTPRESSEL	equ	-2		; selector not present
DYN_LF_NOTPRESPAGE	equ	-3		; page not present

;	Memory and Asciiz Log Format
;	Null byte is NOT copied for the Asciiz log !!!

dtml_s		struc
dtml_token	db	?		; Memory Log Flags
dtml_length	dw	?		; Number of bytes
dtml_bytes	db	?		; bytes loged
dtml_s		ends

*/

/***LP	dynAssert - cause internal error if assertion fails
 *
 *	Given a boolean, this procedure causes an internal error if
 *	the boolean is false.  Typically, the value of this boolean is
 *	derived from some test expression.
 *
 *	dynAssert (f)
 *
 *	ENTRY	f		- boolean value (int)
 *	RETURN	NONE
 *
 *	CALLS	panicfmt
 *
 *	WARNING This procedure is implemented as a macro.
 *
 *	EFFECTS NONE
 */

// XLATOFF
#ifdef	MISCSTRICT
#define dynAssert(e) _assert(e)
#else
#define dynAssert(e)
#endif
// XLATON
