/**************************************************************************** * * This code is Public Domain. It's new for JWasm. * * ======================================================================== * * Description: MS codeview debug info header. Values and structures * in this header are derived from document: * "Microsoft Symbol and Type Information" * Format Specifications for Windows Version 1.0 * Tool Interface Standards (TIS) * * CV 5 format is described in * "Visual C++ 5.0 Symbolic Debug Information Specification"; * the doc is available in MSDN libraries ( 199?-2001 ). * * CV 8 is not "officially" described. * It's an extended CV5 format - 'names' are no longer * prefixed by a 1-byte length, instead they are terminated * by a x'00 (asciiz). * Additionally, the $$SYMBOLS segment has now sub-sections * for filenames, files, linenumbers and symbols. ****************************************************************************/ #ifndef CVDBG_H #define CVDBG_H 1 #define CV4_SIGNATURE 1 #define CV5_SIGNATURE 2 #define CV8_SIGNATURE 4 /* not yet supported */ #define CV_SIGNATURE CV4_SIGNATURE /* default is CV4 */ /* reserved primitive types (0x0000-0x0FFF) */ struct cv_primitive_type { uint_16 size:3, /* see CV_PDS_ below */ reserved:1, /* added to size in CV8? */ type:4, /* see CV_PDT_ below */ mode:3, /* see CV_PDM_ below */ reserved2:1; }; /* typeref type. for CV4, this is uint_16, for CV5/CV8, it's uint_32 */ #if CV_SIGNATURE==CV4_SIGNATURE typedef uint_16 cv_typeref; #else typedef uint_32 cv_typeref; #endif /* bits 4-7 of predefined primitive types */ enum cv_predef_type_types { CV_PDT_SPECIAL = 0x00, /* CV_PDS_SPECIAL_xxx */ CV_PDT_SIGNED_INTEGRAL = 0x01, /* CV_PDS_INTEGRAL_xxx */ CV_PDT_UNSIGNED_INTEGRAL = 0x02, /* CV_PDS_INTEGRAL_xxx */ CV_PDT_BOOLEAN = 0x03, /* CV_PDS_INTEGRAL_xxx */ CV_PDT_REAL = 0x04, /* CV_PDS_REAL_xxx */ CV_PDT_COMPLEX = 0x05, /* CV_PDS_REAL_xxx */ CV_PDT_SPECIAL2 = 0x06, /* CV_PDS_SPECIAL2_xxx */ CV_PDT_REAL_INT_VALUE = 0x07 /* CV_PDS_REAL_INT_xxx */ /* values 08-0F are reserved */ }; /* bits 0-2 of predefined primitive types */ enum cv_predef_type_sizes { CV_PDS_SPECIAL_NO_TYPE = 0x00, CV_PDS_SPECIAL_ABSOLUTE = 0x01, CV_PDS_SPECIAL_SEGMENT = 0x02, CV_PDS_SPECIAL_VOID = 0x03, CV_PDS_SPECIAL_BASIC_CURRENCY = 0x04, CV_PDS_SPECIAL_BASIC_NEAR_STRING = 0x05, CV_PDS_SPECIAL_BASIC_FAR_STRING = 0x06, CV_PDS_SPECIAL_UNTRANSLATED = 0x07, CV_PDS_INTEGRAL_1BYTE = 0x00, CV_PDS_INTEGRAL_2BYTE = 0x01, CV_PDS_INTEGRAL_4BYTE = 0x02, CV_PDS_INTEGRAL_8BYTE = 0x03, /* values 4-7 reserved */ CV_PDS_REAL_32BIT = 0x00, CV_PDS_REAL_64BIT = 0x01, CV_PDS_REAL_80BIT = 0x02, CV_PDS_REAL_128BIT = 0x03, CV_PDS_REAL_48BIT = 0x04, /* values 5-7 reserved */ CV_PDS_SPECIAL2_BIT = 0x00, CV_PDS_SPECIAL2_PASCAL_CHAR = 0x01, /* values 2-7 reserved? */ CV_PDS_REAL_INT_CHAR = 0x00, CV_PDS_REAL_INT_WCHAR = 0x01, CV_PDS_REAL_INT_SINT16 = 0x02, CV_PDS_REAL_INT_UINT16 = 0x03, CV_PDS_REAL_INT_SINT32 = 0x04, CV_PDS_REAL_INT_UINT32 = 0x05, CV_PDS_REAL_INT_SINT64 = 0x06, CV_PDS_REAL_INT_UINT64 = 0x07, }; /* bits 8-10 of predefined primitive types */ enum cv_predef_type_modes { CV_PDM_DIRECT = 0x00, CV_PDM_NEARPTR = 0x01, CV_PDM_FARPTR = 0x02, CV_PDM_HUGEPTR = 0x03, CV_PDM_NEAR32PTR = 0x04, CV_PDM_FAR32PTR = 0x05, CV_PDM_NEAR64PTR = 0x06 /* value 7 reserved */ }; struct cv_attribute { uint_16 access:2, /* see CV_ATTR_ACC_ below */ mprop:3, /* see CV_ATTR_MPR_ below */ pseudo:1, noinherit:1, noconstruct:1, reserved:8; }; enum cv_attr_access { CV_ATTR_ACC_NOPROTECTION = 0, CV_ATTR_ACC_PRIVATE = 1, CV_ATTR_ACC_PROTECTED = 2, CV_ATTR_ACC_PUBLIC = 3, }; enum cv_attr_mprop { CV_ATTR_MPR_VANILLA = 0, CV_ATTR_MPR_VIRTUAL = 1, CV_ATTR_MPR_STATIC = 2, CV_ATTR_MPR_FRIEND = 3, CV_ATTR_MPR_INTRO_VIRTUAL = 4, CV_ATTR_MPR_PURE_VIRTUAL = 5, CV_ATTR_MPR_PURE_INTRO_VIRTUAL = 6, }; enum cv4_leaf_indices { CV4_LF_MODIFIER = 0x0001, CV4_LF_POINTER = 0x0002, /* emitted by jwasm */ CV4_LF_ARRAY = 0x0003, /* emitted by jwasm */ CV4_LF_CLASS = 0x0004, CV4_LF_STRUCTURE = 0x0005, /* emitted by jwasm */ CV4_LF_UNION = 0x0006, /* emitted by jwasm */ CV4_LF_ENUM = 0x0007, CV4_LF_PROCEDURE = 0x0008, /* not yet emitted by jwasm */ //CV4_LF_MFUNCTION = 0x0009, //CV4_LF_VTSHAPE = 0x000A, //CV4_LF_BARRAY = 0x000D, CV4_LF_ARGLIST = 0x0201, /* not yet emitted by jwasm */ CV4_LF_FIELDLIST = 0x0204, /* emitted by jwasm */ CV4_LF_BITFIELD = 0x0206, /* emitted by jwasm */ CV4_LF_MEMBER = 0x0406, /* emitted by jwasm */ }; enum cv5_leaf_indices { CV5_LF_POINTER = 0x1002, CV5_LF_ARRAY = 0x1003, CV5_LF_CLASS = 0x1004, CV5_LF_STRUCTURE = 0x1005, CV5_LF_UNION = 0x1006, CV5_LF_ENUM = 0x1007, CV5_LF_PROCEDURE = 0x1008, CV5_LF_ARGLIST = 0x1201, CV5_LF_FIELDLIST = 0x1203, CV5_LF_BITFIELD = 0x1205, CV5_LF_MEMBER = 0x1405, }; enum cv8_leaf_indices { CV8_LF_ARRAY = 0x1503, CV8_LF_STRUCTURE = 0x1505, CV8_LF_UNION = 0x1506, CV8_LF_MEMBER = 0x150D, }; enum cv_leaf_indices { LF_MODIFIER = 0x0001, LF_LABEL = 0x000E, /* emitted by jwasm */ #if CV_SIGNATURE==CV4_SIGNATURE LF_POINTER = CV4_LF_POINTER, LF_ARRAY = CV4_LF_ARRAY, LF_CLASS = CV4_LF_CLASS, LF_STRUCTURE = CV4_LF_STRUCTURE, LF_UNION = CV4_LF_UNION, LF_ENUM = CV4_LF_ENUM, LF_PROCEDURE = CV4_LF_PROCEDURE, LF_ARGLIST = CV4_LF_ARGLIST, LF_FIELDLIST = CV4_LF_FIELDLIST, LF_BITFIELD = CV4_LF_BITFIELD, LF_MEMBER = CV4_LF_MEMBER, #else LF_POINTER = CV5_LF_POINTER, LF_ARRAY = CV5_LF_ARRAY, LF_CLASS = CV5_LF_CLASS, LF_STRUCTURE = CV5_LF_STRUCTURE, LF_UNION = CV5_LF_UNION, LF_ENUM = CV5_LF_ENUM, LF_PROCEDURE = CV5_LF_PROCEDURE, LF_ARGLIST = CV5_LF_ARGLIST, LF_FIELDLIST = CV5_LF_FIELDLIST, LF_BITFIELD = CV5_LF_BITFIELD, LF_MEMBER = CV5_LF_MEMBER, #endif LF_NUMERIC = 0x8000, LF_CHAR = 0x8000, LF_SHORT = 0x8001, LF_USHORT = 0x8002, LF_LONG = 0x8003, LF_ULONG = 0x8004, LF_PAD0 = 0xF0, LF_PAD1 = 0xF1, LF_PAD2 = 0xF2, LF_PAD3 = 0xF3, LF_PAD4 = 0xF4, LF_PAD5 = 0xF5, LF_PAD6 = 0xF6, LF_PAD7 = 0xF7, LF_PAD8 = 0xF8, LF_PAD9 = 0xF9, LF_PAD10 = 0xFA, LF_PAD11 = 0xFB, LF_PAD12 = 0xFC, LF_PAD13 = 0xFD, LF_PAD14 = 0xFE, LF_PAD15 = 0xFF }; struct cv_typerec { uint_16 size; uint_16 leaf; }; /* values in attribute bits 0-4 */ enum cv_typerec_pointer_types { CV_TYPE_PTRTYPE_NEAR = 0, CV_TYPE_PTRTYPE_FAR = 1, CV_TYPE_PTRTYPE_HUGE = 2, CV_TYPE_PTRTYPE_BASED1 = 3, CV_TYPE_PTRTYPE_BASED2 = 4, CV_TYPE_PTRTYPE_BASED3 = 5, CV_TYPE_PTRTYPE_BASED4 = 6, CV_TYPE_PTRTYPE_BASED5 = 7, CV_TYPE_PTRTYPE_BASED6 = 8, CV_TYPE_PTRTYPE_BASED7 = 9, CV_TYPE_PTRTYPE_NEAR32 = 10, CV_TYPE_PTRTYPE_FAR32 = 11, }; #pragma pack(push, 1) struct cv_typerec_pointer { /* LF_POINTER v2.10: added */ struct cv_typerec tr; uint_16 attribute; union { struct cv_primitive_type pptype; /* predefined primitive type */ cv_typeref type; }; /* variant field ( size? ) */ }; struct cv_typerec_array { /* LF_ARRAY v2.10: added */ struct cv_typerec tr; cv_typeref elemtype; cv_typeref idxtype; uint_16 length; /* numeric leaf */ // length-prefixed name }; struct cv_typerec_structure { /* LF_STRUCTURE */ struct cv_typerec tr; uint_16 count; #if CV_SIGNATURE==CV4_SIGNATURE cv_typeref field; uint_16 property; /* see below */ cv_typeref dList; /* type of derivation list */ cv_typeref vshape;/* type of virtual function table shape descriptor */ #else uint_16 property; /* see below */ cv_typeref field; cv_typeref dList; /* type of derivation list */ cv_typeref vshape;/* type of virtual function table shape descriptor */ #endif uint_16 length; /* numeric leaf, size of structure */ // length-prefixed name }; /* property flags. some bits are for classes only */ enum cv_typerec_structure_property { CVTSP_PACKED = 0x001, /* is packed */ CVTSP_CTOR = 0x002, /* has constructors or destructors */ CVTSP_OVEROPS = 0x004, CVTSP_ISNESTED = 0x008, /* is nested class/structure */ CVTSP_CNESTED = 0x010, /* contains nested classes/structures */ CVTSP_OPASSIGN = 0x020, /* has overloaded assignment */ CVTSP_OPCAST = 0x040, /* has casting methods */ CVTSP_FWDREF = 0x080, /* is a forward ref */ CVTSP_SCOPED = 0x100, /* scoped definition */ }; struct cv_typerec_union { /* LF_UNION */ struct cv_typerec tr; uint_16 count; #if CV_SIGNATURE==CV4_SIGNATURE cv_typeref field; uint_16 property; #else uint_16 property; cv_typeref field; #endif uint_16 length; /* numeric leaf */ // length-prefixed name }; struct cv_typerec_procedure { /* LF_PROCEDURE */ struct cv_typerec tr; cv_typeref rvtype; /* type of return value */ uint_8 call; /* call convention ( C, Pascal, Fastcall, Stdcall, Syscall, Thiscall ) */ uint_8 rsvd; uint_16 numparams; /* number of parameters */ cv_typeref arglist; }; struct cv_typerec_label { /* LF_LABEL */ struct cv_typerec tr; uint_16 mode; /* see below, CV_TYPE_LABEL_ */ }; /* label flags (values for mode) */ enum cv_typerec_label_values { CV_TYPE_LABEL_NEAR = 0x00, CV_TYPE_LABEL_FAR = 0x04 }; struct cv_typerec_arglist { /* LF_ARGLIST */ struct cv_typerec tr; uint_16 argcount; //uint_16 indices[]; }; struct cv_typerec_fieldlist { /* LF_FIELDLIST */ struct cv_typerec tr; }; struct cv_typerec_bitfield { /* LF_BITFIELD */ struct cv_typerec tr; #if CV_SIGNATURE==CV4_SIGNATURE uint_8 length; uint_8 position; cv_typeref type; #else cv_typeref type; uint_8 length; uint_8 position; #endif }; struct cv_typerec_member { /* LF_MEMBER */ uint_16 leaf; #if CV_SIGNATURE==CV4_SIGNATURE cv_typeref type; struct cv_attribute attribute; #else struct cv_attribute attribute; cv_typeref type; #endif uint_16 offset; /* numeric leaf */ // length-prefixed name }; enum cv4_symbol_types { CV4_S_REGISTER = 0x0002, CV4_S_CONSTANT = 0x0003, CV4_S_UDT = 0x0004, CV4_S_BPREL32 = 0x0200, CV4_S_LDATA32 = 0x0201, CV4_S_GDATA32 = 0x0202, //CV4_S_PUB32 = 0x0203, CV4_S_LPROC32 = 0x0204, CV4_S_GPROC32 = 0x0205, //CV4_S_BLOCK32 = 0x0207, CV4_S_REGREL32 = 0x020C, CV4_S_LTHREAD32 = 0x020D, CV4_S_GTHREAD32 = 0x020E, }; /* CV5 symbol types. * the new types > 0x1000 have a 4 byte typeref. */ enum cv5_symbol_types { CV5_S_REGISTER = 0x1001, CV5_S_CONSTANT = 0x1002, CV5_S_UDT = 0x1003, CV5_S_MANYREG = 0x1005, CV5_S_BPREL32 = 0x1006, CV5_S_LDATA32 = 0x1007, CV5_S_GDATA32 = 0x1008, //CV5_S_PUB32 = 0x1009, CV5_S_LPROC32 = 0x100A, CV5_S_GPROC32 = 0x100B, CV5_S_REGREL32 = 0x100D, CV5_S_LTHREAD32 = 0x100E, CV5_S_GTHREAD32 = 0x100F, CV5_S_COMPILE = 0x1013, /* not documented in VC50 Spec */ }; /* CV8 symbol types. * this types also have a 4-byte typeref AND the name is * in asciiz format, not 1-byte-length-prefixed. */ enum cv8_symbol_types { CV8_S_OBJNAME = 0x1101, /* object filename */ CV8_S_BLOCK32 = 0x1103, CV8_S_LABEL32 = 0x1105, CV8_S_CONSTANT = 0x1107, CV8_S_UDT = 0x1108, CV8_S_BPREL32 = 0x110B, CV8_S_LDATA32 = 0x110C, CV8_S_GDATA32 = 0x110D, CV8_S_LPROC32 = 0x110F, CV8_S_GPROC32 = 0x1110, CV8_S_REGREL32 = 0x1111, CV8_S_LTHREAD32 = 0x1112, CV8_S_GTHREAD32 = 0x1113, }; enum cv_symbol_types { S_COMPILE = 0x0001, #if CV_SIGNATURE==CV4_SIGNATURE S_REGISTER = CV4_S_REGISTER, S_CONSTANT = CV4_S_CONSTANT, S_UDT = CV4_S_UDT, #else S_REGISTER = CV5_S_REGISTER, S_CONSTANT = CV5_S_CONSTANT, S_UDT = CV5_S_UDT, #endif //S_SSEARCH = 0x0005, /* used by CVPACK */ S_ENDBLK = 0x0006, /* end of PROC, BLOCK, THUNK, WITH */ //S_SKIP = 0x0007, //S_CVRES = 0x0008, /* reserved for CodeView */ S_OBJNAME = 0x0009, /* didn't change for CV5 ( CV8 is different ) */ //S_ENDARG = 0x000A, /* end of arguments, not needed */ //S_RETURN = 0x000D, S_BPREL16 = 0x0100, S_LDATA16 = 0x0101, S_GDATA16 = 0x0102, //S_PUB16 = 0x0103, /* emitted by linker */ S_LPROC16 = 0x0104, S_GPROC16 = 0x0105, //S_BLOCK16 = 0x0107, S_LABEL16 = 0x0109, //S_REGREL16 = 0x010C, #if CV_SIGNATURE==CV4_SIGNATURE S_BPREL32 = CV4_S_BPREL32, S_LDATA32 = CV4_S_LDATA32, S_GDATA32 = CV4_S_GDATA32, //S_PUB32 = CV4_S_PUB32, S_LPROC32 = CV4_S_LPROC32, S_GPROC32 = CV4_S_GPROC32, S_REGREL32 = CV4_S_REGREL32, S_LTHREAD32 = CV4_S_LTHREAD32, S_GTHREAD32 = CV4_S_GTHREAD32, #else S_BPREL32 = CV5_S_BPREL32, S_LDATA32 = CV5_S_LDATA32, S_GDATA32 = CV5_S_GDATA32, //S_PUB32 = CV5_S_PUB32, S_LPROC32 = CV5_S_LPROC32, S_GPROC32 = CV5_S_GPROC32, S_REGREL32 = CV5_S_REGREL32, S_LTHREAD32 = CV5_S_LTHREAD32, S_GTHREAD32 = CV5_S_GTHREAD32, #endif S_LABEL32 = 0x0209, /* didn't change for CV5 ( CV8 is different ) */ }; struct cv_symrec { uint_16 size; uint_16 type; //uint_8 data[]; }; struct cv_symrec_compile { /* S_COMPILE */ struct cv_symrec sr; uint_8 machine; /* see below enum cv_machines */ uint_8 Language; /* see below enum cv_languages */ union { uint_16 flags; struct { uint_8 PCodePresent:1, FloatPrecision:2, Floatpackage:2, AmbientData:3; /* see below enum cv_ambient_model */ uint_8 AmbientCode:3, /* see below enum cv_ambient_model */ Mode32:1, Reserved:4; }; }; // uint_8 version[]; /* length-prefixed string */ }; enum cv_machines { CV_MACH_8080 = 0, /* ??? */ CV_MACH_8086 = 1, /* also 80186 */ CV_MACH_80286 = 2, CV_MACH_80386 = 3, CV_MACH_80486 = 4, CV_MACH_PENTIUM = 5, CV_MACH_P2 = 6, /* also Pentium Pro */ CV_MACH_P3 = 7, CV_MACH_AMD64 = 0xD0, }; enum cv_languages { CV_LANG_C = 0, CV_LANG_CPP = 1, CV_LANG_FORTRAN = 2, CV_LANG_MASM = 3, CV_LANG_PASCAL = 4, CV_LANG_BASIC = 5, CV_LANG_COBOL = 6 }; enum cv_ambient_model { CV_AMB_NEAR = 0, CV_AMB_FAR = 1, CV_AMB_HUGE = 2, }; struct cv_symrec_register { /* S_REGISTER */ struct cv_symrec sr; cv_typeref type; uint_16 registr; /* low byte is register 1, high byte is (opt) register 2 */ // length-prefixed name }; struct cv_symrec_constant { /* S_CONSTANT */ struct cv_symrec sr; cv_typeref type; uint_16 value; /* numeric leaf */ // length-prefixed name }; struct cv_symrec_udt { /* S_UDT */ struct cv_symrec sr; cv_typeref type; // length-prefixed name }; struct cv_symrec_endblk { /* S_ENDBLK */ struct cv_symrec sr; }; struct cv_symrec_objname { /* S_OBJNAME */ struct cv_symrec sr; uint_32 Signature; // length-prefixed name }; struct cv_symrec_bprel16 { /* S_BPREL16 */ struct cv_symrec sr; int_16 offset; cv_typeref type; // length-prefixed name }; struct cv_symrec_ldata16 { /* S_LDATA16, S_GDATA16 */ struct cv_symrec sr; int_16 offset; uint_16 segment; cv_typeref type; // length-prefixed name }; struct cv_symrec_lproc16 { /* S_LPROC16, S_GPROC16 */ struct cv_symrec sr; uint_32 pParent; uint_32 pEnd; uint_32 pNext; uint_16 proc_length; uint_16 debug_start; uint_16 debug_end; uint_16 offset; uint_16 segment; cv_typeref proctype; /* typeref */ uint_8 flags; /* see enum cv_proc_flags */ // length-prefixed name }; enum cv_proc_flags { CV_PROCF_FPO = 0x01, /* no frame pointer */ CV_PROCF_INTERRUPT = 0x02, /* proc is interrrupt routine */ CV_PROCF_FAR = 0x04, /* proc does FAR return */ CV_PROCF_NEVER = 0x08, /* proc does not return */ }; struct cv_symrec_label16 { /* S_LABEL16 */ struct cv_symrec sr; int_16 offset; uint_16 segment; uint_8 flags; /* see enum cv_proc_flags */ // length-prefixed name }; struct cv_symrec_bprel32 { /* S_BPREL32 */ struct cv_symrec sr; int_32 offset; cv_typeref type; // length-prefixed name }; struct cv_symrec_ldata32 { /* S_LDATA32, S_GDATA32 */ struct cv_symrec sr; #if CV_SIGNATURE==CV4_SIGNATURE int_32 offset; uint_16 segment; cv_typeref type; #else cv_typeref type; int_32 offset; uint_16 segment; #endif // length-prefixed name }; struct cv_symrec_lproc32 { /* S_LPROC32, S_GPROC32 */ struct cv_symrec sr; uint_32 pParent; uint_32 pEnd; uint_32 pNext; uint_32 proc_length; uint_32 debug_start; uint_32 debug_end; #if CV_SIGNATURE==CV4_SIGNATURE uint_32 offset; uint_16 segment; cv_typeref proctype; /* typeref */ #else cv_typeref proctype; /* typeref */ uint_32 offset; uint_16 segment; #endif uint_8 flags; /* see enum cv_proc_flags */ // length-prefixed name }; enum cv_registers { CV_REG_START32 = 17, /* 17-24 are 32-bit GPRs */ CV_REG_ESP = CV_REG_START32+4, CV_REG_EBP = CV_REG_START32+5, #if AMD64_SUPPORT CV_REG_AMD64_START32 = 360, /* 360-367 are 32-bit GPRs R8D-R15D - undocumented! */ CV_REG_AMD64_START64 = 328, /* 328-343 are 64-bit GPRs - undocumented! */ CV_REG_RSP = CV_REG_AMD64_START64+7, CV_REG_RBP = CV_REG_AMD64_START64+6, #endif }; struct cv_symrec_regrel32 { /* S_REGREL32 */ struct cv_symrec sr; int_32 offset; #if CV_SIGNATURE==CV4_SIGNATURE uint_16 reg; cv_typeref type; #else cv_typeref type; uint_16 reg; #endif // length-prefixed name }; struct cv_symrec_label32 { /* S_LABEL32 */ struct cv_symrec sr; int_32 offset; uint_16 segment; uint_8 flags; /* see enum cv_proc_flags */ // length-prefixed name }; #if 0 /* CV8 declarations - not needed currently */ enum cv8_s_sections { CV8_SYMBOLS = 0xF1, CV8_LINNUM = 0xF2, CV8_FILENAMES = 0xF3, CV8_FILES = 0xF4, CV8_SECTYP_F5 = 0xF5, /* unknown */ }; /* CV8 line numbers - not supported yet */ struct cv8_linenumber_item { uint_32 offset; uint_32 line; }; struct cv8_linenumber_header { uint_32 section_start; uint_16 section_index; uint_32 section_length; uint_32 src_file; uint_32 num_items; /* number of cv8_linenumber_info items */ uint_32 length; }; #endif #pragma pack(pop) #endif