You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
413 lines
9.0 KiB
413 lines
9.0 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
bldrthnk.h
|
|
|
|
Abstract:
|
|
|
|
Include file defining a number of structures used by bldrthnk.c. This
|
|
file also includes some M4 preprocessor directives, see INCLUDE_M4.
|
|
|
|
Author:
|
|
|
|
Forrest C. Foltz (forrestf) 15-May-2000
|
|
|
|
|
|
To use:
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
//
|
|
// Maximum identifier name length
|
|
//
|
|
|
|
#define MAX_NAME_LENGTH 128
|
|
|
|
//
|
|
// FIELD_DEF Describes a field definition within a structure's field list.
|
|
//
|
|
|
|
typedef struct _FIELD_DEF {
|
|
CHAR Name[MAX_NAME_LENGTH];
|
|
CHAR TypeName[MAX_NAME_LENGTH];
|
|
ULONG TypeSize;
|
|
ULONG Offset;
|
|
ULONG Size;
|
|
CHAR SizeFormula[MAX_NAME_LENGTH];
|
|
} FIELD_DEF, *PFIELD_DEF;
|
|
|
|
//
|
|
// STRUC_DEF describes a structure.
|
|
//
|
|
|
|
typedef struct _STRUC_DEF {
|
|
|
|
//
|
|
// Name of this structure type
|
|
//
|
|
|
|
CHAR Name[MAX_NAME_LENGTH];
|
|
|
|
//
|
|
// Total size of the structure
|
|
//
|
|
|
|
ULONG Size;
|
|
|
|
//
|
|
// Array of field pointers. Defined as ULONGLONG to ensure an identical
|
|
// layout between 32- and 64-bit objs.
|
|
//
|
|
|
|
ULONGLONG Fields[];
|
|
|
|
} STRUC_DEF, *PSTRUC_DEF;
|
|
|
|
//
|
|
// Master array of pointers to structure definitions.
|
|
//
|
|
typedef struct _DEFINITIONS *PDEFINITIONS;
|
|
typedef struct _DEFINITIONS {
|
|
|
|
//
|
|
// Two signatures, SIG_1 and SIG_2 to facilitate locating this list
|
|
// within an .OBJ.
|
|
//
|
|
|
|
ULONG Sig1;
|
|
ULONG Sig2;
|
|
|
|
//
|
|
// Array of pointers to STRUC_DEFs. Defined as ULONGLONG to ensure
|
|
// identical layout between 32- and 64-bit.
|
|
//
|
|
|
|
ULONGLONG Structures[];
|
|
|
|
} DEFINITIONS;
|
|
|
|
//
|
|
// SIG_1 and SIG_2 are expected to be found in DEFINITIONS.Sig1 and
|
|
// DEFINITIONS.Sig2, respectively.
|
|
//
|
|
|
|
#define SIG_1 (ULONG)'Sig1'
|
|
#define SIG_2 (ULONG)'Sig2'
|
|
|
|
//
|
|
// Macro used to generate a boolean value representing whether the given
|
|
// type is considered signed or unsigned by the compiler.
|
|
//
|
|
|
|
#define IS_SIGNED_TYPE(x) (((x)-1) < ((x)0))
|
|
|
|
#if defined(_WIN64)
|
|
#define ONLY64(x) x
|
|
#else
|
|
#define ONLY64(x) 0
|
|
#endif
|
|
|
|
//
|
|
// Structures will ultimately be described as arrays of COPY_REC structures.
|
|
// Each COPY_REC structure supplies the information necessary to copy a field
|
|
// from a 32-bit structure layout to a 64-bit structure layout.
|
|
//
|
|
|
|
typedef struct _COPY_REC {
|
|
|
|
//
|
|
// Offset of the field in a 32-bit structure.
|
|
//
|
|
|
|
USHORT Offset32;
|
|
|
|
//
|
|
// Offset of the field in a 64-bit structure.
|
|
//
|
|
|
|
USHORT Offset64;
|
|
|
|
//
|
|
// Size of the field in a 32-bit structure.
|
|
//
|
|
|
|
USHORT Size32;
|
|
|
|
//
|
|
// Size of the field in a 64-bit structure.
|
|
//
|
|
|
|
USHORT Size64;
|
|
|
|
//
|
|
// TRUE if the field should be sign-extended.
|
|
//
|
|
|
|
BOOLEAN SignExtend;
|
|
|
|
} COPY_REC, *PCOPY_REC;
|
|
|
|
#if !defined(ASSERT)
|
|
#define ASSERT(x)
|
|
#endif
|
|
|
|
//
|
|
// 64-bit list manipulation macros follow.
|
|
//
|
|
|
|
#define InitializeListHead64( ListHead ) \
|
|
(ListHead)->Flink = PTR_64(ListHead); \
|
|
(ListHead)->Blink = PTR_64(ListHead);
|
|
|
|
#define InsertTailList64( ListHead, Entry ) { \
|
|
PLIST_ENTRY_64 _EX_Blink; \
|
|
PLIST_ENTRY_64 _EX_ListHead; \
|
|
_EX_ListHead = (ListHead); \
|
|
_EX_Blink = PTR_32(_EX_ListHead->Blink); \
|
|
(Entry)->Flink = PTR_64(_EX_ListHead); \
|
|
(Entry)->Blink = PTR_64(_EX_Blink); \
|
|
_EX_Blink->Flink = PTR_64(Entry); \
|
|
_EX_ListHead->Blink = PTR_64(Entry); \
|
|
}
|
|
|
|
VOID
|
|
CopyRec(
|
|
IN PVOID Source,
|
|
OUT PVOID Destination,
|
|
IN PCOPY_REC CopyRecArray
|
|
);
|
|
|
|
#if defined(WANT_BLDRTHNK_FUNCTIONS)
|
|
|
|
ULONG
|
|
StringLen(
|
|
IN PCHAR Str
|
|
)
|
|
{
|
|
if (Str == NULL) {
|
|
return 0;
|
|
} else {
|
|
return strlen(Str)+sizeof(CHAR);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
CopyRec(
|
|
IN PVOID Source,
|
|
OUT PVOID Destination,
|
|
IN PCOPY_REC CopyRecArray
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
CopyRec copies the contents of a 32-bit structure to the equivalent
|
|
64-bit structure.
|
|
|
|
Arguments:
|
|
|
|
Source - Supplies a pointer to the 32-bit source structure.
|
|
|
|
Destination - Supplies a pointer to the 64-bit destination structure.
|
|
|
|
CopyRecArray - Supplies a pointer to a 0-terminated COPY_REC array
|
|
that describes the relationships between the 32- and 64-bit fields
|
|
within the structure.
|
|
|
|
Return value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PCOPY_REC copyRec;
|
|
PCHAR signDst;
|
|
ULONG extendBytes;
|
|
PCHAR src;
|
|
PCHAR dst;
|
|
CHAR sign;
|
|
|
|
copyRec = CopyRecArray;
|
|
while (copyRec->Size32 != 0) {
|
|
|
|
src = (PCHAR)Source + copyRec->Offset32;
|
|
dst = (PCHAR)Destination + copyRec->Offset64;
|
|
|
|
//
|
|
// Determine whether this looks like a KSEG0 pointer
|
|
//
|
|
|
|
if (copyRec->Size32 == sizeof(PVOID) &&
|
|
copyRec->Size64 == sizeof(POINTER64) &&
|
|
copyRec->SignExtend != FALSE &&
|
|
IS_KSEG0_PTR_X86( *(PULONG)src )) {
|
|
|
|
//
|
|
// Source appears to be a KSEG0 pointer. All pointers
|
|
// must be explicitly "thunked" during the copy phase, so
|
|
// set this pointer to a known value that we can look for
|
|
// later in order to detect pointers that haven't been
|
|
// thunked yet.
|
|
//
|
|
|
|
*(POINTER64 *)dst = PTR_64(*(PVOID *)src);
|
|
|
|
} else {
|
|
|
|
memcpy( dst, src, copyRec->Size32 );
|
|
|
|
//
|
|
// Determine whether to sign-extend or zero-extend
|
|
//
|
|
|
|
extendBytes = copyRec->Size64 - copyRec->Size32;
|
|
if (extendBytes > 0) {
|
|
|
|
signDst = dst + copyRec->Size32;
|
|
|
|
if (copyRec->SignExtend != FALSE &&
|
|
(*(signDst-1) & 0x80) != 0) {
|
|
|
|
//
|
|
// Signed value is negative, fill the high bits with
|
|
// ones.
|
|
//
|
|
|
|
sign = 0xFF;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Unsigned value or postitive signed value, fill the high
|
|
// bits with zeros.
|
|
//
|
|
|
|
sign = 0;
|
|
}
|
|
|
|
memset( signDst, sign, extendBytes );
|
|
}
|
|
}
|
|
|
|
copyRec += 1;
|
|
}
|
|
}
|
|
|
|
#endif // WANT_BLDRTHNK_FUNCTIONS
|
|
|
|
#if defined(INCLUDE_M4)
|
|
|
|
define(`IFDEF_WIN64',`#if defined(_WIN64)')
|
|
|
|
//
|
|
// Here begin the M4 macros used to build the structure definition module,
|
|
// which is subsequently compiled by both the 32- and 64-bit compiler, with
|
|
// the resulting object modules processed by bldrthnk.exe.
|
|
//
|
|
//
|
|
// A structure layout file consists of a number of structure definition
|
|
// blocks, terminated by a single DD().
|
|
//
|
|
// For example (underscores prepended to prevent M4 processing):
|
|
//
|
|
//
|
|
// SD( LIST_ENTRY )
|
|
// FD( Flink, PLIST_ENTRY )
|
|
// FD( Blink, PLIST_ENTRY )
|
|
// SE()
|
|
//
|
|
// DD()
|
|
//
|
|
|
|
define(`STRUC_NAME_LIST',`')
|
|
define(`FIELD_NAME_LIST',`')
|
|
|
|
//
|
|
// The SD macro begins the definition of a structure.
|
|
//
|
|
// Usage: SD( <structure_name> )
|
|
//
|
|
|
|
define(`SD', `define(`STRUC_NAME',`$1')
|
|
STRUC_NAME `gs_'STRUC_NAME; define(`_ONLY64',`') define(`STRUC_NAME_LIST', STRUC_NAME_LIST `(ULONGLONG)&g_'STRUC_NAME cma
|
|
)'
|
|
)
|
|
|
|
define(`SD64', `define(`STRUC_NAME',`$1')
|
|
IFDEF_WIN64
|
|
STRUC_NAME `gs_'STRUC_NAME; define(`_ONLY64',`#endif') define(`STRUC_NAME_LIST', STRUC_NAME_LIST ONLY64(`(ULONGLONG)&g_'STRUC_NAME) cma
|
|
)'
|
|
)
|
|
|
|
|
|
//
|
|
// The FD macro defines a field within a structure definition block
|
|
//
|
|
// Usage: FD( <field_name>, <type> )
|
|
//
|
|
|
|
define(`FD', `FIELD_DEF `g_'STRUC_NAME`_'$1 =
|
|
{ "$1",
|
|
"$2",
|
|
sizeof($2),
|
|
FIELD_OFFSET(STRUC_NAME,$1),
|
|
sizeof(`gs_'STRUC_NAME.$1),
|
|
"" };
|
|
define(`FIELD_NAME_LIST', FIELD_NAME_LIST `(ULONGLONG)&g_'STRUC_NAME`_'$1 cma
|
|
)'
|
|
)
|
|
|
|
//
|
|
// The FDC macro works like the previous macro, except that it is applied to
|
|
// a field that points to a buffer that must be copied as well.
|
|
//
|
|
|
|
define(`FDC', `FIELD_DEF `g_'STRUC_NAME`_'$1 =
|
|
{ "$1",
|
|
"$2",
|
|
sizeof($2),
|
|
FIELD_OFFSET(STRUC_NAME,$1),
|
|
sizeof(`gs_'STRUC_NAME.$1),
|
|
$3 };
|
|
define(`FIELD_NAME_LIST', FIELD_NAME_LIST `(ULONGLONG)&g_'STRUC_NAME`_'$1 cma
|
|
)'
|
|
)
|
|
|
|
|
|
//
|
|
// The SE macro marks the end of a structure definition.
|
|
//
|
|
// Usage: SE()
|
|
//
|
|
|
|
define(`SE', `STRUC_DEF `g_'STRUC_NAME = {
|
|
"STRUC_NAME", sizeof(STRUC_NAME),
|
|
{
|
|
define(`cma',`,') FIELD_NAME_LIST undefine(`cma') 0 }
|
|
define(`FIELD_NAME_LIST',`')
|
|
};'
|
|
_ONLY64
|
|
)
|
|
|
|
//
|
|
// The DD macro marks the end of all structure definitions, and results
|
|
// in the generation of a single DEFINITIONS structure.
|
|
//
|
|
// Usage: DD()
|
|
//
|
|
|
|
define(`DD', `DEFINITIONS Definitions = {
|
|
SIG_1, SIG_2,
|
|
{
|
|
define(`cma',`,') STRUC_NAME_LIST undefine(`cma') 0 }
|
|
}; define(`STRUC_NAME_LIST',`')');
|
|
|
|
#endif
|
|
|