diff options
Diffstat (limited to 'include/iprt/formats')
39 files changed, 18533 insertions, 0 deletions
diff --git a/include/iprt/formats/Makefile.kup b/include/iprt/formats/Makefile.kup new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/include/iprt/formats/Makefile.kup diff --git a/include/iprt/formats/apfs.h b/include/iprt/formats/apfs.h new file mode 100644 index 00000000..7d5f1462 --- /dev/null +++ b/include/iprt/formats/apfs.h @@ -0,0 +1,244 @@ +/* $Id: apfs.h $ */ +/** @file + * IPRT, APFS (Apple File System) format. + */ + +/* + * Copyright (C) 2019-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_apfs_h +#define IPRT_INCLUDED_formats_apfs_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_apfs Apple File System structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + +/* + * The filesystem structures were retrieved from: + * https://developer.apple.com/support/downloads/Apple-File-System-Reference.pdf + */ + +/** Physical address of an on-disk block. */ +typedef int64_t APFSPADDR; +/** Object identifier. */ +typedef uint64_t APFSOID; +/** Transaction identifier. */ +typedef uint64_t APFSXID; + +/** Invalid object ID. */ +#define APFS_OID_INVALID UINT64_C(0) +/** Number of reserved object IDs for special structures. */ +#define APFS_OID_RSVD_CNT 1024 +/** Object ID of a super block. */ +#define APFS_OID_NX_SUPERBLOCK UINT64_C(1) + + +/** + * Range of physical addresses. + */ +typedef struct +{ + /** Start address of the range. */ + APFSPADDR PAddrStart; + /** Size of the range in blocks.*/ + uint64_t cBlocks; +} APFSPRANGE; +/** Pointer to a APFS range. */ +typedef APFSPRANGE *PAPFSPRANGE; +/** Pointer to a const APFS range. */ +typedef const APFSPRANGE *PCAPFSPRANGE; + +/** APFS UUID (compatible with our UUID definition). */ +typedef RTUUID APFSUUID; + +/** Maximum object checksum size. */ +#define APFS_OBJ_MAX_CHKSUM_SZ 8 + +/** + * APFS Object header. + */ +typedef struct APFSOBJPHYS +{ + /** The stored checksum of the object. */ + uint8_t abChkSum[APFS_OBJ_MAX_CHKSUM_SZ]; + /** Object ID. */ + APFSOID Oid; + /** Transaction ID. */ + APFSXID Xid; + /** Object type. */ + uint32_t u32Type; + /** Object sub type. */ + uint32_t u32SubType; +} APFSOBJPHYS; +/** Pointer to an APFS object header. */ +typedef APFSOBJPHYS *PAPFSOBJPHYS; +/** Pointer to a const APFS object header. */ +typedef const APFSOBJPHYS *PCAPFSOBJPHYS; + +#define APFS_OBJECT_TYPE_MASK UINT32_C(0x0000ffff) +#define APFS_OBJECT_TYPE_FLAGS_MASK UINT32_C(0xffff0000) + +/** + * APFS EFI jumpstart information. + */ +typedef struct APFSEFIJMPSTART +{ + /** Object header. */ + APFSOBJPHYS ObjHdr; + /** The magic value. */ + uint32_t u32Magic; + /** The version of the structure. */ + uint32_t u32Version; + /** EFI file length in bytes. */ + uint32_t cbEfiFile; + /** Number of extents describing the on disk blocks the file is stored in. */ + uint32_t cExtents; + /** Reserved. */ + uint64_t au64Rsvd0[16]; + /** After this comes a variable size of APFSPRANGE extent structures. */ +} APFSEFIJMPSTART; +/** Pointer to an APFS EFI jumpstart structure. */ +typedef APFSEFIJMPSTART *PAPFSEFIJMPSTART; +/** Pointer to a const APFS EFI jumpstart structure. */ +typedef const APFSEFIJMPSTART *PCAPFSEFIJMPSTART; + +/** EFI jumpstart magic ('RDSJ'). */ +#define APFS_EFIJMPSTART_MAGIC RT_MAKE_U32_FROM_U8('J', 'S', 'D', 'R') +/** EFI jumpstart version. */ +#define APFS_EFIJMPSTART_VERSION UINT32_C(1) + +/** Maximum number of filesystems supported in a single container. */ +#define APFS_NX_SUPERBLOCK_FS_MAX UINT32_C(100) +/** Maximum number of counters in the superblock. */ +#define APFS_NX_SUPERBLOCK_COUNTERS_MAX UINT32_C(32) +/** Number of entries in the ephemeral information array. */ +#define APFS_NX_SUPERBLOCK_EPH_INFO_COUNT UINT32_C(4) + +/** + * APFS super block. + */ +typedef struct +{ + /** Object header. */ + APFSOBJPHYS ObjHdr; + /** The magic value. */ + uint32_t u32Magic; + /** Block size in bytes. */ + uint32_t cbBlock; + /** Number of blocks in the volume. */ + uint64_t cBlocks; + /** Feature flags of the volume. */ + uint64_t fFeatures; + /** Readonly compatible features. */ + uint64_t fRdOnlyCompatFeatures; + /** Incompatible features. */ + uint64_t fIncompatFeatures; + /** UUID of the volume. */ + APFSUUID Uuid; + /** Next free object identifier to use for new objects. */ + APFSOID OidNext; + /** Next free transaction identifier to use for new transactions. */ + APFSOID XidNext; + /** Number of blocks used by the checkpoint descriptor area. */ + uint32_t cXpDescBlocks; + /** Number of blocks used by the checkpoint data area. */ + uint32_t cXpDataBlocks; + /** Base address of checkpoint descriptor area. */ + APFSPADDR PAddrXpDescBase; + /** Base address of checkpoint data area. */ + APFSPADDR PAddrXpDataBase; + /** Next index to use in the checkpoint descriptor area. */ + uint32_t idxXpDescNext; + /** Next index to use in the checkpoint data area. */ + uint32_t idxXpDataNext; + /** Number of blocks in the checkpoint descriptor area used by the checkpoint that this superblock belongs to. */ + uint32_t cXpDescLen; + /** Index of the first valid item in the checkpoint data area. */ + uint32_t idxXpDataFirst; + /** Number of blocks in the checkpoint data area used by the checkpoint that this superblock belongs to. */ + uint32_t cXpDataLen; + /** Ephemeral object identifer of the space manager. */ + APFSOID OidSpaceMgr; + /** Physical object identifier for the containers object map. */ + APFSOID OidOMap; + /** Ephemeral object identifer for the reaper. */ + APFSOID OidReaper; + /** Reserved for testing should be always zero on disk. */ + uint32_t u32TestType; + /** Maximum number of filesystems which can be stored in this container. */ + uint32_t cFsMax; + /** Array of filesystem object identifiers. */ + APFSOID aFsOids[APFS_NX_SUPERBLOCK_FS_MAX]; + /** Array of counters primarily used during debugging. */ + uint64_t aCounters[APFS_NX_SUPERBLOCK_COUNTERS_MAX]; + /** Range of blocks where no space will be allocated, used for shrinking a partition. */ + APFSPRANGE RangeBlocked; + /** Physical object identifier of a tree keeping track of objects needing to be moved out of the block range. */ + APFSOID OidTreeEvictMapping; + /** Container flags. */ + uint64_t fFlags; + /** Address of the EFI jumpstart structure. */ + APFSPADDR PAddrEfiJmpStart; + /** UUID of the containers Fusion set if available. */ + APFSUUID UuidFusion; + /** Address of the containers keybag. */ + APFSPADDR PAddrKeyLocker; + /** Array of fields used in the management of ephemeral data. */ + uint64_t au64EphemeralInfo[APFS_NX_SUPERBLOCK_EPH_INFO_COUNT]; + /** Reserved for testing. */ + APFSOID OidTest; + /** Physical object identifier of the Fusion middle tree. */ + APFSOID OidFusionMt; + /** Ephemeral object identifier of the Fusion write-back cache state. */ + APFSOID OidFusionWbc; + /** Blocks used for the Fusion write-back cache area. */ + APFSPRANGE RangeFusionWbc; +} APFSNXSUPERBLOCK; +/** Pointer to a APFS super block structure. */ +typedef APFSNXSUPERBLOCK *PAPFSNXSUPERBLOCK; +/** Pointer to a const APFS super block structure. */ +typedef const APFSNXSUPERBLOCK *PCAPFSNXSUPERBLOCK; + +/** Superblock magic value ('BSXN'). */ +#define APFS_NX_SUPERBLOCK_MAGIC RT_MAKE_U32_FROM_U8('N', 'X', 'S', 'B') + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_apfs_h */ + diff --git a/include/iprt/formats/asn1.h b/include/iprt/formats/asn1.h new file mode 100644 index 00000000..2f9b2f63 --- /dev/null +++ b/include/iprt/formats/asn1.h @@ -0,0 +1,107 @@ +/** @file + * IPRT - Abstract Syntax Notation One (ASN.1) Definitions. + */ + +/* + * Copyright (C) 2014-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_asn1_h +#define IPRT_INCLUDED_formats_asn1_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/cdefs.h> + + +/** @defgroup grp_rt_formats_asn1 ASN.1 definitions + * @ingroup grp_rt_formats + * + * @{ */ + +/** @name Tag classes. + * @{ */ +#define ASN1_TAGCLASS_UNIVERSAL UINT8_C(0x00) +#define ASN1_TAGCLASS_APPLICATION UINT8_C(0x40) +#define ASN1_TAGCLASS_CONTEXT UINT8_C(0x80) +#define ASN1_TAGCLASS_PRIVATE UINT8_C(0xc0) +#define ASN1_TAGCLASS_MASK UINT8_C(0xc0) +/** @} */ + +/** Primitive encoding. */ +#define ASN1_TAGFLAG_PRIMITIVE UINT8_C(0x00) +/** Constructed encoding, as opposed to primitive. */ +#define ASN1_TAGFLAG_CONSTRUCTED UINT8_C(0x20) + +/** The tag value mask. */ +#define ASN1_TAG_MASK UINT8_C(0x1f) + +/** @name ASN.1 universal tags. + * @{ */ +#define ASN1_TAG_EOC UINT8_C(0x00) +#define ASN1_TAG_BOOLEAN UINT8_C(0x01) +#define ASN1_TAG_INTEGER UINT8_C(0x02) +#define ASN1_TAG_BIT_STRING UINT8_C(0x03) +#define ASN1_TAG_OCTET_STRING UINT8_C(0x04) +#define ASN1_TAG_NULL UINT8_C(0x05) +#define ASN1_TAG_OID UINT8_C(0x06) +#define ASN1_TAG_OBJECT_DESCRIPTOR UINT8_C(0x07) +#define ASN1_TAG_EXTERNAL UINT8_C(0x08) +#define ASN1_TAG_REAL UINT8_C(0x09) +#define ASN1_TAG_ENUMERATED UINT8_C(0x0a) +#define ASN1_TAG_EMBEDDED_PDV UINT8_C(0x0b) +#define ASN1_TAG_UTF8_STRING UINT8_C(0x0c) +#define ASN1_TAG_RELATIVE_OID UINT8_C(0x0d) +#define ASN1_TAG_RESERVED_14 UINT8_C(0x0e) +#define ASN1_TAG_RESERVED_15 UINT8_C(0x0f) +#define ASN1_TAG_SEQUENCE UINT8_C(0x10) +#define ASN1_TAG_SET UINT8_C(0x11) +#define ASN1_TAG_NUMERIC_STRING UINT8_C(0x12) +#define ASN1_TAG_PRINTABLE_STRING UINT8_C(0x13) +#define ASN1_TAG_T61_STRING UINT8_C(0x14) +#define ASN1_TAG_VIDEOTEX_STRING UINT8_C(0x15) +#define ASN1_TAG_IA5_STRING UINT8_C(0x16) +#define ASN1_TAG_UTC_TIME UINT8_C(0x17) /**< Century seems to be 1900 if YY < 50, otherwise 2000. Baka ASN.1! */ +#define ASN1_TAG_GENERALIZED_TIME UINT8_C(0x18) +#define ASN1_TAG_GRAPHIC_STRING UINT8_C(0x19) +#define ASN1_TAG_VISIBLE_STRING UINT8_C(0x1a) +#define ASN1_TAG_GENERAL_STRING UINT8_C(0x1b) +#define ASN1_TAG_UNIVERSAL_STRING UINT8_C(0x1c) +#define ASN1_TAG_CHARACTER_STRING UINT8_C(0x1d) +#define ASN1_TAG_BMP_STRING UINT8_C(0x1e) +#define ASN1_TAG_USE_LONG_FORM UINT8_C(0x1f) +/** @} */ + + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_asn1_h */ + diff --git a/include/iprt/formats/bmp.h b/include/iprt/formats/bmp.h new file mode 100644 index 00000000..4d6c8af7 --- /dev/null +++ b/include/iprt/formats/bmp.h @@ -0,0 +1,192 @@ +/* $Id: bmp.h $ */ +/** @file + * IPRT - Microsoft Bitmap Formats (BMP). + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_bmp_h +#define IPRT_INCLUDED_formats_bmp_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_fmt_bmp Microsoft Bitmaps Formats (BMP) + * @ingroup grp_rt_formats + * @{ + */ + +/** @name BMP header sizes (in bytes). + * @{ */ +#define BMP_HDR_SIZE_FILE 14 +#define BMP_HDR_SIZE_OS21 12 +#define BMP_HDR_SIZE_OS22 64 +#define BMP_HDR_SIZE_WIN3X 40 +/** @} */ + + +/** BMP format file header. */ +#pragma pack(1) +typedef struct BMPFILEHDR +{ + /** File type identifier ("magic"). */ + uint16_t uType; + /** Size of file in bytes. */ + uint32_t cbFileSize; + /** Reserved (should be 0). */ + uint16_t Reserved1; + /** Reserved (should be 0). */ + uint16_t Reserved2; + /** Offset (in bytes) to bitmap data. */ + uint32_t offBits; +} BMPFILEHDR; +#pragma pack() +AssertCompileSize(BMPFILEHDR, BMP_HDR_SIZE_FILE); +/** Pointer to a BMP format file header. */ +typedef BMPFILEHDR *PBMPFILEHDR; + +/** BMP file magic number for BMP / DIB. */ +#define BMP_HDR_MAGIC (RT_H2LE_U16_C(0x4d42)) + +/** OS/2 1.x BMP core header, + * also known as BITMAPCOREHEADER. */ +typedef struct BMPOS2COREHDR +{ + /** Size (in bytes) of remaining header. */ + uint32_t cbSize; + /** Width of bitmap in pixels. */ + uint16_t uWidth; + /** Height of bitmap in pixels. */ + uint16_t uHeight; + /** Number of planes. */ + uint16_t cPlanes; + /** Color bits per pixel. */ + uint16_t cBits; +} BMPOS2COREHDR; +AssertCompileSize(BMPOS2COREHDR, BMP_HDR_SIZE_OS21); +/** Pointer to a OS/2 1.x BMP core header. */ +typedef BMPOS2COREHDR *PBMPOS2COREHDR; + +/** OS/2 2.0 BMP core header, version 2, + * also known as BITMAPCOREHEADER2. */ +typedef struct BMPOS2COREHDR2 +{ + /** Size (in bytes) of remaining header. */ + uint32_t cbSize; + /** Width of bitmap in pixels. */ + uint32_t uWidth; + /** Height of bitmap in pixels. */ + uint32_t uHeight; + /** Number of planes. */ + uint16_t cPlanes; + /** Color bits per pixel. */ + uint16_t cBits; + /** Compression scheme of type BMP_COMPRESSION_TYPE. */ + uint32_t enmCompression; + /** Size of bitmap in bytes. */ + uint32_t cbSizeImage; + /** Horz. resolution in pixels/meter. */ + uint32_t uXPelsPerMeter; + /** Vert. resolution in pixels/meter. */ + uint32_t uYPelsPerMeter; + /** Number of colors in color table. */ + uint32_t cClrUsed; + /** Number of important colors. */ + uint32_t cClrImportant; + /** Resolution measurement Used. */ + uint16_t uUnits; + /** Reserved fields (always 0). */ + uint16_t Reserved; + /** Orientation of bitmap. */ + uint16_t uRecording; + /** Halftone algorithm used on image. */ + uint16_t enmHalftone; + /** Halftone algorithm data. */ + uint32_t uHalftoneParm1; + /** Halftone algorithm data. */ + uint32_t uHalftoneParm2; + /** Color table format (always 0). */ + uint32_t uColorEncoding; + /** Misc. field for application use . */ + uint32_t uIdentifier; +} BMPOS2COREHDR2; +AssertCompileSize(BMPOS2COREHDR2, BMP_HDR_SIZE_OS22); +/** Pointer to an OS/2 2.0 BMP core header version 2. */ +typedef BMPOS2COREHDR2 *PBMPOS2COREHDR2; + +/** Windows 3.x BMP information header Format. */ +typedef struct BMPWIN3XINFOHDR +{ + /** Size (in bytes) of remaining header. */ + uint32_t cbSize; + /** Width of bitmap in pixels. */ + uint32_t uWidth; + /** Height of bitmap in pixels. */ + uint32_t uHeight; + /** Number of planes. */ + uint16_t cPlanes; + /** Color bits per pixel. */ + uint16_t cBits; + /** Compression scheme of type BMP_COMPRESSION_TYPE. */ + uint32_t enmCompression; + /** Size of bitmap in bytes. */ + uint32_t cbSizeImage; + /** Horz. resolution in pixels/meter. */ + uint32_t uXPelsPerMeter; + /** Vert. resolution in pixels/meter. */ + uint32_t uYPelsPerMeter; + /** Number of colors in color table. */ + uint32_t cClrUsed; + /** Number of important colors. */ + uint32_t cClrImportant; +} BMPWIN3XINFOHDR; +AssertCompileSize(BMPWIN3XINFOHDR, BMP_HDR_SIZE_WIN3X); +/** Pointer to a Windows 3.x BMP information header. */ +typedef BMPWIN3XINFOHDR *PBMPWIN3XINFOHDR; + + + +/** @name BMP compression types. + * @{ */ +#define BMP_COMPRESSION_TYPE_NONE 0 +#define BMP_COMPRESSION_TYPE_RLE8 1 +#define BMP_COMPRESSION_TYPE_RLE4 2 +/** @} */ + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_bmp_h */ + diff --git a/include/iprt/formats/codeview.h b/include/iprt/formats/codeview.h new file mode 100644 index 00000000..9f968e1e --- /dev/null +++ b/include/iprt/formats/codeview.h @@ -0,0 +1,870 @@ +/** @file + * IPRT - Microsoft CodeView Debug Information. + */ + +/* + * Copyright (C) 2009-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_codeview_h +#define IPRT_INCLUDED_formats_codeview_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_fmt_codeview Microsoft CodeView Debug Information + * @{ + */ + + +/** + * CodeView Header. There are two of this, base header at the start of the debug + * information and a trailing header at the end. + */ +typedef struct RTCVHDR +{ + /** The magic ('NBxx'), see RTCVHDR_MAGIC_XXX. */ + uint32_t u32Magic; + /** + * Base header: Subsection directory offset relative to this header (start). + * Trailing header: Offset of the base header relative to the end of the file. + * + * Called lfoBase, lfaBase, lfoDirectory, lfoDir and probably other things in + * the various specs/docs available. */ + uint32_t off; +} RTCVHDR; +/** Pointer to a CodeView header. */ +typedef RTCVHDR *PRTCVHDR; + +/** @name CodeView magic values (RTCVHDR::u32Magic). + * @{ */ +/** CodeView from Visual C++ 5.0. Specified in the 2001 MSDN specs.chm file. */ +#define RTCVHDR_MAGIC_NB11 RT_MAKE_U32_FROM_U8('N', 'B', '1', '1') +/** External PDB reference (often referred to as PDB 2.0). */ +#define RTCVHDR_MAGIC_NB10 RT_MAKE_U32_FROM_U8('N', 'B', '1', '0') +/** CodeView v4.10, packed. Specified in the TIS document. */ +#define RTCVHDR_MAGIC_NB09 RT_MAKE_U32_FROM_U8('N', 'B', '0', '9') +/** CodeView v4.00 thru v4.05. Specified in the TIS document? */ +#define RTCVHDR_MAGIC_NB08 RT_MAKE_U32_FROM_U8('N', 'B', '0', '8') +/** Quick C for Windows 1.0 debug info. */ +#define RTCVHDR_MAGIC_NB07 RT_MAKE_U32_FROM_U8('N', 'B', '0', '7') +/** Emitted by ILINK indicating incremental link. Comparable to NB05? */ +#define RTCVHDR_MAGIC_NB06 RT_MAKE_U32_FROM_U8('N', 'B', '0', '6') +/** Emitted by LINK version 5.20 and later before packing. */ +#define RTCVHDR_MAGIC_NB05 RT_MAKE_U32_FROM_U8('N', 'B', '0', '5') +/** Emitted by IBM ILINK for HLL (similar to NB02 in many ways). */ +#define RTCVHDR_MAGIC_NB04 RT_MAKE_U32_FROM_U8('N', 'B', '0', '4') +/** Emitted by LINK version 5.10 (or similar OMF linkers), as shipped with + * Microsoft C v6.0 for example. More or less entirely 16-bit. */ +#define RTCVHDR_MAGIC_NB02 RT_MAKE_U32_FROM_U8('N', 'B', '0', '2') +/* No idea what NB03 might have been. */ +/** AIX debugger format according to "IBM OS/2 16/32-bit Object Module Format + * (OMF) and Linear eXecutable Module Format (LX)" revision 10 (LXOMF.PDF). */ +#define RTCVHDR_MAGIC_NB01 RT_MAKE_U32_FROM_U8('N', 'B', '0', '1') +/** Ancient CodeView format according to LXOMF.PDF. */ +#define RTCVHDR_MAGIC_NB00 RT_MAKE_U32_FROM_U8('N', 'B', '0', '0') +/** @} */ + + +/** @name CV directory headers. + * @{ */ + +/** + * Really old CV directory header used with NB00 and NB02. + * + * Uses 16-bit directory entires (RTCVDIRENT16). + */ +typedef struct RTCVDIRHDR16 +{ + /** The number of directory entries. */ + uint16_t cEntries; +} RTCVDIRHDR16; +/** Pointer to a old CV directory header. */ +typedef RTCVDIRHDR16 *PRTCVDIRHDR16; + +/** + * Simple 32-bit CV directory base header, used by NB04 (aka IBM HLL). + */ +typedef struct RTCVDIRHDR32 +{ + /** The number of bytes of this header structure. */ + uint16_t cbHdr; + /** The number of bytes per entry. */ + uint16_t cbEntry; + /** The number of directory entries. */ + uint32_t cEntries; +} RTCVDIRHDR32; +/** Pointer to a 32-bit CV directory header. */ +typedef RTCVDIRHDR32 *PRTCVDIRHDR32; + +/** + * Extended 32-bit CV directory header as specified in the TIS doc. + * The two extra fields seems to never have been assigned any official purpose. + */ +typedef struct RTCVDIRHDR32EX +{ + /** This starts the same way as the NB04 header. */ + RTCVDIRHDR32 Core; + /** Tentatively decleared as the offset to the next directory generated by + * the incremental linker. Haven't seen this used yet. */ + uint32_t offNextDir; + /** Flags, non defined apparently, so MBZ. */ + uint32_t fFlags; +} RTCVDIRHDR32EX; +/** Pointer to an extended 32-bit CV directory header. */ +typedef RTCVDIRHDR32EX *PRTCVDIRHDR32EX; + +/** @} */ + + +/** + * 16-bit CV directory entry used with NB00 and NB02. + */ +typedef struct RTCVDIRENT16 +{ + /** Subsection type (RTCVSST). */ + uint16_t uSubSectType; + /** Which module (1-based, 0xffff is special). */ + uint16_t iMod; + /** The lowe offset of this subsection relative to the base CV header. */ + uint16_t offLow; + /** The high part of the subsection offset. */ + uint16_t offHigh; + /** The size of the subsection. */ + uint16_t cb; +} RTCVDIRENT16; +AssertCompileSize(RTCVDIRENT16, 10); +/** Pointer to a 16-bit CV directory entry. */ +typedef RTCVDIRENT16 *PRTCVDIRENT16; + + +/** + * 32-bit CV directory entry used starting with NB04. + */ +typedef struct RTCVDIRENT32 +{ + /** Subsection type (RTCVSST). */ + uint16_t uSubSectType; + /** Which module (1-based, 0xffff is special). */ + uint16_t iMod; + /** The offset of this subsection relative to the base CV header. */ + uint32_t off; + /** The size of the subsection. */ + uint32_t cb; +} RTCVDIRENT32; +AssertCompileSize(RTCVDIRENT32, 12); +/** Pointer to a 32-bit CV directory entry. */ +typedef RTCVDIRENT32 *PRTCVDIRENT32; +/** Pointer to a const 32-bit CV directory entry. */ +typedef RTCVDIRENT32 const *PCRTCVDIRENT32; + + +/** + * CodeView subsection types. + */ +typedef enum RTCVSST +{ + /** @name NB00, NB02 and NB04 subsection types. + * The actual format of each subsection varies between NB04 and the others, + * and it may further vary in NB04 depending on the module type. + * @{ */ + kCvSst_OldModule = 0x101, + kCvSst_OldPublic, + kCvSst_OldTypes, + kCvSst_OldSymbols, + kCvSst_OldSrcLines, + kCvSst_OldLibraries, + kCvSst_OldImports, + kCvSst_OldCompacted, + kCvSst_OldSrcLnSeg = 0x109, + kCvSst_OldSrcLines3 = 0x10b, + /** @} */ + + /** @name NB09, NB11 (and possibly NB05, NB06, NB07, and NB08) subsection types. + * @{ */ + kCvSst_Module = 0x120, + kCvSst_Types, + kCvSst_Public, + kCvSst_PublicSym, + kCvSst_Symbols, + kCvSst_AlignSym, + kCvSst_SrcLnSeg, + kCvSst_SrcModule, + kCvSst_Libraries, + kCvSst_GlobalSym, + kCvSst_GlobalPub, + kCvSst_GlobalTypes, + kCvSst_MPC, + kCvSst_SegMap, + kCvSst_SegName, + kCvSst_PreComp, + kCvSst_PreCompMap, + kCvSst_OffsetMap16, + kCvSst_OffsetMap32, + kCvSst_FileIndex = 0x133, + kCvSst_StaticSym + /** @} */ +} RTCVSST; +/** Pointer to a CV subsection type value. */ +typedef RTCVSST *PRTCVSST; +/** Pointer to a const CV subsection type value. */ +typedef RTCVSST const *PCRTCVSST; + + +/** + * CV4 module segment info. + */ +typedef struct RTCVMODSEGINFO32 +{ + /** The segment number. */ + uint16_t iSeg; + /** Explicit padding. */ + uint16_t u16Padding; + /** Offset into the segment. */ + uint32_t off; + /** The size of the contribution. */ + uint32_t cb; +} RTCVMODSEGINFO32; +typedef RTCVMODSEGINFO32 *PRTCVMODSEGINFO32; +typedef RTCVMODSEGINFO32 const *PCRTCVMODSEGINFO32; + + +/** + * CV4 segment map header. + */ +typedef struct RTCVSEGMAPHDR +{ + /** Number of segments descriptors in the table. */ + uint16_t cSegs; + /** Number of logical segment descriptors. */ + uint16_t cLogSegs; +} RTCVSEGMAPHDR; +/** Pointer to a CV4 segment map header. */ +typedef RTCVSEGMAPHDR *PRTCVSEGMAPHDR; +/** Pointer to a const CV4 segment map header. */ +typedef RTCVSEGMAPHDR const *PCRTCVSEGMAPHDR; + +/** + * CV4 Segment map descriptor entry. + */ +typedef struct RTCVSEGMAPDESC +{ + /** Segment flags. */ + uint16_t fFlags; + /** The overlay number. */ + uint16_t iOverlay; + /** Group index into this segment descriptor array. 0 if not relevant. + * The group descriptors are found in the second half of the table. */ + uint16_t iGroup; + /** Complicated. */ + uint16_t iFrame; + /** Offset (byte) into the kCvSst_SegName table of the segment name, or + * 0xffff. */ + uint16_t offSegName; + /** Offset (byte) into the kCvSst_SegName table of the class name, or 0xffff. */ + uint16_t offClassName; + /** Offset into the physical segment. */ + uint32_t off; + /** Size of segment. */ + uint32_t cb; +} RTCVSEGMAPDESC; +/** Pointer to a segment map descriptor entry. */ +typedef RTCVSEGMAPDESC *PRTCVSEGMAPDESC; +/** Pointer to a const segment map descriptor entry. */ +typedef RTCVSEGMAPDESC const *PCRTCVSEGMAPDESC; + +/** @name RTCVSEGMAPDESC_F_XXX - RTCVSEGMAPDESC::fFlags values. + * @{ */ +#define RTCVSEGMAPDESC_F_READ UINT16_C(0x0001) +#define RTCVSEGMAPDESC_F_WRITE UINT16_C(0x0002) +#define RTCVSEGMAPDESC_F_EXECUTE UINT16_C(0x0004) +#define RTCVSEGMAPDESC_F_32BIT UINT16_C(0x0008) +#define RTCVSEGMAPDESC_F_SEL UINT16_C(0x0100) +#define RTCVSEGMAPDESC_F_ABS UINT16_C(0x0200) +#define RTCVSEGMAPDESC_F_GROUP UINT16_C(0x1000) +#define RTCVSEGMAPDESC_F_RESERVED UINT16_C(0xecf0) +/** @} */ + +/** + * CV4 segment map subsection. + */ +typedef struct RTCVSEGMAP +{ + /** The header. */ + RTCVSEGMAPHDR Hdr; + /** Descriptor array. */ + RTCVSEGMAPDESC aDescs[1]; +} RTCVSEGMAP; +/** Pointer to a segment map subsection. */ +typedef RTCVSEGMAP *PRTCVSEGMAP; +/** Pointer to a const segment map subsection. */ +typedef RTCVSEGMAP const *PCRTCVSEGMAP; + + +/** + * CV4 line number segment contribution start/end table entry. + * Part of RTCVSRCMODULE. + */ +typedef struct RTCVSRCRANGE +{ + /** Start segment offset. */ + uint32_t offStart; + /** End segment offset (inclusive?). */ + uint32_t offEnd; +} RTCVSRCRANGE; +/** Pointer to a line number segment contributation. */ +typedef RTCVSRCRANGE *PRTCVSRCRANGE; +/** Pointer to a const line number segment contributation. */ +typedef RTCVSRCRANGE const *PCRTCVSRCRANGE; + +/** + * CV4 header for a line number subsection, used by kCvSst_SrcModule. + * + * The aoffSrcFiles member is followed by an array of segment ranges + * (RTCVSRCRANGE), cSegs in length. This may contain zero entries if the + * information is not known or not possible to express in this manner. + * + * After the range table, a segment index (uint16_t) mapping table follows, also + * cSegs in length. + */ +typedef struct RTCVSRCMODULE +{ + /** The number of files described in this subsection. */ + uint16_t cFiles; + /** The number of code segments this module contributes to. */ + uint16_t cSegs; + /** Offsets of the RTCVSRCFILE entries in this subsection, length given by + * the above cFiles member. */ + uint32_t aoffSrcFiles[1 /*cFiles*/]; + /* RTCVSRCRANGE aSegRanges[cSegs]; */ + /* uint16_t aidxSegs[cSegs]; */ +} RTCVSRCMODULE; +/** Pointer to a source module subsection header. */ +typedef RTCVSRCMODULE *PRTCVSRCMODULE; +/** Pointer to a const source module subsection header. */ +typedef RTCVSRCMODULE const *PCRTCVSRCMODULE; + +/** + * CV4 source file, inside a kCvSst_SrcModule (see RTCVSRCMODULE::aoffSrcFiles) + * + * The aoffSrcLines member is followed by an array of segment ranges + * (RTCVSRCRANGE), cSegs in length. Just like for RTCVSRCMODULE this may + * contain zero entries. + * + * After the range table is the filename, which is preceeded by a 8-bit length + * (actually documented to be 16-bit, but seeing 8-bit here with wlink). + */ +typedef struct RTCVSRCFILE +{ + /** The number segments that this source file contributed to. */ + uint16_t cSegs; + /** Alignment padding. */ + uint16_t uPadding; + /** Offsets of the RTCVSRCLN entries for this source file, length given by + * the above cSegs member. Relative to the start of the subsection. */ + uint32_t aoffSrcLines[1 /*cSegs*/]; + /* RTCVSRCRANGE aSegRanges[cSegs]; */ + /* uint8_t/uint16_t cchName; */ + /* char achName[cchName]; */ +} RTCVSRCFILE; +/** Pointer to a source file. */ +typedef RTCVSRCFILE *PRTCVSRCFILE; +/** Pointer to a const source file. */ +typedef RTCVSRCFILE const *PCRTCVSRCFILE; + +/** + * CV4 line numbers header. + * + * The aoffLines member is followed by an array of line numbers (uint16_t). + */ +typedef struct RTCVSRCLINE +{ + /** The index of the segment these line numbers belong to. */ + uint16_t idxSeg; + /** The number of line number pairs the two following tables. */ + uint16_t cPairs; + /** Segment offsets, cPairs long. */ + uint32_t aoffLines[1 /*cPairs*/]; + /* uint16_t aiLines[cPairs]; */ +} RTCVSRCLINE; +/** Pointer to a line numbers header. */ +typedef RTCVSRCLINE *PRTCVSRCLINE; +/** Pointer to a const line numbers header. */ +typedef RTCVSRCLINE const *PCRTCVSRCLINE; + + +/** + * Global symbol table header, used by kCvSst_GlobalSym and kCvSst_GlobalPub. + */ +typedef struct RTCVGLOBALSYMTABHDR +{ + /** The symbol hash function. */ + uint16_t uSymHash; + /** The address hash function. */ + uint16_t uAddrHash; + /** The amount of symbol information following immediately after the header. */ + uint32_t cbSymbols; + /** The amount of symbol hash tables following the symbols. */ + uint32_t cbSymHash; + /** The amount of address hash tables following the symbol hash tables. */ + uint32_t cbAddrHash; +} RTCVGLOBALSYMTABHDR; +/** Pointer to a global symbol table header. */ +typedef RTCVGLOBALSYMTABHDR *PRTCVGLOBALSYMTABHDR; +/** Pointer to a const global symbol table header. */ +typedef RTCVGLOBALSYMTABHDR const *PCRTCVGLOBALSYMTABHDR; + + +typedef enum RTCVSYMTYPE +{ + /** @name Symbols that doesn't change with compilation model or target machine. + * @{ */ + kCvSymType_Compile = 0x0001, + kCvSymType_Register, + kCvSymType_Constant, + kCvSymType_UDT, + kCvSymType_SSearch, + kCvSymType_End, + kCvSymType_Skip, + kCvSymType_CVReserve, + kCvSymType_ObjName, + kCvSymType_EndArg, + kCvSymType_CobolUDT, + kCvSymType_ManyReg, + kCvSymType_Return, + kCvSymType_EntryThis, + /** @} */ + + /** @name Symbols with 16:16 addresses. + * @{ */ + kCvSymType_BpRel16 = 0x0100, + kCvSymType_LData16, + kCvSymType_GData16, + kCvSymType_Pub16, + kCvSymType_LProc16, + kCvSymType_GProc16, + kCvSymType_Thunk16, + kCvSymType_BLock16, + kCvSymType_With16, + kCvSymType_Label16, + kCvSymType_CExModel16, + kCvSymType_VftPath16, + kCvSymType_RegRel16, + /** @} */ + + /** @name Symbols with 16:32 addresses. + * @{ */ + kCvSymType_BpRel32 = 0x0200, + kCvSymType_LData32, + kCvSymType_GData32, + kCvSymType_Pub32, + kCvSymType_LProc32, + kCvSymType_GProc32, + kCvSymType_Thunk32, + kCvSymType_Block32, + kCvSymType_With32, + kCvSymType_Label32, + kCvSymType_CExModel32, + kCvSymType_VftPath32, + kCvSymType_RegRel32, + kCvSymType_LThread32, + kCvSymType_GThread32, + /** @} */ + + /** @name Symbols for MIPS. + * @{ */ + kCvSymType_LProcMips = 0x0300, + kCvSymType_GProcMips, + /** @} */ + + /** @name Symbols for Microsoft CodeView. + * @{ */ + kCvSymType_ProcRef = 0x0400, + kCvSymType_DataRef, + kCvSymType_Align, + kCvSymType_LProcRef, + /** @} */ + + /** @name Symbols with 32-bit address (I think) and 32-bit type indices. + * @{ */ + kCvSymType_V2_Register = 0x1001, + kCvSymType_V2_Constant, + kCvSymType_V2_Udt, + kCvSymType_V2_CobolUdt, + kCvSymType_V2_ManyReg, + kCvSymType_V2_BpRel, + kCvSymType_V2_LData, + kCvSymType_V2_GData, + kCvSymType_V2_Pub, + kCvSymType_V2_LProc, + kCvSymType_V2_GProc, + kCvSymType_V2_VftTable, + kCvSymType_V2_RegRel, + kCvSymType_V2_LThread, + kCvSymType_V2_GThread, + kCvSymType_V2_Unknown_1010, + kCvSymType_V2_Unknown_1011, + kCvSymType_V2_FrameInfo, + kCvSymType_V2_Compliand, + /** @} */ + + /** @name Version 3 symbol types. + * @{ */ + /** Name of the object file, preceded by a 4-byte language type (ASM=0) */ + kCvSymType_V3_Compliand = 0x1101, + kCvSymType_V3_Thunk, + kCvSymType_V3_Block, + kCvSymType_V3_Unknown_1104, + kCvSymType_V3_Label, /**< RTCVSYMV3LABEL */ + kCvSymType_V3_Register, + kCvSymType_V3_Constant, + kCvSymType_V3_Udt, + kCvSymType_V3_Unknown_1109, + kCvSymType_V3_Unknown_110a, + kCvSymType_V3_BpRel, + kCvSymType_V3_LData, /**< RTCVSYMV3TYPEDNAME */ + kCvSymType_V3_GData, /**< RTCVSYMV3TYPEDNAME */ + kCvSymType_V3_Pub, + kCvSymType_V3_LProc, + kCvSymType_V3_GProc, + kCvSymType_V3_RegRel, + kCvSymType_V3_LThread, + kCvSymType_V3_GThread, + kCvSymType_V3_Unknown_1114, + kCvSymType_V3_Unknown_1115, + kCvSymType_V3_MSTool, /**< RTCVSYMV3MSTOOL */ + + kCvSymType_V3_PubFunc1 = 0x1125, + kCvSymType_V3_PubFunc2 = 0x1127, + kCvSymType_V3_SectInfo = 0x1136, + kCvSymType_V3_SubSectInfo, + kCvSymType_V3_Entrypoint, + kCvSymType_V3_Unknown_1139, + kCvSymType_V3_SecuCookie, + kCvSymType_V3_Unknown_113b, + kCvSymType_V3_MsToolInfo, + kCvSymType_V3_MsToolEnv, + + kCvSymType_VS2013_Local, + kCvSymType_VS2013_FpOff = 0x1144, + kCvSymType_VS2013_LProc32 = 0x1146, + kCvSymType_VS2013_GProc32, + /** @} */ + + kCvSymType_EndOfValues +} RTCVSYMTYPE; +AssertCompile(kCvSymType_V3_Udt == 0x1108); +AssertCompile(kCvSymType_V3_GProc == 0x1110); +AssertCompile(kCvSymType_V3_MSTool == 0x1116); +AssertCompile(kCvSymType_VS2013_Local == 0x113E); +typedef RTCVSYMTYPE *PRTCVSYMTYPE; +typedef RTCVSYMTYPE const *PCRTCVSYMTYPE; + + +/** + * kCvSymType_V3_MSTool format. + */ +typedef struct RTCVSYMV3MSTOOL +{ + /** Language or tool ID (3 == masm). */ + uint32_t uLanguage; + /** Target CPU (0xd0 == AMD64). */ + uint32_t uTargetCpu; + /** Flags. */ + uint32_t fFlags; + /** Version. */ + uint32_t uVersion; + /** The creator name, zero terminated. + * + * It is followed by key/value pairs of zero terminated strings giving more + * details about the current directory ('cwd'), compiler executable ('cl'), + * full command line ('cmd'), source path relative to cwd ('src'), the + * full program database path ('pdb'), and possibly others. Terminated by a + * pair of empty strings, usually. */ + char szCreator[1]; +} RTCVSYMV3MSTOOL; +typedef RTCVSYMV3MSTOOL *PRTCVSYMV3MSTOOL; +typedef RTCVSYMV3MSTOOL const *PCRTCVSYMV3MSTOOL; + +/** + * kCvSymType_V3_Label format. + */ +typedef struct RTCVSYMV3LABEL +{ + /** Offset into iSection of this symbol. */ + uint32_t offSection; + /** The index of the section where the symbol lives. */ + uint16_t iSection; + /** Flags or something. */ + uint8_t fFlags; + /** Zero terminated symbol name (variable length). */ + char szName[1]; +} RTCVSYMV3LABEL; +AssertCompileSize(RTCVSYMV3LABEL, 8); +typedef RTCVSYMV3LABEL *PRTCVSYMV3LABEL; +typedef RTCVSYMV3LABEL const *PCRTCVSYMV3LABEL; + +/** + * kCvSymType_V3_LData and kCvSymType_V3_GData format. + */ +typedef struct RTCVSYMV3TYPEDNAME +{ + /** The type ID. */ + uint32_t idType; + /** Offset into iSection of this symbol. */ + uint32_t offSection; + /** The index of the section where the symbol lives. */ + uint16_t iSection; + /** Zero terminated symbol name (variable length). */ + char szName[2]; +} RTCVSYMV3TYPEDNAME; +AssertCompileSize(RTCVSYMV3TYPEDNAME, 12); +typedef RTCVSYMV3TYPEDNAME *PRTCVSYMV3TYPEDNAME; +typedef RTCVSYMV3TYPEDNAME const *PCRTCVSYMV3TYPEDNAME; + +/** + * kCvSymType_V3_LProc and kCvSymType_V3_GProc format. + */ +typedef struct RTCVSYMV3PROC +{ + /** Lexical scope linking: Parent. */ + uint32_t uParent; + /** Lexical scope linking: End. */ + uint32_t uEnd; + /** Lexical scope linking: Next. */ + uint32_t uNext; + /** The procedure length. */ + uint32_t cbProc; + /** Offset into the procedure where the stack frame has been setup and is an + * excellent position for a function breakpoint. */ + uint32_t offDebugStart; + /** Offset into the procedure where the procedure is ready to return and has a + * return value (if applicable). */ + uint32_t offDebugEnd; + /** The type ID for the procedure. */ + uint32_t idType; + /** Offset into iSection of this procedure. */ + uint32_t offSection; + /** The index of the section where the procedure lives. */ + uint16_t iSection; + /** Flags. */ + uint8_t fFlags; + /** Zero terminated procedure name (variable length). */ + char szName[1]; +} RTCVSYMV3PROC; +AssertCompileSize(RTCVSYMV3PROC, 36); +typedef RTCVSYMV3PROC *PRTCVSYMV3PROC; +typedef RTCVSYMV3PROC const *PCRTCVSYMV3PROC; + + +/** @name $$SYMBOLS signatures. + * @{ */ +/** The $$SYMBOL table signature for CV4. */ +#define RTCVSYMBOLS_SIGNATURE_CV4 UINT32_C(0x00000001) +/** The $$SYMBOL table signature for CV8 (MSVC 8/2005). + * Also seen with MSVC 2010 using -Z7, so maybe more appropriate to call it + * CV7? */ +#define RTCVSYMBOLS_SIGNATURE_CV8 UINT32_C(0x00000004) +/** @} */ + + +/** + * CV8 $$SYMBOLS block header. + */ +typedef struct RTCV8SYMBOLSBLOCK +{ + /** BLock type (RTCV8SYMBLOCK_TYPE_XXX). */ + uint32_t uType; + /** The block length, including this header? */ + uint32_t cb; +} RTCV8SYMBOLSBLOCK; +AssertCompileSize(RTCV8SYMBOLSBLOCK, 8); +typedef RTCV8SYMBOLSBLOCK *PRTCV8SYMBOLSBLOCK; +typedef RTCV8SYMBOLSBLOCK const *PCRTCV8SYMBOLSBLOCK; + +/** @name RTCV8SYMBLOCK_TYPE_XXX - CV8 (MSVC 8/2005) $$SYMBOL table types. + * @{ */ +/** Symbol information. + * Sequence of types. Each type entry starts with a 16-bit length followed + * by a 16-bit RTCVSYMTYPE value. Just like CV4/5, but with C-strings + * instead of pascal. */ +#define RTCV8SYMBLOCK_TYPE_SYMBOLS UINT32_C(0x000000f1) +/** Line numbers for a section. */ +#define RTCV8SYMBLOCK_TYPE_SECT_LINES UINT32_C(0x000000f2) +/** Source file string table. + * The strings are null terminated. Indexed by RTCV8SYMBLOCK_TYPE_SRC_INFO. */ +#define RTCV8SYMBLOCK_TYPE_SRC_STR UINT32_C(0x000000f3) +/** Source file information. */ +#define RTCV8SYMBLOCK_TYPE_SRC_INFO UINT32_C(0x000000f4) +/** @} */ + +/** + * Line number header found in a RTCV8SYMBLOCK_TYPE_SECT_LINES block. + * + * This is followed by a sequence of RTCV8LINESSRCMAP structures. + */ +typedef struct RTCV8LINESHDR +{ + /** Offset into the section. */ + uint32_t offSection; + /** The section number. */ + uint16_t iSection; + /** Padding/zero/maybe-previous-member-is-a-32-bit-value. */ + uint16_t u16Padding; + /** Number of bytes covered by this table, starting at offSection. */ + uint32_t cbSectionCovered; +} RTCV8LINESHDR; +AssertCompileSize(RTCV8LINESHDR, 12); +typedef RTCV8LINESHDR *PRTCV8LINESHDR; +typedef RTCV8LINESHDR const *PCRTCV8LINESHDR; + +/** + * CV8 (MSVC 8/2005) line number source map. + * + * This is followed by an array of RTCV8LINEPAIR. + */ +typedef struct RTCV8LINESSRCMAP +{ + /** The source file, given as an offset (byte) into the source file + * information table (RTCV8SYMBLOCK_TYPE_SRC_INFO). */ + uint32_t offSourceInfo; + /** Number of line numbers following this structure. */ + uint32_t cLines; + /** The size of this source map. */ + uint32_t cb; +} RTCV8LINESSRCMAP; +AssertCompileSize(RTCV8LINESSRCMAP, 12); +typedef RTCV8LINESSRCMAP *PRTCV8LINESSRCMAP; +typedef RTCV8LINESSRCMAP const *PCRTCV8LINESSRCMAP; + +/** + * One line number. + */ +typedef struct RTCV8LINEPAIR +{ + /** Offset into the section of this line number. */ + uint32_t offSection; + /** The line number. */ + uint32_t uLineNumber : 30; + /** Indicates that it's not possible to set breakpoint? */ + uint32_t fEndOfStatement : 1; +} RTCV8LINEPAIR; +AssertCompileSize(RTCV8LINEPAIR, 8); +typedef RTCV8LINEPAIR *PRTCV8LINEPAIR; +typedef RTCV8LINEPAIR const *PCRTCV8LINEPAIR; + +/** + * Source file information found in a RTCV8SYMBLOCK_TYPE_SRC_INFO block. + */ +typedef struct RTCV8SRCINFO +{ + /** The source file name, given as an offset into the string table + * (RTCV8SYMBLOCK_TYPE_SRC_STR). */ + uint32_t offSourceName; + /** Digest/checksum type. */ + uint16_t uDigestType; + union + { + /** RTCV8SRCINFO_DIGEST_TYPE_MD5. */ + struct + { + /** The digest. */ + uint8_t ab[16]; + /** Structur alignment padding. */ + uint8_t abPadding[2]; + } md5; + /** RTCV8SRCINFO_DIGEST_TYPE_NONE: Padding. */ + uint8_t abNone[2]; + } Digest; +} RTCV8SRCINFO; +AssertCompileSize(RTCV8SRCINFO, 24); +typedef RTCV8SRCINFO *PRTCV8SRCINFO; +typedef RTCV8SRCINFO const *PCRTCV8SRCINFO; + +/** @name RTCV8SRCINFO_DIGEST_TYPE_XXX - CV8 source digest types. + * Used by RTCV8SRCINFO::uDigestType. + * @{ */ +#define RTCV8SRCINFO_DIGEST_TYPE_NONE UINT16_C(0x0000) +#define RTCV8SRCINFO_DIGEST_TYPE_MD5 UINT16_C(0x0110) +/** @} */ + + + +/** + * PDB v2.0 in image debug info. + * The URL is constructed from the timestamp and age? + */ +typedef struct CVPDB20INFO +{ + uint32_t u32Magic; /**< CVPDB20INFO_SIGNATURE. */ + int32_t offDbgInfo; /**< Always 0. Used to be the offset to the real debug info. */ + uint32_t uTimestamp; + uint32_t uAge; + uint8_t szPdbFilename[4]; +} CVPDB20INFO; +/** Pointer to in executable image PDB v2.0 info. */ +typedef CVPDB20INFO *PCVPDB20INFO; +/** Pointer to read only in executable image PDB v2.0 info. */ +typedef CVPDB20INFO const *PCCVPDB20INFO; +/** The CVPDB20INFO magic value. */ +#define CVPDB20INFO_MAGIC RT_MAKE_U32_FROM_U8('N','B','1','0') + +/** + * PDB v7.0 in image debug info. + * The URL is constructed from the signature and the age. + */ +#pragma pack(4) +typedef struct CVPDB70INFO +{ + uint32_t u32Magic; /**< CVPDB70INFO_SIGNATURE. */ + RTUUID PdbUuid; + uint32_t uAge; + uint8_t szPdbFilename[4]; +} CVPDB70INFO; +#pragma pack() +AssertCompileMemberOffset(CVPDB70INFO, PdbUuid, 4); +AssertCompileMemberOffset(CVPDB70INFO, uAge, 4 + 16); +/** Pointer to in executable image PDB v7.0 info. */ +typedef CVPDB70INFO *PCVPDB70INFO; +/** Pointer to read only in executable image PDB v7.0 info. */ +typedef CVPDB70INFO const *PCCVPDB70INFO; +/** The CVPDB70INFO magic value. */ +#define CVPDB70INFO_MAGIC RT_MAKE_U32_FROM_U8('R','S','D','S') + + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_codeview_h */ + diff --git a/include/iprt/formats/cpio.h b/include/iprt/formats/cpio.h new file mode 100644 index 00000000..b54804e1 --- /dev/null +++ b/include/iprt/formats/cpio.h @@ -0,0 +1,210 @@ +/** @file + * IPRT - CPIO archive format. + */ + +/* + * Copyright (C) 2020-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_cpio_h +#define IPRT_INCLUDED_formats_cpio_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_cpio CPIO Archive format + * @ingroup grp_rt_formats + * + * @{ */ + +/** This denotes the end of the archive (record with this filename, zero size and + * a zero mode). */ +#define CPIO_EOS_FILE_NAME "TRAILER!!!" + + +/** + * The old binary header. + */ +typedef struct CPIOHDRBIN +{ + /** 0x00: Magic identifying the old header. */ + uint16_t u16Magic; + /** 0x02: Device number. */ + uint16_t u16Dev; + /** 0x04: Inode number. */ + uint16_t u16Inode; + /** 0x06: Mode. */ + uint16_t u16Mode; + /** 0x08: User ID. */ + uint16_t u16Uid; + /** 0x0a: Group ID. */ + uint16_t u16Gid; + /** 0x0c: Number of links to this file. */ + uint16_t u16NLinks; + /** 0x0e: Associated device number for block and character device entries. */ + uint16_t u16RDev; + /** 0x10: Modification time stored as two independent 16bit integers. */ + uint16_t au16MTime[2]; + /** 0x14: Number of bytes in the path name (including zero terminator) following the header. */ + uint16_t u16NameSize; + /** 0x16: Size of the file stored as two independent 16bit integers. */ + uint16_t au16FileSize[2]; +} CPIOHDRBIN; +AssertCompileSize(CPIOHDRBIN, 13 * 2); +typedef CPIOHDRBIN *PCPIOHDRBIN; +typedef const CPIOHDRBIN *PCCPIOHDRBIN; + + +/** The magic for the binary header. */ +#define CPIO_HDR_BIN_MAGIC UINT16_C(070707) + + +/** + * Portable ASCII format header as defined by SUSv2. + */ +typedef struct CPIOHDRSUSV2 +{ + /** 0x00: Magic identifying the header. */ + char achMagic[6]; + /** 0x06: Device number. */ + char achDev[6]; + /** 0x0c: Inode number. */ + char achInode[6]; + /** 0x12: Mode. */ + char achMode[6]; + /** 0x18: User ID. */ + char achUid[6]; + /** 0x1e: Group ID. */ + char achGid[6]; + /** 0x24: Number of links to this file. */ + char achNLinks[6]; + /** 0x2a: Associated device number for block and character device entries. */ + char achRDev[6]; + /** 0x30: Modification time stored as two independent 16bit integers. */ + char achMTime[11]; + /** 0x36: Number of bytes in the path name (including zero terminator) following the header. */ + char achNameSize[6]; + /** 0x3c: Size of the file stored as two independent 16bit integers. */ + char achFileSize[11]; +} CPIOHDRSUSV2; +AssertCompileSize(CPIOHDRSUSV2, 9 * 6 + 2 * 11); +typedef CPIOHDRSUSV2 *PCPIOHDRSUSV2; +typedef const CPIOHDRSUSV2 *PCCPIOHDRSUSV2; + + +/** The magic for the SuSv2 CPIO header. */ +#define CPIO_HDR_SUSV2_MAGIC "070707" + + +/** + * New ASCII format header. + */ +typedef struct CPIOHDRNEW +{ + /** 0x00: Magic identifying the header. */ + char achMagic[6]; + /** 0x06: Inode number. */ + char achInode[8]; + /** 0x0e: Mode. */ + char achMode[8]; + /** 0x16: User ID. */ + char achUid[8]; + /** 0x1e: Group ID. */ + char achGid[8]; + /** 0x26: Number of links to this file. */ + char achNLinks[8]; + /** 0x2e: Modification time. */ + char achMTime[8]; + /** 0x36: Size of the file stored as two independent 16bit integers. */ + char achFileSize[8]; + /** 0x3e: Device major number. */ + char achDevMajor[8]; + /** 0x46: Device minor number. */ + char achDevMinor[8]; + /** 0x4e: Assigned device major number for block or character device files. */ + char achRDevMajor[8]; + /** 0x56: Assigned device minor number for block or character device files. */ + char achRDevMinor[8]; + /** 0x5e: Number of bytes in the path name (including zero terminator) following the header. */ + char achNameSize[8]; + /** 0x66: Checksum of the file data if used. */ + char achCheck[8]; +} CPIOHDRNEW; +AssertCompileSize(CPIOHDRNEW, 6 + 13 * 8); +AssertCompileMemberOffset(CPIOHDRNEW, achMagic, 0x00); +AssertCompileMemberOffset(CPIOHDRNEW, achInode, 0x06); +AssertCompileMemberOffset(CPIOHDRNEW, achMode, 0x0e); +AssertCompileMemberOffset(CPIOHDRNEW, achUid, 0x16); +AssertCompileMemberOffset(CPIOHDRNEW, achGid, 0x1e); +AssertCompileMemberOffset(CPIOHDRNEW, achNLinks, 0x26); +AssertCompileMemberOffset(CPIOHDRNEW, achMTime, 0x2e); +AssertCompileMemberOffset(CPIOHDRNEW, achFileSize, 0x36); +AssertCompileMemberOffset(CPIOHDRNEW, achDevMajor, 0x3e); +AssertCompileMemberOffset(CPIOHDRNEW, achDevMinor, 0x46); +AssertCompileMemberOffset(CPIOHDRNEW, achRDevMajor, 0x4e); +AssertCompileMemberOffset(CPIOHDRNEW, achRDevMinor, 0x56); +AssertCompileMemberOffset(CPIOHDRNEW, achNameSize, 0x5e); +AssertCompileMemberOffset(CPIOHDRNEW, achCheck, 0x66); +typedef CPIOHDRNEW *PCPIOHDRNEW; +typedef const CPIOHDRNEW *PCCPIOHDRNEW; + + +/** The magic for the new ASCII CPIO header. */ +#define CPIO_HDR_NEW_MAGIC "070701" +/** The magic for the new ASCII CPIO header + checksum. */ +#define CPIO_HDR_NEW_CHKSUM_MAGIC "070702" + + +/** + * CPIO header union. + */ +typedef union CPIOHDR +{ + /** byte view. */ + uint8_t ab[110]; + /** The ancient binary header. */ + CPIOHDRBIN AncientBin; + /** The SuSv2 ASCII header. */ + CPIOHDRSUSV2 AsciiSuSv2; + /** The new ASCII header format. */ + CPIOHDRNEW AsciiNew; +} CPIOHDR; +typedef CPIOHDR *PCPIOHDR; +typedef const CPIOHDR *PCCPIOHDR; + + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_cpio_h */ + diff --git a/include/iprt/formats/dwarf.h b/include/iprt/formats/dwarf.h new file mode 100644 index 00000000..01f0cbbb --- /dev/null +++ b/include/iprt/formats/dwarf.h @@ -0,0 +1,542 @@ +/** @file + * IPRT - DWARF constants. + * + * @note dwarf.mac is generated from this file by running 'kmk incs' in the root. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_dwarf_h +#define IPRT_INCLUDED_formats_dwarf_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + + +/** @name Standard DWARF Line Number Opcodes + * @{ */ +#define DW_LNS_extended UINT8_C(0x00) +#define DW_LNS_copy UINT8_C(0x01) +#define DW_LNS_advance_pc UINT8_C(0x02) +#define DW_LNS_advance_line UINT8_C(0x03) +#define DW_LNS_set_file UINT8_C(0x04) +#define DW_LNS_set_column UINT8_C(0x05) +#define DW_LNS_negate_stmt UINT8_C(0x06) +#define DW_LNS_set_basic_block UINT8_C(0x07) +#define DW_LNS_const_add_pc UINT8_C(0x08) +#define DW_LNS_fixed_advance_pc UINT8_C(0x09) +#define DW_LNS_set_prologue_end UINT8_C(0x0a) +#define DW_LNS_set_epilogue_begin UINT8_C(0x0b) +#define DW_LNS_set_isa UINT8_C(0x0c) +#define DW_LNS_what_question_mark UINT8_C(0x0d) +/** @} */ + + +/** @name Extended DWARF Line Number Opcodes + * @{ */ +#define DW_LNE_end_sequence UINT8_C(1) +#define DW_LNE_set_address UINT8_C(2) +#define DW_LNE_define_file UINT8_C(3) +#define DW_LNE_set_descriminator UINT8_C(4) +/** @} */ + + +/** @name DIE Tags. + * @{ */ +#define DW_TAG_array_type UINT16_C(0x0001) +#define DW_TAG_class_type UINT16_C(0x0002) +#define DW_TAG_entry_point UINT16_C(0x0003) +#define DW_TAG_enumeration_type UINT16_C(0x0004) +#define DW_TAG_formal_parameter UINT16_C(0x0005) +#define DW_TAG_imported_declaration UINT16_C(0x0008) +#define DW_TAG_label UINT16_C(0x000a) +#define DW_TAG_lexical_block UINT16_C(0x000b) +#define DW_TAG_member UINT16_C(0x000d) +#define DW_TAG_pointer_type UINT16_C(0x000f) +#define DW_TAG_reference_type UINT16_C(0x0010) +#define DW_TAG_compile_unit UINT16_C(0x0011) +#define DW_TAG_string_type UINT16_C(0x0012) +#define DW_TAG_structure_type UINT16_C(0x0013) +#define DW_TAG_subroutine_type UINT16_C(0x0015) +#define DW_TAG_typedef UINT16_C(0x0016) +#define DW_TAG_union_type UINT16_C(0x0017) +#define DW_TAG_unspecified_parameters UINT16_C(0x0018) +#define DW_TAG_variant UINT16_C(0x0019) +#define DW_TAG_common_block UINT16_C(0x001a) +#define DW_TAG_common_inclusion UINT16_C(0x001b) +#define DW_TAG_inheritance UINT16_C(0x001c) +#define DW_TAG_inlined_subroutine UINT16_C(0x001d) +#define DW_TAG_module UINT16_C(0x001e) +#define DW_TAG_ptr_to_member_type UINT16_C(0x001f) +#define DW_TAG_set_type UINT16_C(0x0020) +#define DW_TAG_subrange_type UINT16_C(0x0021) +#define DW_TAG_with_stmt UINT16_C(0x0022) +#define DW_TAG_access_declaration UINT16_C(0x0023) +#define DW_TAG_base_type UINT16_C(0x0024) +#define DW_TAG_catch_block UINT16_C(0x0025) +#define DW_TAG_const_type UINT16_C(0x0026) +#define DW_TAG_constant UINT16_C(0x0027) +#define DW_TAG_enumerator UINT16_C(0x0028) +#define DW_TAG_file_type UINT16_C(0x0029) +#define DW_TAG_friend UINT16_C(0x002a) +#define DW_TAG_namelist UINT16_C(0x002b) +#define DW_TAG_namelist_item UINT16_C(0x002c) +#define DW_TAG_packed_type UINT16_C(0x002d) +#define DW_TAG_subprogram UINT16_C(0x002e) +#define DW_TAG_template_type_parameter UINT16_C(0x002f) +#define DW_TAG_template_value_parameter UINT16_C(0x0030) +#define DW_TAG_thrown_type UINT16_C(0x0031) +#define DW_TAG_try_block UINT16_C(0x0032) +#define DW_TAG_variant_part UINT16_C(0x0033) +#define DW_TAG_variable UINT16_C(0x0034) +#define DW_TAG_volatile_type UINT16_C(0x0035) +#define DW_TAG_dwarf_procedure UINT16_C(0x0036) +#define DW_TAG_restrict_type UINT16_C(0x0037) +#define DW_TAG_interface_type UINT16_C(0x0038) +#define DW_TAG_namespace UINT16_C(0x0039) +#define DW_TAG_imported_module UINT16_C(0x003a) +#define DW_TAG_unspecified_type UINT16_C(0x003b) +#define DW_TAG_partial_unit UINT16_C(0x003c) +#define DW_TAG_imported_unit UINT16_C(0x003d) +#define DW_TAG_condition UINT16_C(0x003f) +#define DW_TAG_shared_type UINT16_C(0x0040) +#define DW_TAG_type_unit UINT16_C(0x0041) +#define DW_TAG_rvalue_reference_type UINT16_C(0x0042) +#define DW_TAG_template_alias UINT16_C(0x0043) +#define DW_TAG_lo_user UINT16_C(0x4080) +#define DW_TAG_GNU_call_site UINT16_C(0x4109) +#define DW_TAG_GNU_call_site_parameter UINT16_C(0x410a) +#define DW_TAG_WATCOM_address_class_type UINT16_C(0x4100) /**< Watcom extension. */ +#define DW_TAG_WATCOM_namespace UINT16_C(0x4101) /**< Watcom extension. */ +#define DW_TAG_hi_user UINT16_C(0xffff) +/** @} */ + + +/** @name Has children or not (follows DW_TAG_xxx in .debug_abbrev). + * @{ */ +#define DW_CHILDREN_yes 1 +#define DW_CHILDREN_no 0 +/** @} */ + + +/** @name DIE Attributes. + * @{ */ +#define DW_AT_sibling UINT16_C(0x0001) +#define DW_AT_location UINT16_C(0x0002) +#define DW_AT_name UINT16_C(0x0003) +#define DW_AT_ordering UINT16_C(0x0009) +#define DW_AT_byte_size UINT16_C(0x000b) +#define DW_AT_bit_offset UINT16_C(0x000c) +#define DW_AT_bit_size UINT16_C(0x000d) +#define DW_AT_stmt_list UINT16_C(0x0010) +#define DW_AT_low_pc UINT16_C(0x0011) +#define DW_AT_high_pc UINT16_C(0x0012) +#define DW_AT_language UINT16_C(0x0013) +#define DW_AT_discr UINT16_C(0x0015) +#define DW_AT_discr_value UINT16_C(0x0016) +#define DW_AT_visibility UINT16_C(0x0017) +#define DW_AT_import UINT16_C(0x0018) +#define DW_AT_string_length UINT16_C(0x0019) +#define DW_AT_common_reference UINT16_C(0x001a) +#define DW_AT_comp_dir UINT16_C(0x001b) +#define DW_AT_const_value UINT16_C(0x001c) +#define DW_AT_containing_type UINT16_C(0x001d) +#define DW_AT_default_value UINT16_C(0x001e) +#define DW_AT_inline UINT16_C(0x0020) +#define DW_AT_is_optional UINT16_C(0x0021) +#define DW_AT_lower_bound UINT16_C(0x0022) +#define DW_AT_producer UINT16_C(0x0025) +#define DW_AT_prototyped UINT16_C(0x0027) +#define DW_AT_return_addr UINT16_C(0x002a) +#define DW_AT_start_scope UINT16_C(0x002c) +#define DW_AT_bit_stride UINT16_C(0x002e) +#define DW_AT_upper_bound UINT16_C(0x002f) +#define DW_AT_abstract_origin UINT16_C(0x0031) +#define DW_AT_accessibility UINT16_C(0x0032) +#define DW_AT_address_class UINT16_C(0x0033) +#define DW_AT_artificial UINT16_C(0x0034) +#define DW_AT_base_types UINT16_C(0x0035) +#define DW_AT_calling_convention UINT16_C(0x0036) +#define DW_AT_count UINT16_C(0x0037) +#define DW_AT_data_member_location UINT16_C(0x0038) +#define DW_AT_decl_column UINT16_C(0x0039) +#define DW_AT_decl_file UINT16_C(0x003a) +#define DW_AT_decl_line UINT16_C(0x003b) +#define DW_AT_declaration UINT16_C(0x003c) +#define DW_AT_discr_list UINT16_C(0x003d) +#define DW_AT_encoding UINT16_C(0x003e) +#define DW_AT_external UINT16_C(0x003f) +#define DW_AT_frame_base UINT16_C(0x0040) +#define DW_AT_friend UINT16_C(0x0041) +#define DW_AT_identifier_case UINT16_C(0x0042) +#define DW_AT_macro_info UINT16_C(0x0043) +#define DW_AT_namelist_item UINT16_C(0x0044) +#define DW_AT_priority UINT16_C(0x0045) +#define DW_AT_segment UINT16_C(0x0046) +#define DW_AT_specification UINT16_C(0x0047) +#define DW_AT_static_link UINT16_C(0x0048) +#define DW_AT_type UINT16_C(0x0049) +#define DW_AT_use_location UINT16_C(0x004a) +#define DW_AT_variable_parameter UINT16_C(0x004b) +#define DW_AT_virtuality UINT16_C(0x004c) +#define DW_AT_vtable_elem_location UINT16_C(0x004d) +#define DW_AT_allocated UINT16_C(0x004e) +#define DW_AT_associated UINT16_C(0x004f) +#define DW_AT_data_location UINT16_C(0x0050) +#define DW_AT_byte_stride UINT16_C(0x0051) +#define DW_AT_entry_pc UINT16_C(0x0052) +#define DW_AT_use_UTF8 UINT16_C(0x0053) +#define DW_AT_extension UINT16_C(0x0054) +#define DW_AT_ranges UINT16_C(0x0055) +#define DW_AT_trampoline UINT16_C(0x0056) +#define DW_AT_call_column UINT16_C(0x0057) +#define DW_AT_call_file UINT16_C(0x0058) +#define DW_AT_call_line UINT16_C(0x0059) +#define DW_AT_description UINT16_C(0x005a) +#define DW_AT_binary_scale UINT16_C(0x005b) +#define DW_AT_decimal_scale UINT16_C(0x005c) +#define DW_AT_small UINT16_C(0x005d) +#define DW_AT_decimal_sign UINT16_C(0x005e) +#define DW_AT_digit_count UINT16_C(0x005f) +#define DW_AT_picture_string UINT16_C(0x0060) +#define DW_AT_mutable UINT16_C(0x0061) +#define DW_AT_threads_scaled UINT16_C(0x0062) +#define DW_AT_explicit UINT16_C(0x0063) +#define DW_AT_object_pointer UINT16_C(0x0064) +#define DW_AT_endianity UINT16_C(0x0065) +#define DW_AT_elemental UINT16_C(0x0066) +#define DW_AT_pure UINT16_C(0x0067) +#define DW_AT_recursive UINT16_C(0x0068) +#define DW_AT_signature UINT16_C(0x0069) +#define DW_AT_main_subprogram UINT16_C(0x006a) +#define DW_AT_data_bit_offset UINT16_C(0x006b) +#define DW_AT_const_expr UINT16_C(0x006c) +#define DW_AT_enum_class UINT16_C(0x006d) +#define DW_AT_linkage_name UINT16_C(0x006e) +#define DW_AT_lo_user UINT16_C(0x2000) +/** Used by GCC and others, same as DW_AT_linkage_name. See http://wiki.dwarfstd.org/index.php?title=DW_AT_linkage_name*/ +#define DW_AT_MIPS_linkage_name UINT16_C(0x2007) +#define DW_AT_WATCOM_memory_model UINT16_C(0x2082) /**< Watcom extension. */ +#define DW_AT_WATCOM_references_start UINT16_C(0x2083) /**< Watcom extension. */ +#define DW_AT_WATCOM_parm_entry UINT16_C(0x2084) /**< Watcom extension. */ +#define DW_AT_hi_user UINT16_C(0x3fff) +/** @} */ + +/** @name DIE Forms. + * @{ */ +#define DW_FORM_addr UINT16_C(0x01) +/* 0x02 was FORM_REF in DWARF v1, obsolete now. */ +#define DW_FORM_block2 UINT16_C(0x03) +#define DW_FORM_block4 UINT16_C(0x04) +#define DW_FORM_data2 UINT16_C(0x05) +#define DW_FORM_data4 UINT16_C(0x06) +#define DW_FORM_data8 UINT16_C(0x07) +#define DW_FORM_string UINT16_C(0x08) +#define DW_FORM_block UINT16_C(0x09) +#define DW_FORM_block1 UINT16_C(0x0a) +#define DW_FORM_data1 UINT16_C(0x0b) +#define DW_FORM_flag UINT16_C(0x0c) +#define DW_FORM_sdata UINT16_C(0x0d) +#define DW_FORM_strp UINT16_C(0x0e) +#define DW_FORM_udata UINT16_C(0x0f) +#define DW_FORM_ref_addr UINT16_C(0x10) +#define DW_FORM_ref1 UINT16_C(0x11) +#define DW_FORM_ref2 UINT16_C(0x12) +#define DW_FORM_ref4 UINT16_C(0x13) +#define DW_FORM_ref8 UINT16_C(0x14) +#define DW_FORM_ref_udata UINT16_C(0x15) +#define DW_FORM_indirect UINT16_C(0x16) +#define DW_FORM_sec_offset UINT16_C(0x17) +#define DW_FORM_exprloc UINT16_C(0x18) +#define DW_FORM_flag_present UINT16_C(0x19) +#define DW_FORM_ref_sig8 UINT16_C(0x20) +/** @} */ + +/** @name Address classes. + * @{ */ +#define DW_ADDR_none UINT8_C(0) +#define DW_ADDR_i386_near16 UINT8_C(1) +#define DW_ADDR_i386_far16 UINT8_C(2) +#define DW_ADDR_i386_huge16 UINT8_C(3) +#define DW_ADDR_i386_near32 UINT8_C(4) +#define DW_ADDR_i386_far32 UINT8_C(5) +/** @} */ + + +/** @name Location Expression Opcodes + * @{ */ +#define DW_OP_addr UINT8_C(0x03) /**< 1 operand, a constant address (size target specific). */ +#define DW_OP_deref UINT8_C(0x06) /**< 0 operands. */ +#define DW_OP_const1u UINT8_C(0x08) /**< 1 operand, a 1-byte constant. */ +#define DW_OP_const1s UINT8_C(0x09) /**< 1 operand, a 1-byte constant. */ +#define DW_OP_const2u UINT8_C(0x0a) /**< 1 operand, a 2-byte constant. */ +#define DW_OP_const2s UINT8_C(0x0b) /**< 1 operand, a 2-byte constant. */ +#define DW_OP_const4u UINT8_C(0x0c) /**< 1 operand, a 4-byte constant. */ +#define DW_OP_const4s UINT8_C(0x0d) /**< 1 operand, a 4-byte constant. */ +#define DW_OP_const8u UINT8_C(0x0e) /**< 1 operand, a 8-byte constant. */ +#define DW_OP_const8s UINT8_C(0x0f) /**< 1 operand, a 8-byte constant. */ +#define DW_OP_constu UINT8_C(0x10) /**< 1 operand, a ULEB128 constant. */ +#define DW_OP_consts UINT8_C(0x11) /**< 1 operand, a SLEB128 constant. */ +#define DW_OP_dup UINT8_C(0x12) /**< 0 operands. */ +#define DW_OP_drop UINT8_C(0x13) /**< 0 operands. */ +#define DW_OP_over UINT8_C(0x14) /**< 0 operands. */ +#define DW_OP_pick UINT8_C(0x15) /**< 1 operands, a 1-byte stack index. */ +#define DW_OP_swap UINT8_C(0x16) /**< 0 operands. */ +#define DW_OP_rot UINT8_C(0x17) /**< 0 operands. */ +#define DW_OP_xderef UINT8_C(0x18) /**< 0 operands. */ +#define DW_OP_abs UINT8_C(0x19) /**< 0 operands. */ +#define DW_OP_and UINT8_C(0x1a) /**< 0 operands. */ +#define DW_OP_div UINT8_C(0x1b) /**< 0 operands. */ +#define DW_OP_minus UINT8_C(0x1c) /**< 0 operands. */ +#define DW_OP_mod UINT8_C(0x1d) /**< 0 operands. */ +#define DW_OP_mul UINT8_C(0x1e) /**< 0 operands. */ +#define DW_OP_neg UINT8_C(0x1f) /**< 0 operands. */ +#define DW_OP_not UINT8_C(0x20) /**< 0 operands. */ +#define DW_OP_or UINT8_C(0x21) /**< 0 operands. */ +#define DW_OP_plus UINT8_C(0x22) /**< 0 operands. */ +#define DW_OP_plus_uconst UINT8_C(0x23) /**< 1 operands, a ULEB128 addend. */ +#define DW_OP_shl UINT8_C(0x24) /**< 0 operands. */ +#define DW_OP_shr UINT8_C(0x25) /**< 0 operands. */ +#define DW_OP_shra UINT8_C(0x26) /**< 0 operands. */ +#define DW_OP_xor UINT8_C(0x27) /**< 0 operands. */ +#define DW_OP_skip UINT8_C(0x2f) /**< 1 signed 2-byte constant. */ +#define DW_OP_bra UINT8_C(0x28) /**< 1 signed 2-byte constant. */ +#define DW_OP_eq UINT8_C(0x29) /**< 0 operands. */ +#define DW_OP_ge UINT8_C(0x2a) /**< 0 operands. */ +#define DW_OP_gt UINT8_C(0x2b) /**< 0 operands. */ +#define DW_OP_le UINT8_C(0x2c) /**< 0 operands. */ +#define DW_OP_lt UINT8_C(0x2d) /**< 0 operands. */ +#define DW_OP_ne UINT8_C(0x2e) /**< 0 operands. */ +#define DW_OP_lit0 UINT8_C(0x30) /**< 0 operands - literals 0..31 */ +#define DW_OP_lit31 UINT8_C(0x4f) /**< last litteral. */ +#define DW_OP_reg0 UINT8_C(0x50) /**< 0 operands - reg 0..31. */ +#define DW_OP_reg31 UINT8_C(0x6f) /**< last register. */ +#define DW_OP_breg0 UINT8_C(0x70) /**< 1 operand, a SLEB128 offset. */ +#define DW_OP_breg31 UINT8_C(0x8f) /**< last branch register. */ +#define DW_OP_regx UINT8_C(0x90) /**< 1 operand, a ULEB128 register. */ +#define DW_OP_fbreg UINT8_C(0x91) /**< 1 operand, a SLEB128 offset. */ +#define DW_OP_bregx UINT8_C(0x92) /**< 2 operands, a ULEB128 register followed by a SLEB128 offset. */ +#define DW_OP_piece UINT8_C(0x93) /**< 1 operand, a ULEB128 size of piece addressed. */ +#define DW_OP_deref_size UINT8_C(0x94) /**< 1 operand, a 1-byte size of data retrieved. */ +#define DW_OP_xderef_size UINT8_C(0x95) /**< 1 operand, a 1-byte size of data retrieved. */ +#define DW_OP_nop UINT8_C(0x96) /**< 0 operands. */ +#define DW_OP_lo_user UINT8_C(0xe0) /**< First user opcode */ +#define DW_OP_hi_user UINT8_C(0xff) /**< Last user opcode. */ +/** @} */ + +/** @name Exception Handler Pointer Encodings (GCC/LSB). + * @{ */ +#define DW_EH_PE_FORMAT_MASK UINT8_C(0x0f) /**< Format mask. */ +#define DW_EH_PE_APPL_MASK UINT8_C(0x70) /**< Application mask. */ +#define DW_EH_PE_indirect UINT8_C(0x80) /**< Flag: Indirect pointer. */ +#define DW_EH_PE_omit UINT8_C(0xff) /**< Special value: Omitted. */ +#define DW_EH_PE_ptr UINT8_C(0x00) /**< Format: pointer sized, unsigned. */ +#define DW_EH_PE_uleb128 UINT8_C(0x01) /**< Format: unsigned LEB128. */ +#define DW_EH_PE_udata2 UINT8_C(0x02) /**< Format: unsigned 16-bit. */ +#define DW_EH_PE_udata4 UINT8_C(0x03) /**< Format: unsigned 32-bit. */ +#define DW_EH_PE_udata8 UINT8_C(0x04) /**< Format: unsigned 64-bit. */ +#define DW_EH_PE_sleb128 UINT8_C(0x09) /**< Format: signed LEB128. */ +#define DW_EH_PE_sdata2 UINT8_C(0x0a) /**< Format: signed 16-bit. */ +#define DW_EH_PE_sdata4 UINT8_C(0x0b) /**< Format: signed 32-bit. */ +#define DW_EH_PE_sdata8 UINT8_C(0x0c) /**< Format: signed 64-bit. */ +#define DW_EH_PE_absptr UINT8_C(0x00) /**< Application: Absolute */ +#define DW_EH_PE_pcrel UINT8_C(0x10) /**< Application: PC relative, i.e. relative pointer address. */ +#define DW_EH_PE_textrel UINT8_C(0x20) /**< Application: text section relative. */ +#define DW_EH_PE_datarel UINT8_C(0x30) /**< Application: data section relative. */ +#define DW_EH_PE_funcrel UINT8_C(0x40) /**< Application: relative to start of function. */ +#define DW_EH_PE_aligned UINT8_C(0x50) /**< Application: aligned pointer. */ +/** @} */ + +/** @name Call frame instructions. + * @{ */ +/** Mask to use to identify DW_CFA_advance_loc, DW_CFA_offset and DW_CFA_restore. */ +#define DW_CFA_high_bit_mask UINT8_C(0xc0) + +#define DW_CFA_nop UINT8_C(0x00) /**< No operands. */ + +#define DW_CFA_advance_loc UINT8_C(0x40) /**< low 6 bits: delta to advance. */ +#define DW_CFA_set_loc UINT8_C(0x01) /**< op1: address. */ +#define DW_CFA_advance_loc1 UINT8_C(0x02) /**< op1: 1-byte delta. */ +#define DW_CFA_advance_loc2 UINT8_C(0x03) /**< op1: 2-byte delta. */ +#define DW_CFA_advance_loc4 UINT8_C(0x04) /**< op1: 4-byte delta. */ + +#define DW_CFA_offset UINT8_C(0x80) /**< low 6 bits: register; op1: ULEB128 offset. */ +#define DW_CFA_offset_extended UINT8_C(0x05) /**< op1: ULEB128 register; op2: ULEB128 offset. */ +#define DW_CFA_offset_extended_sf UINT8_C(0x11) /**< op1: ULEB128 register; op2: SLEB128 offset. */ +#define DW_CFA_restore UINT8_C(0xc0) /**< low 6 bits: register. */ +#define DW_CFA_restore_extended UINT8_C(0x06) /**< op1: ULEB128 register. */ +#define DW_CFA_undefined UINT8_C(0x07) /**< op1: ULEB128 register. */ +#define DW_CFA_same_value UINT8_C(0x08) /**< op1: ULEB128 register. */ +#define DW_CFA_register UINT8_C(0x09) /**< op1: ULEB128 destination register; op2: ULEB128 source register. */ +#define DW_CFA_expression UINT8_C(0x10) /**< op1: ULEB128 register; op2: BLOCK. */ + +#define DW_CFA_val_offset UINT8_C(0x14) /**< op1: ULEB128 register; op2: ULEB128. */ +#define DW_CFA_val_offset_sf UINT8_C(0x15) /**< op1: ULEB128 register; op2: SLEB128. */ +#define DW_CFA_val_expression UINT8_C(0x16) /**< op1: ULEB128 register; op2: BLOCK. */ + +#define DW_CFA_remember_state UINT8_C(0x0a) /**< No operands. */ +#define DW_CFA_restore_state UINT8_C(0x0b) /**< No operands. */ + +#define DW_CFA_def_cfa UINT8_C(0x0c) /**< op1: ULEB128 register; op2: ULEB128 offset. */ +#define DW_CFA_def_cfa_register UINT8_C(0x0d) /**< op1: ULEB128 register. */ +#define DW_CFA_def_cfa_offset UINT8_C(0x0e) /**< op1: ULEB128 offset. */ +#define DW_CFA_def_cfa_expression UINT8_C(0x0f) /**< op1: BLOCK. */ +#define DW_CFA_def_cfa_sf UINT8_C(0x12) /**< op1: ULEB128 register; op2: SLEB128 offset. */ +#define DW_CFA_def_cfa_offset_sf UINT8_C(0x13) /**< op1: SLEB128 offset. */ + +#define DW_CFA_lo_user UINT8_C(0x1c) /**< User defined operands. */ +#define DW_CFA_MIPS_advance_loc8 UINT8_C(0x1d) /**< op1: 8-byte delta? */ +#define DW_CFA_GNU_window_save UINT8_C(0x2d) /**< op1: ??; op2: ?? */ +#define DW_CFA_GNU_args_size UINT8_C(0x2e) /**< op1: ??; op2: ?? */ +#define DW_CFA_GNU_negative_offset_extended UINT8_C(0x2f) /**< op1: ??; op2: ?? */ +#define DW_CFA_hi_user UINT8_C(0x3f) /**< User defined operands. */ +/** @} */ + + +/** @name DWREG_X86_XXX - 386+ register number mappings. + * @{ */ +#define DWREG_X86_EAX 0 +#define DWREG_X86_ECX 1 +#define DWREG_X86_EDX 2 +#define DWREG_X86_EBX 3 +#define DWREG_X86_ESP 4 +#define DWREG_X86_EBP 5 +#define DWREG_X86_ESI 6 +#define DWREG_X86_EDI 7 +#define DWREG_X86_RA 8 /* return address (=EIP) */ +#define DWREG_X86_EFLAGS 9 +#define DWREG_X86_ST1 11 +#define DWREG_X86_ST2 12 +#define DWREG_X86_ST3 13 +#define DWREG_X86_ST4 14 +#define DWREG_X86_ST5 15 +#define DWREG_X86_ST6 16 +#define DWREG_X86_ST7 17 +#define DWREG_X86_XMM0 21 +#define DWREG_X86_XMM1 22 +#define DWREG_X86_XMM2 23 +#define DWREG_X86_XMM3 24 +#define DWREG_X86_XMM4 25 +#define DWREG_X86_XMM5 26 +#define DWREG_X86_XMM6 27 +#define DWREG_X86_XMM7 28 +#define DWREG_X86_MM0 29 +#define DWREG_X86_MM1 30 +#define DWREG_X86_MM2 31 +#define DWREG_X86_MM3 32 +#define DWREG_X86_MM4 33 +#define DWREG_X86_MM5 34 +#define DWREG_X86_MM6 35 +#define DWREG_X86_MM7 36 +#define DWREG_X86_MXCSR 39 +#define DWREG_X86_ES 40 +#define DWREG_X86_CS 41 +#define DWREG_X86_SS 42 +#define DWREG_X86_DS 43 +#define DWREG_X86_FS 44 +#define DWREG_X86_GS 45 +#define DWREG_X86_TR 48 +#define DWREG_X86_LDTR 49 +/** @} */ + + +/** @name DWREG_AMD64_XXX - AMD64 register number mappings. + * @note This for some braindead reason the first 8 GPR are in intel encoding + * order, unlike the DWREG_X86_XXX variant. Utter stupidity. + * @{ */ +#define DWREG_AMD64_RAX 0 +#define DWREG_AMD64_RDX 1 +#define DWREG_AMD64_RCX 2 +#define DWREG_AMD64_RBX 3 +#define DWREG_AMD64_RSI 4 +#define DWREG_AMD64_RDI 5 +#define DWREG_AMD64_RBP 6 +#define DWREG_AMD64_RSP 7 +#define DWREG_AMD64_R8 8 +#define DWREG_AMD64_R9 9 +#define DWREG_AMD64_R10 10 +#define DWREG_AMD64_R11 11 +#define DWREG_AMD64_R12 12 +#define DWREG_AMD64_R13 13 +#define DWREG_AMD64_R14 14 +#define DWREG_AMD64_R15 15 +#define DWREG_AMD64_RA 16 /* return address (=RIP) */ +#define DWREG_AMD64_XMM0 17 +#define DWREG_AMD64_XMM1 18 +#define DWREG_AMD64_XMM2 19 +#define DWREG_AMD64_XMM3 20 +#define DWREG_AMD64_XMM4 21 +#define DWREG_AMD64_XMM5 22 +#define DWREG_AMD64_XMM6 23 +#define DWREG_AMD64_XMM7 24 +#define DWREG_AMD64_XMM8 25 +#define DWREG_AMD64_XMM9 26 +#define DWREG_AMD64_XMM10 27 +#define DWREG_AMD64_XMM11 28 +#define DWREG_AMD64_XMM12 29 +#define DWREG_AMD64_XMM13 30 +#define DWREG_AMD64_XMM14 31 +#define DWREG_AMD64_XMM15 32 +#define DWREG_AMD64_ST0 33 +#define DWREG_AMD64_ST1 34 +#define DWREG_AMD64_ST2 35 +#define DWREG_AMD64_ST3 36 +#define DWREG_AMD64_ST4 37 +#define DWREG_AMD64_ST5 38 +#define DWREG_AMD64_ST6 39 +#define DWREG_AMD64_ST7 40 +#define DWREG_AMD64_MM0 41 +#define DWREG_AMD64_MM1 42 +#define DWREG_AMD64_MM2 43 +#define DWREG_AMD64_MM3 44 +#define DWREG_AMD64_MM4 45 +#define DWREG_AMD64_MM5 46 +#define DWREG_AMD64_MM6 47 +#define DWREG_AMD64_MM7 48 +#define DWREG_AMD64_RFLAGS 49 +#define DWREG_AMD64_ES 50 +#define DWREG_AMD64_CS 51 +#define DWREG_AMD64_SS 52 +#define DWREG_AMD64_DS 53 +#define DWREG_AMD64_FS 54 +#define DWREG_AMD64_GS 55 +#define DWREG_AMD64_FS_BASE 58 +#define DWREG_AMD64_GS_BASE 59 +#define DWREG_AMD64_TR 62 +#define DWREG_AMD64_LDTR 63 +#define DWREG_AMD64_MXCSR 64 +#define DWREG_AMD64_FCW 65 +#define DWREG_AMD64_FSW 66 +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_dwarf_h */ + diff --git a/include/iprt/formats/dwarf.mac b/include/iprt/formats/dwarf.mac new file mode 100644 index 00000000..0ed4628c --- /dev/null +++ b/include/iprt/formats/dwarf.mac @@ -0,0 +1,471 @@ +;; @file +; IPRT - DWARF constants. +; +; Automatically generated by various.sed. DO NOT EDIT! +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +%ifndef IPRT_INCLUDED_formats_dwarf_h +%define IPRT_INCLUDED_formats_dwarf_h +%ifndef RT_WITHOUT_PRAGMA_ONCE +%endif +%define DW_LNS_extended 0x00 +%define DW_LNS_copy 0x01 +%define DW_LNS_advance_pc 0x02 +%define DW_LNS_advance_line 0x03 +%define DW_LNS_set_file 0x04 +%define DW_LNS_set_column 0x05 +%define DW_LNS_negate_stmt 0x06 +%define DW_LNS_set_basic_block 0x07 +%define DW_LNS_const_add_pc 0x08 +%define DW_LNS_fixed_advance_pc 0x09 +%define DW_LNS_set_prologue_end 0x0a +%define DW_LNS_set_epilogue_begin 0x0b +%define DW_LNS_set_isa 0x0c +%define DW_LNS_what_question_mark 0x0d +%define DW_LNE_end_sequence 1 +%define DW_LNE_set_address 2 +%define DW_LNE_define_file 3 +%define DW_LNE_set_descriminator 4 +%define DW_TAG_array_type 0x0001 +%define DW_TAG_class_type 0x0002 +%define DW_TAG_entry_point 0x0003 +%define DW_TAG_enumeration_type 0x0004 +%define DW_TAG_formal_parameter 0x0005 +%define DW_TAG_imported_declaration 0x0008 +%define DW_TAG_label 0x000a +%define DW_TAG_lexical_block 0x000b +%define DW_TAG_member 0x000d +%define DW_TAG_pointer_type 0x000f +%define DW_TAG_reference_type 0x0010 +%define DW_TAG_compile_unit 0x0011 +%define DW_TAG_string_type 0x0012 +%define DW_TAG_structure_type 0x0013 +%define DW_TAG_subroutine_type 0x0015 +%define DW_TAG_typedef 0x0016 +%define DW_TAG_union_type 0x0017 +%define DW_TAG_unspecified_parameters 0x0018 +%define DW_TAG_variant 0x0019 +%define DW_TAG_common_block 0x001a +%define DW_TAG_common_inclusion 0x001b +%define DW_TAG_inheritance 0x001c +%define DW_TAG_inlined_subroutine 0x001d +%define DW_TAG_module 0x001e +%define DW_TAG_ptr_to_member_type 0x001f +%define DW_TAG_set_type 0x0020 +%define DW_TAG_subrange_type 0x0021 +%define DW_TAG_with_stmt 0x0022 +%define DW_TAG_access_declaration 0x0023 +%define DW_TAG_base_type 0x0024 +%define DW_TAG_catch_block 0x0025 +%define DW_TAG_const_type 0x0026 +%define DW_TAG_constant 0x0027 +%define DW_TAG_enumerator 0x0028 +%define DW_TAG_file_type 0x0029 +%define DW_TAG_friend 0x002a +%define DW_TAG_namelist 0x002b +%define DW_TAG_namelist_item 0x002c +%define DW_TAG_packed_type 0x002d +%define DW_TAG_subprogram 0x002e +%define DW_TAG_template_type_parameter 0x002f +%define DW_TAG_template_value_parameter 0x0030 +%define DW_TAG_thrown_type 0x0031 +%define DW_TAG_try_block 0x0032 +%define DW_TAG_variant_part 0x0033 +%define DW_TAG_variable 0x0034 +%define DW_TAG_volatile_type 0x0035 +%define DW_TAG_dwarf_procedure 0x0036 +%define DW_TAG_restrict_type 0x0037 +%define DW_TAG_interface_type 0x0038 +%define DW_TAG_namespace 0x0039 +%define DW_TAG_imported_module 0x003a +%define DW_TAG_unspecified_type 0x003b +%define DW_TAG_partial_unit 0x003c +%define DW_TAG_imported_unit 0x003d +%define DW_TAG_condition 0x003f +%define DW_TAG_shared_type 0x0040 +%define DW_TAG_type_unit 0x0041 +%define DW_TAG_rvalue_reference_type 0x0042 +%define DW_TAG_template_alias 0x0043 +%define DW_TAG_lo_user 0x4080 +%define DW_TAG_GNU_call_site 0x4109 +%define DW_TAG_GNU_call_site_parameter 0x410a +%define DW_TAG_WATCOM_address_class_type 0x4100 +%define DW_TAG_WATCOM_namespace 0x4101 +%define DW_TAG_hi_user 0xffff +%define DW_CHILDREN_yes 1 +%define DW_CHILDREN_no 0 +%define DW_AT_sibling 0x0001 +%define DW_AT_location 0x0002 +%define DW_AT_name 0x0003 +%define DW_AT_ordering 0x0009 +%define DW_AT_byte_size 0x000b +%define DW_AT_bit_offset 0x000c +%define DW_AT_bit_size 0x000d +%define DW_AT_stmt_list 0x0010 +%define DW_AT_low_pc 0x0011 +%define DW_AT_high_pc 0x0012 +%define DW_AT_language 0x0013 +%define DW_AT_discr 0x0015 +%define DW_AT_discr_value 0x0016 +%define DW_AT_visibility 0x0017 +%define DW_AT_import 0x0018 +%define DW_AT_string_length 0x0019 +%define DW_AT_common_reference 0x001a +%define DW_AT_comp_dir 0x001b +%define DW_AT_const_value 0x001c +%define DW_AT_containing_type 0x001d +%define DW_AT_default_value 0x001e +%define DW_AT_inline 0x0020 +%define DW_AT_is_optional 0x0021 +%define DW_AT_lower_bound 0x0022 +%define DW_AT_producer 0x0025 +%define DW_AT_prototyped 0x0027 +%define DW_AT_return_addr 0x002a +%define DW_AT_start_scope 0x002c +%define DW_AT_bit_stride 0x002e +%define DW_AT_upper_bound 0x002f +%define DW_AT_abstract_origin 0x0031 +%define DW_AT_accessibility 0x0032 +%define DW_AT_address_class 0x0033 +%define DW_AT_artificial 0x0034 +%define DW_AT_base_types 0x0035 +%define DW_AT_calling_convention 0x0036 +%define DW_AT_count 0x0037 +%define DW_AT_data_member_location 0x0038 +%define DW_AT_decl_column 0x0039 +%define DW_AT_decl_file 0x003a +%define DW_AT_decl_line 0x003b +%define DW_AT_declaration 0x003c +%define DW_AT_discr_list 0x003d +%define DW_AT_encoding 0x003e +%define DW_AT_external 0x003f +%define DW_AT_frame_base 0x0040 +%define DW_AT_friend 0x0041 +%define DW_AT_identifier_case 0x0042 +%define DW_AT_macro_info 0x0043 +%define DW_AT_namelist_item 0x0044 +%define DW_AT_priority 0x0045 +%define DW_AT_segment 0x0046 +%define DW_AT_specification 0x0047 +%define DW_AT_static_link 0x0048 +%define DW_AT_type 0x0049 +%define DW_AT_use_location 0x004a +%define DW_AT_variable_parameter 0x004b +%define DW_AT_virtuality 0x004c +%define DW_AT_vtable_elem_location 0x004d +%define DW_AT_allocated 0x004e +%define DW_AT_associated 0x004f +%define DW_AT_data_location 0x0050 +%define DW_AT_byte_stride 0x0051 +%define DW_AT_entry_pc 0x0052 +%define DW_AT_use_UTF8 0x0053 +%define DW_AT_extension 0x0054 +%define DW_AT_ranges 0x0055 +%define DW_AT_trampoline 0x0056 +%define DW_AT_call_column 0x0057 +%define DW_AT_call_file 0x0058 +%define DW_AT_call_line 0x0059 +%define DW_AT_description 0x005a +%define DW_AT_binary_scale 0x005b +%define DW_AT_decimal_scale 0x005c +%define DW_AT_small 0x005d +%define DW_AT_decimal_sign 0x005e +%define DW_AT_digit_count 0x005f +%define DW_AT_picture_string 0x0060 +%define DW_AT_mutable 0x0061 +%define DW_AT_threads_scaled 0x0062 +%define DW_AT_explicit 0x0063 +%define DW_AT_object_pointer 0x0064 +%define DW_AT_endianity 0x0065 +%define DW_AT_elemental 0x0066 +%define DW_AT_pure 0x0067 +%define DW_AT_recursive 0x0068 +%define DW_AT_signature 0x0069 +%define DW_AT_main_subprogram 0x006a +%define DW_AT_data_bit_offset 0x006b +%define DW_AT_const_expr 0x006c +%define DW_AT_enum_class 0x006d +%define DW_AT_linkage_name 0x006e +%define DW_AT_lo_user 0x2000 +%define DW_AT_MIPS_linkage_name 0x2007 +%define DW_AT_WATCOM_memory_model 0x2082 +%define DW_AT_WATCOM_references_start 0x2083 +%define DW_AT_WATCOM_parm_entry 0x2084 +%define DW_AT_hi_user 0x3fff +%define DW_FORM_addr 0x01 +%define DW_FORM_block2 0x03 +%define DW_FORM_block4 0x04 +%define DW_FORM_data2 0x05 +%define DW_FORM_data4 0x06 +%define DW_FORM_data8 0x07 +%define DW_FORM_string 0x08 +%define DW_FORM_block 0x09 +%define DW_FORM_block1 0x0a +%define DW_FORM_data1 0x0b +%define DW_FORM_flag 0x0c +%define DW_FORM_sdata 0x0d +%define DW_FORM_strp 0x0e +%define DW_FORM_udata 0x0f +%define DW_FORM_ref_addr 0x10 +%define DW_FORM_ref1 0x11 +%define DW_FORM_ref2 0x12 +%define DW_FORM_ref4 0x13 +%define DW_FORM_ref8 0x14 +%define DW_FORM_ref_udata 0x15 +%define DW_FORM_indirect 0x16 +%define DW_FORM_sec_offset 0x17 +%define DW_FORM_exprloc 0x18 +%define DW_FORM_flag_present 0x19 +%define DW_FORM_ref_sig8 0x20 +%define DW_ADDR_none 0 +%define DW_ADDR_i386_near16 1 +%define DW_ADDR_i386_far16 2 +%define DW_ADDR_i386_huge16 3 +%define DW_ADDR_i386_near32 4 +%define DW_ADDR_i386_far32 5 +%define DW_OP_addr 0x03 +%define DW_OP_deref 0x06 +%define DW_OP_const1u 0x08 +%define DW_OP_const1s 0x09 +%define DW_OP_const2u 0x0a +%define DW_OP_const2s 0x0b +%define DW_OP_const4u 0x0c +%define DW_OP_const4s 0x0d +%define DW_OP_const8u 0x0e +%define DW_OP_const8s 0x0f +%define DW_OP_constu 0x10 +%define DW_OP_consts 0x11 +%define DW_OP_dup 0x12 +%define DW_OP_drop 0x13 +%define DW_OP_over 0x14 +%define DW_OP_pick 0x15 +%define DW_OP_swap 0x16 +%define DW_OP_rot 0x17 +%define DW_OP_xderef 0x18 +%define DW_OP_abs 0x19 +%define DW_OP_and 0x1a +%define DW_OP_div 0x1b +%define DW_OP_minus 0x1c +%define DW_OP_mod 0x1d +%define DW_OP_mul 0x1e +%define DW_OP_neg 0x1f +%define DW_OP_not 0x20 +%define DW_OP_or 0x21 +%define DW_OP_plus 0x22 +%define DW_OP_plus_uconst 0x23 +%define DW_OP_shl 0x24 +%define DW_OP_shr 0x25 +%define DW_OP_shra 0x26 +%define DW_OP_xor 0x27 +%define DW_OP_skip 0x2f +%define DW_OP_bra 0x28 +%define DW_OP_eq 0x29 +%define DW_OP_ge 0x2a +%define DW_OP_gt 0x2b +%define DW_OP_le 0x2c +%define DW_OP_lt 0x2d +%define DW_OP_ne 0x2e +%define DW_OP_lit0 0x30 +%define DW_OP_lit31 0x4f +%define DW_OP_reg0 0x50 +%define DW_OP_reg31 0x6f +%define DW_OP_breg0 0x70 +%define DW_OP_breg31 0x8f +%define DW_OP_regx 0x90 +%define DW_OP_fbreg 0x91 +%define DW_OP_bregx 0x92 +%define DW_OP_piece 0x93 +%define DW_OP_deref_size 0x94 +%define DW_OP_xderef_size 0x95 +%define DW_OP_nop 0x96 +%define DW_OP_lo_user 0xe0 +%define DW_OP_hi_user 0xff +%define DW_EH_PE_FORMAT_MASK 0x0f +%define DW_EH_PE_APPL_MASK 0x70 +%define DW_EH_PE_indirect 0x80 +%define DW_EH_PE_omit 0xff +%define DW_EH_PE_ptr 0x00 +%define DW_EH_PE_uleb128 0x01 +%define DW_EH_PE_udata2 0x02 +%define DW_EH_PE_udata4 0x03 +%define DW_EH_PE_udata8 0x04 +%define DW_EH_PE_sleb128 0x09 +%define DW_EH_PE_sdata2 0x0a +%define DW_EH_PE_sdata4 0x0b +%define DW_EH_PE_sdata8 0x0c +%define DW_EH_PE_absptr 0x00 +%define DW_EH_PE_pcrel 0x10 +%define DW_EH_PE_textrel 0x20 +%define DW_EH_PE_datarel 0x30 +%define DW_EH_PE_funcrel 0x40 +%define DW_EH_PE_aligned 0x50 +%define DW_CFA_high_bit_mask 0xc0 +%define DW_CFA_nop 0x00 +%define DW_CFA_advance_loc 0x40 +%define DW_CFA_set_loc 0x01 +%define DW_CFA_advance_loc1 0x02 +%define DW_CFA_advance_loc2 0x03 +%define DW_CFA_advance_loc4 0x04 +%define DW_CFA_offset 0x80 +%define DW_CFA_offset_extended 0x05 +%define DW_CFA_offset_extended_sf 0x11 +%define DW_CFA_restore 0xc0 +%define DW_CFA_restore_extended 0x06 +%define DW_CFA_undefined 0x07 +%define DW_CFA_same_value 0x08 +%define DW_CFA_register 0x09 +%define DW_CFA_expression 0x10 +%define DW_CFA_val_offset 0x14 +%define DW_CFA_val_offset_sf 0x15 +%define DW_CFA_val_expression 0x16 +%define DW_CFA_remember_state 0x0a +%define DW_CFA_restore_state 0x0b +%define DW_CFA_def_cfa 0x0c +%define DW_CFA_def_cfa_register 0x0d +%define DW_CFA_def_cfa_offset 0x0e +%define DW_CFA_def_cfa_expression 0x0f +%define DW_CFA_def_cfa_sf 0x12 +%define DW_CFA_def_cfa_offset_sf 0x13 +%define DW_CFA_lo_user 0x1c +%define DW_CFA_MIPS_advance_loc8 0x1d +%define DW_CFA_GNU_window_save 0x2d +%define DW_CFA_GNU_args_size 0x2e +%define DW_CFA_GNU_negative_offset_extended 0x2f +%define DW_CFA_hi_user 0x3f +%define DWREG_X86_EAX 0 +%define DWREG_X86_ECX 1 +%define DWREG_X86_EDX 2 +%define DWREG_X86_EBX 3 +%define DWREG_X86_ESP 4 +%define DWREG_X86_EBP 5 +%define DWREG_X86_ESI 6 +%define DWREG_X86_EDI 7 +%define DWREG_X86_RA 8 +%define DWREG_X86_EFLAGS 9 +%define DWREG_X86_ST1 11 +%define DWREG_X86_ST2 12 +%define DWREG_X86_ST3 13 +%define DWREG_X86_ST4 14 +%define DWREG_X86_ST5 15 +%define DWREG_X86_ST6 16 +%define DWREG_X86_ST7 17 +%define DWREG_X86_XMM0 21 +%define DWREG_X86_XMM1 22 +%define DWREG_X86_XMM2 23 +%define DWREG_X86_XMM3 24 +%define DWREG_X86_XMM4 25 +%define DWREG_X86_XMM5 26 +%define DWREG_X86_XMM6 27 +%define DWREG_X86_XMM7 28 +%define DWREG_X86_MM0 29 +%define DWREG_X86_MM1 30 +%define DWREG_X86_MM2 31 +%define DWREG_X86_MM3 32 +%define DWREG_X86_MM4 33 +%define DWREG_X86_MM5 34 +%define DWREG_X86_MM6 35 +%define DWREG_X86_MM7 36 +%define DWREG_X86_MXCSR 39 +%define DWREG_X86_ES 40 +%define DWREG_X86_CS 41 +%define DWREG_X86_SS 42 +%define DWREG_X86_DS 43 +%define DWREG_X86_FS 44 +%define DWREG_X86_GS 45 +%define DWREG_X86_TR 48 +%define DWREG_X86_LDTR 49 +%define DWREG_AMD64_RAX 0 +%define DWREG_AMD64_RDX 1 +%define DWREG_AMD64_RCX 2 +%define DWREG_AMD64_RBX 3 +%define DWREG_AMD64_RSI 4 +%define DWREG_AMD64_RDI 5 +%define DWREG_AMD64_RBP 6 +%define DWREG_AMD64_RSP 7 +%define DWREG_AMD64_R8 8 +%define DWREG_AMD64_R9 9 +%define DWREG_AMD64_R10 10 +%define DWREG_AMD64_R11 11 +%define DWREG_AMD64_R12 12 +%define DWREG_AMD64_R13 13 +%define DWREG_AMD64_R14 14 +%define DWREG_AMD64_R15 15 +%define DWREG_AMD64_RA 16 +%define DWREG_AMD64_XMM0 17 +%define DWREG_AMD64_XMM1 18 +%define DWREG_AMD64_XMM2 19 +%define DWREG_AMD64_XMM3 20 +%define DWREG_AMD64_XMM4 21 +%define DWREG_AMD64_XMM5 22 +%define DWREG_AMD64_XMM6 23 +%define DWREG_AMD64_XMM7 24 +%define DWREG_AMD64_XMM8 25 +%define DWREG_AMD64_XMM9 26 +%define DWREG_AMD64_XMM10 27 +%define DWREG_AMD64_XMM11 28 +%define DWREG_AMD64_XMM12 29 +%define DWREG_AMD64_XMM13 30 +%define DWREG_AMD64_XMM14 31 +%define DWREG_AMD64_XMM15 32 +%define DWREG_AMD64_ST0 33 +%define DWREG_AMD64_ST1 34 +%define DWREG_AMD64_ST2 35 +%define DWREG_AMD64_ST3 36 +%define DWREG_AMD64_ST4 37 +%define DWREG_AMD64_ST5 38 +%define DWREG_AMD64_ST6 39 +%define DWREG_AMD64_ST7 40 +%define DWREG_AMD64_MM0 41 +%define DWREG_AMD64_MM1 42 +%define DWREG_AMD64_MM2 43 +%define DWREG_AMD64_MM3 44 +%define DWREG_AMD64_MM4 45 +%define DWREG_AMD64_MM5 46 +%define DWREG_AMD64_MM6 47 +%define DWREG_AMD64_MM7 48 +%define DWREG_AMD64_RFLAGS 49 +%define DWREG_AMD64_ES 50 +%define DWREG_AMD64_CS 51 +%define DWREG_AMD64_SS 52 +%define DWREG_AMD64_DS 53 +%define DWREG_AMD64_FS 54 +%define DWREG_AMD64_GS 55 +%define DWREG_AMD64_FS_BASE 58 +%define DWREG_AMD64_GS_BASE 59 +%define DWREG_AMD64_TR 62 +%define DWREG_AMD64_LDTR 63 +%define DWREG_AMD64_MXCSR 64 +%define DWREG_AMD64_FCW 65 +%define DWREG_AMD64_FSW 66 +%endif diff --git a/include/iprt/formats/efi-common.h b/include/iprt/formats/efi-common.h new file mode 100644 index 00000000..a64e1ce7 --- /dev/null +++ b/include/iprt/formats/efi-common.h @@ -0,0 +1,102 @@ +/* $Id: efi-common.h $ */ +/** @file + * IPRT, EFI common definitions. + */ + +/* + * Copyright (C) 2021-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_efi_common_h +#define IPRT_INCLUDED_formats_efi_common_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + +/** + * EFI GUID. + */ +typedef struct EFI_GUID +{ + uint32_t u32Data1; + uint16_t u16Data2; + uint16_t u16Data3; + uint8_t abData4[8]; +} EFI_GUID; +AssertCompileSize(EFI_GUID, 16); +/** Pointer to an EFI GUID. */ +typedef EFI_GUID *PEFI_GUID; +/** Pointer to a const EFI GUID. */ +typedef const EFI_GUID *PCEFI_GUID; + + +/** A Null GUID. */ +#define EFI_NULL_GUID { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }} +/** Global variable GUID. */ +#define EFI_GLOBAL_VARIABLE_GUID \ + { 0x8be4df61, 0x93ca, 0x11d2, { 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c }} +/** SecureBootEnable variable GUID. */ +#define EFI_SECURE_BOOT_ENABLE_DISABLE_GUID \ + { 0xf0a30bc7, 0xaf08, 0x4556, { 0x99, 0xc4, 0x0, 0x10, 0x9, 0xc9, 0x3a, 0x44 } } + + +/** + * EFI time value. + */ +typedef struct EFI_TIME +{ + uint16_t u16Year; + uint8_t u8Month; + uint8_t u8Day; + uint8_t u8Hour; + uint8_t u8Minute; + uint8_t u8Second; + uint8_t bPad0; + uint32_t u32Nanosecond; + int16_t iTimezone; + uint8_t u8Daylight; + uint8_t bPad1; +} EFI_TIME; +AssertCompileSize(EFI_TIME, 16); +/** Pointer to an EFI time abstraction. */ +typedef EFI_TIME *PEFI_TIME; +/** Pointer to a const EFI time abstraction. */ +typedef const EFI_TIME *PCEFI_TIME; + +#define EFI_TIME_TIMEZONE_UNSPECIFIED INT16_C(0x07ff) + +#define EFI_TIME_DAYLIGHT_ADJUST RT_BIT(0) +#define EFI_TIME_DAYLIGHT_INDST RT_BIT(1) + +#endif /* !IPRT_INCLUDED_formats_efi_common_h */ + diff --git a/include/iprt/formats/efi-fat.h b/include/iprt/formats/efi-fat.h new file mode 100644 index 00000000..033540ca --- /dev/null +++ b/include/iprt/formats/efi-fat.h @@ -0,0 +1,92 @@ +/* $Id: efi-fat.h $ */ +/** @file + * IPRT, EFI FAT Binary (used by Apple, contains multiple architectures). + */ + +/* + * Copyright (C) 2019-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_efi_fat_h +#define IPRT_INCLUDED_formats_efi_fat_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + +/* + * Definitions come from http://refit.sourceforge.net/info/fat_binary.html + */ + +/** + * The header structure. + */ +typedef struct EFI_FATHDR +{ + /** The magic identifying the header .*/ + uint32_t u32Magic; + /** Number of files (one per architecture) embedded into the file. */ + uint32_t cFilesEmbedded; +} EFI_FATHDR; +AssertCompileSize(EFI_FATHDR, 8); +typedef EFI_FATHDR *PEFI_FATHDR; + +/** The magic identifying a FAT header. */ +#define EFI_FATHDR_MAGIC UINT32_C(0x0ef1fab9) + +/** + * The direcory entry. + */ +typedef struct EFI_FATDIRENTRY +{ + /** The CPU type the referenced file is for. */ + uint32_t u32CpuType; + /** The CPU sub-type the referenced file is for. */ + uint32_t u32CpuSubType; + /** Offset in bytes where the file is located. */ + uint32_t u32OffsetStart; + /** Length of the file in bytes. */ + uint32_t cbFile; + /** Alignment used for the file. */ + uint32_t u32Alignment; +} EFI_FATDIRENTRY; +AssertCompileSize(EFI_FATDIRENTRY, 20); +typedef EFI_FATDIRENTRY *PEFI_FATDIRENTRY; + +#define EFI_FATDIRENTRY_CPU_TYPE_X86 UINT32_C(0x7) +#define EFI_FATDIRENTRY_CPU_TYPE_AMD64 UINT32_C(0x01000007) + +#define EFI_FATDIRENTRY_CPU_SUB_TYPE_GENERIC UINT32_C(0x3) + + +#endif /* !IPRT_INCLUDED_formats_efi_fat_h */ + diff --git a/include/iprt/formats/efi-fv.h b/include/iprt/formats/efi-fv.h new file mode 100644 index 00000000..fecefedc --- /dev/null +++ b/include/iprt/formats/efi-fv.h @@ -0,0 +1,131 @@ +/* $Id: efi-fv.h $ */ +/** @file + * IPRT, EFI firmware volume (FV) definitions. + */ + +/* + * Copyright (C) 2021-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_efi_fv_h +#define IPRT_INCLUDED_formats_efi_fv_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> +#include <iprt/formats/efi-common.h> + + +/* + * Definitions come from the UEFI PI Spec 1.5 Volume 3 Firmware, chapter 3 "Firmware Storage Code Definitions" + */ + +/** + * The volume header. + */ +typedef struct EFI_FIRMWARE_VOLUME_HEADER +{ + /** Reserved data for the reset vector. */ + uint8_t abZeroVec[16]; + /** The filesystem GUID. */ + EFI_GUID GuidFilesystem; + /** The firmware volume length in bytes including this header. */ + uint64_t cbFv; + /** The signature of the firmware volume header (set to _FVH). */ + uint32_t u32Signature; + /** Firmware volume attributes. */ + uint32_t fAttr; + /** Size of the header in bytes. */ + uint16_t cbFvHdr; + /** Checksum of the header. */ + uint16_t u16Chksum; + /** Offset of the extended header (0 for no extended header). */ + uint16_t offExtHdr; + /** Reserved MBZ. */ + uint8_t bRsvd; + /** Revision of the header. */ + uint8_t bRevision; +} EFI_FIRMWARE_VOLUME_HEADER; +AssertCompileSize(EFI_FIRMWARE_VOLUME_HEADER, 56); +/** Pointer to a EFI firmware volume header. */ +typedef EFI_FIRMWARE_VOLUME_HEADER *PEFI_FIRMWARE_VOLUME_HEADER; +/** Pointer to a const EFI firmware volume header. */ +typedef const EFI_FIRMWARE_VOLUME_HEADER *PCEFI_FIRMWARE_VOLUME_HEADER; + +/** The signature for a firmware volume header. */ +#define EFI_FIRMWARE_VOLUME_HEADER_SIGNATURE RT_MAKE_U32_FROM_U8('_', 'F', 'V', 'H') +/** Revision of the firmware volume header. */ +#define EFI_FIRMWARE_VOLUME_HEADER_REVISION 2 + + +/** + * Firmware block map entry. + */ +typedef struct EFI_FW_BLOCK_MAP +{ + /** Number of blocks for this entry. */ + uint32_t cBlocks; + /** Block size in bytes. */ + uint32_t cbBlock; +} EFI_FW_BLOCK_MAP; +AssertCompileSize(EFI_FW_BLOCK_MAP, 8); +/** Pointer to a firmware volume block map entry. */ +typedef EFI_FW_BLOCK_MAP *PEFI_FW_BLOCK_MAP; +/** Pointer to a const firmware volume block map entry. */ +typedef const EFI_FW_BLOCK_MAP *PCEFI_FW_BLOCK_MAP; + + +/** + * Fault tolerant working block header. + */ +typedef struct EFI_FTW_BLOCK_HEADER +{ + /** GUID identifying the FTW block header. */ + EFI_GUID GuidSignature; + /** The checksum. */ + uint32_t u32Chksum; + /** Flags marking the working block area as valid/invalid. */ + uint32_t fWorkingBlockValid; + /** Size of the write queue. */ + uint64_t cbWriteQueue; +} EFI_FTW_BLOCK_HEADER; +/** Pointer to a fault tolerant working block header. */ +typedef EFI_FTW_BLOCK_HEADER *PEFI_FTW_BLOCK_HEADER; +/** Pointer to a const fault tolerant working block header. */ +typedef const EFI_FTW_BLOCK_HEADER *PCEFI_FTW_BLOCK_HEADER; + +/** The signature for the working block header. */ +#define EFI_WORKING_BLOCK_SIGNATURE_GUID \ + { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }} + +#endif /* !IPRT_INCLUDED_formats_efi_fv_h */ + diff --git a/include/iprt/formats/efi-signature.h b/include/iprt/formats/efi-signature.h new file mode 100644 index 00000000..caa6f824 --- /dev/null +++ b/include/iprt/formats/efi-signature.h @@ -0,0 +1,141 @@ +/* $Id: efi-signature.h $ */ +/** @file + * IPRT, EFI signature database definitions. + */ + +/* + * Copyright (C) 2021-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_efi_signature_h +#define IPRT_INCLUDED_formats_efi_signature_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> +#include <iprt/formats/efi-common.h> + + +/* + * Definitions come from the UEFI 2.6 specification, chapter 30.4.1 + */ + +/** The GUID used for setting and retrieving variables from the variable store. */ +#define EFI_IMAGE_SECURITY_DATABASE_GUID \ + { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }} +/** The GUID used for setting and retrieving the MOK (Machine Owner Key) from the variable store. */ +#define EFI_IMAGE_MOK_DATABASE_GUID \ + { 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 }} + + +/** + * Signature entry data. + */ +typedef struct EFI_SIGNATURE_DATA +{ + /** The GUID of the owner of the signature. */ + EFI_GUID GuidOwner; + /** The signature data follows (size varies depending on the signature type). */ +} EFI_SIGNATURE_DATA; +AssertCompileSize(EFI_SIGNATURE_DATA, 16); +/** Pointer to a signature entry. */ +typedef EFI_SIGNATURE_DATA *PEFI_SIGNATURE_DATA; +/** Pointer to a const signature entry. */ +typedef const EFI_SIGNATURE_DATA *PCEFI_SIGNATURE_DATA; + +/** Microsoft's GUID for signatures. */ +#define EFI_SIGNATURE_OWNER_GUID_MICROSOFT \ + { 0x77fa9abd, 0x0359, 0x4d32, { 0xbd, 0x60, 0x28, 0xf4, 0xe7, 0x8f, 0x78, 0x4b }} + +/** VirtualBox's GUID for signatures. */ +#define EFI_SIGNATURE_OWNER_GUID_VBOX \ + { 0x9400896a, 0x146c, 0x4f4c, { 0x96, 0x47, 0x2c, 0x73, 0x62, 0x0c, 0xa8, 0x94 }} + + +/** + * Signature list header. + */ +typedef struct EFI_SIGNATURE_LIST +{ + /** The signature type stored in this list. */ + EFI_GUID GuidSigType; + /** Size of the signature list in bytes. */ + uint32_t cbSigLst; + /** Size of the optional signature header following this header in bytes. */ + uint32_t cbSigHdr; + /** Size of each signature entry in bytes, must be at least the size of EFI_SIGNATURE_DATA. */ + uint32_t cbSig; + // uint8_t abSigHdr[]; + // EFI_SIGNATURE_DATA aSigs[]; +} EFI_SIGNATURE_LIST; +AssertCompileSize(EFI_SIGNATURE_LIST, 28); +/** Pointer to a signature list header. */ +typedef EFI_SIGNATURE_LIST *PEFI_SIGNATURE_LIST; +/** Pointer to a const signature list header. */ +typedef const EFI_SIGNATURE_LIST *PCEFI_SIGNATURE_LIST; + +/** Signature contains a SHA256 hash. */ +#define EFI_SIGNATURE_TYPE_GUID_SHA256 \ + { 0xc1c41626, 0x504c, 0x4092, { 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 }} +/** Size of a SHA256 signature entry (GUID + 32 bytes for the hash). */ +#define EFI_SIGNATURE_TYPE_SZ_SHA256 UINT32_C(48) + +/** Signature contains a RSA2048 key. */ +#define EFI_SIGNATURE_TYPE_GUID_RSA2048 \ + { 0x3c5766e8, 0x269c, 0x4e34, { 0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6 }} +/** Size of a RSA2048 signature entry (GUID + 256 for the key). */ +#define EFI_SIGNATURE_TYPE_SZ_RSA2048 UINT32_C(272) + +/** Signature contains a RSA2048 signature of a SHA256 hash. */ +#define EFI_SIGNATURE_TYPE_GUID_RSA2048_SHA256 \ + { 0xe2b36190, 0x879b, 0x4a3d, { 0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }} +/** Size of a RSA2048 signature entry (GUID + 256 for the key). */ +#define EFI_SIGNATURE_TYPE_SZ_RSA2048_SHA256 UINT32_C(272) + +/** Signature contains a SHA1 hash. */ +#define EFI_SIGNATURE_TYPE_GUID_SHA1 \ + { 0x826ca512, 0xcf10, 0x4ac9, { 0xb1, 0x87, 0xbe, 0x01, 0x49, 0x66, 0x31, 0xbd }} +/** Size of a SHA1 signature entry (GUID + 20 bytes for the hash). */ +#define EFI_SIGNATURE_TYPE_SZ_SHA1 UINT32_C(36) + +/** Signature contains a RSA2048 signature of a SHA1 hash. */ +#define EFI_SIGNATURE_TYPE_GUID_RSA2048_SHA1 \ + { 0x67f8444f, 0x8743, 0x48f1, { 0xa3, 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }} +/** Size of a RSA2048 signature entry (GUID + 256 for the key). */ +#define EFI_SIGNATURE_TYPE_SZ_RSA2048_SHA1 UINT32_C(272) + +/** Signature contains a DER encoded X.509 certificate (size varies with each certificate). */ +#define EFI_SIGNATURE_TYPE_GUID_X509 \ + { 0xa5c059a1, 0x94e4, 0x4aa7, { 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 }} + +#endif /* !IPRT_INCLUDED_formats_efi_signature_h */ + diff --git a/include/iprt/formats/efi-varstore.h b/include/iprt/formats/efi-varstore.h new file mode 100644 index 00000000..1e341bf7 --- /dev/null +++ b/include/iprt/formats/efi-varstore.h @@ -0,0 +1,160 @@ +/* $Id: efi-varstore.h $ */ +/** @file + * IPRT, EFI variable store (VarStore) definitions. + */ + +/* + * Copyright (C) 2021-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_efi_varstore_h +#define IPRT_INCLUDED_formats_efi_varstore_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> +#include <iprt/formats/efi-common.h> + + +/* + * Definitions come from the EDK2 sources MdeModulePkg/Include/Guid/VariableFormat.h + */ + +/** The filesystem GUID for a variable store stored in a volume header. */ +#define EFI_VARSTORE_FILESYSTEM_GUID \ + { 0xfff12b8d, 0x7696, 0x4c8b, { 0xa9, 0x85, 0x27, 0x47, 0x07, 0x5b, 0x4f, 0x50 }} + + +/** + * The variable store header. + */ +typedef struct EFI_VARSTORE_HEADER +{ + /** The GUID identifying a variable store. */ + EFI_GUID GuidVarStore; + /** Size of the variable store including the header. */ + uint32_t cbVarStore; + /** The format state. */ + uint8_t bFmt; + /** The region health state. */ + uint8_t bState; + /** Reserved. */ + uint8_t abRsvd[6]; +} EFI_VARSTORE_HEADER; +AssertCompileSize(EFI_VARSTORE_HEADER, 28); +/** Pointer to a variable store header. */ +typedef EFI_VARSTORE_HEADER *PEFI_VARSTORE_HEADER; +/** Pointer to a const variable store header. */ +typedef const EFI_VARSTORE_HEADER *PCEFI_VARSTORE_HEADER; + +/** The GUID for a variable store using the authenticated variable header format. */ +#define EFI_VARSTORE_HEADER_GUID_AUTHENTICATED_VARIABLE \ + { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } } +/** The GUID for a variable store using the standard variable header format. */ +#define EFI_VARSTORE_HEADER_GUID_VARIABLE \ + { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d } } + +/** The EFI_VARSTORE_HEADER::bFmt value when the store region is formatted. */ +#define EFI_VARSTORE_HEADER_FMT_FORMATTED 0x5a +/** The EFI_VARSTORE_HEADER::bState value when the store region is healthy. */ +#define EFI_VARSTORE_HEADER_STATE_HEALTHY 0xfe + + +/** + * Authenticated variable header. + */ +#pragma pack(1) +typedef struct EFI_AUTH_VAR_HEADER +{ + /** Contains EFI_AUTH_VAR_HEADER_START to identify the start of a new variable header. */ + uint16_t u16StartId; + /** Variable state. */ + uint8_t bState; + /** Reserved. */ + uint8_t bRsvd; + /** Variable attributes. */ + uint32_t fAttr; + /** Monotonic counter value increased with each change to protect against replay attacks. */ + uint64_t cMonotonic; + /** Timestamp value to protect against replay attacks. */ + EFI_TIME Timestamp; + /** Index of associated public key in database. */ + uint32_t idPubKey; + /** Size of the variable zero terminated unicode name in bytes. */ + uint32_t cbName; + /** Size of the variable data without this header. */ + uint32_t cbData; + /** Producer/Consumer GUID for this variable. */ + EFI_GUID GuidVendor; +} EFI_AUTH_VAR_HEADER; +#pragma pack() +AssertCompileSize(EFI_AUTH_VAR_HEADER, 60); +/** Pointer to a authenticated variable header. */ +typedef EFI_AUTH_VAR_HEADER *PEFI_AUTH_VAR_HEADER; +/** Pointer to a const authenticated variable header. */ +typedef const EFI_AUTH_VAR_HEADER *PCEFI_AUTH_VAR_HEADER; + +/** Value in EFI_AUTH_VAR_HEADER::u16StartId for a valid variable header. */ +#define EFI_AUTH_VAR_HEADER_START 0x55aa +/** @name Possible variable states. + * @{ */ +/** Variable is in the process of being deleted. */ +#define EFI_AUTH_VAR_HEADER_STATE_IN_DELETED_TRANSITION 0xfe +/** Variable was deleted. */ +#define EFI_AUTH_VAR_HEADER_STATE_DELETED 0xfd +/** Variable has only a valid header right now. */ +#define EFI_AUTH_VAR_HEADER_STATE_HDR_VALID_ONLY 0x7f +/** Variable header, name and data are all valid. */ +#define EFI_AUTH_VAR_HEADER_STATE_ADDED 0x3f +/** @} */ + + +/** @name Possible variable attributes. + * @{ */ +/** The variable is stored in non volatile memory. */ +#define EFI_VAR_HEADER_ATTR_NON_VOLATILE RT_BIT_32(0) +/** The variable is accessible by the EFI bootservice stage. */ +#define EFI_VAR_HEADER_ATTR_BOOTSERVICE_ACCESS RT_BIT_32(1) +/** The variable is accessible during runtime. */ +#define EFI_VAR_HEADER_ATTR_RUNTIME_ACCESS RT_BIT_32(2) +/** The variable contains an hardware error record. */ +#define EFI_VAR_HEADER_ATTR_HW_ERROR_RECORD RT_BIT_32(3) +/** The variable can be modified only by an authenticated source. */ +#define EFI_AUTH_VAR_HEADER_ATTR_AUTH_WRITE_ACCESS RT_BIT_32(4) +/** The variable was written with a time based authentication. */ +#define EFI_AUTH_VAR_HEADER_ATTR_TIME_BASED_AUTH_WRITE_ACCESS RT_BIT_32(5) +/** The variable can be appended. */ +#define EFI_AUTH_VAR_HEADER_ATTR_APPEND_WRITE RT_BIT_32(6) +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_efi_varstore_h */ + diff --git a/include/iprt/formats/elf-amd64.h b/include/iprt/formats/elf-amd64.h new file mode 100644 index 00000000..c0c7f0c1 --- /dev/null +++ b/include/iprt/formats/elf-amd64.h @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 1996-1997 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef IPRT_INCLUDED_formats_elf_amd64_h +#define IPRT_INCLUDED_formats_elf_amd64_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +/* + * ELF definitions for the AMD64 architecture. + */ + +#if 0 /* later */ +/* + * Auxiliary vector entries for passing information to the interpreter. + * + * The i386 supplement to the SVR4 ABI specification names this "auxv_t", + * but POSIX lays claim to all symbols ending with "_t". + */ +typedef struct { /* Auxiliary vector entry on initial stack */ + int a_type; /* Entry type. */ + union { + int a_val; /* Integer value. */ + } a_un; +} Elf32_Auxinfo; + + +typedef struct { /* Auxiliary vector entry on initial stack */ + long a_type; /* Entry type. */ + union { + long a_val; /* Integer value. */ + void *a_ptr; /* Address. */ + void (*a_fcn)(void); /* Function pointer (not used). */ + } a_un; +} Elf64_Auxinfo; + +__ElfType(Auxinfo); + +/* Values for a_type. */ +#define AT_NULL 0 /* Terminates the vector. */ +#define AT_IGNORE 1 /* Ignored entry. */ +#define AT_EXECFD 2 /* File descriptor of program to load. */ +#define AT_PHDR 3 /* Program header of program already loaded. */ +#define AT_PHENT 4 /* Size of each program header entry. */ +#define AT_PHNUM 5 /* Number of program header entries. */ +#define AT_PAGESZ 6 /* Page size in bytes. */ +#define AT_BASE 7 /* Interpreter's base address. */ +#define AT_FLAGS 8 /* Flags (unused for i386). */ +#define AT_ENTRY 9 /* Where interpreter should transfer control. */ + +/* + * The following non-standard values are used for passing information + * from John Polstra's testbed program to the dynamic linker. These + * are expected to go away soon. + * + * Unfortunately, these overlap the Linux non-standard values, so they + * must not be used in the same context. + */ +#define AT_BRK 10 /* Starting point for sbrk and brk. */ +#define AT_DEBUG 11 /* Debugging level. */ + +/* + * The following non-standard values are used in Linux ELF binaries. + */ +#define AT_NOTELF 10 /* Program is not ELF ?? */ +#define AT_UID 11 /* Real uid. */ +#define AT_EUID 12 /* Effective uid. */ +#define AT_GID 13 /* Real gid. */ +#define AT_EGID 14 /* Effective gid. */ + +#define AT_COUNT 15 /* Count of defined aux entry types. */ + +#endif /* later */ + +/* + * Relocation types. + */ + +#define R_X86_64_NONE 0 /* No relocation. */ +#define R_X86_64_64 1 /* Add 64 bit symbol value. */ +#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ +#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ +#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ +#define R_X86_64_COPY 5 /* Copy data from shared object. */ +#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ +#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ +#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ +#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ +#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ +#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ +#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ +#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ +#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ +#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ +#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ +#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ +#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ + +#define R_X86_64_COUNT 24 /* Count of defined relocation types. */ + +#endif /* !IPRT_INCLUDED_formats_elf_amd64_h */ + diff --git a/include/iprt/formats/elf-common.h b/include/iprt/formats/elf-common.h new file mode 100644 index 00000000..992ebaed --- /dev/null +++ b/include/iprt/formats/elf-common.h @@ -0,0 +1,348 @@ +/*- + * Copyright (c) 1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef IPRT_INCLUDED_formats_elf_common_h +#define IPRT_INCLUDED_formats_elf_common_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/stdint.h> + +/* + * ELF definitions that are independent of architecture or word size. + */ + +/* + * Note header. The ".note" section contains an array of notes. Each + * begins with this header, aligned to a word boundary. Immediately + * following the note header is n_namesz bytes of name, padded to the + * next word boundary. Then comes n_descsz bytes of descriptor, again + * padded to a word boundary. The values of n_namesz and n_descsz do + * not include the padding. + */ + +typedef struct { + uint32_t n_namesz; /* Length of name. */ + uint32_t n_descsz; /* Length of descriptor. */ + uint32_t n_type; /* Type of this note. */ +} Elf_Note; + +/* Indexes into the e_ident array. Keep synced with + http://www.sco.com/developer/gabi/ch4.eheader.html */ +#define EI_MAG0 0 /* Magic number, byte 0. */ +#define EI_MAG1 1 /* Magic number, byte 1. */ +#define EI_MAG2 2 /* Magic number, byte 2. */ +#define EI_MAG3 3 /* Magic number, byte 3. */ +#define EI_CLASS 4 /* Class of machine. */ +#define EI_DATA 5 /* Data format. */ +#define EI_VERSION 6 /* ELF format version. */ +#define EI_OSABI 7 /* Operating system / ABI identification */ +#define EI_ABIVERSION 8 /* ABI version */ +#define OLD_EI_BRAND 8 /* Start of architecture identification. */ +#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ +#define EI_NIDENT 16 /* Size of e_ident array. */ + +/* Values for the magic number bytes. */ +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" /* magic string */ +#define SELFMAG 4 /* magic string size */ + +/* Values for e_ident[EI_VERSION] and e_version. */ +#define EV_NONE 0 +#define EV_CURRENT 1 + +/* Values for e_ident[EI_CLASS]. */ +#define ELFCLASSNONE 0 /* Unknown class. */ +#define ELFCLASS32 1 /* 32-bit architecture. */ +#define ELFCLASS64 2 /* 64-bit architecture. */ + +/* Values for e_ident[EI_DATA]. */ +#define ELFDATANONE 0 /* Unknown data format. */ +#define ELFDATA2LSB 1 /* 2's complement little-endian. */ +#define ELFDATA2MSB 2 /* 2's complement big-endian. */ + +/* Values for e_ident[EI_OSABI]. */ +#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ +#define ELFOSABI_NONE ELFOSABI_SYSV /* symbol used in old spec */ +#define ELFOSABI_HPUX 1 /* HP-UX operating system */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* GNU/Linux */ +#define ELFOSABI_HURD 4 /* GNU/Hurd */ +#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ +#define ELFOSABI_SOLARIS 6 /* Solaris */ +#define ELFOSABI_MONTEREY 7 /* Monterey */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +/* e_ident */ +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ + +/* Values for e_machine. */ +#define EM_NONE 0 /* Unknown machine. */ +#define EM_M32 1 /* AT&T WE32100. */ +#define EM_SPARC 2 /* Sun SPARC. */ +#define EM_386 3 /* Intel i386. */ +#define EM_68K 4 /* Motorola 68000. */ +#define EM_88K 5 /* Motorola 88000. */ +#define EM_486 6 /* Intel i486. */ +#define EM_860 7 /* Intel i860. */ +#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ + +/* Extensions. This list is not complete. */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ /* Depreciated */ +#define EM_PARISC 15 /* HPPA */ +#define EM_SPARC32PLUS 18 /* SPARC v8plus */ +#define EM_PPC 20 /* PowerPC 32-bit */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_ARM 40 /* ARM */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_IA_64 50 /* Intel IA-64 Processor */ +#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ +#define EM_AMD64 EM_X86_64 /* SunOS compatibility (added by Ramshankar) */ +#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI */ + +/* Special section indexes. */ +#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ +#define SHN_LORESERVE 0xff00 /* First of reserved range. */ +#define SHN_LOPROC 0xff00 /* First processor-specific. */ +#define SHN_HIPROC 0xff1f /* Last processor-specific. */ +#define SHN_ABS 0xfff1 /* Absolute values. */ +#define SHN_COMMON 0xfff2 /* Common data. */ +#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends */ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relocation section - no addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_NUM 12 /* number of section types */ +#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ +#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +/* Flags for sh_flags. */ +#define SHF_WRITE 0x1 /* Section contains writable data. */ +#define SHF_ALLOC 0x2 /* Section occupies memory. */ +#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ +#define SHF_TLS 0x400 /* Section contains TLS data. */ +#define SHF_MASKPROC 0xf0000000 /* Reserved for processor-specific. */ + +/* Values for p_type. */ +#define PT_NULL 0 /* Unused entry. */ +#define PT_LOAD 1 /* Loadable segment. */ +#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ +#define PT_INTERP 3 /* Pathname of interpreter. */ +#define PT_NOTE 4 /* Auxiliary information. */ +#define PT_SHLIB 5 /* Reserved (not used). */ +#define PT_PHDR 6 /* Location of program header itself. */ +#define PT_TLS 7 /* Thread local storage segment */ + +#define PT_COUNT 8 /* Number of defined p_type values. */ + +#define PT_LOOS 0x60000000 /* OS-specific */ +#define PT_HIOS 0x6fffffff /* OS-specific */ +#define PT_LOPROC 0x70000000 /* First processor-specific type. */ +#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ + +#define PT_GNU_EH_FRAME 0x6474e550 /**< GNU/Linux -> .eh_frame_hdr */ +#define PT_GNU_STACK 0x6474e551 /**< GNU/Linux -> stack prot (RWX or RW) */ +#define PT_GNU_RELRO 0x6474e552 /**< GNU/Linux -> make RO after relocations */ +#define PT_GNU_PROPERTY 0x6474e553 /**< GNU/Linux -> .note.gnu.property */ + + +/* Values for p_flags. */ +#define PF_X 0x1 /* Executable. */ +#define PF_W 0x2 /* Writable. */ +#define PF_R 0x4 /* Readable. */ + +/* Values for d_tag. */ +#define DT_NULL 0 /* Terminating entry. */ +#define DT_NEEDED 1 /* String table offset of a needed shared + library. */ +#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ +#define DT_PLTGOT 3 /* Processor-dependent address. */ +#define DT_HASH 4 /* Address of symbol hash table. */ +#define DT_STRTAB 5 /* Address of string table. */ +#define DT_SYMTAB 6 /* Address of symbol table. */ +#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ +#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ +#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ +#define DT_STRSZ 10 /* Size of string table. */ +#define DT_SYMENT 11 /* Size of each symbol table entry. */ +#define DT_INIT 12 /* Address of initialization function. */ +#define DT_FINI 13 /* Address of finalization function. */ +#define DT_SONAME 14 /* String table offset of shared object + name. */ +#define DT_RPATH 15 /* String table offset of library path. [sup] */ +#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ +#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ +#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ +#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ +#define DT_PLTREL 20 /* Type of relocation used for PLT. */ +#define DT_DEBUG 21 /* Reserved (not used). */ +#define DT_TEXTREL 22 /* Indicates there may be relocations in + non-writable segments. [sup] */ +#define DT_JMPREL 23 /* Address of PLT relocations. */ +#define DT_BIND_NOW 24 /* [sup] */ +#define DT_INIT_ARRAY 25 /* Address of the array of pointers to + initialization functions */ +#define DT_FINI_ARRAY 26 /* Address of the array of pointers to + termination functions */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of + initialization functions. */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of + terminationfunctions. */ +#define DT_RUNPATH 29 /* String table offset of a null-terminated + library search path string. */ +#define DT_FLAGS 30 /* Object specific flag values. */ +#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING + and less than DT_LOOS follow the rules for + the interpretation of the d_un union + as follows: even == 'd_ptr', even == 'd_val' + or none */ +#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to + pre-initialization functions. */ +#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of + pre-initialization functions. */ + +#define DT_COUNT 33 /* Number of defined d_tag values. */ + +#define DT_LOOS 0x6000000d /* First OS-specific */ +#define DT_HIOS 0x6fff0000 /* Last OS-specific */ +#define DT_LOPROC 0x70000000 /* First processor-specific type. */ +#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ + +/* Values for DT_FLAGS */ +#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may + make reference to the $ORIGIN substitution + string */ +#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ +#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in + non-writable segments. */ +#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should + process all relocations for the object + containing this entry before transferring + control to the program. */ +#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or + executable contains code using a static + thread-local storage scheme. */ + +/* Values for n_type. Used in core files. */ +#if defined(RT_OS_FREEBSD) +# define NT_PRSTATUS 1 /* Process status. */ +# define NT_FPREGSET 2 /* Floating point registers. */ +# define NT_PRPSINFO 3 /* Process state info. */ +#elif defined(RT_OS_SOLARIS) +# define NT_PRSTATUS 1 /* prstatus_t <sys/old_procfs.h> */ +# define NT_PRFPREG 2 /* prfpregset_t <sys/old_procfs.h> */ +# define NT_PRPSINFO 3 /* prpsinfo_t <sys/old_procfs.h> */ +# define NT_PRXREG 4 /* prxregset_t <sys/procfs.h> */ +# define NT_PLATFORM 5 /* string from sysinfo(SI_PLATFORM) */ +# define NT_AUXV 6 /* auxv_t array <sys/auxv.h> */ +# define NT_LDT 9 /* ssd array <sys/sysi86.h> IA32 only */ +# define NT_PSTATUS 10 /* pstatus_t <sys/procfs.h> */ +# define NT_PSINFO 13 /* psinfo_t <sys/procfs.h> */ +# define NT_PRCRED 14 /* prcred_t <sys/procfs.h> */ +# define NT_UTSNAME 15 /* struct utsname <sys/utsname.h> */ +# define NT_LWPSTATUS 16 /* lwpstatus_t <sys/procfs.h> */ +# define NT_LWPSINFO 17 /* lwpsinfo_t <sys/procfs.h> */ +# define NT_PRPRIV 18 /* prpriv_t <sys/procfs.h> */ +# define NT_PRPRIVINFO 19 /* priv_impl_info_t <sys/priv.h> */ +# define NT_CONTENT 20 /* core_content_t <sys/corectl.h> */ +# define NT_ZONENAME 21 /* string from getzonenamebyid(3C) */ +# define PF_SUNW_FAILURE 0x00100000 /* mapping absent due to failure */ +# define PN_XNUM 0xffff /* extended program header index */ +#elif defined(RT_OS_LINUX) +# define NT_PRSTATUS 1 /* Process status. */ +# define NT_PRFPREG 2 /* Floating point registers. */ +# define NT_PRPSINFO 3 /* Process state info. */ +# define NT_TASKSTRUCT 4 /* Task info. */ +# define NT_AUXV 6 /* Process auxiliary vectors. */ +# define NT_PRXFPREG 0x46e62b7f /* from gdb5.1/include/elf/common.h */ +#endif +/* GNU Build ID in a dedicated section. */ +#define NT_GNU_BUILD_ID 3 + +/* VirtualBox specific NOTE sections (added by Ramshankar) */ +#ifdef VBOX +# define NT_VBOXCORE 0xb00 +# define NT_VBOXCPU 0xb01 +#endif + +/* Symbol Binding - ELFNN_ST_BIND - st_info */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* like global - lower precedence */ +#define STB_LOPROC 13 /* reserved range for processor */ +#define STB_HIPROC 15 /* specific symbol bindings */ + +/* Symbol type - ELFNN_ST_TYPE - st_info */ +#define STT_NOTYPE 0 /* Unspecified type. */ +#define STT_OBJECT 1 /* Data object. */ +#define STT_FUNC 2 /* Function. */ +#define STT_SECTION 3 /* Section. */ +#define STT_FILE 4 /* Source file. */ +#define STT_TLS 6 /* TLS object. */ +#define STT_NUM 7 /* Number of generic symbol types. */ +#define STT_LOPROC 13 /* reserved range for processor */ +#define STT_HIPROC 15 /* specific symbol types */ + +/* Special symbol table indexes. */ +#define STN_UNDEF 0 /* Undefined symbol index. */ + +#endif /* !IPRT_INCLUDED_formats_elf_common_h */ + diff --git a/include/iprt/formats/elf-i386.h b/include/iprt/formats/elf-i386.h new file mode 100644 index 00000000..4ebaafc6 --- /dev/null +++ b/include/iprt/formats/elf-i386.h @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 1996-1997 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef IPRT_INCLUDED_formats_elf_i386_h +#define IPRT_INCLUDED_formats_elf_i386_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#if 0 /* later */ + +/* + * Auxiliary vector entries for passing information to the interpreter. + * + * The i386 supplement to the SVR4 ABI specification names this "auxv_t", + * but POSIX lays claim to all symbols ending with "_t". + */ + +typedef struct { /* Auxiliary vector entry on initial stack */ + int a_type; /* Entry type. */ + union { + long a_val; /* Integer value. */ + void *a_ptr; /* Address. */ + void (*a_fcn)(void); /* Function pointer (not used). */ + } a_un; +} Elf32_Auxinfo; + +#if __ELF_WORD_SIZE == 64 +/* Fake for amd64 loader support */ +typedef struct { + int fake; +} Elf64_Auxinfo; +#endif + +/* Values for a_type. */ +#define AT_NULL 0 /* Terminates the vector. */ +#define AT_IGNORE 1 /* Ignored entry. */ +#define AT_EXECFD 2 /* File descriptor of program to load. */ +#define AT_PHDR 3 /* Program header of program already loaded. */ +#define AT_PHENT 4 /* Size of each program header entry. */ +#define AT_PHNUM 5 /* Number of program header entries. */ +#define AT_PAGESZ 6 /* Page size in bytes. */ +#define AT_BASE 7 /* Interpreter's base address. */ +#define AT_FLAGS 8 /* Flags (unused for i386). */ +#define AT_ENTRY 9 /* Where interpreter should transfer control. */ + +/* + * The following non-standard values are used for passing information + * from John Polstra's testbed program to the dynamic linker. These + * are expected to go away soon. + * + * Unfortunately, these overlap the Linux non-standard values, so they + * must not be used in the same context. + */ +#define AT_BRK 10 /* Starting point for sbrk and brk. */ +#define AT_DEBUG 11 /* Debugging level. */ + +/* + * The following non-standard values are used in Linux ELF binaries. + */ +#define AT_NOTELF 10 /* Program is not ELF ?? */ +#define AT_UID 11 /* Real uid. */ +#define AT_EUID 12 /* Effective uid. */ +#define AT_GID 13 /* Real gid. */ +#define AT_EGID 14 /* Effective gid. */ + +#define AT_COUNT 15 /* Count of defined aux entry types. */ + +#endif /* later */ + + +/* + * Relocation types. + */ + +#define R_386_NONE 0 /* No relocation. */ +#define R_386_32 1 /* Add symbol value. */ +#define R_386_PC32 2 /* Add PC-relative symbol value. */ +#define R_386_GOT32 3 /* Add PC-relative GOT offset. */ +#define R_386_PLT32 4 /* Add PC-relative PLT offset. */ +#define R_386_COPY 5 /* Copy data from shared object. */ +#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ +#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ +#define R_386_RELATIVE 8 /* Add load address of shared object. */ +#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ +#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ +#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ +#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ +#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ +#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ +#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ +#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ +#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ +#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ +#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ +#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ +#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ + +#define R_386_COUNT 38 /* Count of defined relocation types. */ + +#endif /* !IPRT_INCLUDED_formats_elf_i386_h */ + diff --git a/include/iprt/formats/elf.h b/include/iprt/formats/elf.h new file mode 100644 index 00000000..9715cebe --- /dev/null +++ b/include/iprt/formats/elf.h @@ -0,0 +1,98 @@ +/* $Id: elf.h $ */ +/** @file + * ELF types, current architecture. + */ + +/* + * Copyright (C) 2010-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_elf_h +#define IPRT_INCLUDED_formats_elf_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_ARM64) +# include "elf64.h" +typedef Elf64_Addr Elf_Addr; +typedef Elf64_Half Elf_Half; +typedef Elf64_Off Elf_Off; +typedef Elf64_Sword Elf_Sword; +typedef Elf64_Word Elf_Word; +typedef Elf64_Size Elf_Size; +typedef Elf64_Hashelt Elf_Hashelt; +typedef Elf64_Ehdr Elf_Ehdr; +typedef Elf64_Shdr Elf_Shdr; +typedef Elf64_Phdr Elf_Phdr; +typedef Elf64_Nhdr Elf_Nhdr; +typedef Elf64_Dyn Elf_Dyn; +typedef Elf64_Rel Elf_Rel; +typedef Elf64_Rela Elf_Rela; +typedef Elf64_Sym Elf_Sym; + +#define ELF_R_SYM ELF64_R_SYM +#define ELF_R_TYPE ELF64_R_TYPE +#define ELF_R_INFO ELF64_R_INFO +#define ELF_ST_BIND ELF64_ST_BIND +#define ELF_ST_TYPE ELF64_ST_TYPE +#define ELF_ST_INFO ELF64_ST_INFO + +#elif defined(RT_ARCH_X86) +# include "elf32.h" +typedef Elf32_Addr Elf_Addr; +typedef Elf32_Half Elf_Half; +typedef Elf32_Off Elf_Off; +typedef Elf32_Sword Elf_Sword; +typedef Elf32_Word Elf_Word; +typedef Elf32_Size Elf_Size; +typedef Elf32_Hashelt Elf_Hashelt; +typedef Elf32_Ehdr Elf_Ehdr; +typedef Elf32_Shdr Elf_Shdr; +typedef Elf32_Phdr Elf_Phdr; +typedef Elf32_Nhdr Elf_Nhdr; +typedef Elf32_Dyn Elf_Dyn; +typedef Elf32_Rel Elf_Rel; +typedef Elf32_Rela Elf_Rela; +typedef Elf32_Sym Elf_Sym; + +#define ELF_R_SYM ELF32_R_SYM +#define ELF_R_TYPE ELF32_R_TYPE +#define ELF_R_INFO ELF32_R_INFO +#define ELF_ST_BIND ELF32_ST_BIND +#define ELF_ST_TYPE ELF32_ST_TYPE +#define ELF_ST_INFO ELF32_ST_INFO + +#else +# error Unknown arch! +#endif + +#endif /* !IPRT_INCLUDED_formats_elf_h */ + diff --git a/include/iprt/formats/elf32.h b/include/iprt/formats/elf32.h new file mode 100644 index 00000000..3e094546 --- /dev/null +++ b/include/iprt/formats/elf32.h @@ -0,0 +1,200 @@ +/* $Id: elf32.h $ */ +/** @file + * IPRT - ELF 32-bit header. + */ + +/* + * Copyright (C) 2010-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_elf32_h +#define IPRT_INCLUDED_formats_elf32_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/assertcompile.h> +#include "elf-common.h" + +/* + * ELF 32 standard types. + */ +typedef uint32_t Elf32_Addr; +typedef uint16_t Elf32_Half; +typedef uint32_t Elf32_Off; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf32_Word; + +/* + * Ensure type size correctness in accordance to . + * Portable Format Specification (for ELF), Version 1.1, fig 1-2. . + */ +AssertCompileSize(Elf32_Addr, 4); +AssertCompileSize(Elf32_Half, 2); +AssertCompileSize(Elf32_Off, 4); +AssertCompileSize(Elf32_Sword, 4); +AssertCompileSize(Elf32_Word, 4); + +/* + * ELF 32 non-standard types for convenience. + */ +typedef Elf32_Word Elf32_Size; +typedef Elf32_Word Elf32_Hashelt; + +/* + * ELF header. + */ +typedef struct +{ + unsigned char e_ident[16]; /* ELF identification. */ + Elf32_Half e_type; /* Object file type. */ + Elf32_Half e_machine; /* Machine type. */ + Elf32_Word e_version; /* Object file version. */ + Elf32_Addr e_entry; /* Entry point address. */ + Elf32_Off e_phoff; /* Program header offset. */ + Elf32_Off e_shoff; /* Section header offset. */ + Elf32_Word e_flags; /* Processor-specific flags. */ + Elf32_Half e_ehsize; /* ELF header size. */ + Elf32_Half e_phentsize; /* Size of program header entries. */ + Elf32_Half e_phnum; /* Number of program headers. */ + Elf32_Half e_shentsize; /* Size of section header entries. */ + Elf32_Half e_shnum; /* Number of section headers. */ + Elf32_Half e_shstrndx; /* Section name string table index. */ +} Elf32_Ehdr; + +/* + * Section header. + */ +typedef struct +{ + Elf32_Word sh_name; /* Section name. */ + Elf32_Word sh_type; /* Section type. */ + Elf32_Word sh_flags; /* Section attributes. */ + Elf32_Addr sh_addr; /* Virtual address in memory. */ + Elf32_Off sh_offset; /* Offset in file. */ + Elf32_Word sh_size; /* Size of section. */ + Elf32_Word sh_link; /* Link to other section. */ + Elf32_Word sh_info; /* Miscellaneous information. */ + Elf32_Word sh_addralign; /* Address alignment boundary. */ + Elf32_Word sh_entsize; /* Size of entries, if section has table. */ +} Elf32_Shdr; + + +/* + * Program header. + */ +typedef struct +{ + Elf32_Word p_type; /* Type of segment. */ + Elf32_Off p_offset; /* Offset in file. */ + Elf32_Addr p_vaddr; /* Virtual address in memory. */ + Elf32_Addr p_paddr; /* Physical address (reserved). */ + Elf32_Word p_filesz; /* Size of segment in file. */ + Elf32_Word p_memsz; /* Size of segment in memory. */ + Elf32_Word p_flags; /* Segment attributes. */ + Elf32_Word p_align; /* Alignment of segment. */ +} Elf32_Phdr; + + +/* + * Note header. + */ +typedef struct +{ + Elf32_Word n_namesz; /* Length of note's name. */ + Elf32_Word n_descsz; /* Length of note's description. */ + Elf32_Word n_type; /* Type of note. */ +} Elf32_Nhdr; + + +/* + * Symbol table entry. + */ +typedef struct +{ + Elf32_Word st_name; /* Symbol name. */ + Elf32_Addr st_value; /* Symbol value. */ + Elf32_Word st_size; /* Size associated with symbol. */ + unsigned char st_info; /* Type and binding attributes. */ + unsigned char st_other; /* Reserved. */ + Elf32_Half st_shndx; /* Section header table index. */ +} Elf32_Sym; + + +/* + * Relocations. + */ +typedef struct +{ + Elf32_Addr r_offset; /* Location to be relocated. */ + Elf32_Word r_info; /* Symbol index and type of relocation. */ +} Elf32_Rel; + +typedef struct +{ + Elf32_Addr r_offset; /* Location to be relocated. */ + Elf32_Word r_info; /* Symbol index and type of relocation. */ + Elf32_Sword r_addend; /* Constant part of expression. */ +} Elf32_Rela; + +/* + * Dynamic section entry. + * ".dynamic" section contains an array of this. + */ +typedef struct +{ + Elf32_Sword d_tag; /* Type of entry. */ + union + { + Elf32_Word d_val; /* Integer value. */ + Elf32_Addr d_ptr; /* Virtual address value. */ + } d_un; +} Elf32_Dyn; + +/* + * Helper macros. + */ +/** The symbol's type. */ +#define ELF32_ST_TYPE(info) ((info) & 0xF) +/** The symbol's binding. */ +#define ELF32_ST_BIND(info) ((info) >> 4) +/** Make st_info. given binding and type. */ +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/** Relocation type. */ +#define ELF32_R_TYPE(info) ((unsigned char)(info)) +/** Relocation symbol index. */ +#define ELF32_R_SYM(info) ((info) >> 8) +/** Make r_info given the symbol index and type. */ +#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) + + +#endif /* !IPRT_INCLUDED_formats_elf32_h */ + diff --git a/include/iprt/formats/elf64.h b/include/iprt/formats/elf64.h new file mode 100644 index 00000000..dcdfbe6e --- /dev/null +++ b/include/iprt/formats/elf64.h @@ -0,0 +1,199 @@ +/* $Id: elf64.h $ */ +/** @file + * IPRT - ELF 64-bit header. + */ + +/* + * Copyright (C) 2010-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_elf64_h +#define IPRT_INCLUDED_formats_elf64_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/assertcompile.h> +#include "elf-common.h" + +/* + * ELF 64 standard types. + */ +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; +typedef uint16_t Elf64_Half; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +/* + * Ensure type size correctness in accordance to ELF-64 Object File Format, Version 1.5 Draft 2, p2. + */ +AssertCompileSize(Elf64_Addr, 8); +AssertCompileSize(Elf64_Off, 8); +AssertCompileSize(Elf64_Half, 2); +AssertCompileSize(Elf64_Word, 4); +AssertCompileSize(Elf64_Sword, 4); +AssertCompileSize(Elf64_Xword, 8); +AssertCompileSize(Elf64_Sxword, 8); + +/* + * ELF 64 non-standard types for convenience. + */ +typedef Elf64_Xword Elf64_Size; +typedef Elf64_Word Elf64_Hashelt; + +/* + * ELF Header. + */ +typedef struct +{ + unsigned char e_ident[16]; /* ELF identification. */ + Elf64_Half e_type; /* Object file type. */ + Elf64_Half e_machine; /* Machine type. */ + Elf64_Word e_version; /* Object file version. */ + Elf64_Addr e_entry; /* Entry point address. */ + Elf64_Off e_phoff; /* Program header offset. */ + Elf64_Off e_shoff; /* Section header offset. */ + Elf64_Word e_flags; /* Processor-specific flags. */ + Elf64_Half e_ehsize; /* ELF header size. */ + Elf64_Half e_phentsize; /* Size of program header entry. */ + Elf64_Half e_phnum; /* Number of program header entries. */ + Elf64_Half e_shentsize; /* Size of section header entry. */ + Elf64_Half e_shnum; /* Number of section header entries. */ + Elf64_Half e_shstrndx; /* Section name string table index. */ +} Elf64_Ehdr; + +/* + * Section header. + */ +typedef struct +{ + Elf64_Word sh_name; /* Section name. */ + Elf64_Word sh_type; /* Section type. */ + Elf64_Xword sh_flags; /* Section attributes. */ + Elf64_Addr sh_addr; /* Virtual address in memory. */ + Elf64_Off sh_offset; /* Offset in file. */ + Elf64_Xword sh_size; /* Size of section. */ + Elf64_Word sh_link; /* Link to other section. */ + Elf64_Word sh_info; /* Miscellaneous information. */ + Elf64_Xword sh_addralign; /* Address alignment boundary. */ + Elf64_Xword sh_entsize; /* Size of entries, if section has table. */ +} Elf64_Shdr; + +/* + * Program header. + */ +typedef struct +{ + Elf64_Word p_type; /* Type of segment. */ + Elf64_Word p_flags; /* Segment attributes. */ + Elf64_Off p_offset; /* Offset in file. */ + Elf64_Addr p_vaddr; /* Virtual address in memory. */ + Elf64_Addr p_paddr; /* Physical address (reserved). */ + Elf64_Xword p_filesz; /* Size of segment in file. */ + Elf64_Xword p_memsz; /* Size of segment in memory. */ + Elf64_Xword p_align; /* Alignment of segment. */ +} Elf64_Phdr; + +/* + * Note header. + */ +typedef struct +{ + Elf64_Word n_namesz; /* Length of note's name. */ + Elf64_Word n_descsz; /* Length of note's description. */ + Elf64_Word n_type; /* Type of note. */ +} Elf64_Nhdr; + +/* + * Symbol table entry. + */ +typedef struct +{ + Elf64_Word st_name; /* Symbol name. */ + unsigned char st_info; /* Type and binding attributes. */ + unsigned char st_other; /* Reserved. */ + Elf64_Half st_shndx; /* Section header table index. */ + Elf64_Addr st_value; /* Symbol value. */ + Elf64_Xword st_size; /* Size associated with symbol. */ +} Elf64_Sym; + +/* + * Relocations. + */ +typedef struct +{ + Elf64_Addr r_offset; /* Location to be relocated. */ + Elf64_Xword r_info; /* Symbol index and type of relocation. */ +} Elf64_Rel; + +typedef struct +{ + Elf64_Addr r_offset; /* Location to be relocated. */ + Elf64_Xword r_info; /* Symbol index and type of relocation. */ + Elf64_Sxword r_addend; /* Constant part of expression. */ +} Elf64_Rela; + +/* + * Dynamic section entry. + * ".dynamic" section contains an array of this. + */ +typedef struct +{ + Elf64_Sxword d_tag; /* Type of entry. */ + union + { + Elf64_Xword d_val; /* Integer value. */ + Elf64_Addr d_ptr; /* Virtual address value. */ + } d_un; +} Elf64_Dyn; + +/* + * Helper macros. + */ +/** The symbol's type. */ +#define ELF64_ST_TYPE(info) ((info) & 0xF) +/** The symbol's binding. */ +#define ELF64_ST_BIND(info) ((info) >> 4) +/** Make st_info. given binding and type. */ +#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/** Relocation type. */ +#define ELF64_R_TYPE(info) ((unsigned char)(info)) +/** Relocation symbol index. */ +#define ELF64_R_SYM(info) ((info) >> 32) +/** Make r_info given the symbol index and type. */ +#define ELF64_R_INFO(sym, type) (((sym) << 32) + (unsigned char)(type)) + + +#endif /* !IPRT_INCLUDED_formats_elf64_h */ + diff --git a/include/iprt/formats/ext.h b/include/iprt/formats/ext.h new file mode 100644 index 00000000..c005f632 --- /dev/null +++ b/include/iprt/formats/ext.h @@ -0,0 +1,998 @@ +/* $Id: ext.h $ */ +/** @file + * IPRT, Ext2/3/4 format. + */ + +/* + * Copyright (C) 2012-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_ext_h +#define IPRT_INCLUDED_formats_ext_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_ext Extended Filesystem (EXT2/3/4) structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + +/* + * The filesystem structures were retrieved from: + * https://www.kernel.org/doc/html/latest/filesystems/ext4/index.html + */ + +/** Offset where to find the first superblock on the disk, this is constant. */ +#define EXT_SB_OFFSET 1024 + +/** @name EXT_INODE_NR_XXX - Special inode numbers. + * @{ */ +#define EXT_INODE_NR_DEF_BLOCKS 1 /**< List of defective blocks. */ +#define EXT_INODE_NR_ROOT_DIR 2 /**< Root directory. */ +#define EXT_INODE_NR_USER_QUOTA 3 /**< User quota. */ +#define EXT_INODE_NR_GROUP_QUOTA 4 /**< Group quota. */ +#define EXT_INODE_NR_BOOT_LOADER 5 /**< Boot loader. */ +#define EXT_INODE_NR_UNDEL_DIR 6 /**< Undelete directory. */ +#define EXT_INODE_NR_RESV_GRP_DESC 7 /**< Reserved group descriptors inode. */ +#define EXT_INODE_NR_JOURNAL 8 /**< Journal. */ +#define EXT_INODE_NR_EXCLUDE 9 /**< Exclude inode. */ +#define EXT_INODE_NR_REPLICA 10 /**< Replica inode. */ +/** @} */ + +/** + * Ext superblock. + * + * Everything is stored little endian on the disk. + */ +typedef struct EXTSUPERBLOCK +{ + /** 0x00: Total number of inodes in the filesystem. */ + uint32_t cInodesTotal; + /** 0x04: Total number of blocks in the filesystem (low 32bits). */ + uint32_t cBlocksTotalLow; + /** 0x08: Number of blocks reserved for the super user (low 32bits). */ + uint32_t cBlocksRsvdForSuperUserLow; + /** 0x0c: Total number of free blocks (low 32bits). */ + uint32_t cBlocksFreeLow; + /** 0x10: Total number of free inodes. */ + uint32_t cInodesFree; + /** 0x14: First data block. */ + uint32_t iBlockOfSuperblock; + /** 0x18: Block size (calculated as 2^(10 + cBitsShiftLeftBlockSize)). */ + uint32_t cLogBlockSize; + /** 0x1c: Cluster size (calculated as 2^cLogClusterSize). */ + uint32_t cLogClusterSize; + /** 0x20: Number of blocks in each block group. */ + uint32_t cBlocksPerGroup; + /** 0x24: Number of clusters in each block group. */ + uint32_t cClustersPerBlockGroup; + /** 0x28: Number of inodes for each block group. */ + uint32_t cInodesPerBlockGroup; + /** 0x2c: Last mount time in seconds since epoch. */ + uint32_t u32LastMountTime; + /** 0x30: Last written time in seconds since epoch. */ + uint32_t u32LastWrittenTime; + /** 0x34: Number of times the volume was mounted since the last check. */ + uint16_t cMountsSinceLastCheck; + /** 0x36: Number of mounts allowed before a consistency check. */ + uint16_t cMaxMountsUntilCheck; + /** 0x38: Signature to identify a ext2 volume (EXT_SIGNATURE). */ + uint16_t u16Signature; + /** 0x3a: State of the filesystem (EXT_SB_STATE_XXX) */ + uint16_t u16FilesystemState; + /** 0x3c: What to do on an error. */ + uint16_t u16ActionOnError; + /** 0x3e: Minor revision level. */ + uint16_t u16RevLvlMinor; + /** 0x40: Time of last check in seconds since epoch. */ + uint32_t u32LastCheckTime; + /** 0x44: Interval between consistency checks in seconds. */ + uint32_t u32CheckInterval; + /** 0x48: Operating system ID of the filesystem creator (EXT_SB_OS_ID_CREATOR_XXX). */ + uint32_t u32OsIdCreator; + /** 0x4c: Revision level (EXT_SB_REV_XXX). */ + uint32_t u32RevLvl; + /** 0x50: User ID that is allowed to use reserved blocks. */ + uint16_t u16UidReservedBlocks; + /** 0x52: Group ID that is allowed to use reserved blocks. */ + uint16_t u16GidReservedBlocks; + /** 0x54: First non reserved inode number. */ + uint32_t iFirstInodeNonRsvd; + /** 0x58: Size of the inode structure in bytes. */ + uint16_t cbInode; + /** 0x5a: Block group number of this super block. */ + uint16_t iBlkGrpSb; + /** 0x5c: Compatible feature set flags (EXT_SB_FEAT_COMPAT_XXX). */ + uint32_t fFeaturesCompat; + /** 0x60: Incompatible feature set (EXT_SB_FEAT_INCOMPAT_XXX). */ + uint32_t fFeaturesIncompat; + /** 0x64: Readonly-compatible feature set (EXT_SB_FEAT_COMPAT_RO_XXX). */ + uint32_t fFeaturesCompatRo; + /** 0x68: 128bit UUID for the volume. */ + uint8_t au8Uuid[16]; + /** 0x78: Volume name. */ + char achVolumeName[16]; + /** 0x88: Directory were the filesystem was mounted last. */ + char achLastMounted[64]; + /** 0xc8: Bitmap usage algorithm (used for compression). */ + uint32_t u32AlgoUsageBitmap; + /** 0xcc: Number of blocks to try to preallocate for files(?). */ + uint8_t cBlocksPrealloc; + /** 0xcd: Number of blocks to try to preallocate for directories. */ + uint8_t cBlocksPreallocDirectory; + /** 0xce: Number of reserved group descriptor entries for future filesystem expansion. */ + uint16_t cGdtEntriesRsvd; + /** 0xd0: 128bit UUID for the journal superblock. */ + uint8_t au8JournalUuid[16]; + /** 0xe0: Inode number of the journal file. */ + uint32_t iJournalInode; + /** 0xe4: Device number of journal file (if the appropriate feature flag is set). */ + uint32_t u32JournalDev; + /** 0xe8: Start of list of orpaned inodes to delete. */ + uint32_t u32LastOrphan; + /** 0xec: HTREE hash seed. */ + uint32_t au32HashSeedHtree[4]; + /** 0xfc: Default hash algorithm to use for hashes (EXT_SB_HASH_VERSION_DEF_XXX). */ + uint8_t u8HashVersionDef; + /** 0xfd: Journal backup type. */ + uint8_t u8JnlBackupType; + /** 0xfe: Group descriptor size in bytes. */ + uint16_t cbGroupDesc; + /** 0x100: Default mount options (EXT_SB_MNT_OPTS_DEF_XXX). */ + uint32_t fMntOptsDef; + /** 0x104: First metablock block group (if feature is enabled). */ + uint32_t iFirstMetaBg; + /** 0x108: Filesystem creation time in seconds since epoch. */ + uint32_t u32TimeFsCreation; + /** 0x10c: Backup copy of journals inodes block array for the first elements. */ + uint32_t au32JnlBlocks[17]; + /** 0x150: Total number of blocks in the filesystem (high 32bits). */ + uint32_t cBlocksTotalHigh; + /** 0x154: Number of blocks reserved for the super user (high 32bits). */ + uint32_t cBlocksRsvdForSuperUserHigh; + /** 0x158: Total number of free blocks (high 32bits). */ + uint32_t cBlocksFreeHigh; + /** 0x15c: All inodes have at least this number of bytes. */ + uint16_t cbInodesExtraMin; + /** 0x15e: New inodes should reserve this number of bytes. */ + uint16_t cbNewInodesRsv; + /** 0x160: Miscellaneous flags (EXT_SB_F_XXX). */ + uint32_t fFlags; + /** 0x164: RAID stride, number of logical blocks read from or written to the disk + * before moving to the next disk. */ + uint16_t cRaidStride; + /** 0x166: Number of seconds between multi-mount prevention checking. */ + uint16_t cSecMmpInterval; + /** 0x168: Block number for the multi-mount protection data. */ + uint64_t iMmpBlock; + /** 0x170: Raid stride width. */ + uint32_t cRaidStrideWidth; + /** 0x174: Size of a flexible block group (calculated as 2^cLogGroupsPerFlex). */ + uint8_t cLogGroupsPerFlex; + /** 0x175: Metadata checksum algorithm type, only 1 is valid (for CRC32c). */ + uint8_t u8ChksumType; + /** 0x176: Padding. */ + uint16_t u16Padding; + /** 0x178: Number of KiB written to the filesystem so far. */ + uint64_t cKbWritten; + /** 0x180: Inode number of active snapshot. */ + uint32_t iSnapshotInode; + /** 0x184: Sequential ID of active snapshot. */ + uint32_t iSnapshotId; + /** 0x188: Number of blocks reserved for activ snapshot's future use. */ + uint64_t cSnapshotRsvdBlocks; + /** 0x190: Inode number of the head of the on-disk snapshot list. */ + uint32_t iSnapshotListInode; + /** 0x194: Number of errors seen so far. */ + uint32_t cErrorsSeen; + /** 0x198: First time an error happened in seconds since epoch. */ + uint32_t u32TimeFirstError; + /** 0x19c: Inode involved in the first error. */ + uint32_t iInodeFirstError; + /** 0x1a0: Number of block involved of first error. */ + uint64_t iBlkFirstError; + /** 0x1a8: Name of the function where the first error happened. */ + char achFuncFirstError[32]; + /** 0x1c8: Line number where the error happened. */ + uint32_t iLineFirstError; + /** 0x1cc: Time of the most receent error in seconds since epoch. */ + uint32_t u32TimeLastError; + /** 0x1d0: Inode involved in the most recent error. */ + uint32_t iInodeLastError; + /** 0x1d4: Line number where the most recent error happened. */ + uint32_t iLineLastError; + /** 0x1d8: Number of block involved of most recent error. */ + uint64_t iBlkLastError; + /** 0x1e0: Name of the function where the most recent error happened. */ + char achFuncLastError[32]; + /** 0x200: ASCIIz string of mount options. */ + char aszMntOpts[64]; + /** 0x240: Inode number of user quota file. */ + uint32_t iInodeUsrQuota; + /** 0x244: Inode number of group quota file. */ + uint32_t iInodeGrpQuota; + /** 0x248: Overhead blocks/clusters in filesystem. */ + uint32_t cOverheadBlocks; + /** 0x24c: Block groups containing superblock backups. */ + uint32_t aiBlkGrpSbBackups[2]; + /** 0x254: Encryption algorithms in use (EXT_SB_ENCRYPT_ALGO_XXX). */ + uint8_t au8EncryptAlgo[4]; + /** 0x258: Salt for the string2key algorithm for encryption. */ + uint8_t abEncryptPwSalt[16]; + /** 0x268: Inode number of lost+found. */ + uint32_t iInodeLostFound; + /** 0x26c: Inode that tracks project quotas. */ + uint32_t iInodeProjQuota; + /** 0x270: Checksum seed used for the metadata checksum calculations. + * Should be crc32c(~0, au8Uuid). */ + uint32_t u32ChksumSeed; + /** 0x274: Upper 8bits of the u32LastWrittenTime field. */ + uint8_t u32LastWrittenTimeHigh8Bits; + /** 0x275: Upper 8bits of the u32LastMountTime field. */ + uint8_t u32LastMountTimeHigh8Bits; + /** 0x276: Upper 8bits of the u32TimeFsCreation field. */ + uint8_t u32TimeFsCreationHigh8Bits; + /** 0x277: Upper 8bits of the u32LastCheckTime field. */ + uint8_t u32LastCheckTimeHigh8Bits; + /** 0x278: Upper 8bits of the u32TimeFirstError field. */ + uint8_t u32TimeFirstErrorHigh8Bits; + /** 0x279: Upper 8bits of the u32TimeLastError field. */ + uint8_t u32TimeLastErrorHigh8Bits; + /** 0x27a: Zero padding. */ + uint8_t au8Padding[2]; + /** 0x27c: Padding to the end of the block. */ + uint32_t au32Rsvd[96]; + /** 0x3fc: Superblock checksum. */ + uint32_t u32Chksum; +} EXTSUPERBLOCK; +AssertCompileMemberOffset(EXTSUPERBLOCK, u16UidReservedBlocks, 0x50); +AssertCompileMemberOffset(EXTSUPERBLOCK, u32AlgoUsageBitmap, 0xc8); +AssertCompileMemberOffset(EXTSUPERBLOCK, iJournalInode, 0xe0); +AssertCompileMemberOffset(EXTSUPERBLOCK, u8HashVersionDef, 0xfc); +AssertCompileMemberOffset(EXTSUPERBLOCK, fMntOptsDef, 0x100); +AssertCompileMemberOffset(EXTSUPERBLOCK, iBlkLastError, 0x1d8); +AssertCompileMemberOffset(EXTSUPERBLOCK, iInodeLostFound, 0x268); +AssertCompileSize(EXTSUPERBLOCK, 1024); +/** Pointer to an ext super block. */ +typedef EXTSUPERBLOCK *PEXTSUPERBLOCK; +/** Pointer to a const ext super block. */ +typedef EXTSUPERBLOCK const *PCEXTSUPERBLOCK; + +/** Ext signature. */ +#define EXT_SB_SIGNATURE UINT16_C(0xef53) + +/** @name EXT_SB_STATE_XXX - Filesystem state + * @{ */ +/** Clean filesystem state. */ +#define EXT_SB_STATE_CLEAN UINT16_C(0x0001) +/** Error filesystem state. */ +#define EXT_SB_STATE_ERRORS UINT16_C(0x0002) +/** Orphans being recovered state. */ +#define EXT_SB_STATE_ORPHANS_RECOVERING UINT16_C(0x0004) +/** @} */ + +/** @name EXT_SB_OS_ID_CREATOR_XXX - Filesystem creator + * @{ */ +/** Linux. */ +#define EXT_SB_OS_ID_CREATOR_LINUX 0 +/** Hurd. */ +#define EXT_SB_OS_ID_CREATOR_HURD 1 +/** Masix. */ +#define EXT_SB_OS_ID_CREATOR_MASIX 2 +/** FreeBSD. */ +#define EXT_SB_OS_ID_CREATOR_FREEBSD 3 +/** Lites. */ +#define EXT_SB_OS_ID_CREATOR_LITES 4 +/** @} */ + +/** @name EXT_SB_REV_XXX - Superblock revision + * @{ */ +/** Original format (ext2). */ +#define EXT_SB_REV_ORIG 0 +/** Inodes have dynmic sizes. */ +#define EXT_SB_REV_V2_DYN_INODE_SZ 1 +/** @} */ + +/** @name EXT_SB_FEAT_COMPAT_XXX - Compatible features which can be ignored when set + * and not being supported. + * @{ */ +/** Directories can be preallocated. */ +#define EXT_SB_FEAT_COMPAT_DIR_PREALLOC RT_BIT_32(0) +/** Some sort of "imagic" inodes. */ +#define EXT_SB_FEAT_COMPAT_IMAGIC_INODES RT_BIT_32(1) +/** Filesystem has a journal. */ +#define EXT_SB_FEAT_COMPAT_HAS_JOURNAL RT_BIT_32(2) +/** Filesystem supports extended attributes. */ +#define EXT_SB_FEAT_COMPAT_EXT_ATTR RT_BIT_32(3) +/** Filesystem contains reserved group descriptor blocks for filesystem expansion. */ +#define EXT_SB_FEAT_COMPAT_RESIZE_INODE RT_BIT_32(4) +/** Filesystem contains directory indices. */ +#define EXT_SB_FEAT_COMPAT_DIR_INDEX RT_BIT_32(5) +/** Lazy block group - not used. */ +#define EXT_SB_FEAT_COMPAT_LAZY_BG RT_BIT_32(6) +/** Exclude inode - not used. */ +#define EXT_SB_FEAT_COMPAT_EXCLUDE_INODE RT_BIT_32(7) +/** Exclude bitmap - not used. */ +#define EXT_SB_FEAT_COMPAT_EXCLUDE_BITMAP RT_BIT_32(8) +/** Sparse super blocks, super block contains pointers to block groups + * containing backups of the superblock. */ +#define EXT_SB_FEAT_COMPAT_SPARSE_SUPER2 RT_BIT_32(9) +/** @} */ + +/** @name EXT_SB_FEAT_INCOMPAT_XXX - Incompatible features which cause a mounting + * error when set and not being supported. + * @{ */ +/** Filesystem contains compressed files. */ +#define EXT_SB_FEAT_INCOMPAT_COMPRESSION RT_BIT_32(0) +/** Directory entries contain a file type. */ +#define EXT_SB_FEAT_INCOMPAT_DIR_FILETYPE RT_BIT_32(1) +/** Filesystem needs recovery. */ +#define EXT_SB_FEAT_INCOMPAT_RECOVER RT_BIT_32(2) +/** The journal is recorded on a separate device. */ +#define EXT_SB_FEAT_INCOMPAT_JOURNAL_DEV RT_BIT_32(3) +/** Filesystem uses meta block groups. */ +#define EXT_SB_FEAT_INCOMPAT_META_BG RT_BIT_32(4) +/** Files in the filesystem use extents. */ +#define EXT_SB_FEAT_INCOMPAT_EXTENTS RT_BIT_32(6) +/** Filesystem uses 64bit offsets. */ +#define EXT_SB_FEAT_INCOMPAT_64BIT RT_BIT_32(7) +/** Filesystem requires multiple mount preotection. */ +#define EXT_SB_FEAT_INCOMPAT_MMP RT_BIT_32(8) +/** Filesystem uses flexible block groups. */ +#define EXT_SB_FEAT_INCOMPAT_FLEX_BG RT_BIT_32(9) +/** Inodes can be used to store large extended attribute values. */ +#define EXT_SB_FEAT_INCOMPAT_EXT_ATTR_INODE RT_BIT_32(10) +/** Data is contained in directory entries. */ +#define EXT_SB_FEAT_INCOMPAT_DIRDATA RT_BIT_32(12) +/** Metadata checksum seed is stored in the super block. */ +#define EXT_SB_FEAT_INCOMPAT_CSUM_SEED RT_BIT_32(13) +/** Directories can be larger than 2GiB or contain a 3-level HTree. */ +#define EXT_SB_FEAT_INCOMPAT_LARGE_DIR RT_BIT_32(14) +/** Data is inlined in the inode. */ +#define EXT_SB_FEAT_INCOMPAT_INLINE_DATA RT_BIT_32(15) +/** Encrypted inodes are present on the filesystem. */ +#define EXT_SB_FEAT_INCOMPAT_ENCRYPT RT_BIT_32(16) +/** @} */ + +/** @name EXT_SB_FEAT_COMPAT_RO_XXX - Backward compatible features when mounted readonly + * @{ */ +/** Sparse superblocks. */ +#define EXT_SB_FEAT_COMPAT_RO_SPARSE_SUPER RT_BIT_32(0) +/** There is at least one large file (> 2GiB). */ +#define EXT_SB_FEAT_COMPAT_RO_LARGE_FILE RT_BIT_32(1) +/** Actually not used in the Linux kernel and e2fprogs. */ +#define EXT_SB_FEAT_COMPAT_RO_BTREE_DIR RT_BIT_32(2) +/** Filesystem contains files which sizes are not represented as a multiple of 512 byte sectors + * but logical blocks instead. */ +#define EXT_SB_FEAT_COMPAT_RO_HUGE_FILE RT_BIT_32(3) +/** Group descriptors have checksums embedded */ +#define EXT_SB_FEAT_COMPAT_RO_GDT_CHSKUM RT_BIT_32(4) +/** Subdirectory limit of 32000 doesn't apply. The link count is set to 1 if beyond 64999. */ +#define EXT_SB_FEAT_COMPAT_RO_DIR_NLINK RT_BIT_32(5) +/** Inodes can contain extra data. */ +#define EXT_SB_FEAT_COMPAT_RO_EXTRA_INODE_SZ RT_BIT_32(6) +/** There is at least one snapshot on the filesystem. */ +#define EXT_SB_FEAT_COMPAT_RO_HAS_SNAPSHOTS RT_BIT_32(7) +/** Quotas are enabled for this filesystem. */ +#define EXT_SB_FEAT_COMPAT_RO_QUOTA RT_BIT_32(8) +/** The bigalloc feature is enabled, file extents are tracked in units of clusters + * instead of blocks. */ +#define EXT_SB_FEAT_COMPAT_RO_BIGALLOC RT_BIT_32(9) +/** Metadata contains checksums. */ +#define EXT_SB_FEAT_COMPAT_RO_METADATA_CHKSUM RT_BIT_32(10) +/** Filesystem supports replicas. */ +#define EXT_SB_FEAT_COMPAT_RO_REPLICA RT_BIT_32(11) +/** Filesystem is readonly. */ +#define EXT_SB_FEAT_COMPAT_RO_READONLY RT_BIT_32(12) +/** Filesystem tracks project quotas. */ +#define EXT_SB_FEAT_COMPAT_RO_PROJECT RT_BIT_32(13) +/** @} */ + +/** @name EXT_SB_HASH_VERSION_DEF_XXX - Default hash algorithm used + * @{ */ +/** Legacy. */ +#define EXT_SB_HASH_VERSION_DEF_LEGACY 0 +/** Half MD4. */ +#define EXT_SB_HASH_VERSION_DEF_HALF_MD4 1 +/** Tea. */ +#define EXT_SB_HASH_VERSION_DEF_TEA 2 +/** Unsigned legacy. */ +#define EXT_SB_HASH_VERSION_DEF_LEGACY_UNSIGNED 3 +/** Unsigned half MD4. */ +#define EXT_SB_HASH_VERSION_DEF_HALF_MD4_UNSIGNED 4 +/** Unsigned tea. */ +#define EXT_SB_HASH_VERSION_DEF_TEA_UNSIGNED 5 +/** @} */ + +/** @name EXT_SB_MNT_OPTS_DEF_XXX - Default mount options + * @{ */ +/** Print debugging information on (re)mount. */ +#define EXT_SB_MNT_OPTS_DEF_DEBUG RT_BIT_32(0) +/** Created files take the group ID ofthe containing directory. */ +#define EXT_SB_MNT_OPTS_DEF_BSDGROUPS RT_BIT_32(1) +/** Support userspace extended attributes. */ +#define EXT_SB_MNT_OPTS_DEF_XATTR_USER RT_BIT_32(2) +/** Support POSIX access control lists. */ +#define EXT_SB_MNT_OPTS_DEF_ACL RT_BIT_32(3) +/** Do not support 32bit UIDs. */ +#define EXT_SB_MNT_OPTS_DEF_UID16 RT_BIT_32(4) +/** All data and metadata are committed to the journal. */ +#define EXT_SB_MNT_OPTS_DEF_JMODE_DATA RT_BIT_32(5) +/** All data are flushed to the disk before metadata are committed to the journal. */ +#define EXT_SB_MNT_OPTS_DEF_JMODE_ORDERED RT_BIT_32(6) +/** Data ordering not preserved, data may be written after metadata has been written. */ +#define EXT_SB_MNT_OPTS_DEF_JMODE_WBACK (EXT_SB_MNT_OPTS_DEF_JMODE_DATA | EXT_SB_MNT_OPTS_DEF_JMODE_ORDERED) +/** No write flushes. */ +#define EXT_SB_MNT_OPTS_DEF_NOBARRIER RT_BIT_32(8) +/** Track metadata blocks on the filesystem not being used as data blocks. */ +#define EXT_SB_MNT_OPTS_DEF_BLOCK_VALIDITY RT_BIT_32(9) +/** Enables TRIM/DISCARD support. */ +#define EXT_SB_MNT_OPTS_DEF_DISCARD RT_BIT_32(10) +/** Disable delayed allocation. */ +#define EXT_SB_MNT_OPTS_DEF_NODELALLOC RT_BIT_32(11) +/** @} */ + +/** @name EXT_SB_F_XXX - Superblock flags + * @{ */ +/** Signed directory hash used. */ +#define EXT_SB_F_SIGNED_DIR_HASH RT_BIT_32(0) +/** Unsigned directory hash used. */ +#define EXT_SB_F_UNSIGNED_DIR_HASH RT_BIT_32(1) +/** Only used to test development code. */ +#define EXT_SB_F_DEV_CODE RT_BIT_32(3) +/** @} */ + +/** @name EXT_SB_ENCRYPT_ALGO_XXX - Group descriptor flags + * @{ */ +/** Invalid encryption algorithm. */ +#define EXT_SB_ENCRYPT_ALGO_INVALID 0 +/** 256-bit AES in XTS mode. */ +#define EXT_SB_ENCRYPT_ALGO_256BIT_AES_XTS 1 +/** 256-bit AES in GCM mode. */ +#define EXT_SB_ENCRYPT_ALGO_256BIT_AES_GCM 2 +/** 256-bit AES in CBC mode. */ +#define EXT_SB_ENCRYPT_ALGO_256BIT_AES_CBC 3 +/** @} */ + + +/** + * Block group descriptor (32byte version). + */ +typedef struct EXTBLOCKGROUPDESC32 +{ + /** 0x00: Block address of the block bitmap (low 32bits). */ + uint32_t offBlockBitmapLow; + /** 0x04: Block address of the inode bitmap (low 32bits). */ + uint32_t offInodeBitmapLow; + /** 0x08: Start block address of the inode table (low 32bits). */ + uint32_t offInodeTableLow; + /** 0x0c: Number of unallocated blocks in group (low 16bits). */ + uint16_t cBlocksFreeLow; + /** 0x0e: Number of unallocated inodes in group (low 16bits). */ + uint16_t cInodesFreeLow; + /** 0x10: Number of directories in the group (low 16bits). */ + uint16_t cDirectoriesLow; + /** 0x12: Flags (EXT_GROUP_DESC_F_XXX). */ + uint16_t fFlags; + /** 0x14: Location of snapshot exclusion bitmap (lower 32bits) */ + uint32_t offSnapshotExclBitmapLow; + /** 0x18: Block bitmap checksum (lower 16bits). */ + uint16_t u16ChksumBlockBitmapLow; + /** 0x1a: Inode bitmap checksum (lower 16bits). */ + uint16_t u16ChksumInodeBitmapLow; + /** 0x1c: Unused inode entry count in the groups inode table (lower 16bits).*/ + uint16_t cInodeTblUnusedLow; + /** 0x1e: Group descriptor checksum. */ + uint16_t u16Chksum; +} EXTBLOCKGROUPDESC32; +AssertCompileSize(EXTBLOCKGROUPDESC32, 32); +/** Pointer to an ext block group descriptor. */ +typedef EXTBLOCKGROUPDESC32 *PEXTBLOCKGROUPDESC32; +/** Pointer to a const 32 byte block group descriptor. */ +typedef const EXTBLOCKGROUPDESC32 *PCEXTBLOCKGROUPDESC32; + + +/** + * Block group descriptor (64byte version). + */ +typedef struct EXTBLOCKGROUPDESC64 +{ + /** 0x00: Embedded 32 byte descriptor. */ + EXTBLOCKGROUPDESC32 v32; + /** 0x20: Location of block bitmap (upper 32bits). */ + uint32_t offBlockBitmapHigh; + /** 0x24: Location of inode bitmap (upper 32bits). */ + uint32_t offInodeBitmapHigh; + /** 0x28: Location of inode table (upper 32bits). */ + uint32_t offInodeTableHigh; + /** 0x2c: Number of unallocated blocks (upper 16bits). */ + uint16_t cBlocksFreeHigh; + /** 0x2e: Number of unallocated inodes (upper 16bits). */ + uint16_t cInodesFreeHigh; + /** 0x30: Number of directories in the group (upper 16bits). */ + uint16_t cDirectoriesHigh; + /** 0x32: Unused inode entry count in the groups inode table (upper 16bits).*/ + uint16_t cInodeTblUnusedHigh; + /** 0x34: Location of snapshot exclusion bitmap (upper 32bits) */ + uint32_t offSnapshotExclBitmapHigh; + /** 0x38: Block bitmap checksum (upper 16bits). */ + uint16_t u16ChksumBlockBitmapHigh; + /** 0x3a: Inode bitmap checksum (upper 16bits). */ + uint16_t u16ChksumInodeBitmapHigh; + /** 0x3c: Padding to 64 bytes. */ + uint32_t u64Padding; +} EXTBLOCKGROUPDESC64; +AssertCompileSize(EXTBLOCKGROUPDESC64, 64); +/** Pointer to an ext block group descriptor. */ +typedef EXTBLOCKGROUPDESC64 *PEXTBLOCKGROUPDESC64; +/** Pointer to a const 64 byte block group descriptor. */ +typedef const EXTBLOCKGROUPDESC64 *PCEXTBLOCKGROUPDESC64; + +/** @name EXT_GROUP_DESC_F_XXX - Group descriptor flags + * @{ */ +/** Inode table and bitmaps are not initialized. */ +#define EXT_GROUP_DESC_F_INODE_UNINIT RT_BIT(0) +/** Block bitmap is not initialized. */ +#define EXT_GROUP_DESC_F_BLOCK_UNINIT RT_BIT(1) +/** Inode table is zeroed. */ +#define EXT_GROUP_DESC_F_INODE_ZEROED RT_BIT(2) +/** @} */ + + +/** + * Combiend view of the different block gorup descriptor versions. + */ +typedef union EXTBLOCKGROUPDESC +{ + /** 32 byte version. */ + EXTBLOCKGROUPDESC32 v32; + /** 64 byte version. */ + EXTBLOCKGROUPDESC64 v64; + /** Byte view. */ + uint8_t au8[64]; +} EXTBLOCKGROUPDESC; +/** Poiner to a unified block gorup descriptor view. */ +typedef EXTBLOCKGROUPDESC *PEXTBLOCKGROUPDESC; +/** Poiner to a const unified block gorup descriptor view. */ +typedef const EXTBLOCKGROUPDESC *PCEXTBLOCKGROUPDESC; + + +/** Number of block entries in the inodes block map. */ +#define EXT_INODE_BLOCK_ENTRIES 15 + +/** + * Inode table entry (standard 128 byte version). + */ +typedef struct EXTINODE +{ + /** 0x00: File mode (EXT_INODE_FILE_MODE_XXX). */ + uint16_t fMode; + /** 0x02: Owner UID (lower 16bits). */ + uint16_t uUidLow; + /** 0x04: Size in bytes (lower 32bits). */ + uint32_t cbSizeLow; + /** 0x08: Last access time in seconds since epoch. */ + uint32_t u32TimeLastAccess; + /** 0x0c: Last inode change time in seconds since epoch. */ + uint32_t u32TimeLastChange; + /** 0x10: Last data modification time in seconds since epoch. */ + uint32_t u32TimeLastModification; + /** 0x14: Deletion time in seconds since epoch. */ + uint32_t u32TimeDeletion; + /** 0x18: Group ID (lower 16bits). */ + uint16_t uGidLow; + /** 0x1a: Hard link count. */ + uint16_t cHardLinks; + /** 0x1c: Block count (lower 32bits). */ + uint32_t cBlocksLow; + /** 0x20: Inode flags. */ + uint32_t fFlags; + /** 0x24: Operating system dependent data. */ + union + { + /** Linux: Inode version. */ + uint32_t u32LnxVersion; + } Osd1; + /** 0x28: Block map or extent tree. */ + uint32_t au32Block[EXT_INODE_BLOCK_ENTRIES]; + /** 0x64: File version. */ + uint32_t u32Version; + /** 0x68: Extended attribute control block (lower 32bits). */ + uint32_t offExtAttrLow; + /** 0x6c: File/directory size (upper 32bits). */ + uint32_t cbSizeHigh; + /** 0x70: Fragment address (obsolete). */ + uint32_t u32FragmentAddrObs; + /** 0x74: Operating system dependent data 2. */ + union + { + /** Linux related data. */ + struct + { + /** 0x00: Block count (upper 16bits). */ + uint16_t cBlocksHigh; + /** 0x02: Extended attribute block location (upper 16bits). */ + uint16_t offExtAttrHigh; + /** 0x04: Owner UID (upper 16bits). */ + uint16_t uUidHigh; + /** 0x06: Group ID (upper 16bits). */ + uint16_t uGidHigh; + /** 0x08: Inode checksum (lower 16bits). */ + uint16_t u16ChksumLow; + /** 0x0a: Reserved */ + uint16_t u16Rsvd; + } Lnx; + } Osd2; +} EXTINODE; +AssertCompileSize(EXTINODE, 128); +/** Pointer to an inode. */ +typedef EXTINODE *PEXTINODE; +/** Pointer to a const inode. */ +typedef const EXTINODE *PCEXTINODE; + + +/** + * Extra inode data (coming right behind the fixed inode data). + */ +typedef struct EXTINODEEXTRA +{ + /** 0x80: Size of the extra inode data in bytes. */ + uint16_t cbInodeExtra; + /** 0x82: Inode checksum (upper 16bits.) */ + uint16_t u16ChksumHigh; + /** 0x84: Last inode change time, extra time bits for sub-second precision. */ + uint32_t u32ExtraTimeLastChange; + /** 0x88: Last data modification time, extra time bits for sub-second precision. */ + uint32_t u32ExtraTimeLastModification; + /** 0x8c: Last access time, extra time bits for sub-second precision. */ + uint32_t u32ExtraTimeLastAccess; + /** 0x90: File creation time in seconds since epoch. */ + uint32_t u32TimeCreation; + /** 0x94: File creation time, extra time bits for sub-second precision. */ + uint32_t u32ExtraTimeCreation; + /** 0x98: Version number (upper 32bits). */ + uint32_t u32VersionHigh; + /** 0x9c: Project ID. */ + uint32_t u32ProjectId; +} EXTINODEEXTRA; +/** Pointer to extra inode data. */ +typedef EXTINODEEXTRA *PEXTINODEEXTRA; +/** Pointer to a const extra inode data. */ +typedef const EXTINODEEXTRA *PCEXTINODEEXTRA; + + +/** + * Combined inode data. + */ +typedef struct EXTINODECOMB +{ + /** Core inode structure. */ + EXTINODE Core; + /** Any extra inode data which might be present. */ + EXTINODEEXTRA Extra; +} EXTINODECOMB; +/** Pointer to combined inode data. */ +typedef EXTINODECOMB *PEXTINODECOMB; +/** Pointer to a const combined inode data. */ +typedef const EXTINODECOMB *PCEXTINODECOMB; + + + +/** @name EXT_INODE_MODE_XXX - File mode + * @{ */ +/** Others can execute the file. */ +#define EXT_INODE_MODE_EXEC_OTHER RT_BIT(0) +/** Others can write to the file. */ +#define EXT_INODE_MODE_WRITE_OTHER RT_BIT(1) +/** Others can read the file. */ +#define EXT_INODE_MODE_READ_OTHER RT_BIT(2) +/** Members of the same group can execute the file. */ +#define EXT_INODE_MODE_EXEC_GROUP RT_BIT(3) +/** Members of the same group can write to the file. */ +#define EXT_INODE_MODE_WRITE_GROUP RT_BIT(4) +/** Members of the same group can read the file. */ +#define EXT_INODE_MODE_READ_GROUP RT_BIT(5) +/** Owner can execute the file. */ +#define EXT_INODE_MODE_EXEC_OWNER RT_BIT(6) +/** Owner can write to the file. */ +#define EXT_INODE_MODE_WRITE_OWNER RT_BIT(7) +/** Owner can read the file. */ +#define EXT_INODE_MODE_READ_OWNER RT_BIT(8) +/** Sticky file mode. */ +#define EXT_INODE_MODE_STICKY RT_BIT(9) +/** File is set GID. */ +#define EXT_INODE_MODE_SET_GROUP_ID RT_BIT(10) +/** File is set UID. */ +#define EXT_INODE_MODE_SET_USER_ID RT_BIT(11) +/** @} */ + +/** @name EXT_INODE_MODE_TYPE_XXX - File type + * @{ */ +/** Inode represents a FIFO. */ +#define EXT_INODE_MODE_TYPE_FIFO UINT16_C(0x1000) +/** Inode represents a character device. */ +#define EXT_INODE_MODE_TYPE_CHAR UINT16_C(0x2000) +/** Inode represents a directory. */ +#define EXT_INODE_MODE_TYPE_DIR UINT16_C(0x4000) +/** Inode represents a block device. */ +#define EXT_INODE_MODE_TYPE_BLOCK UINT16_C(0x6000) +/** Inode represents a regular file. */ +#define EXT_INODE_MODE_TYPE_REGULAR UINT16_C(0x8000) +/** Inode represents a symlink. */ +#define EXT_INODE_MODE_TYPE_SYMLINK UINT16_C(0xa000) +/** Inode represents a socket. */ +#define EXT_INODE_MODE_TYPE_SOCKET UINT16_C(0xc000) +/** Returns the inode type from the combined mode field. */ +#define EXT_INODE_MODE_TYPE_GET_TYPE(a_Mode) ((a_Mode) & 0xf000) +/** @} */ + +/** @name EXT_INODE_F_XXX - Inode flags + * @{ */ +/** Inode requires secure erase on deletion. */ +#define EXT_INODE_F_SECURE_ERASE RT_BIT_32(0) +/** Inode should be preserved for undeletion during deletion. */ +#define EXT_INODE_F_UNDELETE RT_BIT_32(1) +/** Inode contains compressed data. */ +#define EXT_INODE_F_COMPRESSED RT_BIT_32(2) +/** All writes to this inode must be synchronous. */ +#define EXT_INODE_F_SYNCHRONOUS RT_BIT_32(3) +/** Inode is immutable. */ +#define EXT_INODE_F_IMMUTABLE RT_BIT_32(4) +/** Inode is append only. */ +#define EXT_INODE_F_APPEND_ONLY RT_BIT_32(5) +/** Inode should not be dumped via dump(1). */ +#define EXT_INODE_F_NO_DUMP RT_BIT_32(6) +/** Access time is not updated. */ +#define EXT_INODE_F_NO_ACCESS_TIME RT_BIT_32(7) +/** Dirty compressed file. */ +#define EXT_INODE_F_DIRTY_COMPRESSED RT_BIT_32(8) +/** Inode has one or more compressed clusters. */ +#define EXT_INODE_F_COMPRESSED_BLOCK RT_BIT_32(9) +/** Inode should not be compressed. */ +#define EXT_INODE_F_NO_COMPRESSION RT_BIT_32(10) +/** Inode is encrypted. */ +#define EXT_INODE_F_ENCRYPTED RT_BIT_32(11) +/** Directory has hashed indexes. */ +#define EXT_INODE_F_DIR_HASHED_INDEX RT_BIT_32(12) +/** AFS magic directory. */ +#define EXT_INODE_F_IMAGIC RT_BIT_32(13) +/** Data must always be written through the journal. */ +#define EXT_INODE_F_JOURNAL_DATA RT_BIT_32(14) +/** File tail should not be merged. */ +#define EXT_INODE_F_NOTAIL RT_BIT_32(15) +/** All directory entry data should be written synchronously. */ +#define EXT_INODE_F_DIR_SYNCHRONOUS RT_BIT_32(16) +/** Top of directory hierarchy. */ +#define EXT_INODE_F_TOP_DIRECTORY RT_BIT_32(17) +/** Inode is a huge file. */ +#define EXT_INODE_F_HUGE_FILE RT_BIT_32(18) +/** Inode uses extents. */ +#define EXT_INODE_F_EXTENTS RT_BIT_32(19) +/** Inode stores a large extended attribute value in its data blocks. */ +#define EXT_INODE_F_EXT_ATTR_INODE RT_BIT_32(20) +/** File has blocks allocated past end of file. */ +#define EXT_INODE_F_ALLOC_BLOCKS_EOF RT_BIT_32(21) +/** Inode is a snapshot. */ +#define EXT_INODE_F_SNAPSHOT RT_BIT_32(22) +/** Snapshot is being deleted. */ +#define EXT_INODE_F_SNAPSHOT_DELETED RT_BIT_32(23) +/** Snapshot shrink has completed. */ +#define EXT_INODE_F_SNAPSHOT_SHRUNK RT_BIT_32(24) +/** Inode contains inline data. */ +#define EXT_INODE_F_INLINE_DATA RT_BIT_32(25) +/** Children are created with the same project ID. */ +#define EXT_INODE_F_PROJECT_ID_INHERIT RT_BIT_32(26) +/** Reserved for ext4 library. */ +#define EXT_INODE_F_RESERVED_LIBRARY RT_BIT_32(27) +/** @} */ + + +/** + * Extent tree header. + */ +typedef struct EXTEXTENTHDR +{ + /** 0x00: Magic number for identification. */ + uint16_t u16Magic; + /** 0x02: Number of valid entries following. */ + uint16_t cEntries; + /** 0x04: Maxmimum number of entries that could follow. */ + uint16_t cMax; + /** 0x06: Depth of this extent node in the tree. */ + uint16_t uDepth; + /** 0x08: Generation of the tree (not used by standard ext4). */ + uint32_t cGeneration; +} EXTEXTENTHDR; +AssertCompileSize(EXTEXTENTHDR, 12); +/** Pointer to a extent tree header. */ +typedef EXTEXTENTHDR *PEXTEXTENTHDR; +/** Pointer to a const extent tree header. */ +typedef const EXTEXTENTHDR *PCEXTEXTENTHDR; + +/** Magic number identifying an extent header. */ +#define EXT_EXTENT_HDR_MAGIC UINT16_C(0xf30a) +/** Maximum depth an extent header can have. */ +#define EXT_EXTENT_HDR_DEPTH_MAX UINT16_C(5) + + +/** + * Extent tree index node. + */ +typedef struct EXTEXTENTIDX +{ + /** 0x00: Start file block this node covers. */ + uint32_t iBlock; + /** 0x04: Block number of child extent node (lower 32bits). */ + uint32_t offChildLow; + /** 0x08: Block number of child extent node (upper 16bits). */ + uint16_t offChildHigh; + /** 0x0a: Reserved. */ + uint16_t u16Rsvd; +} EXTEXTENTIDX; +AssertCompileSize(EXTEXTENTIDX, 12); +/** Pointer to an extent tree index node. */ +typedef EXTEXTENTIDX *PEXTEXTENTIDX; +/** Pointer to a const extent tree index node. */ +typedef const EXTEXTENTIDX *PCEXTEXTENTIDX; + + +/** + * Extent tree leaf node. + */ +typedef struct EXTEXTENT +{ + /** 0x00: First file block number this extent covers. */ + uint32_t iBlock; + /** 0x04: Number of blocks covered by this extent. */ + uint16_t cBlocks; + /** 0x06: Block number this extent points to (upper 32bits). */ + uint16_t offStartHigh; + /** 0x08: Block number this extent points to (lower 32bits). */ + uint32_t offStartLow; +} EXTEXTENT; +AssertCompileSize(EXTEXTENT, 12); +/** Pointer to a leaf node. */ +typedef EXTEXTENT *PEXTEXTENT; +/** Pointer to a const leaf node. */ +typedef const EXTEXTENT *PCEXTEXTENT; + +/** Length field limit for a populated extent, fields greater than that limit indicate a sparse extent. */ +#define EXT_EXTENT_LENGTH_LIMIT UINT16_C(32768) + + +/** + * Directory entry. + */ +typedef struct EXTDIRENTRY +{ + /** 0x00: Inode number being referenced by this entry. */ + uint32_t iInodeRef; + /** 0x04: Record length of this directory entry in bytes (multiple of 4). */ + uint16_t cbRecord; + /** 0x06: Version dependent data. */ + union + { + /** Original. */ + struct + { + /** Name length in bytes (maximum 255). */ + uint16_t cbName; + } v1; + /** Version 2. */ + struct + { + /** Name length in bytes (maximum 255). */ + uint8_t cbName; + /** File type (EXT_DIRENTRY_TYPE_XXX). */ + uint8_t uType; + } v2; + } u; + /** 0x08: File name - variable in size. */ + char achName[1]; +} EXTDIRENTRY; +/** Pointer to a directory entry. */ +typedef EXTDIRENTRY *PEXTDIRENTRY; +/** Poiner to a const directory entry. */ +typedef const EXTDIRENTRY *PCEXTDIRENTRY; + + +/** + * Extended directory entry with the maximum size (263 bytes). + */ +#pragma pack(1) +typedef union EXTDIRENTRYEX +{ + /** The directory entry. */ + EXTDIRENTRY Core; + /** The byte view. */ + uint8_t au8[263]; +} EXTDIRENTRYEX; +#pragma pack() +AssertCompileSize(EXTDIRENTRYEX, 263); +/** Pointer to an extended directory entry. */ +typedef EXTDIRENTRYEX *PEXTDIRENTRYEX; +/** Pointer to a const extended directory entry. */ +typedef const EXTDIRENTRYEX *PCEXTDIRENTRYEX; + + +/** @name EXT_DIRENTRY_TYPE_XXX - file type + * @{ */ +/** Entry is of unknown file type. */ +#define EXT_DIRENTRY_TYPE_UNKNOWN 0 +/** Entry is regular file. */ +#define EXT_DIRENTRY_TYPE_REGULAR 1 +/** Entry is another directory. */ +#define EXT_DIRENTRY_TYPE_DIRECTORY 2 +/** Entry is a character device. */ +#define EXT_DIRENTRY_TYPE_CHAR 3 +/** Entry is a block device. */ +#define EXT_DIRENTRY_TYPE_BLOCK 4 +/** Entry is a FIFO. */ +#define EXT_DIRENTRY_TYPE_FIFO 5 +/** Entry is a socket. */ +#define EXT_DIRENTRY_TYPE_SOCKET 6 +/** Entry is a symlink. */ +#define EXT_DIRENTRY_TYPE_SYMLINK 7 +/** Entry is a checksum and uses EXTDIRENTRYCHKSUM. */ +#define EXT_DIRENTRY_TYPE_CHKSUM 0xde +/** @} */ + + +/** + * Tail directory entry (for checksumming). + */ +typedef struct EXTDIRENTRYCHKSUM +{ + /** 0x00: Reserved, must be 0 (overlays with EXTDIRENTRY::iNodeRef). */ + uint32_t u32Rsvd; + /** 0x04: Record length (must be 12). */ + uint16_t cbRecord; + /** 0x06: Reserved (overlays with EXTDIRENTRY::u::v1::cbName). */ + uint8_t u8Rsvd; + /** 0x07: File type (must be 0xde). */ + uint8_t uType; + /** 0x08: Checksum. */ + uint32_t u32Chksum; +} EXTDIRENTRYCHKSUM; +/** Pointer to a tail directory entry. */ +typedef EXTDIRENTRYCHKSUM *PEXTDIRENTRYCHKSUM; +/** Pointer to const tail directory entry. */ +typedef const EXTDIRENTRYCHKSUM *PCEXTDIRENTRYCHKSUM; + + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_ext_h */ + diff --git a/include/iprt/formats/fat.h b/include/iprt/formats/fat.h new file mode 100644 index 00000000..18b952bd --- /dev/null +++ b/include/iprt/formats/fat.h @@ -0,0 +1,759 @@ +/* $Id: fat.h $ */ +/** @file + * IPRT, File Allocation Table (FAT). + */ + +/* + * Copyright (C) 2017-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_fat_h +#define IPRT_INCLUDED_formats_fat_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_fat File Allocation Table (FAT) structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + + +/** @name FAT Media byte values + * @remarks This isn't as simple as it's made out to be here! + * @{ */ +#define FATBPB_MEDIA_FLOPPY_8 UINT8_C(0xe5) +#define FATBPB_MEDIA_FLOPPY_5_DOT_25 UINT8_C(0xed) +#define FATBPB_MEDIA_FLOPPY_3_DOT_5 UINT8_C(0xf0) +/* incomplete, figure out as needed... */ + +/** Checks if @a a_bMedia is a valid media byte. */ +#define FATBPB_MEDIA_IS_VALID(a_bMedia) ( (uint8_t)(a_bMedia) >= 0xf8 \ + || (uint8_t)(a_bMedia) == 0xf0 \ + || (uint8_t)(a_bMedia) == 0xf4 /* obscure - msdos 2.11 */ \ + || (uint8_t)(a_bMedia) == 0xf5 /* obscure - msdos 2.11 */ \ + || (uint8_t)(a_bMedia) == 0xed /* obscure - tandy 2000 */ \ + || (uint8_t)(a_bMedia) == 0xe5 /* obscure - tandy 2000 */ ) +/** @} */ + +/** Checks if @a a_bFatId is a valid FAT ID byte. + * @todo uncertain whether 0xf4 and 0xf5 should be allowed here too. */ +#define FAT_ID_IS_VALID(a_bFatId) ( (uint8_t)(a_bFatId) >= 0xf8 \ + || (uint8_t)(a_bFatId) == 0xf0 \ + || (uint8_t)(a_bFatId) == 0xf4 /* obscure - msdos 2.11 */ \ + || (uint8_t)(a_bFatId) == 0xf5 /* obscure - msdos 2.11 */ \ + || (uint8_t)(a_bFatId) == 0xed /* obscure, tandy 2000 */ \ + || (uint8_t)(a_bFatId) == 0xe5 /* obscure, tandy 2000 */ ) + +/** + * The DOS 2.0 BIOS parameter block (BPB). + * + * This was the first DOS version with a BPB. + */ +#pragma pack(1) +typedef struct FATBPB20 +{ + /** 0x0b / 0x00: The sector size in bytes. */ + uint16_t cbSector; + /** 0x0d / 0x02: Number of sectors per cluster. */ + uint8_t cSectorsPerCluster; + /** 0x0e / 0x03: Number of reserved sectors before the first FAT. */ + uint16_t cReservedSectors; + /** 0x10 / 0x05: Number of FATs. */ + uint8_t cFats; + /** 0x11 / 0x06: Max size of the root directory (0 for FAT32). */ + uint16_t cMaxRootDirEntries; + /** 0x13 / 0x08: Total sector count, zero if 32-bit count is used. */ + uint16_t cTotalSectors16; + /** 0x15 / 0x0a: Media ID. */ + uint8_t bMedia; + /** 0x16 / 0x0b: Number of sectors per FAT (0 for FAT32). */ + uint16_t cSectorsPerFat; +} FATBPB20; +#pragma pack() +AssertCompileSize(FATBPB20, 0xd); +/** Pointer to a DOS 2.0 BPB. */ +typedef FATBPB20 *PFATBPB20; +/** Pointer to a const DOS 2.0 BPB. */ +typedef FATBPB20 const *PCFATBPB20; + + +/** + * The DOS 3.0 BPB changes that survived. + */ +#pragma pack(1) +typedef struct FATBPB30CMN +{ + /** DOS v2.0 BPB. */ + FATBPB20 Bpb20; + /** 0x18 / 0x0d: Sectors per track. Zero means reserved and not used. */ + uint16_t cSectorsPerTrack; + /** 0x1a / 0x0f: Number of heads. Zero means reserved and not used. */ + uint16_t cTracksPerCylinder; +} FATBPB30CMN; +#pragma pack() +AssertCompileSize(FATBPB30CMN, 0x11); + +/** + * The DOS 3.0 BPB. + */ +#pragma pack(1) +typedef struct FATBPB30 +{ + /** DOS v3.0 BPB bits that survived. */ + FATBPB30CMN Core30; + /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero + * on unpartitioned media. */ + uint16_t cHiddenSectors; +} FATBPB30; +#pragma pack() +AssertCompileSize(FATBPB30, 0x13); +/** Pointer to a DOS 3.0 BPB. */ +typedef FATBPB30 *PFATBPB30; +/** Pointer to a const DOS 3.0 BPB. */ +typedef FATBPB30 const *PCFATBPB30; + +/** + * The DOS 3.0 BPB, flattened structure. + */ +#pragma pack(1) +typedef struct FATBPB30FLAT +{ + /** @name New in DOS 2.0 + * @{ */ + /** 0x0b / 0x00: The sector size in bytes. */ + uint16_t cbSector; + /** 0x0d / 0x02: Number of sectors per cluster. */ + uint8_t cSectorsPerCluster; + /** 0x0e / 0x03: Number of reserved sectors before the first FAT. */ + uint16_t cReservedSectors; + /** 0x10 / 0x05: Number of FATs. */ + uint8_t cFats; + /** 0x11 / 0x06: Max size of the root directory (0 for FAT32). */ + uint16_t cMaxRootDirEntries; + /** 0x13 / 0x08: Total sector count, zero if 32-bit count is used. */ + uint16_t cTotalSectors16; + /** 0x15 / 0x0a: Media ID. */ + uint8_t bMedia; + /** 0x16 / 0x0b: Number of sectors per FAT (0 for FAT32). */ + uint16_t cSectorsPerFat; + /** @} */ + /** @name New in DOS 3.0 + * @{ */ + /** 0x18 / 0x0d: Sectors per track. Zero means reserved and not used. */ + uint16_t cSectorsPerTrack; + /** 0x1a / 0x0f: Number of heads. Zero means reserved and not used. */ + uint16_t cTracksPerCylinder; + /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero + * on unpartitioned media. */ + uint16_t cHiddenSectors; + /** @} */ +} FATBPB30FLAT; +#pragma pack() +AssertCompileSize(FATBPB30FLAT, 0x13); +/** Pointer to a flattened DOS 3.0 BPB. */ +typedef FATBPB30FLAT *PFATBPB30FLAT; +/** Pointer to a const flattened DOS 3.0 BPB. */ +typedef FATBPB30FLAT const *PCFATBPB30FLAT; + + +/** + * The DOS 3.2 BPB. + */ +#pragma pack(1) +typedef struct FATBPB32 +{ + /** DOS v3.0 BPB. */ + FATBPB30 Bpb30; + /** 0x1e / 0x13: Number of sectors, including the hidden ones. This is ZERO + * in DOS 3.31+. */ + uint16_t cAnotherTotalSectors; +} FATBPB32; +#pragma pack() +AssertCompileSize(FATBPB32, 0x15); +/** Pointer to a DOS 3.2 BPB. */ +typedef FATBPB32 *PFATBPB32; +/** Pointer to const a DOS 3.2 BPB. */ +typedef FATBPB32 const *PCFATBPB32; + +/** + * The DOS 3.2 BPB, flattened structure. + */ +#pragma pack(1) +typedef struct FATBPB32FLAT +{ + /** @name New in DOS 2.0 + * @{ */ + /** 0x0b / 0x00: The sector size in bytes. */ + uint16_t cbSector; + /** 0x0d / 0x02: Number of sectors per cluster. */ + uint8_t cSectorsPerCluster; + /** 0x0e / 0x03: Number of reserved sectors before the first FAT. */ + uint16_t cReservedSectors; + /** 0x10 / 0x05: Number of FATs. */ + uint8_t cFats; + /** 0x11 / 0x06: Max size of the root directory (0 for FAT32). */ + uint16_t cMaxRootDirEntries; + /** 0x13 / 0x08: Total sector count, zero if 32-bit count is used. */ + uint16_t cTotalSectors16; + /** 0x15 / 0x0a: Media ID. */ + uint8_t bMedia; + /** 0x16 / 0x0b: Number of sectors per FAT (0 for FAT32). */ + uint16_t cSectorsPerFat; + /** @} */ + /** @name New in DOS 3.0 + * @{ */ + /** 0x18 / 0x0d: Sectors per track. Zero means reserved and not used. */ + uint16_t cSectorsPerTrack; + /** 0x1a / 0x0f: Number of heads. Zero means reserved and not used. */ + uint16_t cTracksPerCylinder; + /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero + * on unpartitioned media. */ + uint16_t cHiddenSectors; + /** @} */ + /** @name New in DOS 3.2 + * @{ */ + /** 0x1e / 0x13: Number of sectors, including the hidden ones. This is ZERO + * in DOS 3.31+. */ + uint16_t cAnotherTotalSectors; + /** @} */ +} FATBPB32FLAT; +#pragma pack() +AssertCompileSize(FATBPB32FLAT, 0x15); +/** Pointer to a flattened DOS 3.2 BPB. */ +typedef FATBPB32FLAT *PFATBPB32FLAT; +/** Pointer to a const flattened DOS 3.2 BPB. */ +typedef FATBPB32FLAT const *PCFATBPB32FLAT; + + +/** + * The DOS 3.31 BPB. + */ +#pragma pack(1) +typedef struct FATBPB331 +{ + /** DOS v3.0 BPB bits that survived. */ + FATBPB30CMN Core30; + /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero + * on unpartitioned media. Values higher than 65535 are complicated due to + * the field overlapping FATBPB32::cAnotherTotalSectors */ + uint32_t cHiddenSectors; + /** 0x20 / 0x15: Total logical sectors. Used if count >= 64K, otherwise + * FATBPB20::cTotalSectors16 is used. Zero if 64-bit value used with FAT32. */ + uint32_t cTotalSectors32; +} FATBPB331; +#pragma pack() +AssertCompileSize(FATBPB331, 0x19); +/** Pointer to a DOS 3.31 BPB. */ +typedef FATBPB331 *PFATBPB331; +/** Pointer to a const DOS 3.31 BPB. */ +typedef FATBPB331 const *PCFATBPB331; + +/** + * The DOS 3.31 BPB, flattened structure. + */ +#pragma pack(1) +typedef struct FATBPB331FLAT +{ + /** @name New in DOS 2.0 + * @{ */ + /** 0x0b / 0x00: The sector size in bytes. */ + uint16_t cbSector; + /** 0x0d / 0x02: Number of sectors per cluster. */ + uint8_t cSectorsPerCluster; + /** 0x0e / 0x03: Number of reserved sectors before the first FAT (0 for + * NTFS). */ + uint16_t cReservedSectors; + /** 0x10 / 0x05: Number of FATs (0 for NTFS). */ + uint8_t cFats; + /** 0x11 / 0x06: Max size of the root directory (0 for FAT32 & NTFS). */ + uint16_t cMaxRootDirEntries; + /** 0x13 / 0x08: Total sector count, zero if 32-bit count is used (and for + * NTFS). */ + uint16_t cTotalSectors16; + /** 0x15 / 0x0a: Media ID. */ + uint8_t bMedia; + /** 0x16 / 0x0b: Number of sectors per FAT (0 for FAT32 & NTFS). */ + uint16_t cSectorsPerFat; + /** @} */ + /** @name New in DOS 3.0 + * @{ */ + /** 0x18 / 0x0d: Sectors per track. Zero means reserved and not used. */ + uint16_t cSectorsPerTrack; + /** 0x1a / 0x0f: Number of heads. Zero means reserved and not used. */ + uint16_t cTracksPerCylinder; + /** @} */ + /** @name New in DOS 3.31 + * @{ */ + /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero + * on unpartitioned media. Values higher than 65535 are complicated due to + * the field overlapping FATBPB32::cAnotherTotalSectors */ + uint32_t cHiddenSectors; + /** 0x20 / 0x15: Total logical sectors. Used if count >= 64K, otherwise + * FATBPB20::cTotalSectors16 is used. Zero if 64-bit value used with FAT32. + * (Zero for NTFS). */ + uint32_t cTotalSectors32; + /** @} */ +} FATBPB331FLAT; +#pragma pack() +AssertCompileSize(FATBPB331FLAT, 0x19); +/** Pointer to a flattened DOS 3.31 BPB. */ +typedef FATBPB331FLAT *PFATBPB331FLAT; +/** Pointer to a const flattened DOS 3.31 BPB. */ +typedef FATBPB331FLAT const *PCFATBPB331FLAT; + + +/** + * Extended BIOS parameter block (EBPB). + */ +#pragma pack(1) +typedef struct FATEBPB +{ + /** The BPB. */ + FATBPB331FLAT Bpb; + + /** 0x24 / 0x19: BIOS INT13 pysical drive number. */ + uint8_t bInt13Drive; + /** 0x25 / 0x1a: Reserved. NT used bit 0 for indicating dirty FS, and bit 1 + * for surface scan. */ + uint8_t bReserved; + /** 0x26 / 0x1b: Extended boot signature, FATEBPB_SIGNATURE or + * FATEBPB_SIGNATURE_OLD. */ + uint8_t bExtSignature; + /** 0x27 / 0x1c: The volume serial number. */ + uint32_t uSerialNumber; + /** 0x2b / 0x20: The volume label (space padded). + * @remarks Not available with FATEBPB_SIGNATURE_OLD */ + char achLabel[11]; + /** 0x36 / 0x2b: The file system type (space padded). + * @remarks Not available with FATEBPB_SIGNATURE_OLD */ + char achType[8]; +} FATEBPB; +#pragma pack() +AssertCompileSize(FATEBPB, 0x33); +/** Pointer to an extended BIOS parameter block. */ +typedef FATEBPB *PFATEBPB; +/** Pointer to a const extended BIOS parameter block. */ +typedef FATEBPB const *PCFATEBPB; + +/** FATEBPB::bExtSignature value. */ +#define FATEBPB_SIGNATURE UINT8_C(0x29) +/** FATEBPB::bExtSignature value used by OS/2 1.0-1.1 and PC DOS 3.4. These + * does not have the volume and file system type. */ +#define FATEBPB_SIGNATURE_OLD UINT8_C(0x28) + +/**FATEBPB::achType value for FAT12. */ +#define FATEBPB_TYPE_FAT12 "FAT12 " +/**FATEBPB::achType value for FAT16. */ +#define FATEBPB_TYPE_FAT16 "FAT16 " +/**FATEBPB::achType value for FAT12/FAT16. */ +#define FATEBPB_TYPE_FAT "FAT32 " + + +/** + * FAT32 Extended BIOS parameter block (EBPB). + */ +#pragma pack(1) +typedef struct FAT32EBPB +{ + /** The BPB. */ + FATBPB331FLAT Bpb; + + /** 0x24 / 0x19: Number of sectors per FAT. + * @note To avoid confusion with the FATEBPB signature, values which result in + * 0x00280000 or 0x00290000 when masked by 0x00ff0000 must not be used. */ + uint32_t cSectorsPerFat32; + /** 0x28 / 0x1d: Flags pertaining to FAT mirroring and other stuff. */ + uint16_t fFlags; + /** 0x2a / 0x1f: FAT32 version number (FAT32EBPB_VERSION_0_0). */ + uint16_t uVersion; + /** 0x2c / 0x21: Cluster number of the root directory. */ + uint32_t uRootDirCluster; + /** 0x30 / 0x25: Logical sector number of the information sector. */ + uint16_t uInfoSectorNo; + /** 0x32 / 0x27: Logical sector number of boot sector copy. */ + uint16_t uBootSectorCopySectorNo; + /** 0x34 / 0x29: Reserved, zero (or 0xf6) filled, preserve. */ + uint8_t abReserved[12]; + + /** 0x40 / 0x35: BIOS INT13 pysical drive number + * @remarks Same as FATEBPB::bInt13Drive. */ + uint8_t bInt13Drive; + /** 0x41 / 0x36: Reserved. + * @remarks Same as FATEBPB::bReserved. */ + uint8_t bReserved; + /** 0x42 / 0x37: Extended boot signature (FATEBPB_SIGNATURE, or + * FATEBPB_SIGNATURE_OLD in some special cases). + * @remarks Same as FATEBPB::bExtSignature. */ + uint8_t bExtSignature; + /** 0x43 / 0x38: The volume serial number. + * @remarks Same as FATEBPB::uSerialNumber. */ + uint32_t uSerialNumber; + /** 0x47 / 0x3c: The volume label (space padded). + * @remarks Not available with FATEBPB_SIGNATURE_OLD + * @remarks Same as FATEBPB::achLabel. */ + char achLabel[11]; + /** 0x52 / 0x47: The file system type (space padded), or 64-bit logical sector + * count if both other count fields are zero. In the latter case, the type is + * moved to the OEM name field (FATBOOTSECTOR::achOemName). + * + * @remarks Not available with FATEBPB_SIGNATURE_OLD + * @remarks Same as FATEBPB::achType. */ + union + { + /** Type string variant. */ + char achType[8]; + /** Total sector count if 4G or higher. */ + uint64_t cTotalSectors64; + } u; +} FAT32EBPB; +#pragma pack() +AssertCompileSize(FAT32EBPB, 0x4f); +/** Pointer to a FAT32 extended BIOS parameter block. */ +typedef FAT32EBPB *PFAT32EBPB; +/** Pointer to a const FAT32 extended BIOS parameter block. */ +typedef FAT32EBPB const *PCFAT32EBPB; + +/** FAT32 version 0.0 (FAT32EBPB::uVersion). */ +#define FAT32EBPB_VERSION_0_0 UINT16_C(0x0000) + + +/** + * NTFS extended BIOS parameter block (NTFSEBPB). + */ +#pragma pack(1) +typedef struct NTFSEBPB +{ + /** The BPB. */ + FATBPB331FLAT Bpb; + + /** 0x24 / 0x19: BIOS INT13 pysical drive number. + * @note Same location as FATEBPB::bInt13Drive. */ + uint8_t bInt13Drive; + /** 0x25 / 0x1a: Reserved / flags */ + uint8_t bReserved; + /** 0x26 / 0x1b: Extended boot signature (NTFSEBPB_SIGNATURE). + * @note Same location as FATEBPB::bExtSignature. */ + uint8_t bExtSignature; + /** 0x27 / 0x1c: Reserved */ + uint8_t bReserved2; + + /** 0x28 / 0x1d: Number of sectors. */ + uint64_t cSectors; + /** 0x30 / 0x25: Logical cluster number of the master file table (MFT). */ + uint64_t uLcnMft; + /** 0x38 / 0x2d: Logical cluster number of the MFT mirror. */ + uint64_t uLcnMftMirror; + /** 0x40 / 0x35: Logical clusters per file record segment. + * This is a shift count if negative. */ + int8_t cClustersPerMftRecord; + /** 0x41 / 0x36: Reserved. */ + uint8_t abReserved3[3]; + /** 0x44 / 0x39: The default logical clusters count per index node. + * This is a shift count if negative. */ + int8_t cClustersPerIndexNode; + /** 0x45 / 0x3a: Reserved. */ + uint8_t abReserved4[3]; + /** 0x48 / 0x3d: Volume serial number. + * @note This is larger than the the FAT serial numbers. */ + uint64_t uSerialNumber; + /** 0x50 / 0x45: Checksum. */ + uint32_t uChecksum; +} NTFSEBPB; +#pragma pack() +AssertCompileSize(NTFSEBPB, 0x49); +/** Pointer to a NTFS extended BIOS parameter block. */ +typedef NTFSEBPB *PNTFSEBPB; +/** Pointer to a const NTFS extended BIOS parameter block. */ +typedef NTFSEBPB const *PCNTFSEBPB; + +/** NTFS EBPB signature (NTFSEBPB::bExtSignature). */ +#define NTFSEBPB_SIGNATURE UINT8_C(0x80) + + +/** + * FAT boot sector layout. + */ +#pragma pack(1) +typedef struct FATBOOTSECTOR +{ + /** 0x000: DOS 2.0+ jump sequence. */ + uint8_t abJmp[3]; + /** 0x003: OEM name (who formatted this volume). */ + char achOemName[8]; + /** 0x00b: The BIOS parameter block. + * This varies a lot in size. */ + union + { + FATBPB20 Bpb20; + FATBPB30FLAT Bpb30; + FATBPB32FLAT Bpb32; + FATBPB331FLAT Bpb331; + FATEBPB Ebpb; + FAT32EBPB Fat32Ebpb; + NTFSEBPB Ntfs; + } Bpb; + /** 0x05a: Bootloader code/data/stuff. */ + uint8_t abStuff[0x1a3]; + /** 0x1fd: Old drive number location (DOS 3.2-3.31). */ + uint8_t bOldInt13Drive; + /** 0x1fe: DOS signature (FATBOOTSECTOR_SIGNATURE). */ + uint16_t uSignature; +} FATBOOTSECTOR; +#pragma pack() +AssertCompileSize(FATBOOTSECTOR, 0x200); +/** Pointer to a FAT boot sector. */ +typedef FATBOOTSECTOR *PFATBOOTSECTOR; +/** Pointer to a const FAT boot sector. */ +typedef FATBOOTSECTOR const *PCFATBOOTSECTOR; + +/** Boot sector signature (FATBOOTSECTOR::uSignature). */ +#define FATBOOTSECTOR_SIGNATURE UINT16_C(0xaa55) + + + +/** + * FAT32 info sector (follows the boot sector). + */ +typedef struct FAT32INFOSECTOR +{ + /** 0x000: Signature \#1 (FAT32INFOSECTOR_SIGNATURE_1). */ + uint32_t uSignature1; + /** Reserved, should be zero. */ + uint8_t abReserved1[0x1E0]; + /** 0x1e4: Signature \#1 (FAT32INFOSECTOR_SIGNATURE_2). */ + uint32_t uSignature2; + /** 0x1e8: Last known number of free clusters (informational). */ + uint32_t cFreeClusters; + /** 0x1ec: Last allocated cluster number (informational). This could be used as + * an allocation hint when searching for a free cluster. */ + uint32_t cLastAllocatedCluster; + /** 0x1f0: Reserved, should be zero, preserve. */ + uint8_t abReserved2[12]; + /** 0x1fc: Signature \#3 (FAT32INFOSECTOR_SIGNATURE_3). */ + uint32_t uSignature3; +} FAT32INFOSECTOR; +AssertCompileSize(FAT32INFOSECTOR, 0x200); +/** Pointer to a FAT32 info sector. */ +typedef FAT32INFOSECTOR *PFAT32INFOSECTOR; +/** Pointer to a const FAT32 info sector. */ +typedef FAT32INFOSECTOR const *PCFAT32INFOSECTOR; + +#define FAT32INFOSECTOR_SIGNATURE_1 UINT32_C(0x41615252) +#define FAT32INFOSECTOR_SIGNATURE_2 UINT32_C(0x61417272) +#define FAT32INFOSECTOR_SIGNATURE_3 UINT32_C(0xaa550000) + + +/** @name Special FAT cluster numbers and limits. + * @{ */ +#define FAT_FIRST_DATA_CLUSTER 2 /**< The first data cluster. */ + +#define FAT_MAX_FAT12_TOTAL_CLUSTERS UINT32_C(0x00000ff6) /**< Maximum number of clusters in a 12-bit FAT . */ +#define FAT_MAX_FAT16_TOTAL_CLUSTERS UINT32_C(0x0000fff6) /**< Maximum number of clusters in a 16-bit FAT . */ +#define FAT_MAX_FAT32_TOTAL_CLUSTERS UINT32_C(0x0ffffff6) /**< Maximum number of clusters in a 32-bit FAT . */ + +#define FAT_LAST_FAT12_DATA_CLUSTER UINT32_C(0x00000ff5) /**< The last possible data cluster for FAT12. */ +#define FAT_LAST_FAT16_DATA_CLUSTER UINT32_C(0x0000fff5) /**< The last possible data cluster for FAT16. */ +#define FAT_LAST_FAT32_DATA_CLUSTER UINT32_C(0x0ffffff5) /**< The last possible data cluster for FAT32. */ + +#define FAT_MAX_FAT12_DATA_CLUSTERS UINT32_C(0x00000ff4) /**< Maximum number of data clusters for FAT12. */ +#define FAT_MAX_FAT16_DATA_CLUSTERS UINT32_C(0x0000fff4) /**< Maximum number of data clusters for FAT16. */ +#define FAT_MAX_FAT32_DATA_CLUSTERS UINT32_C(0x0ffffff4) /**< Maximum number of data clusters for FAT32. */ + +#define FAT_MIN_FAT12_DATA_CLUSTERS UINT32_C(0x00000001) /**< Maximum number of data clusters for FAT12. */ +#define FAT_MIN_FAT16_DATA_CLUSTERS UINT32_C(0x00000ff5) /**< Maximum number of data clusters for FAT16. */ +#define FAT_MIN_FAT32_DATA_CLUSTERS UINT32_C(0x0000fff5) /**< Maximum number of data clusters for FAT32. */ + +#define FAT_FIRST_FAT12_EOC UINT32_C(0x00000ff8) /**< The first end-of-file-cluster number for FAT12. */ +#define FAT_FIRST_FAT16_EOC UINT32_C(0x0000fff8) /**< The first end-of-file-cluster number for FAT16. */ +#define FAT_FIRST_FAT32_EOC UINT32_C(0x0ffffff8) /**< The first end-of-file-cluster number for FAT32. */ +/** @} */ + + +/** + * FAT directory entry. + */ +typedef struct FATDIRENTRY +{ + /** 0x00: The directory entry name. + * First character serves as a flag to indicate deleted or not. */ + uint8_t achName[8+3]; + /** 0x0b: Attributes (FAT_ATTR_XXX). */ + uint8_t fAttrib; + /** 0x0c: NT case flags (FATDIRENTRY_CASE_F_XXX). */ + uint8_t fCase; + /** 0x0d: Birth milliseconds (DOS 7.0+ w/VFAT). */ + uint8_t uBirthCentiseconds; + /** 0x0e: Birth time (DOS 7.0+ w/VFAT). */ + uint16_t uBirthTime; + /** 0x10: Birth date (DOS 7.0+ w/VFAT). */ + uint16_t uBirthDate; + /** 0x12: Access date (DOS 7.0+ w/ACCDATA in Config.sys). */ + uint16_t uAccessDate; + union + { + /** 0x14: High cluster word for FAT32. */ + uint16_t idxClusterHigh; + /** 0x14: Index of extended attributes (FAT16/FAT12). */ + uint16_t idxEAs; + } u; + /** 0x16: Modify time (PC-DOS 1.1+, MS-DOS 1.20+). */ + uint16_t uModifyTime; + /** 0x18: Modify date. */ + uint16_t uModifyDate; + /** 0x1a: The data cluster index. */ + uint16_t idxCluster; + /** 0x1c: The file size. */ + uint32_t cbFile; +} FATDIRENTRY; +AssertCompileSize(FATDIRENTRY, 0x20); +AssertCompileMemberOffset(FATDIRENTRY, fAttrib, 0x0b); +AssertCompileMemberOffset(FATDIRENTRY, fCase, 0x0c); +AssertCompileMemberOffset(FATDIRENTRY, uBirthCentiseconds, 0x0d); +AssertCompileMemberOffset(FATDIRENTRY, uBirthTime, 0x0e); +AssertCompileMemberOffset(FATDIRENTRY, uBirthDate, 0x10); +AssertCompileMemberOffset(FATDIRENTRY, uAccessDate, 0x12); +AssertCompileMemberOffset(FATDIRENTRY, u, 0x14); +AssertCompileMemberOffset(FATDIRENTRY, uModifyTime, 0x16); +AssertCompileMemberOffset(FATDIRENTRY, uModifyDate, 0x18); +AssertCompileMemberOffset(FATDIRENTRY, idxCluster, 0x1a); +AssertCompileMemberOffset(FATDIRENTRY, cbFile, 0x1c); +/** Pointer to a FAT directory entry. */ +typedef FATDIRENTRY *PFATDIRENTRY; +/** Pointer to a FAT directory entry. */ +typedef FATDIRENTRY const *PCFATDIRENTRY; + + +/** @name FAT_ATTR_XXX - FATDIRENTRY::fAttrib flags. + * @{ */ +#define FAT_ATTR_READONLY UINT8_C(0x01) +#define FAT_ATTR_HIDDEN UINT8_C(0x02) +#define FAT_ATTR_SYSTEM UINT8_C(0x04) +#define FAT_ATTR_VOLUME UINT8_C(0x08) +#define FAT_ATTR_DIRECTORY UINT8_C(0x10) +#define FAT_ATTR_ARCHIVE UINT8_C(0x20) +#define FAT_ATTR_DEVICE UINT8_C(0x40) +#define FAT_ATTR_RESERVED UINT8_C(0x80) +#define FAT_ATTR_NAME_SLOT UINT8_C(0x0f) /**< Special attribute value for FATDIRNAMESLOT. */ +/** @} */ + +/** @name FATDIRENTRY_CASE_F_XXX - FATDIRENTRY::fCase flags. + * @{ */ +/** Lower cased base name (first 8 chars). */ +#define FATDIRENTRY_CASE_F_LOWER_BASE UINT8_C(0x08) +/** Lower cased filename extension (last 3 chars). */ +#define FATDIRENTRY_CASE_F_LOWER_EXT UINT8_C(0x10) +/** @} */ + +/** @name FATDIRENTRY_CH0_XXX - FATDIRENTRY::achName[0] + * @{ */ +/** Deleted entry. */ +#define FATDIRENTRY_CH0_DELETED UINT8_C(0xe5) +/** End of used directory entries (MS-DOS 1.25+, PC-DOS 2.0+). */ +#define FATDIRENTRY_CH0_END_OF_DIR UINT8_C(0x00) +/** The special dot or dot-dot dir aliases (MS-DOS 1.40+, PC-DOS 2.0+). + * @remarks 0x2e is the ascii table entry of the '.' character. */ +#define FATDIRENTRY_CH0_DOT_ALIAS UINT8_C(0x2e) +/** Escaped 0xe5 leadcharacter (DOS 3.0+). */ +#define FATDIRENTRY_CH0_ESC_E5 UINT8_C(0x05) +/** @} */ + + +/** + * FAT directory alias name slot. + * + * Each slot holds 13 UTF-16 (/ UCS-2) characters, so it takes 20 slots to cover + * a 255 character long name. + */ +#pragma pack(1) +typedef struct FATDIRNAMESLOT +{ + /** The slot sequence number. */ + uint8_t idSlot; + /** The first 5 name chars. + * @remarks misaligned */ + RTUTF16 awcName0[5]; + /** Attributes (FAT_ATTR_XXX). */ + uint8_t fAttrib; + /** Always zero. */ + uint8_t fZero; + /** Alias checksum. */ + uint8_t bChecksum; + /** The next 6 name chars. */ + RTUTF16 awcName1[6]; + /** Always zero (usually cluster entry). */ + uint16_t idxZero; + /** The next 2 name chars. */ + RTUTF16 awcName2[2]; +} FATDIRNAMESLOT; +#pragma pack() +AssertCompileSize(FATDIRNAMESLOT, 0x20); +/** Pointer to a FAT directory entry. */ +typedef FATDIRNAMESLOT *PFATDIRNAMESLOT; +/** Pointer to a FAT directory entry. */ +typedef FATDIRNAMESLOT const *PCFATDIRNAMESLOT; + +/** Slot ID flag indicating that it's the first slot. */ +#define FATDIRNAMESLOT_FIRST_SLOT_FLAG UINT8_C(0x40) +/** Highest slot ID recognized. This allows for 260 characters, however many + * implementation limits it to 255 or 250. */ +#define FATDIRNAMESLOT_HIGHEST_SLOT_ID UINT8_C(0x14) +/** Max number of slots recognized. (This is the same as the higest slot ID + * because the 0 isn't a valid ID.) */ +#define FATDIRNAMESLOT_MAX_SLOTS FATDIRNAMESLOT_HIGHEST_SLOT_ID +/** Number of UTF-16 units per slot. */ +#define FATDIRNAMESLOT_CHARS_PER_SLOT (5 + 6 + 2) + + + +/** + * FAT directory entry union. + */ +typedef union FATDIRENTRYUNION +{ + /** Regular entry view. */ + FATDIRENTRY Entry; + /** Name slot view. */ + FATDIRNAMESLOT Slot; +} FATDIRENTRYUNION; +AssertCompileSize(FATDIRENTRYUNION, 0x20); +/** Pointer to a FAT directory entry union. */ +typedef FATDIRENTRYUNION *PFATDIRENTRYUNION; +/** Pointer to a const FAT directory entry union. */ +typedef FATDIRENTRYUNION const *PCFATDIRENTRYUNION; + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_fat_h */ + diff --git a/include/iprt/formats/hfs.h b/include/iprt/formats/hfs.h new file mode 100644 index 00000000..6201c45a --- /dev/null +++ b/include/iprt/formats/hfs.h @@ -0,0 +1,691 @@ +/** @file + * IPRT - Hierarchical File System (HFS). + */ + +/* + * Copyright (C) 2009-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_hfs_h +#define IPRT_INCLUDED_formats_hfs_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_fmt_hfs HFS - Hierarchical File System. + * @{ + */ + + +/** @name HFS signature words (HFSPlusVolumeHeader::signature) + * @{ */ +#define kHFSSigWord UINT16_C(0x4244) +#define kHFSPlusSigWord UINT16_C(0x482b) +#define kHFSXSigWord UINT16_C(0x4858) +/** @} */ + +/** @name HFS version numbers (HFSPlusVolumeHeader::version). + * @{ */ +#define kHFSPlusVersion UINT16_C(4) +#define kHFSXVersion UINT16_C(5) +/** @} */ + +/** @name HFS mount version numbers (HFSPlusVolumeHeader::lastMountedVersion). + * @{ */ +#define kHFSPlusMountVersion UINT32_C(0x31302e30) +#define kHFSJMountVersion UINT32_C(0x4846534a) +#define kFSKMountVersion UINT32_C(0x46534b21) +/** @} */ + +/** @name Hard link file creators & types. + * @{ */ +#define kHardLinkFileType UINT32_C(0x686c6e6b) +#define kHFSPlusCreator UINT32_C(0x6866732b) +/** @} */ + +/** @name Symlink file creators & types. + * @{ */ +#define kSymLinkFileType UINT32_C(0x736c6e6b) +#define kSymLinkCreator UINT32_C(0x72686170) +/** @} */ + +/** @name Name limits. + * @{ */ +#define kHFSMaxVolumeNameChars UINT8_C(0x1b) +#define kHFSMaxFileNameChars UINT8_C(0x1f) +#define kHFSPlusMaxFileNameChars UINT8_C(0xff) +#define kHFSMaxAttrNameLen UINT8_C(0x7f) +/** @} */ + +/** @name Extent descriptor record densities + * @{ */ +#define kHFSExtentDensity UINT8_C(3) +#define kHFSPlusExtentDensity UINT8_C(8) +/** @} */ + + +/** @name File IDs (various fileID members). + * @{ */ +#define kHFSRootParentID UINT32_C(0x00000001) +#define kHFSRootFolderID UINT32_C(0x00000002) +#define kHFSExtentsFileID UINT32_C(0x00000003) +#define kHFSCatalogFileID UINT32_C(0x00000004) +#define kHFSBadBlockFileID UINT32_C(0x00000005) +#define kHFSAllocationFileID UINT32_C(0x00000006) +#define kHFSStartupFileID UINT32_C(0x00000007) +#define kHFSAttributesFileID UINT32_C(0x00000008) +#define kHFSAttributeDataFileID UINT32_C(0x0000000c) +#define kHFSRepairCatalogFileID UINT32_C(0x0000000e) +#define kHFSBogusExtentFileID UINT32_C(0x0000000f) +#define kHFSFirstUserCatalogNodeID UINT32_C(0x00000010) +/** @} */ + +/** @name Catalog record types. + * @{ */ +#define kHFSFolderRecord UINT16_C(0x0100) +#define kHFSFileRecord UINT16_C(0x0200) +#define kHFSFolderThreadRecord UINT16_C(0x0300) +#define kHFSFileThreadRecord UINT16_C(0x0400) +#define kHFSPlusFolderRecord UINT16_C(0x0001) +#define kHFSPlusFileRecord UINT16_C(0x0002) +#define kHFSPlusFolderThreadRecord UINT16_C(0x0003) +#define kHFSPlusFileThreadRecord UINT16_C(0x0004) +/** @} */ + +/** @name File record bits and masks. + * @{ */ +#define kHFSFileLockedBit 0 +#define kHFSThreadExistsBit 1 +#define kHFSHasAttributesBit 2 +#define kHFSHasSecurityBit 3 +#define kHFSHasFolderCountBit 4 +#define kHFSHasLinkChainBit 5 +#define kHFSHasChildLinkBit 6 +#define kHFSHasDateAddedBit 7 + +#define kHFSFileLockedMask RT_BIT(kHFSFileLockedBit) +#define kHFSThreadExistsMask RT_BIT(kHFSThreadExistsBit) +#define kHFSHasAttributesMask RT_BIT(kHFSHasAttributesBit) +#define kHFSHasSecurityMask RT_BIT(kHFSHasSecurityBit) +#define kHFSHasFolderCountMask RT_BIT(kHFSHasFolderCountBit) +#define kHFSHasLinkChainMask RT_BIT(kHFSHasLinkChainBit) +#define kHFSHasChildLinkMask RT_BIT(kHFSHasChildLinkBit) +#define kHFSHasDateAddedMask RT_BIT(kHFSHasDateAddedBit) +/** @} */ + +/** @name Key and node lengths. + * @{ */ +#define kHFSPlusAttrKeyMaximumLength ( sizeof(HFSPlusAttrKey) - sizeof(uint16_t) ) +#define kHFSPlusAttrKeyMinimumLength ( kHFSPlusAttrKeyMaximumLength - (kHFSMaxAttrNameLen * sizeof(uint16_t)) ) +#define kHFSPlusExtentKeyMaximumLength ( sizeof(HFSPlusExtentKey) - sizeof(uint16_t), +#define kHFSExtentKeyMaximumLength ( sizeof(HFSExtentKey) - sizeof(uint8_t) ) +#define kHFSPlusCatalogKeyMaximumLength ( sizeof(HFSPlusCatalogKey) - sizeof(uint16_t) ) +#define kHFSPlusCatalogKeyMinimumLength ( kHFSPlusCatalogKeyMaximumLength - sizeof(HFSUniStr255) + sizeof(uint16_t) ) +#define kHFSCatalogKeyMaximumLength ( sizeof(HFSCatalogKey) - sizeof(uint8_t) ) +#define kHFSCatalogKeyMinimumLength ( kHFSCatalogKeyMaximumLength - kHFSMaxFileNameChars - 1 + sizeof(uint8_t) ) +#define kHFSPlusCatalogMinNodeSize UINT16_C(0x1000) +#define kHFSPlusExtentMinNodeSize UINT16_C(0x0200) +#define kHFSPlusAttrMinNodeSize UINT16_C(0x1000) +/** @} */ + +/** @name Volume Attribute bits and masks. + * @remarks HFS has only 16-bit wide field, HFS+ has 32-bit. + * @{ */ +#define kHFSVolumeHardwareLockBit 7 +#define kHFSVolumeUnmountedBit 8 +#define kHFSVolumeSparedBlocksBit 9 +#define kHFSVolumeNoCacheRequiredBit 10 +#define kHFSBootVolumeInconsistentBit 11 +#define kHFSCatalogNodeIDsReusedBit 12 +#define kHFSVolumeJournaledBit 13 +#define kHFSVolumeInconsistentBit 14 +#define kHFSVolumeSoftwareLockBit 15 +#define kHFSUnusedNodeFixBit 31 +#define kHFSContentProtectionBit 30 + +#define kHFSVolumeHardwareLockMask RT_BIT(kHFSVolumeHardwareLockBit) +#define kHFSVolumeUnmountedMask RT_BIT(kHFSVolumeUnmountedBit) +#define kHFSVolumeSparedBlocksMask RT_BIT(kHFSVolumeSparedBlocksBit) +#define kHFSVolumeNoCacheRequiredMask RT_BIT(kHFSVolumeNoCacheRequiredBit) +#define kHFSBootVolumeInconsistentMask RT_BIT(kHFSBootVolumeInconsistentBit) +#define kHFSCatalogNodeIDsReusedMask RT_BIT(kHFSCatalogNodeIDsReusedBit) +#define kHFSVolumeJournaledMask RT_BIT(kHFSVolumeJournaledBit) +#define kHFSVolumeInconsistentMask RT_BIT(kHFSVolumeInconsistentBit) +#define kHFSVolumeSoftwareLockMask RT_BIT(kHFSVolumeSoftwareLockBit) +#define kHFSUnusedNodeFixMask RT_BIT(kHFSUnusedNodeFixBit) +#define kHFSContentProtectionMask RT_BIT(kHFSContentProtectionBit) + +#define kHFSMDBAttributesMask UINT16_C(0x8380) +/** @} */ + +/** @name Misc + * @{ */ +#define kHFSUnusedNodesFixDate UINT32_C(0xc5ef2480) + +#define HFSPLUSMETADATAFOLDER "\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80HFS+ Private Data" +#define HFSPLUS_DIR_METADATA_FOLDER ".HFS+ Private Directory Data\xd" +#define HFS_INODE_PREFIX "iNode" +#define HFS_DELETE_PREFIX "temp" +#define HFS_DIRINODE_PREFIX "dir_" +#define FIRST_LINK_XATTR_NAME "com.apple.system.hfs.firstlink" +#define FIRST_LINK_XATTR_REC_SIZE ( sizeof(HFSPlusAttrData) + 10 ) + +/* {b3e20f39-f292-11d6-97a4-00306543ecac} */ +#define HFS_UUID_NAMESPACE_ID "\xB3\xE2\x0F\x39\xF2\x92\x11\xD6\x97\xA4\x00\x30\x65\x43\xEC\xAC" + +#define SET_HFS_TEXT_ENCODING(a_uHint) (UINT32_C(0x656e6300) | (uint8_t)(a_uHint)) +#define GET_HFS_TEXT_ENCODING(a_uHint) ( ((a_uHint) & UINT32_C(0xffffff00)) == UINT32_C(0x656e6300) \ + ? UINT32_C(0x000000ff)(a_uHint) : UINT32_MAX) +/** @} */ + +/** @name B-tree stuff. + * @{ */ +#define kMaxKeyLength 520 + +#define kBTLeafNode (-1) +#define kBTIndexNode 0 +#define kBTHeaderNode 1 +#define kBTMapNode 2 + +#define kBTBadCloseMask RT_BIT_32(0) +#define kBTBigKeysMask RT_BIT_32(1) +#define kBTVariableIndexKeysMask RT_BIT_32(2) + +/** @} */ + +/** @name B-tree compare types (BTHeaderRec::keyCompareType) + * @{ */ +#define kHFSCaseFolding UINT8_C(0xcf) +#define kHFSBinaryCompare UINT8_C(0xbc) +/** @} */ + +/** @name Journal stuff. + * @{ */ +#define JIB_RESERVED_SIZE ( sizeof(uint32_t) * 32 - 85 ) + +#define kJIJournalInFSMask RT_BIT_32(0) +#define kJIJournalOnOtherDeviceMask RT_BIT_32(1) +#define kJIJournalNeedInitMask RT_BIT_32(2) + +#define EXTJNL_CONTENT_TYPE_UUID "4a6f7572-6e61-11aa-aa11-00306543ecac" +/** @} */ + + + +typedef struct HFSUniStr255 +{ + uint16_t length; + RTUTF16 unicode[255]; +} HFSUniStr255; +AssertCompileSize(HFSUniStr255, 0x200); +typedef const HFSUniStr255 * ConstHFSUniStr255Param; + +#pragma pack(1) +typedef struct HFSExtentKey +{ + uint8_t keyLength; + uint8_t forkType; + uint32_t fileID; /**< Misaligned. */ + uint16_t startBLock; +} HFSExtentKey; +#pragma pack() +AssertCompileSize(HFSExtentKey, 8); + +typedef struct HFSPlusExtentKey +{ + uint16_t keyLength; + uint8_t forkType; + uint8_t pad; + uint32_t fileID; + uint32_t startBlock; +} HFSPlusExtentKey; +AssertCompileSize(HFSPlusExtentKey, 12); + +typedef struct HFSExtentDescriptor +{ + uint16_t startBlock; + uint16_t blockCount; +} HFSExtentDescriptor; +AssertCompileSize(HFSExtentDescriptor, 4); + +typedef struct HFSPlusExtentDescriptor +{ + uint32_t startBlock; + uint32_t blockCount; +} HFSPlusExtentDescriptor; +AssertCompileSize(HFSPlusExtentDescriptor, 8); + +typedef HFSExtentDescriptor HFSExtentRecord[3]; +typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[8]; + +typedef struct FndrFileInfo +{ + uint32_t fdType; + uint32_t fdCreator; + uint16_t fdFlags; + struct + { + int16_t v; + int16_t h; + } fdLocation; + uint16_t opaque; +} FndrFileInfo; +AssertCompileSize(FndrFileInfo, 16); + +typedef struct FndrDirInfo +{ + struct + { + int16_t top; + int16_t left; + int16_t bottom; + int16_t right; + } frRect; + uint16_t frFlags; + struct + { + int16_t v; + int16_t h; + } fdLocation; + uint16_t opaque; +} FndrDirInfo; +AssertCompileSize(FndrDirInfo, 16); + +typedef struct FndrOpaqueInfo +{ + int8_t opaque[16]; +} FndrOpaqueInfo; +AssertCompileSize(FndrOpaqueInfo, 16); + +typedef struct FndrExtendedFileInfo +{ + uint32_t reserved1; + uint32_t date_added; + uint16_t extended_flags; + uint16_t reserved2; + uint32_t reserved3; +} FndrExtendedFileInfo; +AssertCompileSize(FndrExtendedFileInfo, 16); + +typedef struct FndrExtendedDirInfo +{ + uint32_t point; + uint32_t date_added; + uint16_t extended_flags; + uint16_t reserved3; + uint32_t reserved4; +} FndrExtendedDirInfo; +AssertCompileSize(FndrExtendedDirInfo, 16); + +typedef struct HFSPlusForkData +{ + uint64_t logicalSize; + uint32_t clumpSize; + uint32_t totalBlocks; + HFSPlusExtentRecord extents; +} HFSPlusForkData; +AssertCompileSize(HFSPlusForkData, 80); + +typedef struct HFSPlusBSDInfo +{ + uint32_t ownerID; + uint32_t groupID; + uint8_t adminFlags; + uint8_t ownerFlags; + uint16_t fileMode; + union + { + uint32_t iNodeNum; + uint32_t linkCount; + uint32_t rawDevice; + } special; +} HFSPlusBSDInfo; +AssertCompileSize(HFSPlusBSDInfo, 16); + +#pragma pack(1) +typedef struct HFSCatalogKey +{ + uint8_t keyLength; + uint8_t reserved; + uint32_t parentID; /**< Misaligned. */ + uint8_t nodeName[kHFSMaxFileNameChars + 1]; +} HFSCatalogKey; +#pragma pack() +AssertCompileSize(HFSCatalogKey, 0x26); + +#pragma pack(1) +typedef struct HFSPlusCatalogKey +{ + uint16_t keyLength; + uint32_t parentID; /**< Misaligned. */ + HFSUniStr255 nodeName; +} HFSPlusCatalogKey; +#pragma pack() +AssertCompileSize(HFSPlusCatalogKey, 0x206); + +#pragma pack(1) +typedef struct HFSCatalogFolder +{ + int16_t recordType; + uint16_t flags; + uint16_t valence; + uint32_t folderID; /**< Misaligned. */ + uint32_t createDate; /**< Misaligned. */ + uint32_t modifyDate; /**< Misaligned. */ + uint32_t backupDate; /**< Misaligned. */ + FndrDirInfo userInfo; + FndrOpaqueInfo finderInfo; + uint32_t reserved[4]; /**< Misaligned. */ +} HFSCatalogFolder; +#pragma pack() +AssertCompileSize(HFSCatalogFolder, 70); + +typedef struct HFSPlusCatalogFolder +{ + int16_t recordType; + uint16_t flags; + uint32_t valence; + uint32_t folderID; + uint32_t createDate; + uint32_t contentModDate; + uint32_t attributeModDate; + uint32_t accessDate; + uint32_t backupDate; + HFSPlusBSDInfo bsdInfo; + FndrDirInfo userInfo; + FndrOpaqueInfo finderInfo; + uint32_t textEncoding; + uint32_t folderCount; +} HFSPlusCatalogFolder; +AssertCompileSize(HFSPlusCatalogFolder, 88); + +#pragma pack(1) +typedef struct HFSCatalogFile +{ + int16_t recordType; + uint8_t flags; + uint8_t fileType; + FndrFileInfo userInfo; + uint32_t fileID; + uint16_t dataStartBlock; + int32_t dataLogicalSize; /**< Misaligned. */ + int32_t dataPhysicalSize; /**< Misaligned. */ + uint16_t rsrcStartBlock; + int32_t rsrcLogicalSize; + int32_t rsrcPhysicalSize; + uint32_t createDate; + uint32_t modifyDate; + uint32_t backupDate; + FndrOpaqueInfo finderInfo; + uint16_t clumpSize; + HFSExtentRecord dataExtents; /**< Misaligned. */ + HFSExtentRecord rsrcExtents; /**< Misaligned. */ + uint32_t reserved; /**< Misaligned. */ +} HFSCatalogFile; +#pragma pack() +AssertCompileSize(HFSCatalogFile, 102); + +#pragma pack(1) +typedef struct HFSPlusCatalogFile +{ + int16_t recordType; + uint16_t flags; + uint32_t reserved1; + uint32_t fileID; + uint32_t createDate; + uint32_t contentModDate; + uint32_t attributeModDate; + uint32_t accessDate; + uint32_t backupDate; + HFSPlusBSDInfo bsdInfo; + FndrFileInfo userInfo; + FndrOpaqueInfo finderInfo; + uint32_t textEncoding; + uint32_t reserved2; + HFSPlusForkData dataFork; + HFSPlusForkData resourceFork; +} HFSPlusCatalogFile; +#pragma pack() +AssertCompileMemberAlignment(HFSPlusCatalogFile, dataFork, 8); +AssertCompileSize(HFSPlusCatalogFile, 248); + +#pragma pack(1) +typedef struct HFSCatalogThread +{ + int16_t recordType; + int32_t reserved[2]; + uint32_t parentID; + uint8_t nodeName[kHFSMaxFileNameChars + 1]; +} HFSCatalogThread; +#pragma pack() +AssertCompileSize(HFSCatalogThread, 46); + +typedef struct HFSPlusCatalogThread +{ + int16_t recordType; + int16_t reserved; + uint32_t parentID; + HFSUniStr255 nodeName; +} HFSPlusCatalogThread; +AssertCompileSize(HFSPlusCatalogThread, 0x208); + +typedef struct HFSPlusAttrForkData +{ + uint32_t recordType; + uint32_t reserved; + HFSPlusForkData theFork; +} HFSPlusAttrForkData; +AssertCompileSize(HFSPlusAttrForkData, 88); + +typedef struct HFSPlusAttrExtents +{ + uint32_t recordType; + uint32_t reserved; + HFSPlusExtentRecord extents; +} HFSPlusAttrExtents; +AssertCompileSize(HFSPlusAttrExtents, 72); + +#pragma pack(1) +typedef struct HFSPlusAttrData +{ + uint32_t recordType; + uint32_t reserved[2]; + uint32_t attrSize; + uint8_t attrData[2]; /**< Causes misaligned struct size. */ +} HFSPlusAttrData; +#pragma pack() +AssertCompileSize(HFSPlusAttrData, 18); + +#pragma pack(1) +typedef struct HFSPlusAttrInlineData +{ + uint32_t recordType; + uint32_t reserved; + uint32_t logicalSize; + uint8_t userData[2]; /**< Causes misaligned struct size. */ +} HFSPlusAttrInlineData; +#pragma pack() +AssertCompileSize(HFSPlusAttrInlineData, 14); + +typedef union HFSPlusAttrRecord +{ + uint32_t recordType; + HFSPlusAttrInlineData inlineData; + HFSPlusAttrData attrData; + HFSPlusAttrForkData forkData; + HFSPlusAttrExtents overflowExtents; +} HFSPlusAttrRecord; +AssertCompileSize(HFSPlusAttrRecord, 88); + +typedef struct HFSPlusAttrKey +{ + uint16_t keyLength; + uint16_t pad; + uint32_t fileID; + uint32_t startBlock; + uint16_t attrNameLen; + RTUTF16 attrName[kHFSMaxAttrNameLen]; +} HFSPlusAttrKey; +AssertCompileSize(HFSPlusAttrKey, 268); + +#pragma pack(1) +typedef struct HFSMasterDirectoryBlock +{ + uint16_t drSigWord; + uint32_t drCrDate; /**< Misaligned. */ + uint32_t drLsMod; /**< Misaligned. */ + uint16_t drAtrb; + uint16_t drNmFls; + uint16_t drVBMSt; + uint16_t drAllocPtr; + uint16_t drNmAlBlks; + uint32_t drAlBlkSiz; + uint32_t drClpSiz; + uint16_t drAlBlSt; + uint32_t drNxCNID; /**< Misaligned. */ + uint16_t drFreeBks; + uint8_t drVN[kHFSMaxVolumeNameChars + 1]; + uint32_t drVolBkUp; + uint16_t drVSeqNum; + uint32_t drWrCnt; /**< Misaligned. */ + uint32_t drXTClpSiz; /**< Misaligned. */ + uint32_t drCTClpSiz; /**< Misaligned. */ + uint16_t drNmRtDirs; + uint32_t drFilCnt; + uint32_t drDirCnt; + uint32_t drFndrInfo[8]; + uint16_t drEmbedSigWord; + HFSExtentDescriptor drEmbedExtent; + uint32_t drXTFlSize; /**< Misaligned. */ + HFSExtentRecord drXTExtRec; + uint32_t drCTFlSize; /**< Misaligned. */ + HFSExtentRecord drCTExtRec; +} HFSMasterDirectoryBlock; +#pragma pack() +AssertCompileSize(HFSMasterDirectoryBlock, 162); + +typedef struct HFSPlusVolumeHeader +{ + uint16_t signature; + uint16_t version; + uint32_t attributes; + uint32_t lastMountedVersion; + uint32_t journalInfoBlock; + uint32_t createDate; + uint32_t modifyDate; + uint32_t backupDate; + uint32_t checkedDate; + uint32_t fileCount; + uint32_t folderCount; + uint32_t blockSize; + uint32_t totalBlocks; + uint32_t freeBlocks; + uint32_t nextAllocation; + uint32_t rsrcClumpSize; + uint32_t dataClumpSize; + uint32_t nextCatalogID; + uint32_t writeCount; + uint64_t encodingsBitmap; + uint8_t finderInfo[32]; + HFSPlusForkData allocationFile; + HFSPlusForkData extentsFile; + HFSPlusForkData catalogFile; + HFSPlusForkData attributesFile; + HFSPlusForkData startupFile; +} HFSPlusVolumeHeader; +AssertCompileMemberAlignment(HFSPlusVolumeHeader, nextCatalogID, 8); +AssertCompileSize(HFSPlusVolumeHeader, 512); + +typedef union BTreeKey +{ + uint8_t length8; + uint16_t length16; + uint8_t rawData[kMaxKeyLength + 2]; +} BTreeKey; +AssertCompileSize(BTreeKey, 522); + +#pragma pack(1) +typedef struct BTNodeDescriptor +{ + uint32_t fLink; + uint32_t bLink; + int8_t kind; + uint8_t height; + uint16_t numRecords; + uint16_t reserved; /**< Causes struct size misalignment. */ +} BTNodeDescriptor; +#pragma pack() +AssertCompileSize(BTNodeDescriptor, 14); + +#pragma pack(1) +typedef struct BTHeaderRec +{ + uint16_t treeDepth; + uint32_t rootNode; /**< Misaligned. */ + uint32_t leafRecords; /**< Misaligned. */ + uint32_t firstLeafNode; /**< Misaligned. */ + uint32_t lastLeafNode; /**< Misaligned. */ + uint16_t nodeSize; + uint16_t maxKeyLength; + uint32_t totalNodes; /**< Misaligned. */ + uint32_t freeNodes; /**< Misaligned. */ + uint16_t reserved1; + uint32_t clumpSize; + uint8_t btreeType; + uint8_t keyCompareType; + uint32_t attributes; /**< Misaligned. */ + uint32_t reserved3[16]; /**< Misaligned. */ +} BTHeaderRec; +#pragma pack() +AssertCompileSize(BTHeaderRec, 106); + +#pragma pack(1) +typedef struct JournalInfoBlock +{ + uint32_t flags; + uint32_t devices_signature[8]; + uint64_t offset; /**< Misaligned (morons). */ + uint64_t size; /**< Misaligned. */ + char ext_jnl_uuid[37]; + char machine_serial_num[48]; + char reserved[JIB_RESERVED_SIZE]; +} JournalInfoBlock; +#pragma pack() +AssertCompileSize(JournalInfoBlock, 180); + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_hfs_h */ + diff --git a/include/iprt/formats/iso9660.h b/include/iprt/formats/iso9660.h new file mode 100644 index 00000000..4b67d497 --- /dev/null +++ b/include/iprt/formats/iso9660.h @@ -0,0 +1,1516 @@ +/* $Id: iso9660.h $ */ +/** @file + * IPRT, ISO 9660 File System + */ + +/* + * Copyright (C) 2017-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_iso9660_h +#define IPRT_INCLUDED_formats_iso9660_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_iso9660 ISO 9660 structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + + +/** The (default) logical sectors size of ISO 9660. */ +#define ISO9660_SECTOR_SIZE 2048 +/** The (default) sector offset mask of ISO 9660. */ +#define ISO9660_SECTOR_OFFSET_MASK 2047 +/** Maximum filename length (level 2 & 3). */ +#define ISO9660_MAX_NAME_LEN 30 + + +/** Accessor for ISO9660U16 and ISO9660U32 that retrievs the member value for + * the host endianess. */ +#ifdef RT_BIG_ENDIAN +# define ISO9660_GET_ENDIAN(a_pInt) ((a_pInt)->be) +#else +# define ISO9660_GET_ENDIAN(a_pInt) ((a_pInt)->le) +#endif + + +/** + * ISO 9660 16-bit unsigned integer type. + */ +typedef struct ISO9660U16 +{ + /** Little endian. */ + uint16_t le; + /** Big endian. */ + uint16_t be; +} ISO9660U16; +/** Pointer to an ISO 9660 16-bit unsigned integer type. */ +typedef ISO9660U16 *PISO9660U16; +/** Pointer to a const ISO 9660 16-bit unsigned integer type. */ +typedef ISO9660U16 const *PCISO9660U16; + +/** ISO 9660 big endian 16-bit unsigned integer. */ +typedef uint16_t ISO9660U16BE; + + +/** + * ISO 9660 32-bit unsigned integer type. + */ +typedef struct ISO9660U32 +{ + /** Little endian. */ + uint32_t le; + /** Big endian. */ + uint32_t be; +} ISO9660U32; +/** Pointer to an ISO 9660 32-bit unsigned integer type. */ +typedef ISO9660U32 *PISO9660U32; +/** Pointer to a const ISO 9660 32-bit unsigned integer type. */ +typedef ISO9660U32 const *PCISO9660U32; + +/** ISO 9660 little endian 32-bit unsigned integer. */ +typedef uint32_t ISO9660U32LE; +/** ISO 9660 big endian 32-bit unsigned integer. */ +typedef uint32_t ISO9660U32BE; + +/** + * ISO 9660 timestamp (date & time). + */ +typedef struct ISO9660TIMESTAMP +{ + /** 0x00: For digit year (0001-9999). */ + char achYear[4]; + /** 0x04: Month of the year (01-12). */ + char achMonth[2]; + /** 0x06: Day of month (01-31). */ + char achDay[2]; + /** 0x08: Hour of day (00-23). */ + char achHour[2]; + /** 0x0a: Minute of hour (00-59). */ + char achMinute[2]; + /** 0x0c: Second of minute (00-59). */ + char achSecond[2]; + /** 0x0e: Hundreth of second (00-99). */ + char achCentisecond[2]; + /** 0x10: The UTC (GMT) offset in 15 min units. */ + int8_t offUtc; +} ISO9660TIMESTAMP; +AssertCompileSize(ISO9660TIMESTAMP, 17); +/** Pointer to an ISO 9660 timestamp. */ +typedef ISO9660TIMESTAMP *PISO9660TIMESTAMP; +/** Pointer to a const ISO 9660 timestamp. */ +typedef ISO9660TIMESTAMP const *PCISO9660TIMESTAMP; + +/** + * ISO 9660 record timestamp (date & time). + */ +typedef struct ISO9660RECTIMESTAMP +{ + /** 0: Years since 1900. */ + uint8_t bYear; + /** 1: Month of year (1-12). */ + uint8_t bMonth; + /** 2: Day of month (1-31). */ + uint8_t bDay; + /** 3: Hour of day (0-23). */ + uint8_t bHour; + /** 4: Minute of hour (0-59). */ + uint8_t bMinute; + /** 5: Second of minute (0-59). */ + uint8_t bSecond; + /** 6: The UTC (GMT) offset in 15 min units. */ + int8_t offUtc; +} ISO9660RECTIMESTAMP; +AssertCompileSize(ISO9660RECTIMESTAMP, 7); +/** Pointer to an ISO 9660 record timestamp. */ +typedef ISO9660RECTIMESTAMP *PISO9660RECTIMESTAMP; +/** Pointer to a const ISO 9660 record timestamp. */ +typedef ISO9660RECTIMESTAMP const *PCISO9660RECTIMESTAMP; + + +/** + * ISO 9660 directory record. + */ +#pragma pack(1) +typedef struct ISO9660DIRREC +{ + /** 0x00: Length of this record in bytes. */ + uint8_t cbDirRec; + /** 0x01: Extended attribute record length in logical blocks. */ + uint8_t cExtAttrBlocks; + /** 0x02: Location of extent (logical block number). + * @note Misaligned. */ + ISO9660U32 offExtent; + /** 0x0a: Size of the data (file section). Does not include EAs. + * @note Misaligned. */ + ISO9660U32 cbData; + /** 0x12: Recording time and date. */ + ISO9660RECTIMESTAMP RecTime; + /** 0x19: File flags (ISO9660_FILE_FLAGS_XXX). */ + uint8_t fFileFlags; + /** 0x1a: File unit size for interlaved mode. */ + uint8_t bFileUnitSize; + /** 0x1b: Interlave gap size. */ + uint8_t bInterleaveGapSize; + /** 0x1c: Volume sequence number where the extent resides. */ + ISO9660U16 VolumeSeqNo; + /** 0x20: Length of file identifier field. */ + uint8_t bFileIdLength; + /** 0x21: File identifier (d-characters or d1-characters). */ + char achFileId[1]; + /* There are more fields following: + * - one byte optional padding so the following field is at an even boundrary. + * - system use field until cbDirRec is reached. + */ +} ISO9660DIRREC; +#pragma pack() +AssertCompileMemberOffset(ISO9660DIRREC, offExtent, 0x02); +AssertCompileMemberOffset(ISO9660DIRREC, cbData, 0x0a); +AssertCompileMemberOffset(ISO9660DIRREC, RecTime, 0x12); +AssertCompileMemberOffset(ISO9660DIRREC, fFileFlags, 0x19); +AssertCompileMemberOffset(ISO9660DIRREC, bFileIdLength, 0x20); +AssertCompileMemberOffset(ISO9660DIRREC, achFileId, 0x21); +/** Pointer to an ISO 9660 directory record. */ +typedef ISO9660DIRREC *PISO9660DIRREC; +/** Pointer to a const ISO 9660 directory record. */ +typedef ISO9660DIRREC const *PCISO9660DIRREC; + +/** @name ISO9660_FILE_FLAGS_XXX + * @{ */ +/** Existence - Hide the file from the user. */ +#define ISO9660_FILE_FLAGS_HIDDEN UINT8_C(0x01) +/** Directory - Indicates a directory as apposed to a regular file (0). */ +#define ISO9660_FILE_FLAGS_DIRECTORY UINT8_C(0x02) +/** Assocated File - Indicates that the file is an associated file. */ +#define ISO9660_FILE_FLAGS_ASSOCIATED_FILE UINT8_C(0x04) +/** Record - Indicates specified file content record format (see EAs). */ +#define ISO9660_FILE_FLAGS_RECORD UINT8_C(0x08) +/** Protection - Indicates owner/group or permission protection in EAs. */ +#define ISO9660_FILE_FLAGS_PROTECTION UINT8_C(0x10) +/** Reserved bit, MBZ. */ +#define ISO9660_FILE_FLAGS_RESERVED_5 UINT8_C(0x20) +/** Reserved bit, MBZ. */ +#define ISO9660_FILE_FLAGS_RESERVED_6 UINT8_C(0x40) +/** Multi-extend - Indicates that this isn't the final record for the file. + * @remarks Use for working around 4 GiB file size limitation. */ +#define ISO9660_FILE_FLAGS_MULTI_EXTENT UINT8_C(0x80) +/** @} */ + + +/** + * ISO 9660 path table record. + */ +#pragma pack(1) +typedef struct ISO9660PATHREC +{ + /** 0x00: Length of the achDirId field in bytes. */ + uint8_t cbDirId; + /** 0x01: Extended attribute record length in bytes? */ + uint8_t cbExtAttr; + /** 0x02: Location of extent (logical block number). + * @note Endianess depends on table. + * @note Misaligned. */ + uint32_t offExtent; + /** 0x06: Parent directory number. + * @note Endianess depends on table. */ + uint16_t idParentRec; + /** 0x08: Directory identifier (d-characters or d1-characters). */ + RT_FLEXIBLE_ARRAY_EXTENSION + char achDirId[RT_FLEXIBLE_ARRAY]; + /* There will be a zero padding byte following if the directory identifier length is odd. */ +} ISO9660PATHREC; +#pragma pack() +AssertCompileMemberOffset(ISO9660PATHREC, cbExtAttr, 0x01); +AssertCompileMemberOffset(ISO9660PATHREC, offExtent, 0x02); +AssertCompileMemberOffset(ISO9660PATHREC, idParentRec, 0x06); +AssertCompileMemberOffset(ISO9660PATHREC, achDirId, 0x08); +/** Pointer to an ISO 9660 path table record. */ +typedef ISO9660PATHREC *PISO9660PATHREC; +/** Pointer to a const ISO 9660 path table record. */ +typedef ISO9660PATHREC const *PCISO9660PATHREC; + + +/** + * ISO 9660 extended attribute record. + */ +typedef struct ISO9660EXATTRREC +{ + /** 0x000: The owner ID. */ + ISO9660U16 idOwner; + /** 0x004: The group ID. */ + ISO9660U16 idGroup; + /** 0x008: File permissions (ISO9660_PERM_XXX). */ + ISO9660U16BE fPermissions; + /** 0x00a: File creation timestamp. */ + ISO9660TIMESTAMP BirthTimestamp; + /** 0x01b: File modification timestamp. */ + ISO9660TIMESTAMP ModifyTimestamp; + /** 0x02c: File expiration timestamp. */ + ISO9660TIMESTAMP ExpireTimestamp; + /** 0x03d: File effective timestamp. */ + ISO9660TIMESTAMP EffectiveTimestamp; + /** 0x04e: Record format. */ + uint8_t bRecordFormat; + /** 0x04f: Record attributes. */ + uint8_t fRecordAttrib; + /** 0x050: Record length. */ + ISO9660U16 RecordLength; + /** 0x054: System identifier (a-characters or a1-characters). */ + char achSystemId[0x20]; + /** 0x074: System specific bytes. */ + uint8_t abSystemUse[64]; + /** 0x0b4: Extended attribute record version (ISO9660EXATTRREC_VERSION). */ + uint8_t bExtRecVersion; + /** 0x0b5: Length of escape sequences. */ + uint8_t cbEscapeSequences; + /** 0x0b6: Reserved for the future, MBZ. */ + uint8_t abReserved183[64]; + /** 0x0f6: Length of the application use field. */ + ISO9660U16 cbAppUse; + /** 0x0fa: Variable sized application use field. */ + RT_FLEXIBLE_ARRAY_EXTENSION + uint8_t abAppUse[RT_FLEXIBLE_ARRAY]; + /* This is followed by escape sequences with length given by cbEscapeSequnces. */ +} ISO9660EXATTRREC; +AssertCompileMemberOffset(ISO9660EXATTRREC, EffectiveTimestamp, 0x03d); +AssertCompileMemberOffset(ISO9660EXATTRREC, cbAppUse, 0x0f6); + +/** The ISO9660EXATTRREC::bExtRecVersion value. */ +#define ISO9660EXATTRREC_VERSION UINT8_C(0x01) + +/** @name ISO9660_PERM_XXX - ISO9660EXATTRREC::fPermissions + * @{ */ +/** @todo figure out this weird permission stuff... */ +/** @} */ + + +/** + * ISO 9660 volume descriptor header. + */ +typedef struct ISO9660VOLDESCHDR +{ + /** Descriptor type ISO9660VOLDESC_TYPE_XXX. */ + uint8_t bDescType; + /** Standard identifier 'CD001' */ + uint8_t achStdId[5]; + /** The descriptor version. */ + uint8_t bDescVersion; + /* (This is followed by the descriptor specific data). */ +} ISO9660VOLDESCHDR; +AssertCompileSize(ISO9660VOLDESCHDR, 7); +/** Pointer to a volume descriptor header. */ +typedef ISO9660VOLDESCHDR *PISO9660VOLDESCHDR; +/** Pointer to a const volume descriptor header. */ +typedef ISO9660VOLDESCHDR const *PCISO9660VOLDESCHDR; + +/** @name ISO9660VOLDESC_TYPE_XXX - volume descriptor types + * @{ */ +/** See ISO9660BOOTRECORD. */ +#define ISO9660VOLDESC_TYPE_BOOT_RECORD UINT8_C(0x00) +/** See ISO9660PRIMARYVOLDESC. */ +#define ISO9660VOLDESC_TYPE_PRIMARY UINT8_C(0x01) +/** See ISO9660SUPVOLDESC. */ +#define ISO9660VOLDESC_TYPE_SUPPLEMENTARY UINT8_C(0x02) +/** See ISO9660VOLPARTDESC. */ +#define ISO9660VOLDESC_TYPE_PARTITION UINT8_C(0x03) +/** Terminates the volume descriptor set. Has no data (zeros), version is 1. */ +#define ISO9660VOLDESC_TYPE_TERMINATOR UINT8_C(0xff) +/** @} */ + +/** The value of ISO9660VOLDESCHDR::achStdId */ +#define ISO9660VOLDESC_STD_ID "CD001" +#define ISO9660VOLDESC_STD_ID_0 'C' +#define ISO9660VOLDESC_STD_ID_1 'D' +#define ISO9660VOLDESC_STD_ID_2 '0' +#define ISO9660VOLDESC_STD_ID_3 '0' +#define ISO9660VOLDESC_STD_ID_4 '1' + + + +/** + * ISO 9660 boot record (volume descriptor). + */ +typedef struct ISO9660BOOTRECORD +{ + /** The volume descriptor header. + * Type is ISO9660VOLDESC_TYPE_BOOT_RECORD and version + * ISO9660BOOTRECORD_VERSION. */ + ISO9660VOLDESCHDR Hdr; + /** Boot system identifier string (a-characters). */ + char achBootSystemId[32]; + /** Boot identifier (a-characters). */ + char achBootId[32]; + /** Boot system specific content. */ + uint8_t abBootSystemSpecific[1977]; +} ISO9660BOOTRECORD; +AssertCompileSize(ISO9660BOOTRECORD, ISO9660_SECTOR_SIZE); +/** Pointer to an ISO 9660 boot record. */ +typedef ISO9660BOOTRECORD *PISO9660BOOTRECORD; +/** Pointer to a const ISO 9660 boot record. */ +typedef ISO9660BOOTRECORD const *PCISO9660BOOTRECORD; + +/** The value of ISO9660BOOTRECORD::Hdr.uDescVersion. */ +#define ISO9660BOOTRECORD_VERSION UINT8_C(1) + + +/** + * ISO 9660 boot record (volume descriptor), El Torito variant. + */ +#pragma pack(1) +typedef struct ISO9660BOOTRECORDELTORITO +{ + /** 0x000: The volume descriptor header. + * Type is ISO9660VOLDESC_TYPE_BOOT_RECORD and version + * ISO9660BOOTRECORD_VERSION. */ + ISO9660VOLDESCHDR Hdr; + /** 0x007: Boot system identifier string, + * zero padded ISO9660BOOTRECORDELTORITO_BOOT_SYSTEM_ID. */ + char achBootSystemId[32]; + /** 0x027: Boot identifier - all zeros. */ + char achBootId[32]; + /** 0x047: Boot catalog location (block offset), always (?) little endian. + * @note Misaligned. */ + uint32_t offBootCatalog; + /** 0x04b: Unused - all zeros. */ + uint8_t abBootSystemSpecific[1973]; +} ISO9660BOOTRECORDELTORITO; +#pragma pack() +AssertCompileSize(ISO9660BOOTRECORDELTORITO, ISO9660_SECTOR_SIZE); +/** Pointer to an ISO 9660 El Torito boot record. */ +typedef ISO9660BOOTRECORDELTORITO *PISO9660BOOTRECORDELTORITO; +/** Pointer to a const ISO 9660 El Torito boot record. */ +typedef ISO9660BOOTRECORDELTORITO const *PCISO9660BOOTRECORDELTORITO; + +/** The value of ISO9660BOOTRECORDELTORITO::achBootSystemId (zero padded). */ +#define ISO9660BOOTRECORDELTORITO_BOOT_SYSTEM_ID "EL TORITO SPECIFICATION" + + +/** + * ISO 9660 primary volume descriptor. + */ +typedef struct ISO9660PRIMARYVOLDESC +{ + /** 0x000: The volume descriptor header. + * Type is ISO9660VOLDESC_TYPE_PRIMARY and version + * ISO9660PRIMARYVOLDESC_VERSION. */ + ISO9660VOLDESCHDR Hdr; + /** 0x007: Explicit alignment zero padding. */ + uint8_t bPadding8; + /** 0x008: System identifier (a-characters). */ + char achSystemId[32]; + /** 0x028: Volume identifier (d-characters). */ + char achVolumeId[32]; + /** 0x048: Unused field, zero filled. */ + ISO9660U32 Unused73; + /** 0x050: Volume space size in logical blocks (cbLogicalBlock). */ + ISO9660U32 VolumeSpaceSize; + /** 0x058: Unused field(s), zero filled. */ + uint8_t abUnused89[32]; + /** 0x078: The number of volumes in the volume set. */ + ISO9660U16 cVolumesInSet; + /** 0x07c: Volume sequence number. */ + ISO9660U16 VolumeSeqNo; + /** 0x080: Logical block size in bytes. */ + ISO9660U16 cbLogicalBlock; + /** 0x084: Path table size. */ + ISO9660U32 cbPathTable; + /** 0x08c: Type L(ittle endian) path table location (block offset). */ + ISO9660U32LE offTypeLPathTable; + /** 0x090: Optional type L(ittle endian) path table location (block offset). */ + ISO9660U32LE offOptionalTypeLPathTable; + /** 0x094: Type M (big endian) path table location (block offset). */ + ISO9660U32BE offTypeMPathTable; + /** 0x098: Optional type M (big endian) path table location (block offset). */ + ISO9660U32BE offOptionalTypeMPathTable; + /** 0x09c: Directory entry for the root directory (union). */ + union + { + uint8_t ab[34]; + ISO9660DIRREC DirRec; + } RootDir; + /** 0x0be: Volume set identifier (d-characters). */ + char achVolumeSetId[128]; + /** 0x13e: Publisher identifier (a-characters). Alternatively, it may refere to + * a file in the root dir if it starts with 0x5f and restricts itself to 8 + * d-characters. */ + char achPublisherId[128]; + /** 0x1be: Data preparer identifier (a-characters). + * Same file reference alternative as previous field. */ + char achDataPreparerId[128]; + /** 0x23e: Application identifier (a-characters). + * Same file reference alternative as previous field. */ + char achApplicationId[128]; + /** 0x2be: Copyright (root) file identifier (d-characters). + * All spaces if none. */ + char achCopyrightFileId[37]; + /** 0x2e3: Abstract (root) file identifier (d-characters). + * All spaces if none. */ + char achAbstractFileId[37]; + /** 0x308: Bibliographic file identifier (d-characters). + * All spaces if none. */ + char achBibliographicFileId[37]; + /** 0x32d: Volume creation date and time. */ + ISO9660TIMESTAMP BirthTime; + /** 0x33e: Volume modification date and time. */ + ISO9660TIMESTAMP ModifyTime; + /** 0x34f: Volume (data) expiration date and time. + * If not specified, don't regard data as obsolete. */ + ISO9660TIMESTAMP ExpireTime; + /** 0x360: Volume (data) effective date and time. + * If not specified, info can be used immediately. */ + ISO9660TIMESTAMP EffectiveTime; + /** 0x371: File structure version (ISO9660_FILE_STRUCTURE_VERSION). */ + uint8_t bFileStructureVersion; + /** 0x372: Reserve for future, MBZ. */ + uint8_t bReserved883; + /** 0x373: Reserve for future. + * mkisofs & genisoimage & libisofs seems to space pad this most of the time. + * Microsoft image (2.56) zero pads it. isomd5sum uses it to store checksum + * info for the iso and space pads it. */ + uint8_t abAppUse[512]; + /** 0x573: Reserved for future standardization, MBZ. */ + uint8_t abReserved1396[653]; +} ISO9660PRIMARYVOLDESC; +AssertCompileSize(ISO9660PRIMARYVOLDESC, ISO9660_SECTOR_SIZE); +/** Pointer to a ISO 9660 primary volume descriptor. */ +typedef ISO9660PRIMARYVOLDESC *PISO9660PRIMARYVOLDESC; +/** Pointer to a const ISO 9660 primary volume descriptor. */ +typedef ISO9660PRIMARYVOLDESC const *PCISO9660PRIMARYVOLDESC; + +/** The value of ISO9660PRIMARYVOLDESC::Hdr.uDescVersion. */ +#define ISO9660PRIMARYVOLDESC_VERSION UINT8_C(1) +/** The value of ISO9660PRIMARYVOLDESC::bFileStructureVersion and + * ISO9660SUPVOLDESC::bFileStructureVersion. */ +#define ISO9660_FILE_STRUCTURE_VERSION UINT8_C(1) + + + +/** + * ISO 9660 supplementary volume descriptor. + * + * This is in the large parts identicial to the primary descriptor, except it + * have a few more fields where the primary one has reserved spaces. + */ +typedef struct ISO9660SUPVOLDESC +{ + /** 0x000: The volume descriptor header. + * Type is ISO9660VOLDESC_TYPE_SUPPLEMENTARY and version + * ISO9660SUPVOLDESC_VERSION. */ + ISO9660VOLDESCHDR Hdr; + /** 0x007: Volume flags (ISO9660SUPVOLDESC_VOL_F_XXX). + * @note This is reserved in the primary volume descriptor. */ + uint8_t fVolumeFlags; + /** 0x008: System identifier (a1-characters) of system that can act upon + * sectors 0 thru 15. + * @note Purpose differs from primary description. */ + char achSystemId[32]; + /** 0x028: Volume identifier (d1-characters). + * @note Character set differs from primary description. */ + char achVolumeId[32]; + /** 0x048: Unused field, zero filled. */ + ISO9660U32 Unused73; + /** 0x050: Volume space size in logical blocks (cbLogicalBlock). */ + ISO9660U32 VolumeSpaceSize; + /** 0x058: Escape sequences. + * Complicated stuff, see ISO 2022 and ECMA-35. + * @note This is reserved in the primary volume descriptor. */ + uint8_t abEscapeSequences[32]; + /** 0x078: The number of volumes in the volume set. */ + ISO9660U16 cVolumesInSet; + /** 0x07c: Volume sequence number. */ + ISO9660U16 VolumeSeqNo; + /** 0x080: Logical block size in bytes. */ + ISO9660U16 cbLogicalBlock; + /** 0x084: Path table size. */ + ISO9660U32 cbPathTable; + /** 0x08c: Type L(ittle endian) path table location (block offset). */ + ISO9660U32LE offTypeLPathTable; + /** 0x090: Optional type L(ittle endian) path table location (block offset). */ + ISO9660U32LE offOptionalTypeLPathTable; + /** 0x094: Type M (big endian) path table location (block offset). */ + ISO9660U32BE offTypeMPathTable; + /** 0x098: Optional type M (big endian) path table location (block offset). */ + ISO9660U32BE offOptionalTypeMPathTable; + /** 0x09c: Directory entry for the root directory (union). */ + union + { + uint8_t ab[34]; + ISO9660DIRREC DirRec; + } RootDir; + /** 0x0be: Volume set identifier (d1-characters). + * @note Character set differs from primary description. */ + char achVolumeSetId[128]; + /** 0x13e: Publisher identifier (a1-characters). Alternatively, it may refere + * to a file in the root dir if it starts with 0x5f and restricts itself to 8 + * d1-characters. + * @note Character set differs from primary description. */ + char achPublisherId[128]; + /** 0x1be: Data preparer identifier (a1-characters). + * Same file reference alternative as previous field. + * @note Character set differs from primary description. */ + char achDataPreparerId[128]; + /** 0x23e: Application identifier (a1-characters). + * Same file reference alternative as previous field. + * @note Character set differs from primary description. */ + char achApplicationId[128]; + /** 0x2be: Copyright (root) file identifier (d1-characters). + * All spaces if none. + * @note Character set differs from primary description. */ + char achCopyrightFileId[37]; + /** 0x2e3: Abstract (root) file identifier (d1-characters). + * All spaces if none. + * @note Character set differs from primary description. */ + char achAbstractFileId[37]; + /** 0x308: Bibliographic file identifier (d1-characters). + * All spaces if none. + * @note Character set differs from primary description. */ + char achBibliographicFileId[37]; + /** 0x32d: Volume creation date and time. */ + ISO9660TIMESTAMP BirthTime; + /** 0x33e: Volume modification date and time. */ + ISO9660TIMESTAMP ModifyTime; + /** 0x34f: Volume (data) expiration date and time. + * If not specified, don't regard data as obsolete. */ + ISO9660TIMESTAMP ExpireTime; + /** 0x360: Volume (data) effective date and time. + * If not specified, info can be used immediately. */ + ISO9660TIMESTAMP EffectiveTime; + /** 0x371: File structure version (ISO9660_FILE_STRUCTURE_VERSION). */ + uint8_t bFileStructureVersion; + /** 0x372: Reserve for future, MBZ. */ + uint8_t bReserved883; + /** 0x373: Reserve for future, MBZ. */ + uint8_t abAppUse[512]; + /** 0x573: Reserved for future standardization, MBZ. */ + uint8_t abReserved1396[653]; +} ISO9660SUPVOLDESC; +AssertCompileSize(ISO9660SUPVOLDESC, ISO9660_SECTOR_SIZE); +/** Pointer to a ISO 9660 supplementary volume descriptor. */ +typedef ISO9660SUPVOLDESC *PISO9660SUPVOLDESC; +/** Pointer to a const ISO 9660 supplementary volume descriptor. */ +typedef ISO9660SUPVOLDESC const *PCISO9660SUPVOLDESC; +/** The value of ISO9660SUPVOLDESC::Hdr.uDescVersion. */ +#define ISO9660SUPVOLDESC_VERSION UINT8_C(1) + +/** @name ISO9660SUPVOLDESC_VOL_F_XXX - ISO9660SUPVOLDESC::fVolumeFlags + * @{ */ +#define ISO9660SUPVOLDESC_VOL_F_ESC_ONLY_REG UINT8_C(0x00) +#define ISO9660SUPVOLDESC_VOL_F_ESC_NOT_REG UINT8_C(0x01) +/** @} */ + + + +/** + * ISO 9660 volume partition descriptor. + */ +typedef struct ISO9660VOLPARTDESC +{ + /** 0x000: The volume descriptor header. + * Type is ISO9660VOLDESC_TYPE_PARTITION and version + * ISO9660VOLPARTDESC_VERSION. */ + ISO9660VOLDESCHDR Hdr; + /** 0x007: Alignment padding. */ + uint8_t bPadding8; + /** 0x008: System identifier (a-characters). */ + char achSystemId[32]; + /** 0x028: Volume partition identifier (d-characters). */ + char achVolumePartitionId[32]; + /** 0x048: The location of the partition (logical block number). */ + ISO9660U32 offVolumePartition; + /** 0x050: The partition size in logical blocks (cbLogicalBlock). */ + ISO9660U32 VolumePartitionSize; + /** 0x058: System specific data. */ + uint8_t achSystemUse[1960]; +} ISO9660VOLPARTDESC; +AssertCompileSize(ISO9660VOLPARTDESC, ISO9660_SECTOR_SIZE); +/** Pointer to an ISO 9660 volume partition description. */ +typedef ISO9660VOLPARTDESC *PISO9660VOLPARTDESC; +/** Pointer to a const ISO 9660 volume partition description. */ +typedef ISO9660VOLPARTDESC const *PCISO9660VOLPARTDESC; +/** The value of ISO9660VOLPARTDESC::Hdr.uDescVersion. */ +#define ISO9660VOLPARTDESC_VERSION UINT8_C(1) + + + +/** @name Joliet escape sequence identifiers. + * + * These bytes appears in the supplementary volume descriptor field + * abEscapeSequences. The ISO9660SUPVOLDESC_VOL_F_ESC_NOT_REG flags will not + * be set. + * + * @{ */ +#define ISO9660_JOLIET_ESC_SEQ_0 UINT8_C(0x25) /**< First escape sequence byte.*/ +#define ISO9660_JOLIET_ESC_SEQ_1 UINT8_C(0x2f) /**< Second escape sequence byte.*/ +#define ISO9660_JOLIET_ESC_SEQ_2_LEVEL_1 UINT8_C(0x40) /**< Third escape sequence byte: level 1 */ +#define ISO9660_JOLIET_ESC_SEQ_2_LEVEL_2 UINT8_C(0x43) /**< Third escape sequence byte: level 2 */ +#define ISO9660_JOLIET_ESC_SEQ_2_LEVEL_3 UINT8_C(0x45) /**< Third escape sequence byte: level 3 */ +/** @} */ + + +/** The size of an El Torito boot catalog entry. */ +#define ISO9660_ELTORITO_ENTRY_SIZE UINT32_C(0x20) + +/** + * El Torito boot catalog: Validation entry. + * + * This is the first entry in the boot catalog. It is followed by a + * ISO9660ELTORITODEFAULTENTRY, which in turn is followed by a + * ISO9660ELTORITOSECTIONHEADER. + */ +typedef struct ISO9660ELTORITOVALIDATIONENTRY +{ + /** 0x00: The header ID (ISO9660_ELTORITO_HEADER_ID_VALIDATION_ENTRY). */ + uint8_t bHeaderId; + /** 0x01: The platform ID (ISO9660_ELTORITO_PLATFORM_ID_XXX). */ + uint8_t bPlatformId; + /** 0x02: Reserved, MBZ. */ + uint16_t u16Reserved; + /** 0x04: String ID of the developer of the CD/DVD-ROM. */ + char achId[24]; + /** 0x1c: The checksum. */ + uint16_t u16Checksum; + /** 0x1e: Key byte 1 (ISO9660_ELTORITO_KEY_BYTE_1). */ + uint8_t bKey1; + /** 0x1f: Key byte 2 (ISO9660_ELTORITO_KEY_BYTE_2). */ + uint8_t bKey2; +} ISO9660ELTORITOVALIDATIONENTRY; +AssertCompileSize(ISO9660ELTORITOVALIDATIONENTRY, ISO9660_ELTORITO_ENTRY_SIZE); +/** Pointer to an El Torito validation entry. */ +typedef ISO9660ELTORITOVALIDATIONENTRY *PISO9660ELTORITOVALIDATIONENTRY; +/** Pointer to a const El Torito validation entry. */ +typedef ISO9660ELTORITOVALIDATIONENTRY const *PCISO9660ELTORITOVALIDATIONENTRY; + +/** ISO9660ELTORITOVALIDATIONENTRY::bKey1 value. */ +#define ISO9660_ELTORITO_KEY_BYTE_1 UINT8_C(0x55) +/** ISO9660ELTORITOVALIDATIONENTRY::bKey2 value. */ +#define ISO9660_ELTORITO_KEY_BYTE_2 UINT8_C(0xaa) + + +/** @name ISO9660_ELTORITO_HEADER_ID_XXX - header IDs. + * @{ */ +/** Header ID for a ISO9660ELTORITOVALIDATIONENTRY. */ +#define ISO9660_ELTORITO_HEADER_ID_VALIDATION_ENTRY UINT8_C(0x01) +/** Header ID for a ISO9660ELTORITOSECTIONHEADER. */ +#define ISO9660_ELTORITO_HEADER_ID_SECTION_HEADER UINT8_C(0x90) +/** Header ID for the final ISO9660ELTORITOSECTIONHEADER. */ +#define ISO9660_ELTORITO_HEADER_ID_FINAL_SECTION_HEADER UINT8_C(0x91) +/** @} */ + + +/** @name ISO9660_ELTORITO_PLATFORM_ID_XXX - El Torito Platform IDs + * @{ */ +#define ISO9660_ELTORITO_PLATFORM_ID_X86 UINT8_C(0x00) /**< 80x86 */ +#define ISO9660_ELTORITO_PLATFORM_ID_PPC UINT8_C(0x01) /**< PowerPC */ +#define ISO9660_ELTORITO_PLATFORM_ID_MAC UINT8_C(0x02) /**< Mac */ +#define ISO9660_ELTORITO_PLATFORM_ID_EFI UINT8_C(0xef) /**< UEFI */ +/** @} */ + + +/** + * El Torito boot catalog: Section header entry. + * + * A non-final section header entry is followed by + * ISO9660ELTORITOSECTIONHEADER::cEntries ISO9660ELTORITOSECTIONTENTRY instances. + */ +typedef struct ISO9660ELTORITOSECTIONHEADER +{ + /** 0x00: Header ID - ISO9660_ELTORITO_HEADER_ID_SECTION_HEADER or + * ISO9660_ELTORITO_HEADER_ID_FINAL_SECTION_HEADER (if final). */ + uint8_t bHeaderId; + /** 0x01: The platform ID (ISO9660_ELTORITO_PLATFORM_ID_XXX). */ + uint8_t bPlatformId; + /** 0x02: Number of entries in this section (i.e. following this header). */ + uint16_t cEntries; + /** 0x04: String ID for the section. */ + char achSectionId[28]; +} ISO9660ELTORITOSECTIONHEADER; +AssertCompileSize(ISO9660ELTORITOSECTIONHEADER, ISO9660_ELTORITO_ENTRY_SIZE); +/** Pointer to an El Torito section header entry. */ +typedef ISO9660ELTORITOSECTIONHEADER *PISO9660ELTORITOSECTIONHEADER; +/** Pointer to a const El Torito section header entry. */ +typedef ISO9660ELTORITOSECTIONHEADER const *PCISO9660ELTORITOSECTIONHEADER; + + +/** + * El Torito boot catalog: Default (initial) entry. + * + * Followed by ISO9660ELTORITOSECTIONHEADER. + * + * Differs from ISO9660ELTORITOSECTIONENTRY in that it doesn't have a + * selection criteria and no media flags (only type). + */ +typedef struct ISO9660ELTORITODEFAULTENTRY +{ + /** 0x00: Boot indicator (ISO9660_ELTORITO_BOOT_INDICATOR_XXX). */ + uint8_t bBootIndicator; + /** 0x01: Boot media type. The first four bits are defined by + * ISO9660_ELTORITO_BOOT_MEDIA_TYPE_XXX, whereas the top four bits MBZ. */ + uint8_t bBootMediaType; + /** 0x02: Load segment - load address divided by 0x10. */ + uint16_t uLoadSeg; + /** 0x04: System type from image partition table. */ + uint8_t bSystemType; + /** 0x05: Unused, MBZ. */ + uint8_t bUnused; + /** 0x06: Number of emulated 512 byte sectors to load. */ + uint16_t cEmulatedSectorsToLoad; + /** 0x08: Image location in the ISO (block offset), always (?) little endian. */ + uint32_t offBootImage; + /** 0x0c: Reserved, MBZ */ + uint8_t abReserved[20]; +} ISO9660ELTORITODEFAULTENTRY; +AssertCompileSize(ISO9660ELTORITODEFAULTENTRY, ISO9660_ELTORITO_ENTRY_SIZE); +/** Pointer to an El Torito default (initial) entry. */ +typedef ISO9660ELTORITODEFAULTENTRY *PISO9660ELTORITODEFAULTENTRY; +/** Pointer to a const El Torito default (initial) entry. */ +typedef ISO9660ELTORITODEFAULTENTRY const *PCISO9660ELTORITODEFAULTENTRY; + + +/** + * El Torito boot catalg: Section entry. + */ +typedef struct ISO9660ELTORITOSECTIONENTRY +{ + /** 0x00: Boot indicator (ISO9660_ELTORITO_BOOT_INDICATOR_XXX). */ + uint8_t bBootIndicator; + /** 0x01: Boot media type and flags. The first four bits are defined by + * ISO9660_ELTORITO_BOOT_MEDIA_TYPE_XXX and the top four bits by + * ISO9660_ELTORITO_BOOT_MEDIA_F_XXX. */ + uint8_t bBootMediaType; + /** 0x02: Load segment - load address divided by 0x10. */ + uint16_t uLoadSeg; + /** 0x04: System type from image partition table. */ + uint8_t bSystemType; + /** 0x05: Unused, MBZ. */ + uint8_t bUnused; + /** 0x06: Number of emulated 512 byte sectors to load. */ + uint16_t cEmulatedSectorsToLoad; + /** 0x08: Image location in the ISO (block offset), always (?) little endian. */ + uint32_t offBootImage; + /** 0x0c: Selection criteria type (ISO9660_ELTORITO_SEL_CRIT_TYPE_XXX). */ + uint8_t bSelectionCriteriaType; + /** 0x0c: Selection criteria specific data. */ + uint8_t abSelectionCriteria[19]; +} ISO9660ELTORITOSECTIONENTRY; +AssertCompileSize(ISO9660ELTORITOSECTIONENTRY, ISO9660_ELTORITO_ENTRY_SIZE); +/** Pointer to an El Torito default (initial) entry. */ +typedef ISO9660ELTORITOSECTIONENTRY *PISO9660ELTORITOSECTIONENTRY; +/** Pointer to a const El Torito default (initial) entry. */ +typedef ISO9660ELTORITOSECTIONENTRY const *PCISO9660ELTORITOSECTIONENTRY; + + +/** @name ISO9660_ELTORITO_BOOT_INDICATOR_XXX - Boot indicators. + * @{ */ +#define ISO9660_ELTORITO_BOOT_INDICATOR_BOOTABLE UINT8_C(0x88) +#define ISO9660_ELTORITO_BOOT_INDICATOR_NOT_BOOTABLE UINT8_C(0x00) +/** @} */ + +/** @name ISO9660_ELTORITO_BOOT_MEDIA_TYPE_XXX - Boot media types. + * @{ */ +#define ISO9660_ELTORITO_BOOT_MEDIA_TYPE_NO_EMULATION UINT8_C(0x0) +#define ISO9660_ELTORITO_BOOT_MEDIA_TYPE_FLOPPY_1_2_MB UINT8_C(0x1) +#define ISO9660_ELTORITO_BOOT_MEDIA_TYPE_FLOPPY_1_44_MB UINT8_C(0x2) +#define ISO9660_ELTORITO_BOOT_MEDIA_TYPE_FLOPPY_2_88_MB UINT8_C(0x3) +#define ISO9660_ELTORITO_BOOT_MEDIA_TYPE_HARD_DISK UINT8_C(0x4) +#define ISO9660_ELTORITO_BOOT_MEDIA_TYPE_MASK UINT8_C(0xf) /**< The media type mask. */ +/** @} */ + +/** @name ISO9660_ELTORITO_BOOT_MEDIA_F_XXX - Boot media flags. + * These only applies to the section entry, not to the default (initial) entry. + * @{ */ +#define ISO9660_ELTORITO_BOOT_MEDIA_F_RESERVED UINT8_C(0x10) /**< Reserved bit, MBZ. */ +#define ISO9660_ELTORITO_BOOT_MEDIA_F_CONTINUATION UINT8_C(0x20) /**< Contiunation entry follows. */ +#define ISO9660_ELTORITO_BOOT_MEDIA_F_ATAPI_DRIVER UINT8_C(0x40) /**< Image contains an ATAPI driver. */ +#define ISO9660_ELTORITO_BOOT_MEDIA_F_SCSI_DRIVERS UINT8_C(0x80) /**< Image contains SCSI drivers. */ +#define ISO9660_ELTORITO_BOOT_MEDIA_F_MASK UINT8_C(0xf0) /**< The media/entry flag mask. */ +/** @} */ + +/** @name ISO9660_ELTORITO_SEL_CRIT_TYPE_XXX - Selection criteria type. + * @{ */ +#define ISO9660_ELTORITO_SEL_CRIT_TYPE_NONE UINT8_C(0x00) /**< No selection criteria */ +#define ISO9660_ELTORITO_SEL_CRIT_TYPE_LANG_AND_VERSION UINT8_C(0x01) /**< Language and version (IBM). */ +/** @} */ + + +/** + * El Torito boot catalog: Section entry extension. + * + * This is used for carrying additional selection criteria data. It follows + * a ISO9660ELTORITOSECTIONENTRY. + */ +typedef struct ISO9660ELTORITOSECTIONENTRYEXT +{ + /** 0x00: Extension indicator (ISO9660_ELTORITO_SECTION_ENTRY_EXT_ID). */ + uint8_t bExtensionId; + /** 0x01: Selection criteria extension flags (ISO9660_ELTORITO_SECTION_ENTRY_EXT_F_XXX). */ + uint8_t fFlags; + /** 0x02: Selection critiera data. */ + uint8_t abSelectionCriteria[30]; +} ISO9660ELTORITOSECTIONENTRYEXT; +AssertCompileSize(ISO9660ELTORITOSECTIONENTRYEXT, ISO9660_ELTORITO_ENTRY_SIZE); +/** Pointer to an El Torito default (initial) entry. */ +typedef ISO9660ELTORITOSECTIONENTRYEXT *PISO9660ELTORITOSECTIONENTRYEXT; +/** Pointer to a const El Torito default (initial) entry. */ +typedef ISO9660ELTORITOSECTIONENTRYEXT const *PCISO9660ELTORITOSECTIONENTRYEXT; + +/** Value of ISO9660ELTORITOSECTIONENTRYEXT::bExtensionId. */ +#define ISO9660_ELTORITO_SECTION_ENTRY_EXT_ID UINT8_C(0x44) + +/** @name ISO9660_ELTORITO_SECTION_ENTRY_EXT_F_XXX - ISO9660ELTORITOSECTIONENTRYEXT::fFlags + * @{ */ +#define ISO9660_ELTORITO_SECTION_ENTRY_EXT_F_MORE UINT8_C(0x20) /**< Further extension entries follows. */ +#define ISO9660_ELTORITO_SECTION_ENTRY_EXT_F_UNUSED_MASK UINT8_C(0xef) /**< Mask of all unused bits. */ +/** @} */ + + +/** + * Boot information table used by isolinux and GRUB2 El Torito boot files. + */ +typedef struct ISO9660SYSLINUXINFOTABLE +{ + /** 0x00/0x08: Offset of the primary volume descriptor (block offset). */ + uint32_t offPrimaryVolDesc; + /** 0x04/0x0c: Offset of the boot file (block offset). */ + uint32_t offBootFile; + /** 0x08/0x10: Size of the boot file in bytes. */ + uint32_t cbBootFile; + /** 0x0c/0x14: Boot file checksum. + * This is the sum of all the 32-bit words in the image, start at the end of + * this structure (i.e. offset 64). */ + uint32_t uChecksum; + /** 0x10/0x18: Reserved for future fun. */ + uint32_t auReserved[10]; +} ISO9660SYSLINUXINFOTABLE; +AssertCompileSize(ISO9660SYSLINUXINFOTABLE, 56); +/** Pointer to a syslinux boot information table. */ +typedef ISO9660SYSLINUXINFOTABLE *PISO9660SYSLINUXINFOTABLE; +/** Pointer to a const syslinux boot information table. */ +typedef ISO9660SYSLINUXINFOTABLE const *PCISO9660SYSLINUXINFOTABLE; + +/** The file offset of the isolinux boot info table. */ +#define ISO9660SYSLINUXINFOTABLE_OFFSET 8 + + + +/** + * System Use Sharing Protocol Protocol (SUSP) header. + */ +typedef struct ISO9660SUSPHDR +{ + /** Signature byte 1. */ + uint8_t bSig1; + /** Signature byte 2. */ + uint8_t bSig2; + /** Length of the entry (including the header). */ + uint8_t cbEntry; + /** Entry version number. */ + uint8_t bVersion; +} ISO9660SUSPHDR; +AssertCompileSize(ISO9660SUSPHDR, 4); +/** Pointer to a SUSP header. */ +typedef ISO9660SUSPHDR *PISO9660SUSPHDR; +/** Pointer to a const SUSP header. */ +typedef ISO9660SUSPHDR const *PCISO9660SUSPHDR; + + +/** + * SUSP continuation entry (CE). + */ +typedef struct ISO9660SUSPCE +{ + /** Header (ISO9660SUSPCE_SIG1, ISO9660SUSPCE_SIG2, ISO9660SUSPCE_VER). */ + ISO9660SUSPHDR Hdr; + /** The offset of the continutation data block (block offset). */ + ISO9660U32 offBlock; + /** The byte offset in the block of the contiuation data. */ + ISO9660U32 offData; + /** The size of the continuation data. */ + ISO9660U32 cbData; +} ISO9660SUSPCE; +/** Pointer to a SUSP continuation entry. */ +typedef ISO9660SUSPCE *PISO9660SUSPCE; +/** Pointer to a const SUSP continuation entry. */ +typedef ISO9660SUSPCE const *PCISO9660SUSPCE; +#define ISO9660SUSPCE_SIG1 'C' /**< SUSP continutation entry signature byte 1. */ +#define ISO9660SUSPCE_SIG2 'E' /**< SUSP continutation entry signature byte 2. */ +#define ISO9660SUSPCE_LEN 28 /**< SUSP continutation entry length. */ +#define ISO9660SUSPCE_VER 1 /**< SUSP continutation entry version number. */ +AssertCompileSize(ISO9660SUSPCE, ISO9660SUSPCE_LEN); + + +/** + * SUSP padding entry (PD). + */ +typedef struct ISO9660SUSPPD +{ + /** Header (ISO9660SUSPPD_SIG1, ISO9660SUSPPD_SIG2, ISO9660SUSPPD_VER). */ + ISO9660SUSPHDR Hdr; + /* Padding follows. */ +} ISO9660SUSPPD; +AssertCompileSize(ISO9660SUSPPD, 4); +/** Pointer to a SUSP padding entry. */ +typedef ISO9660SUSPPD *PISO9660SUSPPD; +/** Pointer to a const SUSP padding entry. */ +typedef ISO9660SUSPPD const *PCISO9660SUSPPD; +#define ISO9660SUSPPD_SIG1 'P' /**< SUSP padding entry signature byte 1. */ +#define ISO9660SUSPPD_SIG2 'D' /**< SUSP padding entry signature byte 2. */ +#define ISO9660SUSPPD_VER 1 /**< SUSP padding entry version number. */ + + +/** + * SUSP system use protocol entry (SP) + * + * This is only used in the '.' record of the root directory. + */ +typedef struct ISO9660SUSPSP +{ + /** Header (ISO9660SUSPSP_SIG1, ISO9660SUSPSP_SIG2, + * ISO9660SUSPSP_LEN, ISO9660SUSPSP_VER). */ + ISO9660SUSPHDR Hdr; + /** Check byte 1 (ISO9660SUSPSP_CHECK1). */ + uint8_t bCheck1; + /** Check byte 2 (ISO9660SUSPSP_CHECK2). */ + uint8_t bCheck2; + /** Number of bytes to skip within the system use field of each directory + * entry (except the '.' entry of the root, since that's where this is). */ + uint8_t cbSkip; +} ISO9660SUSPSP; +/** Pointer to a SUSP entry. */ +typedef ISO9660SUSPSP *PISO9660SUSPSP; +/** Pointer to a const SUSP entry. */ +typedef ISO9660SUSPSP const *PCISO9660SUSPSP; +#define ISO9660SUSPSP_SIG1 'S' /**< SUSP system use protocol entry signature byte 1. */ +#define ISO9660SUSPSP_SIG2 'P' /**< SUSP system use protocol entry signature byte 2. */ +#define ISO9660SUSPSP_VER 1 /**< SUSP system use protocol entry version number. */ +#define ISO9660SUSPSP_LEN 7 /**< SUSP system use protocol entry length (fixed). */ +#define ISO9660SUSPSP_CHECK1 UINT8_C(0xbe) /**< SUSP system use protocol entry check byte 1. */ +#define ISO9660SUSPSP_CHECK2 UINT8_C(0xef) /**< SUSP system use protocol entry check byte 2. */ +AssertCompileSize(ISO9660SUSPSP, ISO9660SUSPSP_LEN); + + +/** + * SUSP terminator entry (ST) + * + * Used to terminate system use entries. + */ +typedef struct ISO9660SUSPST +{ + /** Header (ISO9660SUSPST_SIG1, ISO9660SUSPST_SIG2, + * ISO9660SUSPST_LEN, ISO9660SUSPST_VER). */ + ISO9660SUSPHDR Hdr; +} ISO9660SUSPST; +/** Pointer to a SUSP padding entry. */ +typedef ISO9660SUSPST *PISO9660SUSPST; +/** Pointer to a const SUSP padding entry. */ +typedef ISO9660SUSPST const *PCISO9660SUSPST; +#define ISO9660SUSPST_SIG1 'S' /**< SUSP system use protocol entry signature byte 1. */ +#define ISO9660SUSPST_SIG2 'T' /**< SUSP system use protocol entry signature byte 2. */ +#define ISO9660SUSPST_VER 1 /**< SUSP system use protocol entry version number. */ +#define ISO9660SUSPST_LEN 4 /**< SUSP system use protocol entry length (fixed). */ +AssertCompileSize(ISO9660SUSPST, ISO9660SUSPST_LEN); + + +/** + * SUSP extension record entry (ER) + * + * This is only used in the '.' record of the root directory. There can be multiple of these. + */ +typedef struct ISO9660SUSPER +{ + /** Header (ISO9660SUSPER_SIG1, ISO9660SUSPER_SIG2, ISO9660SUSPER_VER). */ + ISO9660SUSPHDR Hdr; + /** The length of the identifier component. */ + uint8_t cchIdentifier; + /** The length of the description component. */ + uint8_t cchDescription; + /** The length of the source component. */ + uint8_t cchSource; + /** The extension version number. */ + uint8_t bVersion; + /** The payload: first @a cchIdentifier chars of identifier string, second + * @a cchDescription chars of description string, thrid @a cchSource chars + * of source string. Variable length. */ + char achPayload[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} ISO9660SUSPER; +/** Pointer to a SUSP padding entry. */ +typedef ISO9660SUSPER *PISO9660SUSPER; +/** Pointer to a const SUSP padding entry. */ +typedef ISO9660SUSPER const *PCISO9660SUSPER; +#define ISO9660SUSPER_SIG1 'E' /**< SUSP extension record entry signature byte 1. */ +#define ISO9660SUSPER_SIG2 'R' /**< SUSP extension record entry signature byte 2. */ +#define ISO9660SUSPER_VER 1 /**< SUSP extension record entry version number. */ +#define ISO9660SUSPER_OFF_PAYLOAD 8 /**< SUSP extension record entry payload member offset. */ +AssertCompileMemberOffset(ISO9660SUSPER, achPayload, ISO9660SUSPER_OFF_PAYLOAD); + +/** + * SUSP extension sequence entry (ES) + * + * This is only used in the '.' record of the root directory. + */ +typedef struct ISO9660SUSPES +{ + /** Header (ISO9660SUSPES_SIG1, ISO9660SUSPES_SIG2, ISO9660SUSPES_VER). */ + ISO9660SUSPHDR Hdr; + /** The ER entry sequence number of the extension comming first. */ + uint8_t iFirstExtension; +} ISO9660SUSPES; +/** Pointer to a SUSP padding entry. */ +typedef ISO9660SUSPES *PISO9660SUSPES; +/** Pointer to a const SUSP padding entry. */ +typedef ISO9660SUSPES const *PCISO9660SUSPES; +#define ISO9660SUSPES_SIG1 'E' /**< SUSP extension sequence entry signature byte 1. */ +#define ISO9660SUSPES_SIG2 'S' /**< SUSP extension sequence entry signature byte 2. */ +#define ISO9660SUSPES_VER 1 /**< SUSP extension sequence entry version number. */ +#define ISO9660SUSPES_LEN 5 /**< SUSP extension sequence entry length (fixed). */ +AssertCompileSize(ISO9660SUSPES, ISO9660SUSPES_LEN); + + +/** RRIP ER identifier string from Rock Ridge Interchange Protocol v1.10 specs. */ +#define ISO9660_RRIP_ID "RRIP_1991A" +/** RRIP ER recommended description string (from RRIP v1.10 specs). */ +#define ISO9660_RRIP_DESC "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS" +/** RRIP ER recommended source string (from RRIP v1.10 specs). */ +#define ISO9660_RRIP_SRC "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION." +/** RRIP ER version field value from the Rock Ridge Interchange Protocol v1.10 specs. */ +#define ISO9660_RRIP_VER 1 +/** The length of a RRIP v1.10 ER record. + * The record must be constructed using ISO9660_RRIP_ID, ISO9660_RRIP_DESC + * and ISO9660_RRIP_SRC. */ +#define ISO9660_RRIP_ER_LEN ((uint8_t)( ISO9660SUSPER_OFF_PAYLOAD \ + + sizeof(ISO9660_RRIP_ID) - 1 \ + + sizeof(ISO9660_RRIP_DESC) - 1 \ + + sizeof(ISO9660_RRIP_SRC) - 1 )) + +/** RRIP ER identifier string from RRIP IEEE P1282 v1.12 draft. */ +#define ISO9660_RRIP_1_12_ID "IEEE_P1282" +/** RRIP ER recommended description string (RRIP IEEE P1282 v1.12 draft). */ +#define ISO9660_RRIP_1_12_DESC "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS." +/** RRIP ER recommended source string (RRIP IEEE P1282 v1.12 draft). */ +#define ISO9660_RRIP_1_12_SRC "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION." +/** RRIP ER version field value from the Rock Ridge Interchange Protocol v1.12 specs. */ +#define ISO9660_RRIP_1_12_VER 1 +/** The length of a RRIP v1.12 ER record. + * The record must be constructed using ISO9660_RRIP_1_12_ID, + * ISO9660_RRIP_1_12_DESC and ISO9660_RRIP_1_12_SRC. */ +#define ISO9660_RRIP_1_12_ER_LEN ((uint8_t)( ISO9660SUSPER_OFF_PAYLOAD \ + + sizeof(ISO9660_RRIP_1_12_ID) - 1 \ + + sizeof(ISO9660_RRIP_1_12_DESC) - 1 \ + + sizeof(ISO9660_RRIP_1_12_SRC) - 1 )) + + +/** + * Rock ridge interchange protocol - RR. + */ +typedef struct ISO9660RRIPRR +{ + /** Header (ISO9660RRIPRR_SIG1, ISO9660RRIPRR_SIG2, + * ISO9660RRIPRR_LEN, ISO9660RRIPRR_VER). */ + ISO9660SUSPHDR Hdr; + /** Flags indicating which RRIP entries are present (). */ + uint8_t fFlags; +} ISO9660RRIPRR; +/** Pointer to a RRIP RR entry. */ +typedef ISO9660RRIPRR *PISO9660RRIPRR; +/** Pointer to a const RRIP RR entry. */ +typedef ISO9660RRIPRR const *PCISO9660RRIPRR; +#define ISO9660RRIPRR_SIG1 'R' /**< RRIP RR entry signature byte 1. */ +#define ISO9660RRIPRR_SIG2 'R' /**< RRIP RR entry signature byte 2. */ +#define ISO9660RRIPRR_VER 1 /**< RRIP RR entry version number. */ +#define ISO9660RRIPRR_LEN 5 /**< RRIP RR entry length (fixed). */ +AssertCompileSize(ISO9660RRIPRR, ISO9660RRIPRR_LEN); + +/** @name ISO9660RRIP_RR_F_XXX - Indicates which RRIP entries are present. + * @{ */ +#define ISO9660RRIP_RR_F_PX UINT8_C(0x01) +#define ISO9660RRIP_RR_F_PN UINT8_C(0x02) +#define ISO9660RRIP_RR_F_SL UINT8_C(0x04) +#define ISO9660RRIP_RR_F_NM UINT8_C(0x08) +#define ISO9660RRIP_RR_F_CL UINT8_C(0x10) +#define ISO9660RRIP_RR_F_PL UINT8_C(0x20) +#define ISO9660RRIP_RR_F_RE UINT8_C(0x40) +#define ISO9660RRIP_RR_F_TF UINT8_C(0x80) +/** @} */ + +/** + * Rock ridge interchange protocol - posix attribute entry (PX). + */ +typedef struct ISO9660RRIPPX +{ + /** Header (ISO9660RRIPPX_SIG1, ISO9660RRIPPX_SIG2, + * ISO9660RRIPPX_LEN, ISO9660RRIPPX_VER). */ + ISO9660SUSPHDR Hdr; + /** The file mode (RTFS_UNIX_XXX, RTFS_TYPE_XXX). */ + ISO9660U32 fMode; + /** Number of hardlinks. */ + ISO9660U32 cHardlinks; + /** User ID. */ + ISO9660U32 uid; + /** Group ID. */ + ISO9660U32 gid; + /** Inode number. */ + ISO9660U32 INode; +} ISO9660RRIPPX; +/** Pointer to a RRIP posix attribute entry. */ +typedef ISO9660RRIPPX *PISO9660RRIPPX; +/** Pointer to a const RRIP posix attribute entry. */ +typedef ISO9660RRIPPX const *PCISO9660RRIPPX; +#define ISO9660RRIPPX_SIG1 'P' /**< RRIP posix attribute entry signature byte 1. */ +#define ISO9660RRIPPX_SIG2 'X' /**< RRIP posix attribute entry signature byte 2. */ +#define ISO9660RRIPPX_VER 1 /**< RRIP posix attribute entry version number. */ +#define ISO9660RRIPPX_LEN 44 /**< RRIP posix attribute entry length (fixed). */ +AssertCompileSize(ISO9660RRIPPX, ISO9660RRIPPX_LEN); +#define ISO9660RRIPPX_LEN_NO_INODE 36 /**< RRIP posix attribute entry length without inode (fixed). */ + + +/** + * Rock ridge interchange protocol - timestamp entry (TF). + */ +typedef struct ISO9660RRIPTF +{ + /** Header (ISO9660RRIPTF_SIG1, ISO9660RRIPTF_SIG2, ISO9660RRIPTF_VER). */ + ISO9660SUSPHDR Hdr; + /** Flags, ISO9660RRIPTF_F_XXX. */ + uint8_t fFlags; + /** Timestamp payload bytes (variable size and format). */ + uint8_t abPayload[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} ISO9660RRIPTF; +AssertCompileMemberOffset(ISO9660RRIPTF, abPayload, 5); +/** Pointer to a RRIP timestamp entry. */ +typedef ISO9660RRIPTF *PISO9660RRIPTF; +/** Pointer to a const RRIP timestamp entry. */ +typedef ISO9660RRIPTF const *PCISO9660RRIPTF; +#define ISO9660RRIPTF_SIG1 'T' /**< RRIP child link entry signature byte 1. */ +#define ISO9660RRIPTF_SIG2 'F' /**< RRIP child link entry signature byte 2. */ +#define ISO9660RRIPTF_VER 1 /**< RRIP child link entry version number. */ + +/** @name ISO9660RRIPTF_F_XXX - Timestmap flags. + * @{ */ +#define ISO9660RRIPTF_F_BIRTH UINT8_C(0x01) /**< Birth (creation) timestamp is recorded. */ +#define ISO9660RRIPTF_F_MODIFY UINT8_C(0x02) /**< Modification timestamp is recorded. */ +#define ISO9660RRIPTF_F_ACCESS UINT8_C(0x04) /**< Accessed timestamp is recorded. */ +#define ISO9660RRIPTF_F_CHANGE UINT8_C(0x08) /**< Attribute change timestamp is recorded. */ +#define ISO9660RRIPTF_F_BACKUP UINT8_C(0x10) /**< Backup timestamp is recorded. */ +#define ISO9660RRIPTF_F_EXPIRATION UINT8_C(0x20) /**< Expiration timestamp is recorded. */ +#define ISO9660RRIPTF_F_EFFECTIVE UINT8_C(0x40) /**< Effective timestamp is recorded. */ +#define ISO9660RRIPTF_F_LONG_FORM UINT8_C(0x80) /**< If set ISO9660TIMESTAMP is used, otherwise ISO9660RECTIMESTAMP. */ +/** @} */ + +/** + * Calculates the length of a 'TF' entry given the flags. + * + * @returns Length in bytes. + * @param fFlags The flags (ISO9660RRIPTF_F_XXX). + */ +DECLINLINE(uint8_t) Iso9660RripTfCalcLength(uint8_t fFlags) +{ + unsigned cTimestamps = ((fFlags & ISO9660RRIPTF_F_BIRTH) != 0) + + ((fFlags & ISO9660RRIPTF_F_MODIFY) != 0) + + ((fFlags & ISO9660RRIPTF_F_ACCESS) != 0) + + ((fFlags & ISO9660RRIPTF_F_CHANGE) != 0) + + ((fFlags & ISO9660RRIPTF_F_BACKUP) != 0) + + ((fFlags & ISO9660RRIPTF_F_EXPIRATION) != 0) + + ((fFlags & ISO9660RRIPTF_F_EFFECTIVE) != 0); + return (uint8_t)( cTimestamps * (fFlags & ISO9660RRIPTF_F_LONG_FORM ? sizeof(ISO9660TIMESTAMP) : sizeof(ISO9660RECTIMESTAMP)) + + RT_OFFSETOF(ISO9660RRIPTF, abPayload)); +} + + +/** + * Rock ridge interchange protocol - posix device number entry (PN). + * + * Mandatory for block or character devices. + */ +typedef struct ISO9660RRIPPN +{ + /** Header (ISO9660RRIPPN_SIG1, ISO9660RRIPPN_SIG2, + * ISO9660RRIPPN_LEN, ISO9660RRIPPN_VER). */ + ISO9660SUSPHDR Hdr; + /** The major device number. */ + ISO9660U32 Major; + /** The minor device number. */ + ISO9660U32 Minor; +} ISO9660RRIPPN; +/** Pointer to a RRIP posix attribute entry. */ +typedef ISO9660RRIPPN *PISO9660RRIPPN; +/** Pointer to a const RRIP posix attribute entry. */ +typedef ISO9660RRIPPN const *PCISO9660RRIPPN; +#define ISO9660RRIPPN_SIG1 'P' /**< RRIP posix device number entry signature byte 1. */ +#define ISO9660RRIPPN_SIG2 'N' /**< RRIP posix device number entry signature byte 2. */ +#define ISO9660RRIPPN_VER 1 /**< RRIP posix device number entry version number. */ +#define ISO9660RRIPPN_LEN 20 /**< RRIP posix device number entry length (fixed). */ +AssertCompileSize(ISO9660RRIPPN, ISO9660RRIPPN_LEN); + +/** + * Rock ridge interchange protocol - symlink entry (SL). + * + * Mandatory for symbolic links. + */ +typedef struct ISO9660RRIPSL +{ + /** Header (ISO9660RRIPSL_SIG1, ISO9660RRIPSL_SIG2, ISO9660RRIPSL_VER). */ + ISO9660SUSPHDR Hdr; + /** Flags (0 or ISO9660RRIP_SL_F_CONTINUE). */ + uint8_t fFlags; + /** Variable length of components. First byte in each component is a + * combination of ISO9660RRIP_SL_C_XXX flag values. The second byte the + * length of character data following it. */ + uint8_t abComponents[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} ISO9660RRIPSL; +AssertCompileMemberOffset(ISO9660RRIPSL, abComponents, 5); +/** Pointer to a RRIP symbolic link entry. */ +typedef ISO9660RRIPSL *PISO9660RRIPSL; +/** Pointer to a const RRIP symbolic link entry. */ +typedef ISO9660RRIPSL const *PCISO9660RRIPSL; +#define ISO9660RRIPSL_SIG1 'S' /**< RRIP symbolic link entry signature byte 1. */ +#define ISO9660RRIPSL_SIG2 'L' /**< RRIP symbolic link entry signature byte 2. */ +#define ISO9660RRIPSL_VER 1 /**< RRIP symbolic link entry version number. */ +/** ISO9660RRIPSL.fFlags - When set another symlink entry follows this one. */ +#define ISO9660RRIP_SL_F_CONTINUE UINT8_C(0x01) +/** @name ISO9660RRIP_SL_C_XXX - Symlink component flags. + * @note These matches ISO9660RRIP_NM_F_XXX. + * @{ */ +/** Indicates that the component continues in the next entry. */ +#define ISO9660RRIP_SL_C_CONTINUE UINT8_C(0x01) +/** Refer to '.' (the current dir). */ +#define ISO9660RRIP_SL_C_CURRENT UINT8_C(0x02) +/** Refer to '..' (the parent dir). */ +#define ISO9660RRIP_SL_C_PARENT UINT8_C(0x04) +/** Refer to '/' (the root dir). */ +#define ISO9660RRIP_SL_C_ROOT UINT8_C(0x08) +/** Reserved / historically was mount point reference. */ +#define ISO9660RRIP_SL_C_MOUNT_POINT UINT8_C(0x10) +/** Reserved / historically was uname network node name. */ +#define ISO9660RRIP_SL_C_UNAME UINT8_C(0x20) +/** Reserved mask (considers historically bits reserved). */ +#define ISO9660RRIP_SL_C_RESERVED_MASK UINT8_C(0xf0) +/** @} */ + + +/** + * Rock ridge interchange protocol - name entry (NM). + */ +typedef struct ISO9660RRIPNM +{ + /** Header (ISO9660RRIPNM_SIG1, ISO9660RRIPNM_SIG2, ISO9660RRIPNM_VER). */ + ISO9660SUSPHDR Hdr; + /** Flags (ISO9660RRIP_NM_F_XXX). */ + uint8_t fFlags; + /** The name part (if any). */ + char achName[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} ISO9660RRIPNM; +AssertCompileMemberOffset(ISO9660RRIPNM, achName, 5); +/** Pointer to a RRIP name entry. */ +typedef ISO9660RRIPNM *PISO9660RRIPNM; +/** Pointer to a const RRIP name entry. */ +typedef ISO9660RRIPNM const *PCISO9660RRIPNM; +#define ISO9660RRIPNM_SIG1 'N' /**< RRIP name entry signature byte 1. */ +#define ISO9660RRIPNM_SIG2 'M' /**< RRIP name entry signature byte 2. */ +#define ISO9660RRIPNM_VER 1 /**< RRIP name entry version number. */ +/** @name ISO9660RRIP_NM_F_XXX - Name flags. + * @note These matches ISO9660RRIP_SL_C_XXX. + * @{ */ +/** Indicates there are more 'NM' entries. */ +#define ISO9660RRIP_NM_F_CONTINUE UINT8_C(0x01) +/** Refer to '.' (the current dir). */ +#define ISO9660RRIP_NM_F_CURRENT UINT8_C(0x02) +/** Refer to '..' (the parent dir). */ +#define ISO9660RRIP_NM_F_PARENT UINT8_C(0x04) +/** Reserved / historically was uname network node name. */ +#define ISO9660RRIP_NM_F_UNAME UINT8_C(0x20) +/** Reserved mask (considers historical bits reserved). */ +#define ISO9660RRIP_NM_F_RESERVED_MASK UINT8_C(0xf8) +/** @} */ + +/** Maximum name length in one 'NM' entry. */ +#define ISO9660RRIPNM_MAX_NAME_LEN 250 + + +/** + * Rock ridge interchange protocol - child link entry (CL). + * + * This is used for relocated directories. Relocated directries are employed + * to bypass the ISO 9660 maximum tree depth of 8. + * + * The size of the directory and everything else is found in the '.' entry in + * the specified location. Only the name (NM or dir rec) and this link record + * should be used. + */ +typedef struct ISO9660RRIPCL +{ + /** Header (ISO9660RRIPCL_SIG1, ISO9660RRIPCL_SIG2, + * ISO9660RRIPCL_LEN, ISO9660RRIPCL_VER). */ + ISO9660SUSPHDR Hdr; + /** The offset of the directory data (block offset). */ + ISO9660U32 offExtend; +} ISO9660RRIPCL; +/** Pointer to a RRIP child link entry. */ +typedef ISO9660RRIPCL *PISO9660RRIPCL; +/** Pointer to a const RRIP child link entry. */ +typedef ISO9660RRIPCL const *PCISO9660RRIPCL; +#define ISO9660RRIPCL_SIG1 'C' /**< RRIP child link entry signature byte 1. */ +#define ISO9660RRIPCL_SIG2 'L' /**< RRIP child link entry signature byte 2. */ +#define ISO9660RRIPCL_VER 1 /**< RRIP child link entry version number. */ +#define ISO9660RRIPCL_LEN 12 /**< RRIP child link entry length. */ +AssertCompileSize(ISO9660RRIPCL, ISO9660RRIPCL_LEN); + + +/** + * Rock ridge interchange protocol - parent link entry (PL). + * + * This is used in relocated directories. Relocated directries are employed + * to bypass the ISO 9660 maximum tree depth of 8. + * + * The size of the directory and everything else is found in the '.' entry in + * the specified location. Only the name (NM or dir rec) and this link record + * should be used. + */ +typedef struct ISO9660RRIPPL +{ + /** Header (ISO9660RRIPPL_SIG1, ISO9660RRIPPL_SIG2, + * ISO9660RRIPPL_LEN, ISO9660RRIPPL_VER). */ + ISO9660SUSPHDR Hdr; + /** The offset of the directory data (block offset). */ + ISO9660U32 offExtend; +} ISO9660RRIPPL; +/** Pointer to a RRIP parent link entry. */ +typedef ISO9660RRIPPL *PISO9660RRIPPL; +/** Pointer to a const RRIP parent link entry. */ +typedef ISO9660RRIPPL const *PCISO9660RRIPPL; +#define ISO9660RRIPPL_SIG1 'P' /**< RRIP parent link entry signature byte 1. */ +#define ISO9660RRIPPL_SIG2 'L' /**< RRIP parent link entry signature byte 2. */ +#define ISO9660RRIPPL_VER 1 /**< RRIP parent link entry version number. */ +#define ISO9660RRIPPL_LEN 12 /**< RRIP parent link entry length. */ +AssertCompileSize(ISO9660RRIPPL, ISO9660RRIPPL_LEN); + + +/** + * Rock ridge interchange protocol - relocated entry (RE). + * + * This is used in the directory record for a relocated directory in the + * holding place high up in the directory hierarchy. The system may choose to + * ignore/hide entries with this entry present. + */ +typedef struct ISO9660RRIPRE +{ + /** Header (ISO9660RRIPRE_SIG1, ISO9660RRIPRE_SIG2, + * ISO9660RRIPRE_LEN, ISO9660RRIPRE_VER). */ + ISO9660SUSPHDR Hdr; +} ISO9660RRIPRE; +/** Pointer to a RRIP parent link entry. */ +typedef ISO9660RRIPRE *PISO9660RRIPRE; +/** Pointer to a const RRIP parent link entry. */ +typedef ISO9660RRIPRE const *PCISO9660RRIPRE; +#define ISO9660RRIPRE_SIG1 'R' /**< RRIP relocated entry signature byte 1. */ +#define ISO9660RRIPRE_SIG2 'E' /**< RRIP relocated entry signature byte 2. */ +#define ISO9660RRIPRE_VER 1 /**< RRIP relocated entry version number. */ +#define ISO9660RRIPRE_LEN 4 /**< RRIP relocated entry length. */ +AssertCompileSize(ISO9660RRIPRE, ISO9660RRIPRE_LEN); + + +/** + * Rock ridge interchange protocol - sparse file entry (SF). + */ +#pragma pack(1) +typedef struct ISO9660RRIPSF +{ + /** Header (ISO9660RRIPSF_SIG1, ISO9660RRIPSF_SIG2, + * ISO9660RRIPSF_LEN, ISO9660RRIPSF_VER). */ + ISO9660SUSPHDR Hdr; + /** The high 32-bits of the 64-bit sparse file size. */ + ISO9660U32 cbSparseHi; + /** The low 32-bits of the 64-bit sparse file size. */ + ISO9660U32 cbSparseLo; + /** The table depth. */ + uint8_t cDepth; +} ISO9660RRIPSF; +#pragma pack() +/** Pointer to a RRIP symbolic link entry. */ +typedef ISO9660RRIPSF *PISO9660RRIPSF; +/** Pointer to a const RRIP symbolic link entry. */ +typedef ISO9660RRIPSF const *PCISO9660RRIPSF; +#define ISO9660RRIPSF_SIG1 'S' /**< RRIP spare file entry signature byte 1. */ +#define ISO9660RRIPSF_SIG2 'F' /**< RRIP spare file entry signature byte 2. */ +#define ISO9660RRIPSF_VER 1 /**< RRIP spare file entry version number. */ +#define ISO9660RRIPSF_LEN 21 /**< RRIP spare file entry length. */ +AssertCompileSize(ISO9660RRIPSF, ISO9660RRIPSF_LEN); + +/** @name ISO9660RRIP_SF_TAB_F_XXX - Sparse table format. + * @{ */ +/** The 24-bit logical block number mask. + * This is somewhat complicated, see docs. MBZ for EMPTY. */ +#define ISO9660RRIP_SF_TAB_F_BLOCK_MASK UINT32_C(0x00ffffff) +/** Reserved bits, MBZ. */ +#define ISO9660RRIP_SF_TAB_F_RESERVED RT_BIT_32() +/** References a sub-table with 256 entries (ISO9660U32). */ +#define ISO9660RRIP_SF_TAB_F_TABLE RT_BIT_32(30) +/** Zero data region. */ +#define ISO9660RRIP_SF_TAB_F_EMPTY RT_BIT_32(31) +/** @} */ + + +/** + * SUSP and RRIP union. + */ +typedef union ISO9660SUSPUNION +{ + ISO9660SUSPHDR Hdr; /**< SUSP header . */ + ISO9660SUSPCE CE; /**< SUSP continuation entry. */ + ISO9660SUSPPD PD; /**< SUSP padding entry. */ + ISO9660SUSPSP SP; /**< SUSP system use protocol entry. */ + ISO9660SUSPST ST; /**< SUSP terminator entry. */ + ISO9660SUSPER ER; /**< SUSP extension record entry. */ + ISO9660SUSPES ES; /**< SUSP extension sequence entry. */ + ISO9660RRIPRR RR; /**< RRIP optimization entry. */ + ISO9660RRIPPX PX; /**< RRIP posix attribute entry. */ + ISO9660RRIPTF TF; /**< RRIP timestamp entry. */ + ISO9660RRIPPN PN; /**< RRIP posix device number entry. */ + ISO9660RRIPSF SF; /**< RRIP sparse file entry. */ + ISO9660RRIPSL SL; /**< RRIP symbolic link entry. */ + ISO9660RRIPNM NM; /**< RRIP name entry. */ + ISO9660RRIPCL CL; /**< RRIP child link entry. */ + ISO9660RRIPPL PL; /**< RRIP parent link entry. */ + ISO9660RRIPRE RE; /**< RRIP relocated entry. */ +} ISO9660SUSPUNION; +/** Pointer to a SUSP and RRIP union. */ +typedef ISO9660SUSPUNION *PISO9660SUSPUNION; +/** Pointer to a const SUSP and RRIP union. */ +typedef ISO9660SUSPUNION *PCISO9660SUSPUNION; + + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_iso9660_h */ + diff --git a/include/iprt/formats/lx.h b/include/iprt/formats/lx.h new file mode 100644 index 00000000..b01a5ab8 --- /dev/null +++ b/include/iprt/formats/lx.h @@ -0,0 +1,510 @@ +/* $Id: lx.h $ */ +/** @file + * LX structures, types and defines. + */ + +/* + * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef IPRT_INCLUDED_formats_lx_h +#define IPRT_INCLUDED_formats_lx_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + +RT_C_DECLS_BEGIN + +/** @defgroup grp_rt_formats_lx LX executable format (OS/2) + * @ingroup grp_rt_formats + * @{ */ + +#ifndef IMAGE_OS2_SIGNATURE_LX +/** LX signature ("LX") */ +# define IMAGE_LX_SIGNATURE K_LE2H_U16('L' | ('X' << 8)) +#endif + +/** + * Linear eXecutable header. + * This structure is exactly 196 bytes long. + */ +typedef struct e32_exe +{ + uint8_t e32_magic[2]; + uint8_t e32_border; + uint8_t e32_worder; + uint32_t e32_level; + uint16_t e32_cpu; + uint16_t e32_os; + uint32_t e32_ver; + uint32_t e32_mflags; + uint32_t e32_mpages; + uint32_t e32_startobj; + uint32_t e32_eip; + uint32_t e32_stackobj; + uint32_t e32_esp; + uint32_t e32_pagesize; + uint32_t e32_pageshift; + /** The size of the fixup section. + * The fixup section consists of the fixup page table, the fixup record table, + * the import module table, and the import procedure name table. + */ + uint32_t e32_fixupsize; + uint32_t e32_fixupsum; + /** The size of the resident loader section. + * This includes the object table, the object page map table, the resource table, the resident name table, + * the entry table, the module format directives table, and the page checksum table (?). */ + uint32_t e32_ldrsize; + /** The checksum of the loader section. 0 if not calculated. */ + uint32_t e32_ldrsum; + /** The offset of the object table relative to this structure. */ + uint32_t e32_objtab; + /** Count of objects. */ + uint32_t e32_objcnt; + /** The offset of the object page map table relative to this structure. */ + uint32_t e32_objmap; + /** The offset of the object iterated pages (whatever this is used for) relative to the start of the file. */ + uint32_t e32_itermap; + /** The offset of the resource table relative to this structure. */ + uint32_t e32_rsrctab; + /** The number of entries in the resource table. */ + uint32_t e32_rsrccnt; + /** The offset of the resident name table relative to this structure. */ + uint32_t e32_restab; + /** The offset of the entry (export) table relative to this structure. */ + uint32_t e32_enttab; + /** The offset of the module format directives table relative to this structure. */ + uint32_t e32_dirtab; + /** The number of entries in the module format directives table. */ + uint32_t e32_dircnt; + /** The offset of the fixup page table relative to this structure. */ + uint32_t e32_fpagetab; + /** The offset of the fixup record table relative to this structure. */ + uint32_t e32_frectab; + /** The offset of the import module name table relative to this structure. */ + uint32_t e32_impmod; + /** The number of entries in the import module name table. */ + uint32_t e32_impmodcnt; + /** The offset of the import procedure name table relative to this structure. */ + uint32_t e32_impproc; + /** The offset of the page checksum table relative to this structure. */ + uint32_t e32_pagesum; + /** The offset of the data pages relative to the start of the file. */ + uint32_t e32_datapage; + /** The number of preload pages (ignored). */ + uint32_t e32_preload; + /** The offset of the non-resident name table relative to the start of the file. */ + uint32_t e32_nrestab; + /** The size of the non-resident name table. */ + uint32_t e32_cbnrestab; + uint32_t e32_nressum; + uint32_t e32_autodata; + uint32_t e32_debuginfo; + uint32_t e32_debuglen; + uint32_t e32_instpreload; + uint32_t e32_instdemand; + uint32_t e32_heapsize; + uint32_t e32_stacksize; + uint8_t e32_res3[20]; +} e32_exe; +AssertCompileSize(struct e32_exe, 196); + +/** e32_magic[0] */ +#define E32MAGIC1 'L' +/** e32_magic[1] */ +#define E32MAGIC2 'X' +/** MAKEWORD(e32_magic[0], e32_magic[1]) */ +#define E32MAGIC 0x584c +/** e32_border - little endian */ +#define E32LEBO 0 +/** e32_border - big endian */ +#define E32BEBO 1 +/** e32_worder - little endian */ +#define E32LEWO 0 +/** e32_worder - big endian */ +#define E32BEWO 1 +/** e32_level */ +#define E32LEVEL UINT32_C(0) +/** e32_cpu - 80286 */ +#define E32CPU286 1 +/** e32_cpu - 80386 */ +#define E32CPU386 2 +/** e32_cpu - 80486 */ +#define E32CPU486 3 +/** e32_pagesize */ +#define OBJPAGELEN UINT32_C(0x1000) + + +/** @name e32_mflags + * @{ */ +/** App Type: Fullscreen only. */ +#define E32NOPMW UINT32_C(0x00000100) +/** App Type: PM API. */ +#define E32PMAPI UINT32_C(0x00000300) +/** App Type: PM VIO compatible. */ +#define E32PMW UINT32_C(0x00000200) +/** Application type mask. */ +#define E32APPMASK UINT32_C(0x00000300) +/** Executable module. */ +#define E32MODEXE UINT32_C(0x00000000) +/** Dynamic link library (DLL / library) module. */ +#define E32MODDLL UINT32_C(0x00008000) +/** Protected memory DLL. */ +#define E32PROTDLL UINT32_C(0x00010000) +/** Physical Device Driver. */ +#define E32MODPDEV UINT32_C(0x00020000) +/** Virtual Device Driver. */ +#define E32MODVDEV UINT32_C(0x00028000) +/** Device driver */ +#define E32DEVICE E32MODPDEV +/** Dynamic link library (DLL / library) module. */ +#define E32NOTP E32MODDLL +/** Protected memory DLL. */ +#define E32MODPROTDLL (E32MODDLL | E32PROTDLL) +/** Module Type mask. */ +#define E32MODMASK UINT32_C(0x00038000) +/** Not loadable (linker error). */ +#define E32NOLOAD UINT32_C(0x00002000) +/** No internal fixups. */ +#define E32NOINTFIX UINT32_C(0x00000010) +/** No external fixups (i.e. imports). */ +#define E32NOEXTFIX UINT32_C(0x00000020) +/** System DLL, no internal fixups. */ +#define E32SYSDLL UINT32_C(0x00000008) +/** Global (set) or per instance (cleared) library initialization. */ +#define E32LIBINIT UINT32_C(0x00000004) +/** Global (set) or per instance (cleared) library termination. */ +#define E32LIBTERM UINT32_C(0x40000000) +/** Indicates when set in an executable that the process isn't SMP safe. */ +#define E32NOTMPSAFE UINT32_C(0x00080000) +/** @} */ + + +/** @defgroup grp_rt_formats_lx_relocs Relocations (aka Fixups). + * @{ */ +typedef union r32_offset +{ + uint16_t offset16; + uint32_t offset32; +} r32_offset; +AssertCompileSize(r32_offset, 4); + +/** A relocation. + * @remark this structure isn't very usable since LX relocations comes in too many size variations. + */ +#pragma pack(1) +typedef struct r32_rlc +{ + uint8_t nr_stype; + uint8_t nr_flags; + int16_t r32_soff; + uint16_t r32_objmod; + + union targetid + { + r32_offset intref; + union extfixup + { + r32_offset proc; + uint32_t ord; + } extref; + struct addfixup + { + uint16_t entry; + r32_offset addval; + } addfix; + } r32_target; + uint16_t r32_srccount; + uint16_t r32_chain; +} r32_rlc; +#pragma pack() +AssertCompileSize(r32_rlc, 16); +/** @} */ + +/** @name Some attempt at size constanstants. + * @{ + */ +#define RINTSIZE16 8 +#define RINTSIZE32 10 +#define RORDSIZE 8 +#define RNAMSIZE16 8 +#define RNAMSIZE32 10 +#define RADDSIZE16 10 +#define RADDSIZE32 12 +/** @} */ + +/** @name nr_stype (source flags) + * @{ */ +#define NRSBYT 0x00 +#define NRSSEG 0x02 +#define NRSPTR 0x03 +#define NRSOFF 0x05 +#define NRPTR48 0x06 +#define NROFF32 0x07 +#define NRSOFF32 0x08 +#define NRSTYP 0x0f +#define NRSRCMASK 0x0f +#define NRALIAS 0x10 +#define NRCHAIN 0x20 +/** @} */ + +/** @name nr_flags (target flags) + * @{ */ +#define NRRINT 0x00 +#define NRRORD 0x01 +#define NRRNAM 0x02 +#define NRRENT 0x03 +#define NRRTYP 0x03 +#define NRADD 0x04 +#define NRICHAIN 0x08 +#define NR32BITOFF 0x10 +#define NR32BITADD 0x20 +#define NR16OBJMOD 0x40 +#define NR8BITORD 0x80 +/** @} */ + +/** @} */ + + +/** @defgroup grp_rt_formats_lx_object_tab The Object Table (aka segment table) + * @{ */ + +/** The Object Table Entry. */ +typedef struct o32_obj +{ + /** The size of the object. */ + uint32_t o32_size; + /** The base address of the object. */ + uint32_t o32_base; + /** Object flags. */ + uint32_t o32_flags; + /** Page map index. */ + uint32_t o32_pagemap; + /** Page map size. (doesn't need to be o32_size >> page shift). */ + uint32_t o32_mapsize; + /** Reserved */ + uint32_t o32_reserved; +} o32_obj; +AssertCompileSize(o32_obj, 24); + +/** @name o32_flags + * @{ */ +/** Read access. */ +#define OBJREAD UINT32_C(0x00000001) +/** Write access. */ +#define OBJWRITE UINT32_C(0x00000002) +/** Execute access. */ +#define OBJEXEC UINT32_C(0x00000004) +/** Resource object. */ +#define OBJRSRC UINT32_C(0x00000008) +/** The object is discarable (i.e. don't swap, just load in pages from the executable). + * This overlaps a bit with object type. */ +#define OBJDISCARD UINT32_C(0x00000010) +/** The object is shared. */ +#define OBJSHARED UINT32_C(0x00000020) +/** The object has preload pages. */ +#define OBJPRELOAD UINT32_C(0x00000040) +/** The object has invalid pages. */ +#define OBJINVALID UINT32_C(0x00000080) +/** Non-permanent, link386 bug. */ +#define LNKNONPERM UINT32_C(0x00000600) +/** Non-permanent, correct 'value'. */ +#define OBJNONPERM UINT32_C(0x00000000) +/** Obj Type: The object is permanent and swappable. */ +#define OBJPERM UINT32_C(0x00000100) +/** Obj Type: The object is permanent and resident (i.e. not swappable). */ +#define OBJRESIDENT UINT32_C(0x00000200) +/** Obj Type: The object is resident and contigious. */ +#define OBJCONTIG UINT32_C(0x00000300) +/** Obj Type: The object is permanent and long locable. */ +#define OBJDYNAMIC UINT32_C(0x00000400) +/** Object type mask. */ +#define OBJTYPEMASK UINT32_C(0x00000700) +/** x86: The object require an 16:16 alias. */ +#define OBJALIAS16 UINT32_C(0x00001000) +/** x86: Big/Default selector setting, i.e. toggle 32-bit or 16-bit. */ +#define OBJBIGDEF UINT32_C(0x00002000) +/** x86: conforming selector setting (weird stuff). */ +#define OBJCONFORM UINT32_C(0x00004000) +/** x86: IOPL. */ +#define OBJIOPL UINT32_C(0x00008000) +/** @} */ + +/** A Object Page Map Entry. */ +typedef struct o32_map +{ + /** The file offset of the page. */ + uint32_t o32_pagedataoffset; + /** The number of bytes of raw page data. */ + uint16_t o32_pagesize; + /** Per page flags describing how the page is encoded in the file. */ + uint16_t o32_pageflags; +} o32_map; +AssertCompileSize(o32_map, 8); + +/** @name o32 o32_pageflags + * @{ + */ +/** Raw page (uncompressed) in the file. */ +#define VALID UINT16_C(0x0000) +/** RLE encoded page in file. */ +#define ITERDATA UINT16_C(0x0001) +/** Invalid page, nothing in the file. */ +#define INVALID UINT16_C(0x0002) +/** Zero page, nothing in file. */ +#define ZEROED UINT16_C(0x0003) +/** range of pages (what is this?) */ +#define RANGE UINT16_C(0x0004) +/** Compressed page in file. */ +#define ITERDATA2 UINT16_C(0x0005) +/** @} */ + + +/** Iteration Record format (RLE compressed page). */ +#pragma pack(1) +typedef struct LX_Iter +{ + /** Number of iterations. */ + uint16_t LX_nIter; + /** The number of bytes that's being iterated. */ + uint16_t LX_nBytes; + /** The bytes. */ + uint8_t LX_Iterdata; +} LX_Iter; +#pragma pack() +AssertCompileSize(LX_Iter, 5); + +/** @} */ + + +/** A Resource Table Entry */ +#pragma pack(1) +typedef struct rsrc32 +{ + /** Resource Type. */ + uint16_t type; + /** Resource ID. */ + uint16_t name; + /** Resource size in bytes. */ + uint32_t cb; + /** The index of the object containing the resource. */ + uint16_t obj; + /** Offset of the resource that within the object. */ + uint32_t offset; +} rsrc32; +#pragma pack() +AssertCompileSize(rsrc32, 14); + + +/** @defgroup grp_rt_formats_lx_entry_tab The Entry Table (aka Export Table) + * @{ */ + +/** Entry bundle. + * Header descripting up to 255 entries that follows immediatly after this structure. */ +typedef struct b32_bundle +{ + /** The number of entries. */ + uint8_t b32_cnt; + /** The type of bundle. */ + uint8_t b32_type; + /** The index of the object containing these entry points. */ + uint16_t b32_obj; +} b32_bundle; +AssertCompileSize(b32_bundle, 4); + +/** @name b32_type + * @{ */ +/** Empty bundle, filling up unused ranges of ordinals. */ +#define EMPTY 0x00 +/** 16-bit offset entry point. */ +#define ENTRY16 0x01 +/** 16-bit callgate entry point. */ +#define GATE16 0x02 +/** 32-bit offset entry point. */ +#define ENTRY32 0x03 +/** Forwarder entry point. */ +#define ENTRYFWD 0x04 +/** Typing information present indicator. */ +#define TYPEINFO 0x80 +/** @} */ + + +/** Entry point. */ +#pragma pack(1) +typedef struct e32_entry +{ + /** Entry point flags */ + uint8_t e32_flags; /* Entry point flags */ + union entrykind + { + /** ENTRY16 or ENTRY32. */ + r32_offset e32_offset; + /** GATE16 */ + struct scallgate + { + /** Offset into segment. */ + uint16_t offset; + /** The callgate selector */ + uint16_t callgate; + } e32_callgate; + /** ENTRYFWD */ + struct fwd + { + /** Module ordinal number (i.e. into the import module table). */ + uint16_t modord; + /** Procedure name or ordinal number. */ + uint32_t value; + } e32_fwd; + } e32_variant; +} e32_entry; +#pragma pack() + +/** @name e32_flags + * @{ */ +/** Exported entry (set) or private entry (clear). */ +#define E32EXPORT 0x01 +/** Uses shared data. */ +#define E32SHARED 0x02 +/** Parameter word count mask. */ +#define E32PARAMS 0xf8 +/** ENTRYFWD: Imported by ordinal (set) or by name (clear). */ +#define FWD_ORDINAL 0x01 +/** @} */ + +/** @name dunno + * @{ */ +#define FIXENT16 3 +#define FIXENT32 5 +#define GATEENT16 5 +#define FWDENT 7 +/** @} */ + +/** @} */ +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_formats_lx_h */ + diff --git a/include/iprt/formats/mach-o.h b/include/iprt/formats/mach-o.h new file mode 100644 index 00000000..20350c13 --- /dev/null +++ b/include/iprt/formats/mach-o.h @@ -0,0 +1,860 @@ +/* $Id: mach-o.h $ */ +/** @file + * IPRT - Mach-O Structures and Constants. + */ + +/* + * Copyright (C) 2011-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_mach_o_h +#define IPRT_INCLUDED_formats_mach_o_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + +#ifndef CPU_ARCH_MASK + +/* cputype */ +#define CPU_ARCH_MASK INT32_C(0xff000000) +#define CPU_ARCH_ABI64 INT32_C(0x01000000) +#define CPU_ARCH_ABI64_32 INT32_C(0x02000000) /**< LP32 on 64-bit hardware */ + +#define CPU_TYPE_ANY INT32_C(-1) +#define CPU_TYPE_VAX INT32_C(1) +#define CPU_TYPE_MC680x0 INT32_C(6) +#define CPU_TYPE_X86 INT32_C(7) +#define CPU_TYPE_I386 CPU_TYPE_X86 +#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64) +#define CPU_TYPE_MC98000 INT32_C(10) +#define CPU_TYPE_HPPA INT32_C(11) +#define CPU_TYPE_ARM INT32_C(12) +#define CPU_TYPE_ARM32 CPU_TYPE_ARM +#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) +#define CPU_TYPE_ARM64_32 (CPU_TYPE_ARM | CPU_ARCH_ABI64_32) +#define CPU_TYPE_MC88000 INT32_C(13) +#define CPU_TYPE_SPARC INT32_C(14) +#define CPU_TYPE_I860 INT32_C(15) +#define CPU_TYPE_POWERPC INT32_C(18) +#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) + +/* cpusubtype */ +#define CPU_SUBTYPE_MULTIPLE INT32_C(-1) +#define CPU_SUBTYPE_LITTLE_ENDIAN INT32_C(0) +#define CPU_SUBTYPE_BIG_ENDIAN INT32_C(1) + +#define CPU_SUBTYPE_VAX_ALL INT32_C(0) +#define CPU_SUBTYPE_VAX780 INT32_C(1) +#define CPU_SUBTYPE_VAX785 INT32_C(2) +#define CPU_SUBTYPE_VAX750 INT32_C(3) +#define CPU_SUBTYPE_VAX730 INT32_C(4) +#define CPU_SUBTYPE_UVAXI INT32_C(5) +#define CPU_SUBTYPE_UVAXII INT32_C(6) +#define CPU_SUBTYPE_VAX8200 INT32_C(7) +#define CPU_SUBTYPE_VAX8500 INT32_C(8) +#define CPU_SUBTYPE_VAX8600 INT32_C(9) +#define CPU_SUBTYPE_VAX8650 INT32_C(10) +#define CPU_SUBTYPE_VAX8800 INT32_C(11) +#define CPU_SUBTYPE_UVAXIII INT32_C(12) + +#define CPU_SUBTYPE_MC680x0_ALL INT32_C(1) +#define CPU_SUBTYPE_MC68030 INT32_C(1) +#define CPU_SUBTYPE_MC68040 INT32_C(2) +#define CPU_SUBTYPE_MC68030_ONLY INT32_C(3) + +#define CPU_SUBTYPE_INTEL(fam, model) ( (int32_t )(((model) << 4) | (fam)) ) +#define CPU_SUBTYPE_INTEL_FAMILY(subtype) ( (subtype) & 0xf ) +#define CPU_SUBTYPE_INTEL_MODEL(subtype) ( (subtype) >> 4 ) +#define CPU_SUBTYPE_INTEL_FAMILY_MAX 0xf +#define CPU_SUBTYPE_INTEL_MODEL_ALL 0 + +#define CPU_SUBTYPE_I386_ALL CPU_SUBTYPE_INTEL(3, 0) +#define CPU_SUBTYPE_386 CPU_SUBTYPE_INTEL(3, 0) +#define CPU_SUBTYPE_486 CPU_SUBTYPE_INTEL(4, 0) +#define CPU_SUBTYPE_486SX CPU_SUBTYPE_INTEL(4, 8) +#define CPU_SUBTYPE_586 CPU_SUBTYPE_INTEL(5, 0) +#define CPU_SUBTYPE_PENT CPU_SUBTYPE_INTEL(5, 0) +#define CPU_SUBTYPE_PENTPRO CPU_SUBTYPE_INTEL(6, 1) +#define CPU_SUBTYPE_PENTII_M3 CPU_SUBTYPE_INTEL(6, 3) +#define CPU_SUBTYPE_PENTII_M5 CPU_SUBTYPE_INTEL(6, 5) +#define CPU_SUBTYPE_CELERON CPU_SUBTYPE_INTEL(7, 6) +#define CPU_SUBTYPE_CELERON_MOBILE CPU_SUBTYPE_INTEL(7, 7) +#define CPU_SUBTYPE_PENTIUM_3 CPU_SUBTYPE_INTEL(8, 0) +#define CPU_SUBTYPE_PENTIUM_3_M CPU_SUBTYPE_INTEL(8, 1) +#define CPU_SUBTYPE_PENTIUM_3_XEON CPU_SUBTYPE_INTEL(8, 2) +#define CPU_SUBTYPE_PENTIUM_M CPU_SUBTYPE_INTEL(9, 0) +#define CPU_SUBTYPE_PENTIUM_4 CPU_SUBTYPE_INTEL(10, 0) +#define CPU_SUBTYPE_PENTIUM_4_M CPU_SUBTYPE_INTEL(10, 1) +#define CPU_SUBTYPE_ITANIUM CPU_SUBTYPE_INTEL(11, 0) +#define CPU_SUBTYPE_ITANIUM_2 CPU_SUBTYPE_INTEL(11, 1) +#define CPU_SUBTYPE_XEON CPU_SUBTYPE_INTEL(12, 0) +#define CPU_SUBTYPE_XEON_MP CPU_SUBTYPE_INTEL(12, 1) + +#define CPU_SUBTYPE_X86_ALL INT32_C(3) +#define CPU_SUBTYPE_X86_64_ALL INT32_C(3) +#define CPU_SUBTYPE_X86_ARCH1 INT32_C(4) + +#define CPU_SUBTYPE_MIPS_ALL INT32_C(0) +#define CPU_SUBTYPE_MIPS_R2300 INT32_C(1) +#define CPU_SUBTYPE_MIPS_R2600 INT32_C(2) +#define CPU_SUBTYPE_MIPS_R2800 INT32_C(3) +#define CPU_SUBTYPE_MIPS_R2000a INT32_C(4) +#define CPU_SUBTYPE_MIPS_R2000 INT32_C(5) +#define CPU_SUBTYPE_MIPS_R3000a INT32_C(6) +#define CPU_SUBTYPE_MIPS_R3000 INT32_C(7) + +#define CPU_SUBTYPE_MC98000_ALL INT32_C(0) +#define CPU_SUBTYPE_MC98601 INT32_C(1) + +#define CPU_SUBTYPE_HPPA_ALL INT32_C(0) +#define CPU_SUBTYPE_HPPA_7100 INT32_C(0) +#define CPU_SUBTYPE_HPPA_7100LC INT32_C(1) + +#define CPU_SUBTYPE_ARM_ALL INT32_C(0) +#define CPU_SUBTYPE_ARM_V4T INT32_C(5) +#define CPU_SUBTYPE_ARM_V6 INT32_C(6) +#define CPU_SUBTYPE_ARM_V5TEJ INT32_C(7) +#define CPU_SUBTYPE_ARM_XSCALE INT32_C(8) +#define CPU_SUBTYPE_ARM_V7 INT32_C(9) +#define CPU_SUBTYPE_ARM_V7F INT32_C(10) +#define CPU_SUBTYPE_ARM_V7S INT32_C(11) +#define CPU_SUBTYPE_ARM_V7K INT32_C(12) +#define CPU_SUBTYPE_ARM_V8 INT32_C(13) +#define CPU_SUBTYPE_ARM_V6M INT32_C(14) +#define CPU_SUBTYPE_ARM_V7M INT32_C(15) +#define CPU_SUBTYPE_ARM_V7EM INT32_C(16) +#define CPU_SUBTYPE_ARM_V8M INT32_C(17) + +#define CPU_SUBTYPE_ARM64_ALL INT32_C(0) +#define CPU_SUBTYPE_ARM64_V8 INT32_C(1) +#define CPU_SUBTYPE_ARM64E INT32_C(2) +#define CPU_SUBTYPE_ARM64_PTR_AUTH_MASK UINT32_C(0x0f000000) +#define CPU_SUBTYPE_ARM64_PTR_AUTH_VERSION(a) ( ((a) & CPU_SUBTYPE_ARM64_PTR_AUTH_MASK) >> 24 ) + +#define CPU_SUBTYPE_ARM64_32_ALL INT32_C(0) +#define CPU_SUBTYPE_ARM64_32_V8 INT32_C(1) + +#define CPU_SUBTYPE_MC88000_ALL INT32_C(0) +#define CPU_SUBTYPE_MC88100 INT32_C(1) +#define CPU_SUBTYPE_MC88110 INT32_C(2) + +#define CPU_SUBTYPE_SPARC_ALL INT32_C(0) + +#define CPU_SUBTYPE_I860_ALL INT32_C(0) +#define CPU_SUBTYPE_I860_860 INT32_C(1) + +#define CPU_SUBTYPE_POWERPC_ALL INT32_C(0) +#define CPU_SUBTYPE_POWERPC_601 INT32_C(1) +#define CPU_SUBTYPE_POWERPC_602 INT32_C(2) +#define CPU_SUBTYPE_POWERPC_603 INT32_C(3) +#define CPU_SUBTYPE_POWERPC_603e INT32_C(4) +#define CPU_SUBTYPE_POWERPC_603ev INT32_C(5) +#define CPU_SUBTYPE_POWERPC_604 INT32_C(6) +#define CPU_SUBTYPE_POWERPC_604e INT32_C(7) +#define CPU_SUBTYPE_POWERPC_620 INT32_C(8) +#define CPU_SUBTYPE_POWERPC_750 INT32_C(9) +#define CPU_SUBTYPE_POWERPC_7400 INT32_C(10) +#define CPU_SUBTYPE_POWERPC_7450 INT32_C(11) +#define CPU_SUBTYPE_POWERPC_Max INT32_C(10) +#define CPU_SUBTYPE_POWERPC_SCVger INT32_C(11) +#define CPU_SUBTYPE_POWERPC_970 INT32_C(100) + +#define CPU_SUBTYPE_MASK UINT32_C(0xff000000) +#define CPU_SUBTYPE_LIB64 UINT32_C(0x80000000) + +#endif /* !CPU_ARCH_MASK */ + + +typedef struct fat_header +{ + uint32_t magic; + uint32_t nfat_arch; +} fat_header_t; + +#ifndef IMAGE_FAT_SIGNATURE +# define IMAGE_FAT_SIGNATURE UINT32_C(0xcafebabe) +#endif +#ifndef IMAGE_FAT_SIGNATURE_OE +# define IMAGE_FAT_SIGNATURE_OE UINT32_C(0xbebafeca) +#endif + +typedef struct fat_arch +{ + int32_t cputype; + int32_t cpusubtype; + uint32_t offset; + uint32_t size; + uint32_t align; +} fat_arch_t; + +typedef struct mach_header_32 +{ + uint32_t magic; + int32_t cputype; + int32_t cpusubtype; + uint32_t filetype; + uint32_t ncmds; + uint32_t sizeofcmds; + uint32_t flags; +} mach_header_32_t; + +/* magic */ +#ifndef IMAGE_MACHO32_SIGNATURE +# define IMAGE_MACHO32_SIGNATURE UINT32_C(0xfeedface) +#endif +#ifndef IMAGE_MACHO32_SIGNATURE_OE +# define IMAGE_MACHO32_SIGNATURE_OE UINT32_C(0xcefaedfe) +#endif +#define MH_MAGIC IMAGE_MACHO32_SIGNATURE +#define MH_CIGAM IMAGE_MACHO32_SIGNATURE_OE + +typedef struct mach_header_64 +{ + uint32_t magic; /**< 0x00 */ + int32_t cputype; /**< 0x04 */ + int32_t cpusubtype; /**< 0x08 */ + uint32_t filetype; /**< 0x0c */ + uint32_t ncmds; /**< 0x10 */ + uint32_t sizeofcmds; /**< 0x14 */ + uint32_t flags; /**< 0x18 */ + uint32_t reserved; /**< 0x1c */ +} mach_header_64_t; +AssertCompileSize(mach_header_64_t, 0x20); + +/* magic */ +#ifndef IMAGE_MACHO64_SIGNATURE +# define IMAGE_MACHO64_SIGNATURE UINT32_C(0xfeedfacf) +#endif +#ifndef IMAGE_MACHO64_SIGNATURE_OE +# define IMAGE_MACHO64_SIGNATURE_OE UINT32_C(0xfefaedfe) +#endif +#define MH_MAGIC_64 IMAGE_MACHO64_SIGNATURE +#define MH_CIGAM_64 IMAGE_MACHO64_SIGNATURE_OE + +/* mach_header_* filetype */ +#define MH_OBJECT UINT32_C(1) +#define MH_EXECUTE UINT32_C(2) +#define MH_FVMLIB UINT32_C(3) +#define MH_CORE UINT32_C(4) +#define MH_PRELOAD UINT32_C(5) +#define MH_DYLIB UINT32_C(6) +#define MH_DYLINKER UINT32_C(7) +#define MH_BUNDLE UINT32_C(8) +#define MH_DYLIB_STUB UINT32_C(9) +#define MH_DSYM UINT32_C(10) +#define MH_KEXT_BUNDLE UINT32_C(11) + +/* mach_header_* flags */ +#define MH_NOUNDEFS UINT32_C(0x00000001) +#define MH_INCRLINK UINT32_C(0x00000002) +#define MH_DYLDLINK UINT32_C(0x00000004) +#define MH_BINDATLOAD UINT32_C(0x00000008) +#define MH_PREBOUND UINT32_C(0x00000010) +#define MH_SPLIT_SEGS UINT32_C(0x00000020) +#define MH_LAZY_INIT UINT32_C(0x00000040) +#define MH_TWOLEVEL UINT32_C(0x00000080) +#define MH_FORCE_FLAT UINT32_C(0x00000100) +#define MH_NOMULTIDEFS UINT32_C(0x00000200) +#define MH_NOFIXPREBINDING UINT32_C(0x00000400) +#define MH_PREBINDABLE UINT32_C(0x00000800) +#define MH_ALLMODSBOUND UINT32_C(0x00001000) +#define MH_SUBSECTIONS_VIA_SYMBOLS UINT32_C(0x00002000) +#define MH_CANONICAL UINT32_C(0x00004000) +#define MH_WEAK_DEFINES UINT32_C(0x00008000) +#define MH_BINDS_TO_WEAK UINT32_C(0x00010000) +#define MH_ALLOW_STACK_EXECUTION UINT32_C(0x00020000) +#define MH_ROOT_SAFE UINT32_C(0x00040000) +#define MH_SETUID_SAFE UINT32_C(0x00080000) +#define MH_NO_REEXPORTED_DYLIBS UINT32_C(0x00100000) +#define MH_PIE UINT32_C(0x00200000) +#define MH_DEAD_STRIPPABLE_DYLIB UINT32_C(0x00400000) +#define MH_HAS_TLV_DESCRIPTORS UINT32_C(0x00800000) +#define MH_NO_HEAP_EXECUTION UINT32_C(0x01000000) +#define MH_UNKNOWN UINT32_C(0x80000000) +#define MH_VALID_FLAGS UINT32_C(0x81ffffff) + + +typedef struct load_command +{ + uint32_t cmd; + uint32_t cmdsize; +} load_command_t; + +/* load cmd */ +#define LC_REQ_DYLD UINT32_C(0x80000000) +#define LC_SEGMENT_32 UINT32_C(0x01) +#define LC_SYMTAB UINT32_C(0x02) +#define LC_SYMSEG UINT32_C(0x03) +#define LC_THREAD UINT32_C(0x04) +#define LC_UNIXTHREAD UINT32_C(0x05) +#define LC_LOADFVMLIB UINT32_C(0x06) +#define LC_IDFVMLIB UINT32_C(0x07) +#define LC_IDENT UINT32_C(0x08) +#define LC_FVMFILE UINT32_C(0x09) +#define LC_PREPAGE UINT32_C(0x0a) +#define LC_DYSYMTAB UINT32_C(0x0b) +#define LC_LOAD_DYLIB UINT32_C(0x0c) +#define LC_ID_DYLIB UINT32_C(0x0d) +#define LC_LOAD_DYLINKER UINT32_C(0x0e) +#define LC_ID_DYLINKER UINT32_C(0x0f) +#define LC_PREBOUND_DYLIB UINT32_C(0x10) +#define LC_ROUTINES UINT32_C(0x11) +#define LC_SUB_FRAMEWORK UINT32_C(0x12) +#define LC_SUB_UMBRELLA UINT32_C(0x13) +#define LC_SUB_CLIENT UINT32_C(0x14) +#define LC_SUB_LIBRARY UINT32_C(0x15) +#define LC_TWOLEVEL_HINTS UINT32_C(0x16) +#define LC_PREBIND_CKSUM UINT32_C(0x17) +#define LC_LOAD_WEAK_DYLIB (UINT32_C(0x18) | LC_REQ_DYLD) +#define LC_SEGMENT_64 UINT32_C(0x19) +#define LC_ROUTINES_64 UINT32_C(0x1a) +#define LC_UUID UINT32_C(0x1b) +#define LC_RPATH (UINT32_C(0x1c) | LC_REQ_DYLD) +#define LC_CODE_SIGNATURE UINT32_C(0x1d) +#define LC_SEGMENT_SPLIT_INFO UINT32_C(0x1e) +#define LC_REEXPORT_DYLIB (UINT32_C(0x1f) | LC_REQ_DYLD) +#define LC_LAZY_LOAD_DYLIB UINT32_C(0x20) +#define LC_ENCRYPTION_INFO UINT32_C(0x21) +#define LC_DYLD_INFO UINT32_C(0x22) +#define LC_DYLD_INFO_ONLY (UINT32_C(0x22) | LC_REQ_DYLD) +#define LC_LOAD_UPWARD_DYLIB (UINT32_C(0x23) | LC_REQ_DYLD) +#define LC_VERSION_MIN_MACOSX UINT32_C(0x24) +#define LC_VERSION_MIN_IPHONEOS UINT32_C(0x25) +#define LC_FUNCTION_STARTS UINT32_C(0x26) +#define LC_DYLD_ENVIRONMENT UINT32_C(0x27) +#define LC_MAIN (UINT32_C(0x28) | LC_REQ_DYLD) +#define LC_DATA_IN_CODE UINT32_C(0x29) +#define LC_SOURCE_VERSION UINT32_C(0x2a) /**< source_version_command */ +#define LC_DYLIB_CODE_SIGN_DRS UINT32_C(0x2b) +#define LC_ENCRYPTION_INFO_64 UINT32_C(0x2c) +#define LC_LINKER_OPTION UINT32_C(0x2d) +#define LC_LINKER_OPTIMIZATION_HINT UINT32_C(0x2e) +#define LC_VERSION_MIN_TVOS UINT32_C(0x2f) +#define LC_VERSION_MIN_WATCHOS UINT32_C(0x30) +#define LC_NOTE UINT32_C(0x31) +#define LC_BUILD_VERSION UINT32_C(0x32) + + +typedef struct lc_str +{ + uint32_t offset; +} lc_str_t; + +typedef struct segment_command_32 +{ + uint32_t cmd; + uint32_t cmdsize; + char segname[16]; + uint32_t vmaddr; + uint32_t vmsize; + uint32_t fileoff; + uint32_t filesize; + uint32_t maxprot; + uint32_t initprot; + uint32_t nsects; + uint32_t flags; +} segment_command_32_t; + +typedef struct segment_command_64 +{ + uint32_t cmd; + uint32_t cmdsize; + char segname[16]; + uint64_t vmaddr; + uint64_t vmsize; + uint64_t fileoff; + uint64_t filesize; + uint32_t maxprot; + uint32_t initprot; + uint32_t nsects; + uint32_t flags; +} segment_command_64_t; + +/* segment flags */ +#define SG_HIGHVM UINT32_C(0x00000001) +#define SG_FVMLIB UINT32_C(0x00000002) +#define SG_NORELOC UINT32_C(0x00000004) +#define SG_PROTECTED_VERSION_1 UINT32_C(0x00000008) +#define SG_READ_ONLY UINT32_C(0x00000010) /**< Make it read-only after applying fixups. @since 10.14 */ + +/* maxprot/initprot */ +#ifndef VM_PROT_NONE +# define VM_PROT_NONE UINT32_C(0x00000000) +# define VM_PROT_READ UINT32_C(0x00000001) +# define VM_PROT_WRITE UINT32_C(0x00000002) +# define VM_PROT_EXECUTE UINT32_C(0x00000004) +# define VM_PROT_ALL UINT32_C(0x00000007) +#endif + +typedef struct section_32 +{ + char sectname[16]; + char segname[16]; + uint32_t addr; + uint32_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + /** For S_LAZY_SYMBOL_POINTERS, S_NON_LAZY_SYMBOL_POINTERS and S_SYMBOL_STUBS + * this is the index into the indirect symbol table. */ + uint32_t reserved1; + /** For S_SYMBOL_STUBS this is the entry size. */ + uint32_t reserved2; +} section_32_t; + +typedef struct section_64 +{ + char sectname[16]; + char segname[16]; + uint64_t addr; + uint64_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + /** For S_LAZY_SYMBOL_POINTERS, S_NON_LAZY_SYMBOL_POINTERS and S_SYMBOL_STUBS + * this is the index into the indirect symbol table. */ + uint32_t reserved1; + uint32_t reserved2; + uint32_t reserved3; +} section_64_t; + +/* section flags */ +#define SECTION_TYPE UINT32_C(0xff) +#define S_REGULAR UINT32_C(0x00) +#define S_ZEROFILL UINT32_C(0x01) +#define S_CSTRING_LITERALS UINT32_C(0x02) +#define S_4BYTE_LITERALS UINT32_C(0x03) +#define S_8BYTE_LITERALS UINT32_C(0x04) +#define S_LITERAL_POINTERS UINT32_C(0x05) +#define S_NON_LAZY_SYMBOL_POINTERS UINT32_C(0x06) +#define S_LAZY_SYMBOL_POINTERS UINT32_C(0x07) +#define S_SYMBOL_STUBS UINT32_C(0x08) +#define S_MOD_INIT_FUNC_POINTERS UINT32_C(0x09) +#define S_MOD_TERM_FUNC_POINTERS UINT32_C(0x0a) +#define S_COALESCED UINT32_C(0x0b) +#define S_GB_ZEROFILL UINT32_C(0x0c) +#define S_INTERPOSING UINT32_C(0x0d) +#define S_16BYTE_LITERALS UINT32_C(0x0e) +#define S_DTRACE_DOF UINT32_C(0x0f) +#define S_LAZY_DYLIB_SYMBOL_POINTERS UINT32_C(0x10) +#define S_THREAD_LOCAL_REGULAR UINT32_C(0x11) +#define S_THREAD_LOCAL_ZEROFILL UINT32_C(0x12) +#define S_THREAD_LOCAL_VARIABLES UINT32_C(0x13) +#define S_THREAD_LOCAL_VARIABLE_POINTERS UINT32_C(0x14) +#define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS UINT32_C(0x15) + + + + +#define SECTION_ATTRIBUTES UINT32_C(0xffffff00) +#define SECTION_ATTRIBUTES_USR UINT32_C(0xff000000) +#define S_ATTR_PURE_INSTRUCTIONS UINT32_C(0x80000000) +#define S_ATTR_NO_TOC UINT32_C(0x40000000) +#define S_ATTR_STRIP_STATIC_SYMS UINT32_C(0x20000000) +#define S_ATTR_NO_DEAD_STRIP UINT32_C(0x10000000) +#define S_ATTR_LIVE_SUPPORT UINT32_C(0x08000000) +#define S_ATTR_SELF_MODIFYING_CODE UINT32_C(0x04000000) +#define S_ATTR_DEBUG UINT32_C(0x02000000) +#define SECTION_ATTRIBUTES_SYS UINT32_C(0x00ffff00) +#define S_ATTR_SOME_INSTRUCTIONS UINT32_C(0x00000400) +#define S_ATTR_EXT_RELOC UINT32_C(0x00000200) +#define S_ATTR_LOC_RELOC UINT32_C(0x00000100) + +/* standard section names */ +#define SEG_PAGEZERO "__PAGEZERO" +#define SEG_TEXT "__TEXT" +#define SECT_TEXT "__text" +#define SECT_FVMLIB_INIT0 "__fvmlib_init0" +#define SECT_FVMLIB_INIT1 "__fvmlib_init1" +#define SEG_DATA "__DATA" +#define SECT_DATA "__data" +#define SECT_BSS "__bss" +#define SECT_COMMON "__common" +#define SEG_OBJC "__OBJC" +#define SECT_OBJC_SYMBOLS "__symbol_table" +#define SECT_OBJC_MODULES "__module_info" +#define SECT_OBJC_STRINGS "__selector_strs" +#define SECT_OBJC_REFS "__selector_refs" +#define SEG_ICON "__ICON" +#define SECT_ICON_HEADER "__header" +#define SECT_ICON_TIFF "__tiff" +#define SEG_LINKEDIT "__LINKEDIT" +#define SEG_UNIXSTACK "__UNIXSTACK" +#define SEG_IMPORT "__IMPORT" + +typedef struct thread_command +{ + uint32_t cmd; + uint32_t cmdsize; +} thread_command_t; + +typedef struct symtab_command +{ + uint32_t cmd; + uint32_t cmdsize; + uint32_t symoff; + uint32_t nsyms; + uint32_t stroff; + uint32_t strsize; +} symtab_command_t; + +typedef struct dysymtab_command +{ + uint32_t cmd; + uint32_t cmdsize; + /** @name Symbol groupings. + * @{ */ + uint32_t ilocalsym; /**< Index into the symbol table of the first local symbol. */ + uint32_t nlocalsym; /**< Number of local symbols. */ + uint32_t iextdefsym; /**< Index into the symbol table of the first externally defined symbol. */ + uint32_t nextdefsym; /**< Number of externally defined symbols. */ + uint32_t iundefsym; /**< Index into the symbol table of the first undefined symbol. */ + uint32_t nundefsym; /**< Number of undefined symbols. */ + /** @} */ + uint32_t tocoff; /**< Table of content file offset. (usually empty) */ + uint32_t ntoc; /**< Number of entries in TOC. */ + uint32_t modtaboff; /** The module table file offset. (usually empty) */ + uint32_t nmodtab; /**< Number of entries in the module table. */ + /** @name Dynamic symbol tables. + * @{ */ + uint32_t extrefsymoff; /**< Externally referenceable symbol table file offset. @sa dylib_reference_t */ + uint32_t nextrefsym; /**< Number externally referenceable symbols. */ + uint32_t indirectsymboff; /**< Indirect symbol table (32-bit symtab indexes) for thunks and offset tables. */ + uint32_t nindirectsymb; /**< Number of indirect symbol table entries. */ + /** @} */ + /** @name Relocations. + * @{ */ + uint32_t extreloff; /**< External relocations (r_address is relative to first segment (i.e. RVA)). */ + uint32_t nextrel; /**< Number of external relocations. */ + uint32_t locreloff; /**< Local relocations (r_address is relative to first segment (i.e. RVA)). */ + uint32_t nlocrel; /**< Number of local relocations. */ + /** @} */ +} dysymtab_command_t; +AssertCompileSize(dysymtab_command_t, 80); + +/** Special indirect symbol table entry value, stripped local symbol. */ +#define INDIRECT_SYMBOL_LOCAL UINT32_C(0x80000000) +/** Special indirect symbol table entry value, stripped absolute symbol. */ +#define INDIRECT_SYMBOL_ABS UINT32_C(0x40000000) + +typedef struct dylib_reference +{ + uint32_t isym : 24; /**< Symbol table index. */ + uint32_t flags : 8; /**< REFERENCE_FLAG_XXX? */ +} dylib_reference_t; +AssertCompileSize(dylib_reference_t, 4); + + +typedef struct dylib_table_of_contents +{ + uint32_t symbol_index; /**< External symbol table entry. */ + uint32_t module_index; /**< The module table index of the module defining it. */ +} dylib_table_of_contents_t; +AssertCompileSize(dylib_table_of_contents_t, 8); + + +/** 32-bit module table entry. */ +typedef struct dylib_module +{ + uint32_t module_name; + uint32_t iextdefsym; + uint32_t nextdefsym; + uint32_t irefsym; + uint32_t nrefsym; + uint32_t ilocalsym; + uint32_t nlocalsym; + uint32_t iextrel; + uint32_t nextrel; + uint32_t iinit_iterm; + uint32_t ninit_nterm; + uint32_t objc_module_info_addr; + uint32_t objc_module_info_size; +} dylib_module_32_t; +AssertCompileSize(dylib_module_32_t, 13*4); + +/* a 64-bit module table entry */ +typedef struct dylib_module_64 +{ + uint32_t module_name; + uint32_t iextdefsym; + uint32_t nextdefsym; + uint32_t irefsym; + uint32_t nrefsym; + uint32_t ilocalsym; + uint32_t nlocalsym; + uint32_t iextrel; + uint32_t nextrel; + uint32_t iinit_iterm; + uint32_t ninit_nterm; + uint32_t objc_module_info_size; + uint64_t objc_module_info_addr; +} dylib_module_64_t; +AssertCompileSize(dylib_module_64_t, 12*4+8); + +typedef struct uuid_command +{ + uint32_t cmd; + uint32_t cmdsize; + uint8_t uuid[16]; +} uuid_command_t; +AssertCompileSize(uuid_command_t, 24); + +typedef struct linkedit_data_command +{ + uint32_t cmd; /**< LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS */ + uint32_t cmdsize; /**< Size of this structure (16). */ + uint32_t dataoff; /**< Offset into the file of the data. */ + uint32_t datasize; /**< The size of the data. */ +} linkedit_data_command_t; +AssertCompileSize(linkedit_data_command_t, 16); + +typedef struct version_min_command +{ + uint32_t cmd; /**< LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS, LC_VERSION_MIN_WATCHOS */ + uint32_t cmdsize; /**< Size of this structure (16). */ + uint32_t version; /**< 31..16=major, 15..8=minor, 7..0=patch. */ + uint32_t reserved; /**< MBZ. */ +} version_min_command_t; +AssertCompileSize(version_min_command_t, 16); + +typedef struct build_tool_version +{ + uint32_t tool; /**< TOOL_XXX */ + uint32_t version; /**< 31..16=major, 15..8=minor, 7..0=patch. */ +} build_tool_version_t; +AssertCompileSize(build_tool_version_t, 8); + +/** @name TOOL_XXX - Values for build_tool_version::tool + * @{ */ +#define TOOL_CLANG 1 +#define TOOL_SWIFT 2 +#define TOOL_LD 3 +/** @} */ + +typedef struct build_version_command +{ + uint32_t cmd; /**< LC_BUILD_VERSION */ + uint32_t cmdsize; /**< Size of this structure (at least 24). */ + uint32_t platform; /**< PLATFORM_XXX */ + uint32_t minos; /**< Minimum OS version: 31..16=major, 15..8=minor, 7..0=patch */ + uint32_t sdk; /**< SDK version: 31..16=major, 15..8=minor, 7..0=patch */ + uint32_t ntools; /**< Number of build_tool_version entries following in aTools. */ + RT_FLEXIBLE_ARRAY_EXTENSION + build_tool_version_t aTools[RT_FLEXIBLE_ARRAY]; +} build_version_command_t; +AssertCompileMemberOffset(build_version_command_t, aTools, 24); + +/** @name PLATFORM_XXX - Values for build_version_command::platform + * @{ */ +#define PLATFORM_MACOS 1 +#define PLATFORM_IOS 2 +#define PLATFORM_TVOS 3 +#define PLATFORM_WATCHOS 4 +/** @} */ + +typedef struct source_version_command +{ + uint32_t cmd; /**< LC_SOURCE_VERSION */ + uint32_t cmdsize; /**< Size of this structure (16). */ + uint64_t version; /**< A.B.C.D.E, where A is 24 bits wide and the rest 10 bits each. */ +} source_version_command_t; +AssertCompileSize(source_version_command_t, 16); + + +typedef struct macho_nlist_32 +{ + union + { + int32_t n_strx; + } n_un; + uint8_t n_type; + uint8_t n_sect; + int16_t n_desc; + uint32_t n_value; +} macho_nlist_32_t; + + +typedef struct macho_nlist_64 +{ + union + { + uint32_t n_strx; + } n_un; + uint8_t n_type; + uint8_t n_sect; + int16_t n_desc; + uint64_t n_value; +} macho_nlist_64_t; + +#define MACHO_N_EXT UINT8_C(0x01) +#define MACHO_N_PEXT UINT8_C(0x10) + +#define MACHO_N_TYPE UINT8_C(0x0e) +#define MACHO_N_UNDF UINT8_C(0x00) +#define MACHO_N_ABS UINT8_C(0x02) +#define MACHO_N_INDR UINT8_C(0x0a) +#define MACHO_N_PBUD UINT8_C(0x0c) +#define MACHO_N_SECT UINT8_C(0x0e) + +#define MACHO_N_STAB UINT8_C(0xe0) +#define MACHO_N_GSYM UINT8_C(0x20) +#define MACHO_N_FNAME UINT8_C(0x22) +#define MACHO_N_FUN UINT8_C(0x24) +#define MACHO_N_STSYM UINT8_C(0x26) +#define MACHO_N_LCSYM UINT8_C(0x28) +#define MACHO_N_BNSYM UINT8_C(0x2e) +#define MACHO_N_PC UINT8_C(0x30) +#define MACHO_N_OPT UINT8_C(0x3c) +#define MACHO_N_RSYM UINT8_C(0x40) +#define MACHO_N_SLINE UINT8_C(0x44) +#define MACHO_N_ENSYM UINT8_C(0x4e) +#define MACHO_N_SSYM UINT8_C(0x60) +#define MACHO_N_SO UINT8_C(0x64) +#define MACHO_N_OSO UINT8_C(0x66) +#define MACHO_N_LSYM UINT8_C(0x80) +#define MACHO_N_BINCL UINT8_C(0x82) +#define MACHO_N_SOL UINT8_C(0x84) +#define MACHO_N_PARAMS UINT8_C(0x86) +#define MACHO_N_VERSION UINT8_C(0x88) +#define MACHO_N_OLEVEL UINT8_C(0x8A) +#define MACHO_N_PSYM UINT8_C(0xa0) +#define MACHO_N_EINCL UINT8_C(0xa2) +#define MACHO_N_ENTRY UINT8_C(0xa4) +#define MACHO_N_LBRAC UINT8_C(0xc0) +#define MACHO_N_EXCL UINT8_C(0xc2) +#define MACHO_N_RBRAC UINT8_C(0xe0) +#define MACHO_N_BCOMM UINT8_C(0xe2) +#define MACHO_N_ECOMM UINT8_C(0xe4) +#define MACHO_N_ECOML UINT8_C(0xe8) +#define MACHO_N_LENG UINT8_C(0xfe) + +#define MACHO_NO_SECT UINT8_C(0x00) +#define MACHO_MAX_SECT UINT8_C(0xff) + +#define REFERENCE_TYPE UINT16_C(0x000f) +#define REFERENCE_FLAG_UNDEFINED_NON_LAZY 0 +#define REFERENCE_FLAG_UNDEFINED_LAZY 1 +#define REFERENCE_FLAG_DEFINED 2 +#define REFERENCE_FLAG_PRIVATE_DEFINED 3 +#define REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY 4 +#define REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY 5 +#define REFERENCED_DYNAMICALLY UINT16_C(0x0010) + +#define GET_LIBRARY_ORDINAL(a_n_desc) \ + RT_BYTE2(a_n_desc) +#define SET_LIBRARY_ORDINAL(a_n_desc, a_ordinal) \ + do { (a_n_desc) = RT_MAKE_U16(RT_BYTE1(a_n_desc), a_ordinal); } while (0) + +#define SELF_LIBRARY_ORDINAL 0x00 +#define MAX_LIBRARY_ORDINAL 0xfd +#define DYNAMIC_LOOKUP_ORDINAL 0xfe +#define EXECUTABLE_ORDINAL 0xff + +#define N_NO_DEAD_STRIP UINT16_C(0x0020) +#define N_DESC_DISCARDED UINT16_C(0x0020) +#define N_WEAK_REF UINT16_C(0x0040) +#define N_WEAK_DEF UINT16_C(0x0080) +#define N_REF_TO_WEAK UINT16_C(0x0080) +#define N_SYMBOL_RESOLVER UINT16_C(0x0100) +#define N_ALT_ENTRY UINT16_C(0x0200) + +typedef struct macho_relocation_info +{ + int32_t r_address; + uint32_t r_symbolnum : 24; + uint32_t r_pcrel : 1; + uint32_t r_length : 2; + uint32_t r_extern : 1; + uint32_t r_type : 4; +} macho_relocation_info_t; +AssertCompileSize(macho_relocation_info_t, 8); + +#define R_ABS 0 +#define R_SCATTERED UINT32_C(0x80000000) + +typedef struct scattered_relocation_info +{ +#ifdef RT_LITTLE_ENDIAN + uint32_t r_address : 24; + uint32_t r_type : 4; + uint32_t r_length : 2; + uint32_t r_pcrel : 1; + uint32_t r_scattered : 1; +#elif defined(RT_BIG_ENDIAN) + uint32_t r_scattered : 1; + uint32_t r_pcrel : 1; + uint32_t r_length : 2; + uint32_t r_type : 4; + uint32_t r_address : 24; +#else +# error "Neither K_ENDIAN isn't LITTLE or BIG!" +#endif + int32_t r_value; +} scattered_relocation_info_t; +AssertCompileSize(scattered_relocation_info_t, 8); + +typedef union +{ + macho_relocation_info_t r; + scattered_relocation_info_t s; +} macho_relocation_union_t; +AssertCompileSize(macho_relocation_union_t, 8); + +typedef enum reloc_type_generic +{ + GENERIC_RELOC_VANILLA = 0, + GENERIC_RELOC_PAIR, + GENERIC_RELOC_SECTDIFF, + GENERIC_RELOC_PB_LA_PTR, + GENERIC_RELOC_LOCAL_SECTDIFF +} reloc_type_generic_t; + +typedef enum reloc_type_x86_64 +{ + X86_64_RELOC_UNSIGNED = 0, + X86_64_RELOC_SIGNED, + X86_64_RELOC_BRANCH, + X86_64_RELOC_GOT_LOAD, + X86_64_RELOC_GOT, + X86_64_RELOC_SUBTRACTOR, + X86_64_RELOC_SIGNED_1, + X86_64_RELOC_SIGNED_2, + X86_64_RELOC_SIGNED_4 +} reloc_type_x86_64_t; + +#endif /* !IPRT_INCLUDED_formats_mach_o_h */ + diff --git a/include/iprt/formats/mz.h b/include/iprt/formats/mz.h new file mode 100644 index 00000000..34bcd4ff --- /dev/null +++ b/include/iprt/formats/mz.h @@ -0,0 +1,77 @@ +/* $Id: mz.h $ */ +/** @file + * IPRT, MZ Executable Header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_mz_h +#define IPRT_INCLUDED_formats_mz_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + +typedef struct _IMAGE_DOS_HEADER +{ + uint16_t e_magic; + uint16_t e_cblp; + uint16_t e_cp; + uint16_t e_crlc; + uint16_t e_cparhdr; + uint16_t e_minalloc; + uint16_t e_maxalloc; + uint16_t e_ss; + uint16_t e_sp; + uint16_t e_csum; + uint16_t e_ip; + uint16_t e_cs; + uint16_t e_lfarlc; + uint16_t e_ovno; + uint16_t e_res[4]; + uint16_t e_oemid; + uint16_t e_oeminfo; + uint16_t e_res2[10]; + uint32_t e_lfanew; +} IMAGE_DOS_HEADER; +AssertCompileSize(IMAGE_DOS_HEADER, 0x40); +typedef IMAGE_DOS_HEADER *PIMAGE_DOS_HEADER; + +#ifndef IMAGE_DOS_SIGNATURE +# define IMAGE_DOS_SIGNATURE ('M' | ('Z' << 8)) /* fix endianness */ +#endif + + +#endif /* !IPRT_INCLUDED_formats_mz_h */ + diff --git a/include/iprt/formats/mz.mac b/include/iprt/formats/mz.mac new file mode 100644 index 00000000..b84bf761 --- /dev/null +++ b/include/iprt/formats/mz.mac @@ -0,0 +1,66 @@ +;; @file +; IPRT - MZ (DOS Executable Header) definitions for YASM/NASM. +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +%ifndef ___iprt_formats_mz_mac +%define ___iprt_formats_mz_mac + +struc IMAGE_DOS_HEADER + .e_magic resw 1 + .e_cblp resw 1 + .e_cp resw 1 + .e_crlc resw 1 + .e_cparhdr resw 1 + .e_minalloc resw 1 + .e_maxalloc resw 1 + .e_ss resw 1 + .e_sp resw 1 + .e_csum resw 1 + .e_ip resw 1 + .e_cs resw 1 + .e_lfarlc resw 1 + .e_ovno resw 1 + .e_res resw 4 + .e_oemid resw 1 + .e_oeminfo resw 1 + .e_res2 resw 10 + .e_lfanew resd 1 +endstruc + +%ifndef IMAGE_DOS_SIGNATURE + %define IMAGE_DOS_SIGNATURE 0x5a4d +%endif + +%endif + diff --git a/include/iprt/formats/ntfs.h b/include/iprt/formats/ntfs.h new file mode 100644 index 00000000..577ce847 --- /dev/null +++ b/include/iprt/formats/ntfs.h @@ -0,0 +1,782 @@ +/* $Id: ntfs.h $ */ +/** @file + * IPRT, NT File System (NTFS). + */ + +/* + * Copyright (C) 2017-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_ntfs_h +#define IPRT_INCLUDED_formats_ntfs_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/formats/fat.h> + + +/** @defgroup grp_rt_formats_ntfs NT File System (NTFS) structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + +/** Value of the FATBOOTSECTOR::achOemName for an NTFS file system. */ +#define NTFS_OEM_ID_MAGIC "NTFS " + + +/** @name NTFS_MFT_IDX_XXX - Predefined MFT indexes. + * @{ */ +#define NTFS_MFT_IDX_MFT 0 /**< The MFT itself. */ +#define NTFS_MFT_IDX_MFT_MIRROR 1 /**< Mirror MFT (partial?). */ +#define NTFS_MFT_IDX_LOG_FILE 2 /**< Journalling log. */ +#define NTFS_MFT_IDX_VOLUME 3 /**< Volume attributes. */ +#define NTFS_MFT_IDX_ATTRIB_DEF 4 /**< Attribute definitions. */ +#define NTFS_MFT_IDX_ROOT 5 /**< The root directory. */ +#define NTFS_MFT_IDX_BITMAP 6 /**< Allocation bitmap. */ +#define NTFS_MFT_IDX_BOOT 7 /**< The boot sector. */ +#define NTFS_MFT_IDX_BAD_CLUSTER 8 /**< Bad cluster table. */ +#define NTFS_MFT_IDX_SECURITY 9 /**< Shared security descriptors (w2k and later). */ +#define NTFS_MFT_IDX_UP_CASE 10 /**< Unicode upper case table. */ +#define NTFS_MFT_IDX_EXTEND 11 /**< Directory containing further system files. */ +#define NTFS_MFT_IDX_FIRST_USER 16 /**< The first user file. */ +/** @} */ + +/** + * NTFS MFT record reference. + */ +typedef union NTFSMFTREF +{ + /** unsigned 64-bit view. */ + uint64_t u64; + /** unsigned 32-bit view. */ + uint32_t au32[2]; + /** unsigned 16-bit view. */ + uint16_t au16[4]; + + /** Structured view. */ + struct + { + /** Index of the master file table record. */ + RT_GCC_EXTENSION uint64_t idxMft : 48; + /** MFT record reuse sequence number (for catching dangling references). */ + RT_GCC_EXTENSION uint64_t uRecReuseSeqNo : 16; + } s; +} NTFSMFTREF; +AssertCompileSize(NTFSMFTREF, 8); +/** Pointer to a NTFS MFT record reference. */ +typedef NTFSMFTREF *PNTFSMFTREF; +/** Pointer to a const NTFS MFT record reference. */ +typedef NTFSMFTREF const *PCNTFSMFTREF; + +/** @name NTFSMFTREF_GET_IDX + * Gets the MFT index number (host endian) from a MFT reference. */ +/** @name NTFSMFTREF_GET_SEQ + * Gets the MFT reuse sequence number (host endian) from a MFT reference. */ +/** @name NTFSMFTREF_SET_IDX + * Sets the MFT index number of a MFT reference. */ +/** @name NTFSMFTREF_SET_SEQ + * Sets the MFT reuse sequence number of a MFT reference. */ +/** @name NTFSMFTREF_SET + * Sets the values of a MFT reference. */ +#ifdef RT_LITTLE_ENDIAN +# define NTFSMFTREF_GET_IDX(a_pMftRef) ((a_pMftRef)->s.idxMft) +# define NTFSMFTREF_GET_SEQ(a_pMftRef) ((a_pMftRef)->s.uRecReuseSeqNo) +# define NTFSMFTREF_SET_SEQ(a_pMftRef, a_uValue) do { (a_pMftRef)->s.uRecReuseSeqNo = (a_uValue); } while (0) +# define NTFSMFTREF_SET_IDX(a_pMftRef, a_uValue) do { (a_pMftRef)->s.idxMft = (a_uValue); } while (0) +# define NTFSMFTREF_SET(a_pMftRef, a_idx, a_uSeq) \ + do { \ + (a_pMftRef)->s.idxMft = (a_idx); \ + (a_pMftRef)->s.uRecReuseSeqNo = (a_uSeq); \ + } while (0) +#else +# define NTFSMFTREF_GET_IDX(a_pMftRef) (RT_LE2H_U64((a_pMftRef)->u64) & UINT64_C(0x0000ffffffffffff)) +# define NTFSMFTREF_GET_SEQ(a_pMftRef) RT_LE2H_U16((uint16_t)(a_pMftRef)->u64) +# define NTFSMFTREF_SET_SEQ(a_pMftRef, a_uValue) do { (a_pMftRef)->au16[3] = RT_H2LE_U16(a_uValue); } while (0) +# define NTFSMFTREF_SET_IDX(a_pMftRef, a_uValue) \ + do { \ + (a_pMftRef)->au32[0] = RT_H2LE_U32((uint32_t)(a_uValue)); \ + (a_pMftRef)->au16[2] = RT_H2LE_U16((uint16_t)((a_uValue) >> 32)); \ + } while (0) +# define NTFSMFTREF_SET(a_pMftRef, a_idx, a_uSeq) \ + do { \ + (a_pMftRef)->au32[0] = RT_H2LE_U32((uint32_t)(a_idx)); \ + (a_pMftRef)->au16[2] = RT_H2LE_U16((uint16_t)((a_idx) >> 32)); \ + (a_pMftRef)->au16[3] = RT_H2LE_U16((uint16_t)(a_uSeq)); \ + } while (0) +#endif +/** Check that the reference is zero. */ +#define NTFSMFTREF_IS_ZERO(a_pMftRef) ((a_pMftRef)->u64 == 0) + + +/** + * NTFS record header. + */ +typedef struct NTFSRECHDR +{ + /** Magic number (usually ASCII). */ + uint32_t uMagic; + /** Offset of the update sequence array from the start of the record. */ + uint16_t offUpdateSeqArray; + /** Number of entries in the update sequence array. (uint16_t sized entries) */ + uint16_t cUpdateSeqEntries; +} NTFSRECHDR; +AssertCompileSize(NTFSRECHDR, 8); +/** Pointer to a NTFS record header. */ +typedef NTFSRECHDR *PNTFSRECHDR; +/** Pointer to a const NTFS record header. */ +typedef NTFSRECHDR const *PCNTFSRECHDR; + +/** The multi-sector update sequence stride. + * @see https://msdn.microsoft.com/en-us/library/bb470212%28v=vs.85%29.aspx + * @see NTFSRECHDR::offUpdateSeqArray, NTFSRECHDR::cUpdateSeqEntries + */ +#define NTFS_MULTI_SECTOR_STRIDE 512 + + +/** + * NTFS file record (in the MFT). + */ +typedef struct NTFSRECFILE +{ + /** 0x00: Header with NTFSREC_MAGIC_FILE. */ + NTFSRECHDR Hdr; + /** 0x08: Log file sequence number. */ + uint64_t uLsn; + /** 0x10: MFT record reuse sequence number (for dangling MFT references). */ + uint16_t uRecReuseSeqNo; + /** 0x12: Number of hard links. */ + uint16_t cLinks; + /** 0x14: Offset of the first attribute (relative to start of record). */ + uint16_t offFirstAttrib; + /** 0x16: Record flags (NTFSRECFILE_F_XXX). */ + uint16_t fFlags; + /** 0x18: Number of byte in use in this MFT record. */ + uint32_t cbRecUsed; + /** 0x1c: The MFT record size. */ + uint32_t cbRecSize; + /** 0x20: Reference to the base MFT record. */ + NTFSMFTREF BaseMftRec; + /** 0x28: Next attribute instance number. */ + uint16_t idNextAttrib; + /** 0x2a: Padding if NTFS 3.1+, update sequence array if older. */ + uint16_t uPaddingOrUsa; + /** 0x2c: MFT index of this record. */ + uint32_t idxMftSelf; +} NTFSRECFILE; +AssertCompileSize(NTFSRECFILE, 0x30); +/** Pointer to a NTFS file record. */ +typedef NTFSRECFILE *PNTFSRECFILE; +/** Pointer to a const NTFS file record. */ +typedef NTFSRECFILE const *PCNTFSRECFILE; + + +/** NTFS 'FILE' record magic value. */ +#define NTFSREC_MAGIC_FILE RT_H2LE_U32_C(UINT32_C(0x454c4946)) + +/** @name NTFSRECFILE_F_XXX - NTFSRECFILE::fFlags. + * @{ */ +/** MFT record is in use. */ +#define NTFSRECFILE_F_IN_USE RT_H2LE_U16_C(UINT16_C(0x0001)) +/** Directory record. */ +#define NTFSRECFILE_F_DIRECTORY RT_H2LE_U16_C(UINT16_C(0x0002)) +/** @} */ + + +/** @name NTFS_AT_XXX - Attribute types + * @{ */ +#define NTFS_AT_UNUSED RT_H2LE_U32_C(UINT32_C(0x00000000)) +/** NTFSATSTDINFO */ +#define NTFS_AT_STANDARD_INFORMATION RT_H2LE_U32_C(UINT32_C(0x00000010)) +/** NTFSATLISTENTRY */ +#define NTFS_AT_ATTRIBUTE_LIST RT_H2LE_U32_C(UINT32_C(0x00000020)) +/** NTFSATFILENAME */ +#define NTFS_AT_FILENAME RT_H2LE_U32_C(UINT32_C(0x00000030)) +#define NTFS_AT_OBJECT_ID RT_H2LE_U32_C(UINT32_C(0x00000040)) +#define NTFS_AT_SECURITY_DESCRIPTOR RT_H2LE_U32_C(UINT32_C(0x00000050)) +#define NTFS_AT_VOLUME_NAME RT_H2LE_U32_C(UINT32_C(0x00000060)) +/** NTFSATVOLUMEINFO */ +#define NTFS_AT_VOLUME_INFORMATION RT_H2LE_U32_C(UINT32_C(0x00000070)) +#define NTFS_AT_DATA RT_H2LE_U32_C(UINT32_C(0x00000080)) +/** NTFSATINDEXROOT */ +#define NTFS_AT_INDEX_ROOT RT_H2LE_U32_C(UINT32_C(0x00000090)) +#define NTFS_AT_INDEX_ALLOCATION RT_H2LE_U32_C(UINT32_C(0x000000a0)) +#define NTFS_AT_BITMAP RT_H2LE_U32_C(UINT32_C(0x000000b0)) +#define NTFS_AT_REPARSE_POINT RT_H2LE_U32_C(UINT32_C(0x000000c0)) +#define NTFS_AT_EA_INFORMATION RT_H2LE_U32_C(UINT32_C(0x000000d0)) +#define NTFS_AT_EA RT_H2LE_U32_C(UINT32_C(0x000000e0)) +#define NTFS_AT_PROPERTY_SET RT_H2LE_U32_C(UINT32_C(0x000000f0)) +#define NTFS_AT_LOGGED_UTILITY_STREAM RT_H2LE_U32_C(UINT32_C(0x00000100)) +#define NTFS_AT_FIRST_USER_DEFINED RT_H2LE_U32_C(UINT32_C(0x00001000)) +#define NTFS_AT_END RT_H2LE_U32_C(UINT32_C(0xffffffff)) +/** @} */ + +/** @name NTFS_AF_XXX - Attribute flags. + * @{ */ +#define NTFS_AF_COMPR_FMT_NONE RT_H2LE_U16_C(UINT16_C(0x0000)) +/** See RtlCompressBuffer / COMPRESSION_FORMAT_LZNT1. */ +#define NTFS_AF_COMPR_FMT_LZNT1 RT_H2LE_U16_C(UINT16_C(0x0001)) +/** See RtlCompressBuffer / COMPRESSION_FORMAT_XPRESS_HUFF. */ +#define NTFS_AF_COMPR_FMT_XPRESS RT_H2LE_U16_C(UINT16_C(0x0002)) +/** See RtlCompressBuffer / COMPRESSION_FORMAT_XPRESS_HUFF. */ +#define NTFS_AF_COMPR_FMT_XPRESS_HUFF RT_H2LE_U16_C(UINT16_C(0x0003)) +#define NTFS_AF_COMPR_FMT_MASK RT_H2LE_U16_C(UINT16_C(0x00ff)) +#define NTFS_AF_ENCRYPTED RT_H2LE_U16_C(UINT16_C(0x4000)) +#define NTFS_AF_SPARSE RT_H2LE_U16_C(UINT16_C(0x8000)) +/** @} */ + +/** + * NTFS attribute header. + * + * This has three forms: + * - Resident + * - Non-resident, no compression + * - Non-resident, compressed. + * + * Each form translates to a different header size. + */ +typedef struct NTFSATTRIBHDR +{ + /** 0x00: Attribute type (NTFS_AT_XXX). */ + uint32_t uAttrType; + /** 0x04: Length of this attribute (resident part). */ + uint32_t cbAttrib; + /** 0x08: Set (1) if non-resident attribute, 0 if resident. */ + uint8_t fNonResident; + /** 0x09: Attribute name length (can be zero). */ + uint8_t cwcName; + /** 0x0a: Offset of the name string (relative to the start of this header). */ + uint16_t offName; + /** 0x0c: NTFS_AF_XXX. */ + uint16_t fFlags; + /** 0x0e: Attribute instance number. Unique within the MFT record. */ + uint16_t idAttrib; + /** 0x10: Data depending on the fNonResident member value. */ + union + { + /** Resident attributes. */ + struct + { + /** 0x10: Attribute value length. */ + uint32_t cbValue; + /** 0x14: Offset of the value (relative to the start of this header). */ + uint16_t offValue; + /** 0x16: NTFS_RES_AF_XXX. */ + uint8_t fFlags; + /** 0x17: Reserved. */ + uint8_t bReserved; + } Res; + + /** Non-resident attributes. */ + struct + { + /** 0x10: The first virtual cluster containing data. + * + * This is mainly for internal checking when the run list doesn't fit in one + * MFT record. It can also be used to avoid recording a sparse run at the + * beginning of the data covered by this attribute record. */ + int64_t iVcnFirst; + /** 0x18: The last virtual cluster containing data (inclusive). */ + int64_t iVcnLast; + /** 0x20: Offset of the mapping pair program. This program gives us a mapping + * between VNC and LCN for the attribute value. */ + uint16_t offMappingPairs; + /** 0x22: Power of two compression unit size in clusters (cbCluster << uCompessionUnit). + * Zero means uncompressed. */ + uint8_t uCompressionUnit; + /** 0x23: Reserved */ + uint8_t abReserved[5]; + /** 0x28: Allocated size (rouneded to cluster). + * @note Only set in the first attribute record (iVcnFirst == 0). */ + int64_t cbAllocated; + /** 0x30: The exact length of the data. + * @note Only set in the first attribute record (iVcnFirst == 0). */ + int64_t cbData; + /** 0x38: The length of the initialized data. (Not necessarily + * rounded up to cluster size.) + * @note Only set in the first attribute record (iVcnFirst == 0). */ + int64_t cbInitialized; + /** 0x40: Compressed size if compressed, otherwise absent. */ + int64_t cbCompressed; + } NonRes; + } u; +} NTFSATTRIBHDR; +AssertCompileSize(NTFSATTRIBHDR, 0x48); +AssertCompileMemberOffset(NTFSATTRIBHDR, u.Res, 0x10); +AssertCompileMemberOffset(NTFSATTRIBHDR, u.Res.bReserved, 0x17); +AssertCompileMemberOffset(NTFSATTRIBHDR, u.NonRes, 0x10); +AssertCompileMemberOffset(NTFSATTRIBHDR, u.NonRes.cbCompressed, 0x40); +/** Pointer to a NTFS attribute header. */ +typedef NTFSATTRIBHDR *PNTFSATTRIBHDR; +/** Pointer to a const NTFS attribute header. */ +typedef NTFSATTRIBHDR const *PCNTFSATTRIBHDR; + +/** @name NTFSATTRIBHDR_SIZE_XXX - Attribute header sizes. + * @{ */ +/** Attribute header size for resident values. */ +#define NTFSATTRIBHDR_SIZE_RESIDENT (0x18) +/** Attribute header size for uncompressed non-resident values. */ +#define NTFSATTRIBHDR_SIZE_NONRES_UNCOMPRESSED (0x40) +/** Attribute header size for compressed non-resident values. */ +#define NTFSATTRIBHDR_SIZE_NONRES_COMPRESSED (0x48) +/** @} */ + +/** Get the pointer to the embedded name from an attribute. + * @note ASSUMES the caller check that there is a name. */ +#define NTFSATTRIBHDR_GET_NAME(a_pAttrHdr) ( (PRTUTF16)((uintptr_t)(a_pAttrHdr) + (a_pAttrHdr)->offName) ) + +/** Get the pointer to resident value. + * @note ASSUMES the caller checks that it's resident and valid. */ +#define NTFSATTRIBHDR_GET_RES_VALUE_PTR(a_pAttrHdr) ( (uint8_t *)(a_pAttrHdr) + (a_pAttrHdr)->u.Res.offValue ) + + +/** @name NTFS_RES_AF_XXX + * @{ */ +/** Attribute is referenced in an index. */ +#define NTFS_RES_AF_INDEXED UINT8_C(0x01) +/** @} */ + +/** + * Attribute list entry (NTFS_AT_ATTRIBUTE_LIST). + * + * This is used to deal with a file having attributes in more than one MFT + * record. A prominent example is an fragment file (unnamed data attribute) + * which mapping pairs doesn't fit in a single MFT record. + * + * This attribute can be non-resident, however it's mapping pair program must + * fit in the base MFT record. + */ +typedef struct NTFSATLISTENTRY +{ + /** 0x00: Attribute type (NTFS_AT_XXX). */ + uint32_t uAttrType; + /** 0x04: Length of this entry. */ + uint16_t cbEntry; + /** 0x06: Attribute name length (zero if none). */ + uint8_t cwcName; + /** 0x07: Name offset. */ + uint8_t offName; + /** 0x08: The first VNC for this part of the attribute value. */ + int64_t iVcnFirst; + /** 0x10: The MFT record holding the actual attribute. */ + NTFSMFTREF InMftRec; + /** 0x18: Attribute instance number. Unique within the MFT record. */ + uint16_t idAttrib; + /** 0x1a: Maybe where the attribute name starts. */ + RT_FLEXIBLE_ARRAY_EXTENSION + RTUTF16 wszName[RT_FLEXIBLE_ARRAY]; +} NTFSATLISTENTRY; +AssertCompileMemberOffset(NTFSATLISTENTRY, idAttrib, 0x18); +/** Pointer to a NTFS attribute list entry. */ +typedef NTFSATLISTENTRY *PNTFSATLISTENTRY; +/** Pointer to a const NTFS attribute list entry. */ +typedef NTFSATLISTENTRY const *PCNTFSATLISTENTRY; + +/** Unaligned minimum entry size (no name). */ +#define NTFSATLISTENTRY_SIZE_MINIMAL 0x1a + + + +/** + * NTFS standard file info attribute (NTFS_AT_STANDARD_INFORMATION). + */ +typedef struct NTFSATSTDINFO +{ + /** 0x00: Creation timestamp. */ + int64_t iCreationTime; + /** 0x08: Last data modification timestamp. */ + int64_t iLastDataModTime; + /** 0x10: Last MFT record modification timestamp. */ + int64_t iLastMftModTime; + /** 0x18: Last access timestamp. */ + int64_t iLastAccessTime; + /** 0x20: File attributes. */ + uint32_t fFileAttribs; + /** 0x24: Maximum number of file versions allowed. + * @note NTFS 3.x, padding in 1.2 */ + uint32_t cMaxFileVersions; + /** 0x28: Current file version number. + * @note NTFS 3.x, padding in 1.2 */ + uint32_t uFileVersion; + /** 0x2c: Class ID (whatever that is). + * @note NTFS 3.x, padding in 1.2 */ + uint32_t idClass; + /** 0x30: Owner ID. + * Translated via $Q index in NTFS_MFT_IDX_EXTENDED/$Quota. + * @note NTFS 3.x, not present in 1.2 */ + uint32_t idOwner; + /** 0x34: Security ID. Translated via $SII index and $SDS data stream in + * NTFS_MFT_IDX_SECURITY. + * @note NTFS 3.x, not present in 1.2 */ + uint32_t idSecurity; + /** 0x38: Total quota charged for this file. + * @note NTFS 3.x, not present in 1.2 */ + uint64_t cbQuotaChared; + /** 0x40: Last update sequence number, index into $UsnJrnl. + * @note NTFS 3.x, not present in 1.2 */ + uint64_t idxUpdateSequence; +} NTFSATSTDINFO; +AssertCompileSize(NTFSATSTDINFO, 0x48); +/** Pointer to NTFS standard file info. */ +typedef NTFSATSTDINFO *PNTFSATSTDINFO; +/** Pointer to const NTFS standard file info. */ +typedef NTFSATSTDINFO const *PCNTFSATSTDINFO; + +/** The size of NTFSATSTDINFO in NTFS v1.2 and earlier. */ +#define NTFSATSTDINFO_SIZE_NTFS_V12 (0x30) + +/** @name NTFS_FA_XXX - NTFS file attributes (host endian). + * @{ */ +#define NTFS_FA_READONLY UINT32_C(0x00000001) +#define NTFS_FA_HIDDEN UINT32_C(0x00000002) +#define NTFS_FA_SYSTEM UINT32_C(0x00000004) +#define NTFS_FA_DIRECTORY UINT32_C(0x00000010) +#define NTFS_FA_ARCHIVE UINT32_C(0x00000020) +#define NTFS_FA_DEVICE UINT32_C(0x00000040) +#define NTFS_FA_NORMAL UINT32_C(0x00000080) +#define NTFS_FA_TEMPORARY UINT32_C(0x00000100) +#define NTFS_FA_SPARSE_FILE UINT32_C(0x00000200) +#define NTFS_FA_REPARSE_POINT UINT32_C(0x00000400) +#define NTFS_FA_COMPRESSED UINT32_C(0x00000800) +#define NTFS_FA_OFFLINE UINT32_C(0x00001000) +#define NTFS_FA_NOT_CONTENT_INDEXED UINT32_C(0x00002000) +#define NTFS_FA_ENCRYPTED UINT32_C(0x00004000) +#define NTFS_FA_VALID_FLAGS UINT32_C(0x00007fb7) +#define NTFS_FA_VALID_SET_FLAGS UINT32_C(0x000031a7) +#define NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT UINT32_C(0x10000000) /**< This means directory apparently. */ +#define NTFS_FA_DUP_VIEW_INDEX_PRESENT UINT32_C(0x20000000) /**< ?? */ +/** @} */ + + + +/** + * NTFS filename attribute (NTFS_AT_FILENAME). + */ +typedef struct NTFSATFILENAME +{ + /** 0x00: The parent directory MFT record. */ + NTFSMFTREF ParentDirMftRec; + /** 0x08: Creation timestamp. */ + int64_t iCreationTime; + /** 0x10: Last data modification timestamp. */ + int64_t iLastDataModTime; + /** 0x18: Last MFT record modification timestamp. */ + int64_t iLastMftModTime; + /** 0x20: Last access timestamp. */ + int64_t iLastAccessTime; + /** 0x28: Allocated disk space for the unnamed data attribute. */ + int64_t cbAllocated; + /** 0x30: Actual size of unnamed data attribute. */ + int64_t cbData; + /** 0x38: File attributes (NTFS_FA_XXX). */ + uint32_t fFileAttribs; + union + { + /** 0x3c: Packed EA length. */ + uint16_t cbPackedEas; + /** 0x3c: Reparse tag, if no EAs. */ + uint32_t uReparseTag; + } u; + /** 0x40: Filename length in unicode chars. */ + uint8_t cwcFilename; + /** 0x41: Filename type (NTFS_FILENAME_T_XXX). */ + uint8_t fFilenameType; + /** 0x42: The filename. */ + RT_FLEXIBLE_ARRAY_EXTENSION + RTUTF16 wszFilename[RT_FLEXIBLE_ARRAY]; +} NTFSATFILENAME; +AssertCompileMemberOffset(NTFSATFILENAME, cbData, 0x30); +AssertCompileMemberOffset(NTFSATFILENAME, u.cbPackedEas, 0x3c); +AssertCompileMemberOffset(NTFSATFILENAME, u.uReparseTag, 0x3c); +AssertCompileMemberOffset(NTFSATFILENAME, wszFilename, 0x42); +/** Pointer to a NTFS filename attribute. */ +typedef NTFSATFILENAME *PNTFSATFILENAME; +/** Pointer to a const NTFS filename attribute. */ +typedef NTFSATFILENAME const *PCNTFSATFILENAME; + +/** @name NTFS_FILENAME_T_XXX - filename types + * @{ */ +#define NTFS_FILENAME_T_POSIX 0 +#define NTFS_FILENAME_T_WINDOWS 1 +#define NTFS_FILENAME_T_DOS 2 +#define NTFS_FILENAME_T_WINDOWS_AND_DSO 3 +/** @} */ + + +/** + * NTFS volume information (NTFS_AT_VOLUME_INFORMATION). + * + * This is found in the special NTFS_MFT_IDX_VOLUME file. + */ +typedef struct NTFSATVOLUMEINFO +{ + /** 0x00: Reserved bytes. */ + uint8_t abReserved[8]; + /** 0x08: Major NTFS version number. */ + uint8_t uMajorVersion; + /** 0x09: Minor NTFS version number. */ + uint8_t uMinorVersion; + /** 0x0a: Volume flags (NTFS_VOLUME_F_XXX) */ + uint16_t fFlags; +} NTFSATVOLUMEINFO; +AssertCompileSize(NTFSATVOLUMEINFO, 12); +/** Pointer to NTFS volume information. */ +typedef NTFSATVOLUMEINFO *PNTFSATVOLUMEINFO; +/** Pointer to const NTFS volume information. */ +typedef NTFSATVOLUMEINFO const *PCNTFSATVOLUMEINFO; + +/** @name NTFS_VOLUME_F_XXX + * @{ */ +#define NTFS_VOLUME_F_DIRTY RT_H2LE_U16_C(0x0001) /**< Volume is dirty. */ +#define NTFS_VOLUME_F_RESIZE_LOG_FILE RT_H2LE_U16_C(0x0002) /**< */ +#define NTFS_VOLUME_F_UPGRADE_ON_MOUNT RT_H2LE_U16_C(0x0004) /**< */ +#define NTFS_VOLUME_F_MOUNTED_ON_NT4 RT_H2LE_U16_C(0x0008) /**< */ +#define NTFS_VOLUME_F_DELETE_USN_UNDERWAY RT_H2LE_U16_C(0x0010) /**< */ +#define NTFS_VOLUME_F_REPAIR_OBJECT_ID RT_H2LE_U16_C(0x0020) /**< */ +#define NTFS_VOLUME_F_CHKDSK_UNDERWAY RT_H2LE_U16_C(0x4000) /**< */ +#define NTFS_VOLUME_F_MODIFIED_BY_CHKDSK RT_H2LE_U16_C(0x8000) /**< */ + +#define NTFS_VOLUME_F_KNOWN_MASK RT_H2LE_U16_C(0xc03f) +#define NTFS_VOLUME_F_MOUNT_READONLY_MASK RT_H2LE_U16_C(0xc027) +/** @} */ + + +/** The attribute name used by the index attributes on NTFS directories, + * ASCII stirng variant. */ +#define NTFS_DIR_ATTRIBUTE_NAME "$I30" + +/** + * NTFS index header. + * + * This is used by NTFSATINDEXROOT and NTFSATINDEXALLOC as a prelude to the + * sequence of entries in a node. + */ +typedef struct NTFSINDEXHDR +{ + /** 0x00: Offset of the first entry relative to this header. */ + uint32_t offFirstEntry; + /** 0x04: Current index size in bytes, including this header. */ + uint32_t cbUsed; + /** 0x08: Number of bytes allocated for the index (including this header). */ + uint32_t cbAllocated; + /** 0x0c: Flags (NTFSINDEXHDR_F_XXX). */ + uint8_t fFlags; + /** 0x0d: Reserved bytes. */ + uint8_t abReserved[3]; + /* NTFSIDXENTRYHDR sequence typically follows here */ +} NTFSINDEXHDR; +AssertCompileSize(NTFSINDEXHDR, 16); +/** Pointer to a NTFS index header. */ +typedef NTFSINDEXHDR *PNTFSINDEXHDR; +/** Pointer to a const NTFS index header. */ +typedef NTFSINDEXHDR const *PCNTFSINDEXHDR; + +/** @name NTFSINDEXHDR_F_XXX + * @{ */ +/** An internal node (as opposed to a leaf node if clear). + * This means that the entries will have trailing node references (VCN). */ +#define NTFSINDEXHDR_F_INTERNAL UINT8_C(0x01) +/** @} */ + +/** Gets the pointer to the first entry header for an index. */ +#define NTFSINDEXHDR_GET_FIRST_ENTRY(a_pIndexHdr) \ + ( (PNTFSIDXENTRYHDR)((uint8_t *)(a_pIndexHdr) + RT_LE2H_U32((a_pIndexHdr)->offFirstEntry)) ) + + +/** + * NTFS index root node (NTFS_AT_INDEX_ROOT). + * + * This is a generic index structure, but is most prominently used for + * implementating directories. The index is structured like B-tree, meaning + * each node contains multiple entries, and each entry contains data regardless + * of whether it's a leaf node or not. + * + * The index is sorted in ascending order according to the collation rules + * defined by the root node (NTFSATINDEXROOT::uCollationRules, see also (see + * NTFS_COLLATION_XXX). + * + * @note The root directory contains a '.' entry, others don't. + */ +typedef struct NTFSATINDEXROOT +{ + /** 0x00: The index type (NTFSATINDEXROOT_TYPE_XXX). */ + uint32_t uType; + /** 0x04: The sorting rules to use (NTFS_COLLATION_XXX). */ + uint32_t uCollationRules; + /** 0x08: Number of bytes in + * Index node size (in bytes). */ + uint32_t cbIndexNode; + /** 0x0c: Number of node addresses per node. + * This sounds weird right? A subnode is generally addressed as a virtual + * cluster when cbIndexNode >= cbCluster, but when clusters are large NTFS uses + * 512 bytes chunks. + * + * (You would've thought it would be simpler to just use cbIndexNode as the + * addressing unit, maybe storing the log2 here to avoid a ffs call.) */ + uint8_t cAddressesPerIndexNode; + /** 0x0d: Reserved padding or something. */ + uint8_t abReserved[3]; + /** 0x10: Index header detailing the entries that follows. */ + NTFSINDEXHDR Hdr; + /* 0x20: NTFSIDXENTRYHDR sequence typically follows here */ +} NTFSATINDEXROOT; +AssertCompileSize(NTFSATINDEXROOT, 32); +/** Pointer to a NTFS index root. */ +typedef NTFSATINDEXROOT *PNTFSATINDEXROOT; +/** Pointer to a const NTFS index root. */ +typedef NTFSATINDEXROOT const *PCNTFSATINDEXROOT; + +/** @name NTFSATINDEXROOT_TYPE_XXX + * @{ */ +/** View index. */ +#define NTFSATINDEXROOT_TYPE_VIEW RT_H2LE_U32_C(UINT32_C(0x00000000)) +/** Directory index, NTFSATFILENAME follows NTFSINDEXENTRY. */ +#define NTFSATINDEXROOT_TYPE_DIR RT_H2LE_U32_C(UINT32_C(0x00000030)) +/** @} */ + +/** @name NTFS_COLLATION_XXX - index sorting rules + * @{ */ +/** Little endian binary compare (or plain byte compare if you like). */ +#define NTFS_COLLATION_BINARY RT_H2LE_U32_C(UINT32_C(0x00000000)) +/** Same as NTFS_COLLATION_UNICODE_STRING. */ +#define NTFS_COLLATION_FILENAME RT_H2LE_U32_C(UINT32_C(0x00000001)) +/** Compare the uppercased unicode characters. */ +#define NTFS_COLLATION_UNICODE_STRING RT_H2LE_U32_C(UINT32_C(0x00000002)) + +/** Single little endian 32-bit unsigned integer value as sort key. */ +#define NTFS_COLLATION_UINT32 RT_H2LE_U32_C(UINT32_C(0x00000010)) +/** Little endian SID value as sort key. */ +#define NTFS_COLLATION_SID RT_H2LE_U32_C(UINT32_C(0x00000011)) +/** Two little endian 32-bit unsigned integer values used as sorting key. */ +#define NTFS_COLLATION_UINT32_PAIR RT_H2LE_U32_C(UINT32_C(0x00000012)) +/** Sequence of little endian 32-bit unsigned integer values used as sorting key. */ +#define NTFS_COLLATION_UINT32_SEQ RT_H2LE_U32_C(UINT32_C(0x00000013)) +/** @} */ + + +/** + * NTFS index non-root node. + */ +typedef struct NTFSATINDEXALLOC +{ + /** 0x00: Header with NTFSREC_MAGIC_INDEX_ALLOC. */ + NTFSRECHDR RecHdr; + /** 0x08: Log file sequence number. */ + uint64_t uLsn; + /** 0x10: The node address of this node (for consistency checking and + * perhaps data reconstruction). + * @see NTFSATINDEXROOT::cAddressesPerIndexNode for node addressing. */ + int64_t iSelfAddress; + /** 0x18: Index header detailing the entries that follows. */ + NTFSINDEXHDR Hdr; + /* 0x28: NTFSIDXENTRYHDR sequence typically follows here */ +} NTFSATINDEXALLOC; +AssertCompileSize(NTFSATINDEXALLOC, 40); +/** Pointer to a NTFS index non-root node. */ +typedef NTFSATINDEXALLOC *PNTFSATINDEXALLOC; +/** Pointer to a const NTFS index non-root node. */ +typedef NTFSATINDEXALLOC const *PCNTFSATINDEXALLOC; + +/** NTFS 'INDX' attribute magic value (NTFSATINDEXALLOC). + * @todo sort out the record / attribute name clash here. */ +#define NTFSREC_MAGIC_INDEX_ALLOC RT_H2LE_U32_C(UINT32_C(0x58444e49)) + + +/** + * NTFS index entry header. + * + * Each entry in a node starts with this header. It is immediately followed by + * the key data (NTFSIDXENTRYHDR::cbKey). When + * + */ +typedef struct NTFSIDXENTRYHDR +{ + union + { + /** 0x00: NTFSATINDEXROOT_TYPE_DIR: Reference to the MFT record being indexed here. + * @note This is invalid if NTFSIDXENTRYHDR_F_END is set (no key data). */ + NTFSMFTREF FileMftRec; + /** 0x00: NTFSATINDEXROOT_TYPE_VIEW: Go figure later if necessary. */ + struct + { + /** 0x00: Offset to the data relative to this header. + * @note This is invalid if NTFSIDXENTRYHDR_F_END is set (no key data). */ + uint16_t offData; + /** 0x02: Size of data at offData. + * @note This is invalid if NTFSIDXENTRYHDR_F_END is set (no key data). */ + uint16_t cbData; + /** 0x04: Reserved. */ + uint32_t uReserved; + } View; + } u; + + /** 0x08: Size of this entry, 8-byte aligned. */ + uint16_t cbEntry; + /** 0x0a: Key length (unaligned). */ + uint16_t cbKey; + /** 0x0c: Entry flags, NTFSIDXENTRYHDR_F_XXX. */ + uint16_t fFlags; + /** 0x0e: Reserved. */ + uint16_t uReserved; +} NTFSIDXENTRYHDR; +AssertCompileSize(NTFSIDXENTRYHDR, 16); +/** Pointer to a NTFS index entry header. */ +typedef NTFSIDXENTRYHDR *PNTFSIDXENTRYHDR; +/** Pointer to a const NTFS index entry header. */ +typedef NTFSIDXENTRYHDR const *PCNTFSIDXENTRYHDR; + +/** @name NTFSIDXENTRYHDR_F_XXX - NTFSIDXENTRYHDR::fFlags + * @{ */ +/** Indicates an internal node (as opposed to a leaf node). + * This indicates that there is a 64-bit integer value at the very end of the + * entry (NTFSIDXENTRYHDR::cbEntry - 8) giving the virtual cluster number of the + * subnode. The subnode and all its decendants contain keys that are lower than + * the key in this entry. + */ +#define NTFSIDXENTRYHDR_F_INTERNAL RT_H2LE_U16_C(UINT16_C(0x0001)) +/** Set if special end entry in a node. + * This does not have any key data, but can point to a subnode with + * higher keys. */ +#define NTFSIDXENTRYHDR_F_END RT_H2LE_U16_C(UINT16_C(0x0002)) +/** @} */ + +/** Gets the pointer to the next index entry header. */ +#define NTFSIDXENTRYHDR_GET_NEXT(a_pEntryHdr) \ + ( (PNTFSIDXENTRYHDR)((uintptr_t)(a_pEntryHdr) + RT_LE2H_U16((a_pEntryHdr)->cbEntry)) ) +/** Gets the subnode address from an index entry. + * @see NTFSATINDEXROOT::cAddressesPerIndexNode for node addressing. + * @note Only invoke when NTFSIDXENTRYHDR_F_INTERNAL is set! */ +#define NTFSIDXENTRYHDR_GET_SUBNODE(a_pEntryHdr) \ + ( *(int64_t *)((uintptr_t)(a_pEntryHdr) + RT_LE2H_U16((a_pEntryHdr)->cbEntry) - sizeof(int64_t)) ) + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_ntfs_h */ + diff --git a/include/iprt/formats/omf.h b/include/iprt/formats/omf.h new file mode 100644 index 00000000..063886d2 --- /dev/null +++ b/include/iprt/formats/omf.h @@ -0,0 +1,260 @@ +/* $Id: omf.h $ */ +/** @file + * IPRT - Relocatable Object Module Format (OMF). + * + * @remarks For a more details description, see specification from Tools + * Interface Standards (TIS), version 1.1 dated May 2015. + * Typically named found as OMF_v1.1.pdf. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_omf_h +#define IPRT_INCLUDED_formats_omf_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/stdint.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_omf Relocatable Object Module Format (OMF) structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + +/** + * OMF record header. + */ +#pragma pack(1) +typedef struct OMFRECHDR +{ + /** The record type. */ + uint8_t bType; + /** The record length, excluding the this header. */ + uint16_t cbLen; +} OMFRECHDR; +#pragma pack() +AssertCompileSize(OMFRECHDR, 3); +/** Pointer to an OMF header. */ +typedef OMFRECHDR *POMFRECHDR; +/** Pointer to a const OMF header. */ +typedef OMFRECHDR *PCOMFRECHDR; + +/** The max OMF record length, including the header. */ +#define OMF_MAX_RECORD_LENGTH UINT16_C(1024) + +/** The max OMF record payload, including CRC byte. */ +#define OMF_MAX_RECORD_PAYLOAD UINT16_C(1021) + + +/** @name OMF Record Types (OMFRECHDR::bType). + * @{ */ +/** Record type flag indicating 32-bit record. */ +#define OMF_REC32 UINT8_C(0x01) +/** Object file header record. + * Is followed by a length prefixed string */ +#define OMF_THEADR UINT8_C(0x80) +/** Comment record. + * Is followed by a comment type byte and a commen class byte, thereafter comes + * type specific byte sequence. */ +#define OMF_COMENT UINT8_C(0x88) +/** Local name table referenced by segment and group defintions. + * Array of length prefixed strings. Multi record. */ +#define OMF_LNAMES UINT8_C(0x96) +/** 16-bit segment definition. + * Complicated, see TIS docs. */ +#define OMF_SEGDEF16 UINT8_C(0x98) +/** 32-bit segment definition. + * Complicated, see TIS docs. */ +#define OMF_SEGDEF32 UINT8_C(0x99) +/** Segment group definition. + * Starts with an LNAMES index (one or two bytes) of the group name. Followed + * by an array which entries consists of a 0xff byte and a segment + * defintion index (one or two bytes). */ +#define OMF_GRPDEF UINT8_C(0x9a) +/** External symbol defintions. + * Array where each entry is a length prefixed symbol name string followed by a + * one or two byte type number. */ +#define OMF_EXTDEF UINT8_C(0x8c) +/** 16-but public symbol definitions. + * Starts with a group index (one or two bytes) and a segment index (ditto) + * which indicates which group/segment the symbols belong to. + * Is followed by an array with entries consiting of a length prefixed symbol + * name string, a two byte segment offset, and a one or two byte type index. */ +#define OMF_PUBDEF16 UINT8_C(0x90) +/** 32-but public symbol definitions. + * Identical to #OMF_PUBDEF16 except that the symbol offset field is four + * byte. */ +#define OMF_PUBDEF32 UINT8_C(0x91) +/** 16-bit local symbol definitions. + * Same format as #OMF_PUBDEF16. */ +#define OMF_LPUBDEF16 UINT8_C(0xb6) +/** 16-bit local symbol definitions. + * Same format as #OMF_PUBDEF32. */ +#define OMF_LPUBDEF32 UINT8_C(0xb7) +/** Logical enumerated data record (a chunk of raw segment bits). + * Starts with the index of the segment it contributes to (one or two bytes) and + * is followed by the offset into the segment of the bytes (two bytes). + * After that comes the raw data bytes. */ +#define OMF_LEDATA16 UINT8_C(0xa0) +/** Logical enumerated data record (a chunk of raw segment bits). + * Identical to #OMF_LEDATA16 except that is has a the segment offset field is + * four bytes. */ +#define OMF_LEDATA32 UINT8_C(0xa1) +/** 16-bit fixup record. + * Complicated, see TIS docs. */ +#define OMF_FIXUPP16 UINT8_C(0x9c) +/** 32-bit fixup record. + * Complicated, see TIS docs. */ +#define OMF_FIXUPP32 UINT8_C(0x9d) +/** 16-bit line numbers record. */ +#define OMF_LINNUM16 UINT8_C(0x94) +/** 32-bit line numbers record. */ +#define OMF_LINNUM32 UINT8_C(0x95) +/** 16-bit object file end record. + * Duh! wrong bitfield order. + * + * Starts with a byte bitfield indicating module type: bit 0 is set if this is a + * main program module; bit 1 is set if this is a start address is available; + * bits 2 thru 6 are reserved and must be zero; bit 7 is set to indicate + * a non-absolute start address. + * + * When bit 1 is set what follow is: A FIXUPP byte, one or two byte frame datum, + * one or two byte target datum, and a 2 byte target displacement. */ +#define OMF_MODEND16 UINT8_C(0x8a) +/** 32-bit object file end record. + * Identical to #OMF_MODEND16 except that is has a 4 byte target + * displacement field. */ +#define OMF_MODEND32 UINT8_C(0x8b) +/** @} */ + +/** @name OMF COMENT Type Flags + * @{ */ +/** Comment type: Don't remove comment when object is manipulated. */ +#define OMF_CTYP_NO_PURGE UINT8_C(0x80) +/** Comment type: Don't include in object listing. */ +#define OMF_CTYP_NO_LIST UINT8_C(0x40) +/** @} */ + +/** @name OMF COMENT Classes + * @{ */ +/** Comment class: Dependency file. + * Is followed by a dword timestamp (1980 based?) and a length prefix + * filename string. */ +#define OMF_CCLS_DEP_FILE UINT8_C(0x88) +/** Comment class: Link pass separator. + * Contains a byte with the value 01 to indicate the linker can stop pass 1 + * processing now. */ +#define OMF_CCLS_LINK_PASS_SEP UINT8_C(0xa2) +/** Comment class: Borland type information. */ +#define OMF_CCLS_BORLAND_TYPES UINT8_C(0xe3) +/** Comment class: Borland symbol information. */ +#define OMF_CCLS_BORLAND_SYMBOLS UINT8_C(0xe6) +/** Comment class: Borland source file (applies to subsequent LINNUMs). */ +#define OMF_CCLS_BORLAND_SRC_FILE UINT8_C(0xe8) +/** Comment class: Borland dependency files. */ +#define OMF_CCLS_BORLAND_DEP_FILES UINT8_C(0xe9) +/** @} */ + +/** @name OMF SEGDEF Attrib. + * @{ */ +#define OMF_SEG_ATTR_ALIGN_ABS (UINT8_C(0) << 5) /**< SEGDEF attrib A: absolute - frame and offset fields present. */ +#define OMF_SEG_ATTR_ALIGN_BYTE (UINT8_C(1) << 5) /**< SEGDEF attrib A: 1-byte alignment. */ +#define OMF_SEG_ATTR_ALIGN_WORD (UINT8_C(2) << 5) /**< SEGDEF attrib A: 2-byte alignment. */ +#define OMF_SEG_ATTR_ALIGN_PARA (UINT8_C(3) << 5) /**< SEGDEF attrib A: 16-byte alignment. */ +#define OMF_SEG_ATTR_ALIGN_PAGE (UINT8_C(4) << 5) /**< SEGDEF attrib A: 4096-byte alignment (or 256-byte). */ +#define OMF_SEG_ATTR_ALIGN_DWORD (UINT8_C(5) << 5) /**< SEGDEF attrib A: 4-byte alignment. */ +#define OMF_SEG_ATTR_ALIGN_6 (UINT8_C(6) << 5) /**< SEGDEF attrib A: not supported (load-time locatable, paragraph aligned). */ +#define OMF_SEG_ATTR_ALIGN_7 (UINT8_C(7) << 5) /**< SEGDEF attrib A: undefined. */ +#define OMF_SEG_ATTR_ALIGN_MASK (UINT8_C(7) << 5) /**< SEGDEF attrib A: Mask for the alignment field. */ +#define OMF_SEG_ATTR_ALIGN_SHIFT 5 /**< SEGDEF attrib A: Shift count for the alignment field. */ + +#define OMF_SEG_ATTR_COMB_PRIVATE (UINT8_C(0) << 2) /**< SEGDEF attrib C: Private - do not combine with anyone. */ +#define OMF_SEG_ATTR_COMB_1 (UINT8_C(1) << 2) /**< SEGDEF attrib C: Reserved */ +#define OMF_SEG_ATTR_COMB_PUBLIC (UINT8_C(2) << 2) /**< SEGDEF attrib C: Public - append at offset meeting alignment. */ +#define OMF_SEG_ATTR_COMB_3 (UINT8_C(3) << 2) /**< SEGDEF attrib C: Reserved */ +#define OMF_SEG_ATTR_COMB_PUBLIC_4 (UINT8_C(4) << 2) /**< SEGDEF attrib C: Public - append at offset meeting alignment. */ +#define OMF_SEG_ATTR_COMB_STACK (UINT8_C(5) << 2) /**< SEGDEF attrib C: Stack - same as public, but forced byte alignment. */ +#define OMF_SEG_ATTR_COMB_COMMON (UINT8_C(6) << 2) /**< SEGDEF attrib C: Common - overlay using maximum size. */ +#define OMF_SEG_ATTR_COMB_PUBLIC_7 (UINT8_C(5) << 2) /**< SEGDEF attrib C: Public - append at offset meeting alignment. */ +#define OMF_SEG_ATTR_COMB_MASK (UINT8_C(7) << 2) /**< SEGDEF attrib C: Mask for the combination field. */ +#define OMF_SEG_ATTR_COMB_SHIFT 2 /**< SEGDEF attrib C: Shift count for the combination field. */ +#define OMF_SEG_ATTR_BIG UINT8_C(2) /**< SEGDEF attrib B: Big segment 64K / 4GB. */ +#define OMF_SEG_ATTR_USE32 UINT8_C(1) /**< SEGDEF attrib P: Indicates 32-bit data or code. */ +#define OMF_SEG_ATTR_USE16 UINT8_C(0) /**< SEGDEF attrib ~P: Just for spelling out !USE32. */ +/** @} */ + + +/** @name OMF FIXUPP Locations. + * @{ */ +#define OMF_FIX_LOC_8BIT_LOW_BYTE UINT8_C(0) /**< FIXUP location: low byte (offset or displacement). */ +#define OMF_FIX_LOC_16BIT_OFFSET UINT8_C(1) /**< FIXUP location: 16-bit offset. */ +#define OMF_FIX_LOC_16BIT_SEGMENT UINT8_C(2) /**< FIXUP location: 16-bit segment. */ +#define OMF_FIX_LOC_1616FAR UINT8_C(3) /**< FIXUP location: 16:16 far pointer. */ +#define OMF_FIX_LOC_8BIT_HIGH_BYTE UINT8_C(4) /**< FIXUP location: high byte (offset). Not supported by MS/IBM. */ +#define OMF_FIX_LOC_16BIT_OFFSET_LDR UINT8_C(5) /**< FIXUP location: 16-bit loader resolved offset, same a 1 for linker. PharLab conflict. */ +#define OMF_FIX_LOC_RESERVED_FAR1632 UINT8_C(6) /**< FIXUP location: PharLab 16:32 far pointers, not defined by MS/IBM. */ +#define OMF_FIX_LOC_RESERVED_7 UINT8_C(7) /**< FIXUP location: Not defined. */ +#define OMF_FIX_LOC_RESERVED_8 UINT8_C(8) /**< FIXUP location: Not defined. */ +#define OMF_FIX_LOC_32BIT_OFFSET UINT8_C(9) /**< FIXUP location: 32-bit offset. */ +#define OMF_FIX_LOC_RESERVED_10 UINT8_C(10) /**< FIXUP location: Not defined. */ +#define OMF_FIX_LOC_1632FAR UINT8_C(11) /**< FIXUP location: 16:32 far pointer. */ +#define OMF_FIX_LOC_RESERVED_12 UINT8_C(12) /**< FIXUP location: Not defined. */ +#define OMF_FIX_LOC_32BIT_OFFSET_LDR UINT8_C(13) /**< FIXUP location: 32-bit loader resolved offset, same as 9 for linker. */ +/** @} */ +/** @name OMF FIXUPP Targets + * @{ */ +#define OMF_FIX_T_SEGDEF UINT8_C(0) /**< FIXUP target: SEGDEF index. */ +#define OMF_FIX_T_GRPDEF UINT8_C(1) /**< FIXUP target: GRPDEF index. */ +#define OMF_FIX_T_EXTDEF UINT8_C(2) /**< FIXUP target: EXTDEF index. */ +#define OMF_FIX_T_FRAME_NO UINT8_C(3) /**< FIXUP target: Explicit frame number, not supported by MS/IBM. */ +#define OMF_FIX_T_SEGDEF_NO_DISP UINT8_C(4) /**< FIXUP target: SEGDEF index only, displacement take as 0. */ +#define OMF_FIX_T_GRPDEF_NO_DISP UINT8_C(5) /**< FIXUP target: GRPDEF index only, displacement take as 0. */ +#define OMF_FIX_T_EXTDEF_NO_DISP UINT8_C(6) /**< FIXUP target: EXTDEF index only, displacement take as 0. */ +/** @} */ +/** @name OMF FIXUPP Frames + * @{ */ +#define OMF_FIX_F_SEGDEF UINT8_C(0) /**< FIXUP frame: SEGDEF index. */ +#define OMF_FIX_F_GRPDEF UINT8_C(1) /**< FIXUP frame: GRPDEF index. */ +#define OMF_FIX_F_EXTDEF UINT8_C(2) /**< FIXUP frame: EXTDEF index. */ +#define OMF_FIX_F_FRAME_NO UINT8_C(3) /**< FIXUP frame: Explicit frame number, not supported by any linkers. */ +#define OMF_FIX_F_LXDATA_SEG UINT8_C(4) /**< FIXUP frame: Determined from the data being fixed up. (No index field.) */ +#define OMF_FIX_F_TARGET_SEG UINT8_C(5) /**< FIXUP frame: Determined from the target. (No index field.) */ +#define OMF_FIX_F_RESERVED_6 UINT8_C(6) /**< FIXUP frame: Reserved. */ +/** @} */ + + +/** @} */ +#endif /* !IPRT_INCLUDED_formats_omf_h */ + diff --git a/include/iprt/formats/pe.mac b/include/iprt/formats/pe.mac new file mode 100644 index 00000000..5031ec47 --- /dev/null +++ b/include/iprt/formats/pe.mac @@ -0,0 +1,732 @@ +;; @file +; IPRT - Windows PE definitions for YASM/NASM. +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +%ifndef ___iprt_format_pe_mac +%define ___iprt_format_pe_mac + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + + +;******************************************************************************* +;* Defined Constants And Macros * +;******************************************************************************* +%define IMAGE_NT_SIGNATURE 0x00004550 + +; file header +%define IMAGE_FILE_MACHINE_I386 0x014c +%define IMAGE_FILE_MACHINE_AMD64 0x8664 + +%define IMAGE_FILE_RELOCS_STRIPPED 0x0001 +%define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 +%define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 +%define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 +%define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 +%define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 +%define IMAGE_FILE_16BIT_MACHINE 0x0040 +%define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 +%define IMAGE_FILE_32BIT_MACHINE 0x0100 +%define IMAGE_FILE_DEBUG_STRIPPED 0x0200 +%define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 +%define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 +%define IMAGE_FILE_SYSTEM 0x1000 +%define IMAGE_FILE_DLL 0x2000 +%define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 +%define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + + +; optional header +%define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10B +%define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20B + +%define IMAGE_SUBSYSTEM_UNKNOWN 0x0 +%define IMAGE_SUBSYSTEM_NATIVE 0x1 +%define IMAGE_SUBSYSTEM_WINDOWS_GUI 0x2 +%define IMAGE_SUBSYSTEM_WINDOWS_CUI 0x3 +%define IMAGE_SUBSYSTEM_OS2_GUI 0x4 +%define IMAGE_SUBSYSTEM_OS2_CUI 0x5 +%define IMAGE_SUBSYSTEM_POSIX_CUI 0x7 + +%define IMAGE_LIBRARY_PROCESS_INIT 0x0001 +%define IMAGE_LIBRARY_PROCESS_TERM 0x0002 +%define IMAGE_LIBRARY_THREAD_INIT 0x0004 +%define IMAGE_LIBRARY_THREAD_TERM 0x0008 +%define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 +%define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 +%define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 +%define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 +%define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 + +%define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 0x10 + +%define IMAGE_DIRECTORY_ENTRY_EXPORT 0x0 +%define IMAGE_DIRECTORY_ENTRY_IMPORT 0x1 +%define IMAGE_DIRECTORY_ENTRY_RESOURCE 0x2 +%define IMAGE_DIRECTORY_ENTRY_EXCEPTION 0x3 +%define IMAGE_DIRECTORY_ENTRY_SECURITY 0x4 +%define IMAGE_DIRECTORY_ENTRY_BASERELOC 0x5 +%define IMAGE_DIRECTORY_ENTRY_DEBUG 0x6 +%define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 0x7 +%define IMAGE_DIRECTORY_ENTRY_COPYRIGHT IMAGE_DIRECTORY_ENTRY_ARCHITECTURE +%define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 0x8 +%define IMAGE_DIRECTORY_ENTRY_TLS 0x9 +%define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 0xa +%define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 0xb +%define IMAGE_DIRECTORY_ENTRY_IAT 0xc +%define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 0xd +%define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 0xe + + +; section header +%define IMAGE_SIZEOF_SHORT_NAME 0x8 + +%define IMAGE_SCN_TYPE_REG 0x00000000 +%define IMAGE_SCN_TYPE_DSECT 0x00000001 +%define IMAGE_SCN_TYPE_NOLOAD 0x00000002 +%define IMAGE_SCN_TYPE_GROUP 0x00000004 +%define IMAGE_SCN_TYPE_NO_PAD 0x00000008 +%define IMAGE_SCN_TYPE_COPY 0x00000010 + +%define IMAGE_SCN_CNT_CODE 0x00000020 +%define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +%define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 + +%define IMAGE_SCN_LNK_OTHER 0x00000100 +%define IMAGE_SCN_LNK_INFO 0x00000200 +%define IMAGE_SCN_TYPE_OVER 0x00000400 +%define IMAGE_SCN_LNK_REMOVE 0x00000800 +%define IMAGE_SCN_LNK_COMDAT 0x00001000 +%define IMAGE_SCN_MEM_PROTECTED 0x00004000 +%define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 +%define IMAGE_SCN_GPREL 0x00008000 +%define IMAGE_SCN_MEM_FARDATA 0x00008000 +%define IMAGE_SCN_MEM_SYSHEAP 0x00010000 +%define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +%define IMAGE_SCN_MEM_16BIT 0x00020000 +%define IMAGE_SCN_MEM_LOCKED 0x00040000 +%define IMAGE_SCN_MEM_PRELOAD 0x00080000 + +%define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +%define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +%define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +%define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +%define IMAGE_SCN_ALIGN_16BYTES 0x00500000 +%define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +%define IMAGE_SCN_ALIGN_64BYTES 0x00700000 +%define IMAGE_SCN_ALIGN_128BYTES 0x00800000 +%define IMAGE_SCN_ALIGN_256BYTES 0x00900000 +%define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 +%define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 +%define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 +%define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 +%define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 +%define IMAGE_SCN_ALIGN_MASK 0x00F00000 +%define IMAGE_SCN_ALIGN_SHIFT 20 + +%define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 +%define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +%define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +%define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +%define IMAGE_SCN_MEM_SHARED 0x10000000 +%define IMAGE_SCN_MEM_EXECUTE 0x20000000 +%define IMAGE_SCN_MEM_READ 0x40000000 +%define IMAGE_SCN_MEM_WRITE 0x80000000 + + +; relocations +%define IMAGE_REL_BASED_ABSOLUTE 0x0 +%define IMAGE_REL_BASED_HIGH 0x1 +%define IMAGE_REL_BASED_LOW 0x2 +%define IMAGE_REL_BASED_HIGHLOW 0x3 +%define IMAGE_REL_BASED_HIGHADJ 0x4 +%define IMAGE_REL_BASED_MIPS_JMPADDR 0x5 +%define IMAGE_REL_BASED_MIPS_JMPADDR16 0x9 +%define IMAGE_REL_BASED_IA64_IMM64 0x9 +%define IMAGE_REL_BASED_DIR64 0xa +%define IMAGE_REL_BASED_HIGH3ADJ 0xb + + +; imports +%define IMAGE_ORDINAL_FLAG32 0x80000000 +%define IMAGE_ORDINAL_FLAG64 UINT64_MAX(0x8000000000000000) + + +; debug dir +%define IMAGE_DEBUG_TYPE_UNKNOWN UINT32_C(0x0) +%define IMAGE_DEBUG_TYPE_COFF UINT32_C(0x1) +%define IMAGE_DEBUG_TYPE_CODEVIEW UINT32_C(0x2) +%define IMAGE_DEBUG_TYPE_FPO UINT32_C(0x3) +%define IMAGE_DEBUG_TYPE_MISC UINT32_C(0x4) +%define IMAGE_DEBUG_TYPE_EXCEPTION UINT32_C(0x5) +%define IMAGE_DEBUG_TYPE_FIXUP UINT32_C(0x6) +%define IMAGE_DEBUG_TYPE_OMAP_TO_SRC UINT32_C(0x7) +%define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC UINT32_C(0x8) +%define IMAGE_DEBUG_TYPE_BORLAND UINT32_C(0x9) +%define IMAGE_DEBUG_TYPE_RESERVED10 UINT32_C(0x10) + +%define IMAGE_DEBUG_MISC_EXENAME UINT32_C(1) + +; security directory +%define WIN_CERT_REVISION_1_0 UINT16_C(0x0100) +%define WIN_CERT_REVISION_2_0 UINT16_C(0x0200) + +%define WIN_CERT_TYPE_X509 UINT16_C(1) +%define WIN_CERT_TYPE_PKCS_SIGNED_DATA UINT16_C(2) +%define WIN_CERT_TYPE_RESERVED_1 UINT16_C(3) +%define WIN_CERT_TYPE_TS_STACK_SIGNED UINT16_C(4) +%define WIN_CERT_TYPE_EFI_PKCS115 UINT16_C(0x0ef0) +%define WIN_CERT_TYPE_EFI_GUID UINT16_C(0x0ef1) + + +; For .DBG files. +%define IMAGE_SEPARATE_DEBUG_SIGNATURE UINT16_C(0x4944) + +%define IMAGE_SIZE_OF_SYMBOL 18 +%define IMAGE_SIZE_OF_SYMBOL_EX 20 + +%define IMAGE_SYM_UNDEFINED INT16_C(0) +%define IMAGE_SYM_ABSOLUTE INT16_C(-1) +%define IMAGE_SYM_DEBUG INT16_C(-2) + +%define IMAGE_SYM_CLASS_END_OF_FUNCTION UINT8_C(0xff) ; -1 +%define IMAGE_SYM_CLASS_NULL UINT8_C(0) +%define IMAGE_SYM_CLASS_AUTOMATIC UINT8_C(1) +%define IMAGE_SYM_CLASS_EXTERNAL UINT8_C(2) +%define IMAGE_SYM_CLASS_STATIC UINT8_C(3) +%define IMAGE_SYM_CLASS_REGISTER UINT8_C(4) +%define IMAGE_SYM_CLASS_EXTERNAL_DEF UINT8_C(5) +%define IMAGE_SYM_CLASS_LABEL UINT8_C(6) +%define IMAGE_SYM_CLASS_UNDEFINED_LABEL UINT8_C(7) +%define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT UINT8_C(8) +%define IMAGE_SYM_CLASS_ARGUMENT UINT8_C(9) +%define IMAGE_SYM_CLASS_STRUCT_TAG UINT8_C(10) +%define IMAGE_SYM_CLASS_MEMBER_OF_UNION UINT8_C(11) +%define IMAGE_SYM_CLASS_UNION_TAG UINT8_C(12) +%define IMAGE_SYM_CLASS_TYPE_DEFINITION UINT8_C(13) +%define IMAGE_SYM_CLASS_UNDEFINED_STATIC UINT8_C(14) +%define IMAGE_SYM_CLASS_ENUM_TAG UINT8_C(15) +%define IMAGE_SYM_CLASS_MEMBER_OF_ENUM UINT8_C(16) +%define IMAGE_SYM_CLASS_REGISTER_PARAM UINT8_C(17) +%define IMAGE_SYM_CLASS_BIT_FIELD UINT8_C(18) +%define IMAGE_SYM_CLASS_FAR_EXTERNAL UINT8_C(68) +%define IMAGE_SYM_CLASS_BLOCK UINT8_C(100) +%define IMAGE_SYM_CLASS_FUNCTION UINT8_C(101) +%define IMAGE_SYM_CLASS_END_OF_STRUCT UINT8_C(102) +%define IMAGE_SYM_CLASS_FILE UINT8_C(103) +%define IMAGE_SYM_CLASS_SECTION UINT8_C(104) +%define IMAGE_SYM_CLASS_WEAK_EXTERNAL UINT8_C(105) +%define IMAGE_SYM_CLASS_CLR_TOKEN UINT8_C(107) + + +%define IMAGE_SYM_TYPE_NULL UINT16_C(0x0000) +%define IMAGE_SYM_TYPE_VOID UINT16_C(0x0001) +%define IMAGE_SYM_TYPE_CHAR UINT16_C(0x0002) +%define IMAGE_SYM_TYPE_SHORT UINT16_C(0x0003) +%define IMAGE_SYM_TYPE_INT UINT16_C(0x0004) +%define IMAGE_SYM_TYPE_LONG UINT16_C(0x0005) +%define IMAGE_SYM_TYPE_FLOAT UINT16_C(0x0006) +%define IMAGE_SYM_TYPE_DOUBLE UINT16_C(0x0007) +%define IMAGE_SYM_TYPE_STRUCT UINT16_C(0x0008) +%define IMAGE_SYM_TYPE_UNION UINT16_C(0x0009) +%define IMAGE_SYM_TYPE_ENUM UINT16_C(0x000a) +%define IMAGE_SYM_TYPE_MOE UINT16_C(0x000b) +%define IMAGE_SYM_TYPE_BYTE UINT16_C(0x000c) +%define IMAGE_SYM_TYPE_WORD UINT16_C(0x000d) +%define IMAGE_SYM_TYPE_UINT UINT16_C(0x000e) +%define IMAGE_SYM_TYPE_DWORD UINT16_C(0x000f) +%define IMAGE_SYM_TYPE_PCODE UINT16_C(0x8000) + +%define IMAGE_SYM_DTYPE_NULL UINT16_C(0x0) +%define IMAGE_SYM_DTYPE_POINTER UINT16_C(0x1) +%define IMAGE_SYM_DTYPE_FUNCTION UINT16_C(0x2) +%define IMAGE_SYM_DTYPE_ARRAY UINT16_C(0x3) + + +%define N_BTMASK UINT16_C(0x000f) +%define N_TMASK UINT16_C(0x0030) +%define N_TMASK1 UINT16_C(0x00c0) +%define N_TMASK2 UINT16_C(0x00f0) +%define N_BTSHFT 4 +%define N_TSHIFT 2 + + +;******************************************************************************* +;* Structures and Typedefs * +;******************************************************************************* + +struc IMAGE_FILE_HEADER + .Machine resw 1 ;;< 0x00 + .NumberOfSections resw 1 ;;< 0x02 + .TimeDateStamp resd 1 ;;< 0x04 + .PointerToSymbolTable resd 1 ;;< 0x08 + .NumberOfSymbols resd 1 ;;< 0x0c + .SizeOfOptionalHeader resw 1 ;;< 0x10 + .Characteristics resw 1 ;;< 0x12 +endstruc +AssertCompileSize(IMAGE_FILE_HEADER, 0x14) + +struc IMAGE_DATA_DIRECTORY + .VirtualAddress resd 1 + .Size resd 1 +endstruc + + +struc IMAGE_OPTIONAL_HEADER32 + .Magic resw 1 ;;< 0x00 + .MajorLinkerVersion resb 1 ;;< 0x02 + .MinorLinkerVersion resb 1 ;;< 0x03 + .SizeOfCode resd 1 ;;< 0x04 + .SizeOfInitializedData resd 1 ;;< 0x08 + .SizeOfUninitializedData resd 1 ;;< 0x0c + .AddressOfEntryPoint resd 1 ;;< 0x10 + .BaseOfCode resd 1 ;;< 0x14 + .BaseOfData resd 1 ;;< 0x18 + .ImageBase resd 1 ;;< 0x1c + .SectionAlignment resd 1 ;;< 0x20 + .FileAlignment resd 1 ;;< 0x24 + .MajorOperatingSystemVersion resw 1 ;;< 0x28 + .MinorOperatingSystemVersion resw 1 ;;< 0x2a + .MajorImageVersion resw 1 ;;< 0x2c + .MinorImageVersion resw 1 ;;< 0x2e + .MajorSubsystemVersion resw 1 ;;< 0x30 + .MinorSubsystemVersion resw 1 ;;< 0x32 + .Win32VersionValue resd 1 ;;< 0x34 + .SizeOfImage resd 1 ;;< 0x38 + .SizeOfHeaders resd 1 ;;< 0x3c + .CheckSum resd 1 ;;< 0x40 + .Subsystem resw 1 ;;< 0x44 + .DllCharacteristics resw 1 ;;< 0x46 + .SizeOfStackReserve resd 1 ;;< 0x48 + .SizeOfStackCommit resd 1 ;;< 0x4c + .SizeOfHeapReserve resd 1 ;;< 0x50 + .SizeOfHeapCommit resd 1 ;;< 0x54 + .LoaderFlags resd 1 ;;< 0x58 + .NumberOfRvaAndSizes resd 1 ;;< 0x5c + .DataDirectory resb IMAGE_DATA_DIRECTORY_size * IMAGE_NUMBEROF_DIRECTORY_ENTRIES ;;< 0x60; 0x10*8 = 0x80 +endstruc +AssertCompileSize(IMAGE_OPTIONAL_HEADER32, 0xe0); + +struc IMAGE_OPTIONAL_HEADER64 + .Magic resw 1 ;;< 0x00 + .MajorLinkerVersion resb 1 ;;< 0x02 + .MinorLinkerVersion resb 1 ;;< 0x03 + .SizeOfCode resd 1 ;;< 0x04 + .SizeOfInitializedData resd 1 ;;< 0x08 + .SizeOfUninitializedData resd 1 ;;< 0x0c + .AddressOfEntryPoint resd 1 ;;< 0x10 + .BaseOfCode resd 1 ;;< 0x14 + .ImageBase resq 1 ;;< 0x18 + .SectionAlignment resd 1 ;;< 0x20 + .FileAlignment resd 1 ;;< 0x24 + .MajorOperatingSystemVersion resw 1 ;;< 0x28 + .MinorOperatingSystemVersion resw 1 ;;< 0x2a + .MajorImageVersion resw 1 ;;< 0x2c + .MinorImageVersion resw 1 ;;< 0x2e + .MajorSubsystemVersion resw 1 ;;< 0x30 + .MinorSubsystemVersion resw 1 ;;< 0x32 + .Win32VersionValue resd 1 ;;< 0x34 + .SizeOfImage resd 1 ;;< 0x38 + .SizeOfHeaders resd 1 ;;< 0x3c + .CheckSum resd 1 ;;< 0x40 + .Subsystem resw 1 ;;< 0x44 + .DllCharacteristics resw 1 ;;< 0x46 + .SizeOfStackReserve resq 1 ;;< 0x48 + .SizeOfStackCommit resq 1 ;;< 0x50 + .SizeOfHeapReserve resq 1 ;;< 0x58 + .SizeOfHeapCommit resq 1 ;;< 0x60 + .LoaderFlags resd 1 ;;< 0x68 + .NumberOfRvaAndSizes resd 1 ;;< 0x6c + .DataDirectory resb IMAGE_DATA_DIRECTORY_size * IMAGE_NUMBEROF_DIRECTORY_ENTRIES ;;< 0x70; 0x10*8 = 0x80 +endstruc ; size: 0xf0 +AssertCompileSize(IMAGE_OPTIONAL_HEADER64, 0xf0); + + +struc IMAGE_NT_HEADERS32 + .Signature resd 1 ;;< 0x00 + .FileHeader resb IMAGE_FILE_HEADER_size ; ;;< 0x04 + .OptionalHeader resb IMAGE_OPTIONAL_HEADER32_size ;;< 0x18 +endstruc ; size: 0xf8 +AssertCompileSize(IMAGE_NT_HEADERS32, 0xf8); +AssertCompileMemberOffset(IMAGE_NT_HEADERS32, FileHeader, 4); +AssertCompileMemberOffset(IMAGE_NT_HEADERS32, OptionalHeader, 24); + +struc IMAGE_NT_HEADERS64 + .Signature resd 1 ;;< 0x00 + .FileHeader resb IMAGE_FILE_HEADER_size ;;< 0x04 + .OptionalHeader resb IMAGE_OPTIONAL_HEADER64_size ;;< 0x18 +endstruc ; size: 0x108 +AssertCompileSize(IMAGE_NT_HEADERS64, 0x108); +AssertCompileMemberOffset(IMAGE_NT_HEADERS64, FileHeader, 4); +AssertCompileMemberOffset(IMAGE_NT_HEADERS64, OptionalHeader, 24); + + +struc IMAGE_SECTION_HEADER + .Name resb IMAGE_SIZEOF_SHORT_NAME + .Misc.VirtualSize resd 1 + .VirtualAddress resd 1 + .SizeOfRawData resd 1 + .PointerToRawData resd 1 + .PointerToRelocations resd 1 + .PointerToLinenumbers resd 1 + .NumberOfRelocations resw 1 + .NumberOfLinenumbers resw 1 + .Characteristics resd 1 +endstruc +%define IMAGE_SECTION_HEADER.Misc.PhysicalAddress IMAGE_SECTION_HEADER.Misc.VirtualSize + + +struc IMAGE_BASE_RELOCATION + .VirtualAddress resd 1 + .SizeOfBlock resd 1 +endstruc + + +struc IMAGE_EXPORT_DIRECTORY + .Characteristics resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .Name resd 1 + .Base resd 1 + .NumberOfFunctions resd 1 + .NumberOfNames resd 1 + .AddressOfFunctions resd 1 + .AddressOfNames resd 1 + .AddressOfNameOrdinals resd 1 +endstruc + + +struc IMAGE_IMPORT_DESCRIPTOR + .u.Characteristics resd 1 + .TimeDateStamp resd 1 + .ForwarderChain resd 1 + .Name resd 1 + .FirstThunk resd 1 +endstruc +%define IMAGE_IMPORT_DESCRIPTOR.u.OriginalFirstThunk IMAGE_IMPORT_DESCRIPTOR.u.Characteristics + +struc IMAGE_IMPORT_BY_NAME + .Hint resw 1 + .Name resb 1 +endstruc + + +struc IMAGE_THUNK_DATA64 + .u1.ForwarderString resq 1 +endstruc +%define IMAGE_THUNK_DATA64.u1.Function IMAGE_THUNK_DATA64.u1.ForwarderString +%define IMAGE_THUNK_DATA64.u1.Ordinal IMAGE_THUNK_DATA64.u1.ForwarderString +%define IMAGE_THUNK_DATA64.u1.AddressOfData IMAGE_THUNK_DATA64.u1.ForwarderString + +struc IMAGE_THUNK_DATA32 + .u1.ForwarderString resd 1 +endstruc +%define IMAGE_THUNK_DATA32.u1.Function IMAGE_THUNK_DATA32.u1.ForwarderString +%define IMAGE_THUNK_DATA32.u1.Ordinal IMAGE_THUNK_DATA32.u1.ForwarderString +%define IMAGE_THUNK_DATA32.u1.AddressOfData IMAGE_THUNK_DATA32.u1.ForwarderString + + +struc IMAGE_LOAD_CONFIG_DIRECTORY32 + .Size resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .GlobalFlagsClear resd 1 + .GlobalFlagsSet resd 1 + .CriticalSectionDefaultTimeout resd 1 + .DeCommitFreeBlockThreshold resd 1 + .DeCommitTotalFreeThreshold resd 1 + .LockPrefixTable resd 1 + .MaximumAllocationSize resd 1 + .VirtualMemoryThreshold resd 1 + .ProcessHeapFlags resd 1 + .ProcessAffinityMask resd 1 + .CSDVersion resw 1 + .Reserved1 resw 1 + .EditList resd 1 + .SecurityCookie resd 1 + .SEHandlerTable resd 1 + .SEHandlerCount resd 1 +endstruc + +struc IMAGE_LOAD_CONFIG_DIRECTORY64 + .Size resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .GlobalFlagsClear resd 1 + .GlobalFlagsSet resd 1 + .CriticalSectionDefaultTimeout resd 1 + .DeCommitFreeBlockThreshold resq 1 + .DeCommitTotalFreeThreshold resq 1 + .LockPrefixTable resq 1 + .MaximumAllocationSize resq 1 + .VirtualMemoryThreshold resq 1 + .ProcessAffinityMask resq 1 + .ProcessHeapFlags resd 1 + .CSDVersion resw 1 + .Reserved1 resw 1 + .EditList resq 1 + .SecurityCookie resq 1 + .SEHandlerTable resq 1 + .SEHandlerCount resq 1 +endstruc + + +struc IMAGE_DEBUG_DIRECTORY + .Characteristics resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .Type resd 1 + .SizeOfData resd 1 + .AddressOfRawData resd 1 + .PointerToRawData resd 1 +endstruc + +struc IMAGE_DEBUG_MISC + .DataType resd 1 + .Length resd 1 + .Unicode resb 1 + .Reserved resb 3 + .Data resb 1 +endstruc + + +struc WIN_CERTIFICATE + .dwLength resd 1 + .wRevision resw 1 + .wCertificateType resw 1 + .bCertificate resb 8 +endstruc + +;; The header of a .DBG file (NT4). +struc IMAGE_SEPARATE_DEBUG_HEADER + .Signature resw 1 ;;< 0x00 + .Flags resw 1 ;;< 0x02 + .Machine resw 1 ;;< 0x04 + .Characteristics resw 1 ;;< 0x06 + .TimeDateStamp resd 1 ;;< 0x08 + .CheckSum resd 1 ;;< 0x0c + .ImageBase resd 1 ;;< 0x10 + .SizeOfImage resd 1 ;;< 0x14 + .NumberOfSections resd 1 ;;< 0x18 + .ExportedNamesSize resd 1 ;;< 0x1c + .DebugDirectorySize resd 1 ;;< 0x20 + .SectionAlignment resd 1 ;;< 0x24 + .Reserved resd 2 ;;< 0x28 +endstruc ; size: 0x30 +AssertCompileSize(IMAGE_SEPARATE_DEBUG_HEADER, 0x30); + + +struc IMAGE_COFF_SYMBOLS_HEADER + .NumberOfSymbols resd 1 + .LvaToFirstSymbol resd 1 + .NumberOfLinenumbers resd 1 + .LvaToFirstLinenumber resd 1 + .RvaToFirstByteOfCode resd 1 + .RvaToLastByteOfCode resd 1 + .RvaToFirstByteOfData resd 1 + .RvaToLastByteOfData resd 1 +endstruc +AssertCompileSize(IMAGE_COFF_SYMBOLS_HEADER, 0x20); + + +struc IMAGE_LINENUMBER + .Type.VirtualAddress resd 1 + .Linenumber resw 1 +endstruc +AssertCompileSize(IMAGE_LINENUMBER, 6); +%define IMAGE_LINENUMBER.Type.SymbolTableIndex IMAGE_LINENUMBER.Type.VirtualAddress + + +;;#pragma pack(2) +;;struc IMAGE_SYMBOL +;;{ +;; union +;; { +;; uint8_t ShortName[8]; +;; struct +;; { +;; .Short resd 1 +;; .Long resd 1 +;; } Name; +;; uint32_t LongName[2]; +;; } N; +;; +;; .Value resd 1 +;; int16_t SectionNumber; +;; .Type resw 1 +;; .StorageClass resb 1 +;; .NumberOfAuxSymbols resb 1 +;;} IMAGE_SYMBOL; +;;#pragma pack() +;;AssertCompileSize(IMAGE_SYMBOL, IMAGE_SIZE_OF_SYMBOL); +;; +;; +;;#pragma pack(2) +;;typedef struct IMAGE_AUX_SYMBOL_TOKEN_DEF +;;{ +;; .bAuxType resb 1 +;; .bReserved resb 1 +;; .SymbolTableIndex resd 1 +;; uint8_t rgbReserved[12]; +;;} IMAGE_AUX_SYMBOL_TOKEN_DEF; +;;#pragma pack() +;;AssertCompileSize(IMAGE_AUX_SYMBOL_TOKEN_DEF, IMAGE_SIZE_OF_SYMBOL); +;; +;; +;;#pragma pack(1) +;;typedef union _IMAGE_AUX_SYMBOL +;;{ +;; struct +;; { +;; .TagIndex resd 1 +;; union +;; { +;; struct +;; { +;; .Linenumber resw 1 +;; .Size resw 1 +;; } LnSz; +;; } Misc; +;; union +;; { +;; struct +;; { +;; .PointerToLinenumber resd 1 +;; .PointerToNextFunction resd 1 +;; } Function; +;; struct +;; { +;; uint16_t Dimension[4]; +;; } Array; +;; } FcnAry; +;; .TvIndex resw 1 +;; } Sym; +;; +;; struct +;; { +;; uint8_t Name[IMAGE_SIZE_OF_SYMBOL]; +;; } File; +;; +;; struct +;; { +;; .Length resd 1 +;; .NumberOfRelocations resw 1 +;; .NumberOfLinenumbers resw 1 +;; .CheckSum resd 1 +;; .Number resw 1 +;; .Selection resb 1 +;; .bReserved resb 1 +;; .HighNumber resw 1 +;; } Section; +;; +;; IMAGE_AUX_SYMBOL_TOKEN_DEF TokenDef; +;; struct +;; { +;; .crc resd 1 +;; uint8_t rgbReserved[14]; +;; } CRC; +;;} IMAGE_AUX_SYMBOL; +;;#pragma pack() +;;AssertCompileSize(IMAGE_AUX_SYMBOL, IMAGE_SIZE_OF_SYMBOL); +;; +;; +;; +;;struc IMAGE_SYMBOL_EX +;;{ +;; union +;; { +;; uint8_t ShortName[8]; +;; struct +;; { +;; .Short resd 1 +;; .Long resd 1 +;; } Name; +;; uint32_t LongName[2]; +;; } N; +;; +;; .Value resd 1 +;; int32_t SectionNumber; /* The difference from IMAGE_SYMBOL +;; .Type resw 1 +;; .StorageClass resb 1 +;; .NumberOfAuxSymbols resb 1 +;;} IMAGE_SYMBOL_EX; +;;AssertCompileSize(IMAGE_SYMBOL_EX, IMAGE_SIZE_OF_SYMBOL_EX); +;; +;; +;;typedef union _IMAGE_AUX_SYMBOL_EX +;;{ +;; struct +;; { +;; .WeakDefaultSymIndex resd 1 +;; .WeakSearchType resd 1 +;; uint8_t rgbReserved[12]; +;; } Sym; +;; +;; struct +;; { +;; uint8_t Name[IMAGE_SIZE_OF_SYMBOL_EX]; +;; } File; +;; +;; struct +;; { +;; .Length resd 1 +;; .NumberOfRelocations resw 1 +;; .NumberOfLinenumbers resw 1 +;; .CheckSum resd 1 +;; .Number resw 1 +;; .Selection resb 1 +;; .bReserved resb 1 +;; .HighNumber resw 1 +;; uint8_t rgbReserved[2]; +;; } Section; +;; +;; IMAGE_AUX_SYMBOL_TOKEN_DEF TokenDef; +;; +;; struct +;; { +;; .crc resd 1 +;; uint8_t rgbReserved[16]; +;; } CRC; +;;} IMAGE_AUX_SYMBOL_EX; +;;AssertCompileSize(IMAGE_AUX_SYMBOL_EX, IMAGE_SIZE_OF_SYMBOL_EX); + +%endif + diff --git a/include/iprt/formats/pecoff.h b/include/iprt/formats/pecoff.h new file mode 100644 index 00000000..27f42397 --- /dev/null +++ b/include/iprt/formats/pecoff.h @@ -0,0 +1,2610 @@ +/* $Id: pecoff.h $ */ +/** @file + * IPRT - Windows NT PE & COFF Structures and Constants. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_pecoff_h +#define IPRT_INCLUDED_formats_pecoff_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_pecoff PE & Microsoft COFF structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + + +/** + * PE & COFF file header. + * + * This starts COFF files, while in PE files it's preceeded by the PE signature + * (see IMAGE_NT_HEADERS32, IMAGE_NT_HEADERS64). + */ +typedef struct _IMAGE_FILE_HEADER +{ + uint16_t Machine; /**< 0x00 */ + uint16_t NumberOfSections; /**< 0x02 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint32_t PointerToSymbolTable; /**< 0x08 */ + uint32_t NumberOfSymbols; /**< 0x0c */ + uint16_t SizeOfOptionalHeader; /**< 0x10 */ + uint16_t Characteristics; /**< 0x12 */ +} IMAGE_FILE_HEADER; /* size: 0x14 */ +AssertCompileSize(IMAGE_FILE_HEADER, 0x14); +typedef IMAGE_FILE_HEADER *PIMAGE_FILE_HEADER; +typedef IMAGE_FILE_HEADER const *PCIMAGE_FILE_HEADER; + + +/** @name PE & COFF machine types. + * Used by IMAGE_FILE_HEADER::Machine and IMAGE_SEPARATE_DEBUG_HEADER::Machine. + * @{ */ +/** X86 compatible CPU, 32-bit instructions. */ +#define IMAGE_FILE_MACHINE_I386 UINT16_C(0x014c) +/** AMD64 compatible CPU, 64-bit instructions. */ +#define IMAGE_FILE_MACHINE_AMD64 UINT16_C(0x8664) + +/** Unknown target CPU. */ +#define IMAGE_FILE_MACHINE_UNKNOWN UINT16_C(0x0000) +/** Basic-16 (whatever that is). */ +#define IMAGE_FILE_MACHINE_BASIC_16 UINT16_C(0x0142) +/** Basic-16 (whatever that is) w/ transfer vector(s?) (TV). */ +#define IMAGE_FILE_MACHINE_BASIC_16_TV UINT16_C(0x0143) +/** Intel iAPX 16 (8086?). */ +#define IMAGE_FILE_MACHINE_IAPX16 UINT16_C(0x0144) +/** Intel iAPX 16 (8086?) w/ transfer vector(s?) (TV). */ +#define IMAGE_FILE_MACHINE_IAPX16_TV UINT16_C(0x0145) +/** Intel iAPX 20 (80286?). */ +#define IMAGE_FILE_MACHINE_IAPX20 UINT16_C(0x0144) +/** Intel iAPX 20 (80286?) w/ transfer vector(s?) (TV). */ +#define IMAGE_FILE_MACHINE_IAPX20_TV UINT16_C(0x0145) +/** X86 compatible CPU, 8086. */ +#define IMAGE_FILE_MACHINE_I8086 UINT16_C(0x0148) +/** X86 compatible CPU, 8086 w/ transfer vector(s?) (TV). */ +#define IMAGE_FILE_MACHINE_I8086_TV UINT16_C(0x0149) +/** X86 compatible CPU, 80286 small model program. */ +#define IMAGE_FILE_MACHINE_I286_SMALL UINT16_C(0x014a) +/** Motorola 68000. */ +#define IMAGE_FILE_MACHINE_MC68 UINT16_C(0x0150) +/** Motorola 68000 w/ writable text sections. */ +#define IMAGE_FILE_MACHINE_MC68_WR UINT16_C(0x0150) +/** Motorola 68000 w/ transfer vector(s?). */ +#define IMAGE_FILE_MACHINE_MC68_TV UINT16_C(0x0151) +/** Motorola 68000 w/ demand paged text. + * @note shared with 80286 large model program. */ +#define IMAGE_FILE_MACHINE_MC68_PG UINT16_C(0x0152) +/** X86 compatible CPU, 80286 large model program. + * @note shared with MC68000 w/ demand paged text */ +#define IMAGE_FILE_MACHINE_I286_LARGE UINT16_C(0x0152) +/** IBM 370 (writable text). */ +#define IMAGE_FILE_MACHINE_U370_WR UINT16_C(0x0158) +/** Amdahl 470/580 (writable text). */ +#define IMAGE_FILE_MACHINE_AMDAHL_470_WR UINT16_C(0x0159) +/** Amdahl 470/580 (read only text). */ +#define IMAGE_FILE_MACHINE_AMDAHL_470_RO UINT16_C(0x015c) +/** IBM 370 (read only text). */ +#define IMAGE_FILE_MACHINE_U370_RO UINT16_C(0x015d) +/** MIPS R4000 CPU, little endian. */ +#define IMAGE_FILE_MACHINE_R4000 UINT16_C(0x0166) +/** MIPS CPU, little endian, Windows CE (?) v2 designation. */ +#define IMAGE_FILE_MACHINE_WCEMIPSV2 UINT16_C(0x0169) +/** VAX-11/750 and VAX-11/780 (writable text). */ +#define IMAGE_FILE_MACHINE_VAX_WR UINT16_C(0x0178) +/** VAX-11/750 and VAX-11/780 (read-only text). */ +#define IMAGE_FILE_MACHINE_VAX_RO UINT16_C(0x017d) +/** Hitachi SH3 CPU. */ +#define IMAGE_FILE_MACHINE_SH3 UINT16_C(0x01a2) +/** Hitachi SH3 DSP. */ +#define IMAGE_FILE_MACHINE_SH3DSP UINT16_C(0x01a3) +/** Hitachi SH4 CPU. */ +#define IMAGE_FILE_MACHINE_SH4 UINT16_C(0x01a6) +/** Hitachi SH5 CPU. */ +#define IMAGE_FILE_MACHINE_SH5 UINT16_C(0x01a8) +/** Little endian ARM CPU. */ +#define IMAGE_FILE_MACHINE_ARM UINT16_C(0x01c0) +/** ARM or Thumb stuff. */ +#define IMAGE_FILE_MACHINE_THUMB UINT16_C(0x01c2) +/** ARMv7 or higher CPU, Thumb mode. */ +#define IMAGE_FILE_MACHINE_ARMNT UINT16_C(0x01c4) +/** Matshushita AM33 CPU. */ +#define IMAGE_FILE_MACHINE_AM33 UINT16_C(0x01d3) +/** Power PC CPU, little endian. */ +#define IMAGE_FILE_MACHINE_POWERPC UINT16_C(0x01f0) +/** Power PC CPU with FPU, also little endian? */ +#define IMAGE_FILE_MACHINE_POWERPCFP UINT16_C(0x01f1) +/** "Itanic" CPU. */ +#define IMAGE_FILE_MACHINE_IA64 UINT16_C(0x0200) +/** MIPS CPU, compact 16-bit instructions only? */ +#define IMAGE_FILE_MACHINE_MIPS16 UINT16_C(0x0266) +/** MIPS CPU with FPU, full 32-bit instructions only? */ +#define IMAGE_FILE_MACHINE_MIPSFPU UINT16_C(0x0366) +/** MIPS CPU with FPU, compact 16-bit instructions? */ +#define IMAGE_FILE_MACHINE_MIPSFPU16 UINT16_C(0x0466) +/** EFI byte code. */ +#define IMAGE_FILE_MACHINE_EBC UINT16_C(0x0ebc) +/** Mitsubishi M32R CPU, little endian. */ +#define IMAGE_FILE_MACHINE_M32R UINT16_C(0x9041) +/** ARMv8 CPU, 64-bit mode. */ +#define IMAGE_FILE_MACHINE_ARM64 UINT16_C(0xaa64) +/** @} */ + +/** @name File header characteristics (IMAGE_FILE_HEADER::Characteristics) + * @{ */ +#define IMAGE_FILE_RELOCS_STRIPPED UINT16_C(0x0001) +#define IMAGE_FILE_EXECUTABLE_IMAGE UINT16_C(0x0002) +#define IMAGE_FILE_LINE_NUMS_STRIPPED UINT16_C(0x0004) +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED UINT16_C(0x0008) +#define IMAGE_FILE_AGGRESIVE_WS_TRIM UINT16_C(0x0010) +#define IMAGE_FILE_LARGE_ADDRESS_AWARE UINT16_C(0x0020) +#define IMAGE_FILE_16BIT_MACHINE UINT16_C(0x0040) +#define IMAGE_FILE_BYTES_REVERSED_LO UINT16_C(0x0080) +#define IMAGE_FILE_32BIT_MACHINE UINT16_C(0x0100) +#define IMAGE_FILE_DEBUG_STRIPPED UINT16_C(0x0200) +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP UINT16_C(0x0400) +#define IMAGE_FILE_NET_RUN_FROM_SWAP UINT16_C(0x0800) +#define IMAGE_FILE_SYSTEM UINT16_C(0x1000) /**< (COFF/IAPX*: Used to indicate 80186 instructions) */ +#define IMAGE_FILE_DLL UINT16_C(0x2000) /**< (COFF/IAPX*: Used to indicate 80286 instructions) */ +#define IMAGE_FILE_UP_SYSTEM_ONLY UINT16_C(0x4000) +#define IMAGE_FILE_BYTES_REVERSED_HI UINT16_C(0x8000) +/** @} */ + + +/** + * PE data directory. + * + * This is used to locate data in the loaded image so the dynamic linker or + * others can make use of it. However, in the case of + * IMAGE_DIRECTORY_ENTRY_SECURITY it is referring to raw file offsets. + */ +typedef struct _IMAGE_DATA_DIRECTORY +{ + uint32_t VirtualAddress; + uint32_t Size; +} IMAGE_DATA_DIRECTORY; +AssertCompileSize(IMAGE_DATA_DIRECTORY, 0x8); +typedef IMAGE_DATA_DIRECTORY *PIMAGE_DATA_DIRECTORY; +typedef IMAGE_DATA_DIRECTORY const *PCIMAGE_DATA_DIRECTORY; + +/** The standard number of data directories in the optional header. + * I.e. the dimensions of IMAGE_OPTIONAL_HEADER32::DataDirectory and + * IMAGE_OPTIONAL_HEADER64::DataDirectory. + */ +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 0x10 + + +/** + * PE optional header, 32-bit version. + */ +typedef struct _IMAGE_OPTIONAL_HEADER32 +{ + uint16_t Magic; /**< 0x00 */ + uint8_t MajorLinkerVersion; /**< 0x02 */ + uint8_t MinorLinkerVersion; /**< 0x03 */ + uint32_t SizeOfCode; /**< 0x04 */ + uint32_t SizeOfInitializedData; /**< 0x08 */ + uint32_t SizeOfUninitializedData; /**< 0x0c */ + uint32_t AddressOfEntryPoint; /**< 0x10 */ + uint32_t BaseOfCode; /**< 0x14 */ + uint32_t BaseOfData; /**< 0x18 */ + uint32_t ImageBase; /**< 0x1c */ + uint32_t SectionAlignment; /**< 0x20 */ + uint32_t FileAlignment; /**< 0x24 */ + uint16_t MajorOperatingSystemVersion; /**< 0x28 */ + uint16_t MinorOperatingSystemVersion; /**< 0x2a */ + uint16_t MajorImageVersion; /**< 0x2c */ + uint16_t MinorImageVersion; /**< 0x2e */ + uint16_t MajorSubsystemVersion; /**< 0x30 */ + uint16_t MinorSubsystemVersion; /**< 0x32 */ + uint32_t Win32VersionValue; /**< 0x34 */ + uint32_t SizeOfImage; /**< 0x38 */ + uint32_t SizeOfHeaders; /**< 0x3c */ + uint32_t CheckSum; /**< 0x40 */ + uint16_t Subsystem; /**< 0x44 */ + uint16_t DllCharacteristics; /**< 0x46 */ + uint32_t SizeOfStackReserve; /**< 0x48 */ + uint32_t SizeOfStackCommit; /**< 0x4c */ + uint32_t SizeOfHeapReserve; /**< 0x50 */ + uint32_t SizeOfHeapCommit; /**< 0x54 */ + uint32_t LoaderFlags; /**< 0x58 */ + uint32_t NumberOfRvaAndSizes; /**< 0x5c */ + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; /**< 0x60; 0x10*8 = 0x80 */ +} IMAGE_OPTIONAL_HEADER32; /* size: 0xe0 */ +AssertCompileSize(IMAGE_OPTIONAL_HEADER32, 0xe0); +typedef IMAGE_OPTIONAL_HEADER32 *PIMAGE_OPTIONAL_HEADER32; +typedef IMAGE_OPTIONAL_HEADER32 const *PCIMAGE_OPTIONAL_HEADER32; + +/** + * PE optional header, 64-bit version. + */ +typedef struct _IMAGE_OPTIONAL_HEADER64 +{ + uint16_t Magic; /**< 0x00 */ + uint8_t MajorLinkerVersion; /**< 0x02 */ + uint8_t MinorLinkerVersion; /**< 0x03 */ + uint32_t SizeOfCode; /**< 0x04 */ + uint32_t SizeOfInitializedData; /**< 0x08 */ + uint32_t SizeOfUninitializedData; /**< 0x0c */ + uint32_t AddressOfEntryPoint; /**< 0x10 */ + uint32_t BaseOfCode; /**< 0x14 */ + uint64_t ImageBase; /**< 0x18 */ + uint32_t SectionAlignment; /**< 0x20 */ + uint32_t FileAlignment; /**< 0x24 */ + uint16_t MajorOperatingSystemVersion; /**< 0x28 */ + uint16_t MinorOperatingSystemVersion; /**< 0x2a */ + uint16_t MajorImageVersion; /**< 0x2c */ + uint16_t MinorImageVersion; /**< 0x2e */ + uint16_t MajorSubsystemVersion; /**< 0x30 */ + uint16_t MinorSubsystemVersion; /**< 0x32 */ + uint32_t Win32VersionValue; /**< 0x34 */ + uint32_t SizeOfImage; /**< 0x38 */ + uint32_t SizeOfHeaders; /**< 0x3c */ + uint32_t CheckSum; /**< 0x40 */ + uint16_t Subsystem; /**< 0x44 */ + uint16_t DllCharacteristics; /**< 0x46 */ + uint64_t SizeOfStackReserve; /**< 0x48 */ + uint64_t SizeOfStackCommit; /**< 0x50 */ + uint64_t SizeOfHeapReserve; /**< 0x58 */ + uint64_t SizeOfHeapCommit; /**< 0x60 */ + uint32_t LoaderFlags; /**< 0x68 */ + uint32_t NumberOfRvaAndSizes; /**< 0x6c */ + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; /**< 0x70; 0x10*8 = 0x80 */ +} IMAGE_OPTIONAL_HEADER64; /* size: 0xf0 */ +AssertCompileSize(IMAGE_OPTIONAL_HEADER64, 0xf0); +typedef IMAGE_OPTIONAL_HEADER64 *PIMAGE_OPTIONAL_HEADER64; +typedef IMAGE_OPTIONAL_HEADER64 const *PCIMAGE_OPTIONAL_HEADER64; + +/** @name Optional header magic values. + * @{ */ +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC UINT16_C(0x010b) +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC UINT16_C(0x020b) +/** @} */ + +/** @name IMAGE_SUBSYSTEM_XXX - Optional header subsystems. + * IMAGE_OPTIONAL_HEADER32::Subsystem, IMAGE_OPTIONAL_HEADER64::Subsystem + * @{ */ +#define IMAGE_SUBSYSTEM_UNKNOWN UINT16_C(0x0000) +#define IMAGE_SUBSYSTEM_NATIVE UINT16_C(0x0001) +#define IMAGE_SUBSYSTEM_WINDOWS_GUI UINT16_C(0x0002) +#define IMAGE_SUBSYSTEM_WINDOWS_CUI UINT16_C(0x0003) +#define IMAGE_SUBSYSTEM_OS2_GUI UINT16_C(0x0004) +#define IMAGE_SUBSYSTEM_OS2_CUI UINT16_C(0x0005) +#define IMAGE_SUBSYSTEM_POSIX_CUI UINT16_C(0x0007) +/** @} */ + +/** @name Optional header characteristics. + * @{ */ +#define IMAGE_LIBRARY_PROCESS_INIT UINT16_C(0x0001) +#define IMAGE_LIBRARY_PROCESS_TERM UINT16_C(0x0002) +#define IMAGE_LIBRARY_THREAD_INIT UINT16_C(0x0004) +#define IMAGE_LIBRARY_THREAD_TERM UINT16_C(0x0008) +#define IMAGE_DLLCHARACTERISTICS_RESERVED UINT16_C(0x0010) +#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA UINT16_C(0x0020) +#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE UINT16_C(0x0040) +#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY UINT16_C(0x0080) +#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT UINT16_C(0x0100) +#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION UINT16_C(0x0200) +#define IMAGE_DLLCHARACTERISTICS_NO_SEH UINT16_C(0x0400) +#define IMAGE_DLLCHARACTERISTICS_NO_BIND UINT16_C(0x0800) +#define IMAGE_DLLCHARACTERISTICS_APPCONTAINER UINT16_C(0x1000) +#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER UINT16_C(0x2000) +#define IMAGE_DLLCHARACTERISTICS_GUARD_CF UINT16_C(0x4000) +#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE UINT16_C(0x8000) +/** @} */ + + +/** @name IMAGE_DIRECTORY_ENTRY_XXX - Data directory indexes. + * Used to index IMAGE_OPTIONAL_HEADER32::DataDirectory and + * IMAGE_OPTIONAL_HEADER64::DataDirectory + * @{ */ +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0x0 +#define IMAGE_DIRECTORY_ENTRY_IMPORT 0x1 +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 0x2 +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 0x3 +#define IMAGE_DIRECTORY_ENTRY_SECURITY 0x4 +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 0x5 +#define IMAGE_DIRECTORY_ENTRY_DEBUG 0x6 +#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 0x7 +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT IMAGE_DIRECTORY_ENTRY_ARCHITECTURE +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 0x8 +#define IMAGE_DIRECTORY_ENTRY_TLS 0x9 +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 0xa +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 0xb +#define IMAGE_DIRECTORY_ENTRY_IAT 0xc +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 0xd +#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 0xe +/** @} */ + + +/** + * PE (NT) headers, 32-bit version. + */ +typedef struct _IMAGE_NT_HEADERS32 +{ + uint32_t Signature; /**< 0x00 */ + IMAGE_FILE_HEADER FileHeader; /**< 0x04 */ + IMAGE_OPTIONAL_HEADER32 OptionalHeader; /**< 0x18 */ +} IMAGE_NT_HEADERS32; /* size: 0xf8 */ +AssertCompileSize(IMAGE_NT_HEADERS32, 0xf8); +AssertCompileMemberOffset(IMAGE_NT_HEADERS32, FileHeader, 4); +AssertCompileMemberOffset(IMAGE_NT_HEADERS32, OptionalHeader, 24); +typedef IMAGE_NT_HEADERS32 *PIMAGE_NT_HEADERS32; +typedef IMAGE_NT_HEADERS32 const *PCIMAGE_NT_HEADERS32; + +/** + * PE (NT) headers, 64-bit version. + */ +typedef struct _IMAGE_NT_HEADERS64 +{ + uint32_t Signature; /**< 0x00 */ + IMAGE_FILE_HEADER FileHeader; /**< 0x04 */ + IMAGE_OPTIONAL_HEADER64 OptionalHeader; /**< 0x18 */ +} IMAGE_NT_HEADERS64; /**< 0x108 */ +AssertCompileSize(IMAGE_NT_HEADERS64, 0x108); +AssertCompileMemberOffset(IMAGE_NT_HEADERS64, FileHeader, 4); +AssertCompileMemberOffset(IMAGE_NT_HEADERS64, OptionalHeader, 24); +typedef IMAGE_NT_HEADERS64 *PIMAGE_NT_HEADERS64; +typedef IMAGE_NT_HEADERS64 const *PCIMAGE_NT_HEADERS64; + +/** The PE signature. + * Used by IMAGE_NT_HEADERS32::Signature, IMAGE_NT_HEADERS64::Signature. */ +#define IMAGE_NT_SIGNATURE UINT32_C(0x00004550) + + +/** Section header short name length (IMAGE_SECTION_HEADER::Name). */ +#define IMAGE_SIZEOF_SHORT_NAME 0x8 + +/** + * PE & COFF section header. + */ +typedef struct _IMAGE_SECTION_HEADER +{ + uint8_t Name[IMAGE_SIZEOF_SHORT_NAME]; + union + { + uint32_t PhysicalAddress; + uint32_t VirtualSize; + } Misc; + uint32_t VirtualAddress; + uint32_t SizeOfRawData; + uint32_t PointerToRawData; + uint32_t PointerToRelocations; + uint32_t PointerToLinenumbers; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t Characteristics; +} IMAGE_SECTION_HEADER; +AssertCompileSize(IMAGE_SECTION_HEADER, 40); +typedef IMAGE_SECTION_HEADER *PIMAGE_SECTION_HEADER; +typedef IMAGE_SECTION_HEADER const *PCIMAGE_SECTION_HEADER; + +/** @name IMAGE_SCN_XXX - Section header characteristics. + * Used by IMAGE_SECTION_HEADER::Characteristics. + * @{ */ +#define IMAGE_SCN_TYPE_REG UINT32_C(0x00000000) +#define IMAGE_SCN_TYPE_DSECT UINT32_C(0x00000001) +#define IMAGE_SCN_TYPE_NOLOAD UINT32_C(0x00000002) +#define IMAGE_SCN_TYPE_GROUP UINT32_C(0x00000004) +#define IMAGE_SCN_TYPE_NO_PAD UINT32_C(0x00000008) +#define IMAGE_SCN_TYPE_COPY UINT32_C(0x00000010) + +#define IMAGE_SCN_CNT_CODE UINT32_C(0x00000020) +#define IMAGE_SCN_CNT_INITIALIZED_DATA UINT32_C(0x00000040) +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA UINT32_C(0x00000080) + +#define IMAGE_SCN_LNK_OTHER UINT32_C(0x00000100) +#define IMAGE_SCN_LNK_INFO UINT32_C(0x00000200) +#define IMAGE_SCN_TYPE_OVER UINT32_C(0x00000400) +#define IMAGE_SCN_LNK_REMOVE UINT32_C(0x00000800) +#define IMAGE_SCN_LNK_COMDAT UINT32_C(0x00001000) +#define IMAGE_SCN_MEM_PROTECTED UINT32_C(0x00004000) +#define IMAGE_SCN_NO_DEFER_SPEC_EXC UINT32_C(0x00004000) +#define IMAGE_SCN_GPREL UINT32_C(0x00008000) +#define IMAGE_SCN_MEM_FARDATA UINT32_C(0x00008000) +#define IMAGE_SCN_MEM_SYSHEAP UINT32_C(0x00010000) +#define IMAGE_SCN_MEM_PURGEABLE UINT32_C(0x00020000) +#define IMAGE_SCN_MEM_16BIT UINT32_C(0x00020000) +#define IMAGE_SCN_MEM_LOCKED UINT32_C(0x00040000) +#define IMAGE_SCN_MEM_PRELOAD UINT32_C(0x00080000) + +#define IMAGE_SCN_ALIGN_1BYTES UINT32_C(0x00100000) +#define IMAGE_SCN_ALIGN_2BYTES UINT32_C(0x00200000) +#define IMAGE_SCN_ALIGN_4BYTES UINT32_C(0x00300000) +#define IMAGE_SCN_ALIGN_8BYTES UINT32_C(0x00400000) +#define IMAGE_SCN_ALIGN_16BYTES UINT32_C(0x00500000) +#define IMAGE_SCN_ALIGN_32BYTES UINT32_C(0x00600000) +#define IMAGE_SCN_ALIGN_64BYTES UINT32_C(0x00700000) +#define IMAGE_SCN_ALIGN_128BYTES UINT32_C(0x00800000) +#define IMAGE_SCN_ALIGN_256BYTES UINT32_C(0x00900000) +#define IMAGE_SCN_ALIGN_512BYTES UINT32_C(0x00A00000) +#define IMAGE_SCN_ALIGN_1024BYTES UINT32_C(0x00B00000) +#define IMAGE_SCN_ALIGN_2048BYTES UINT32_C(0x00C00000) +#define IMAGE_SCN_ALIGN_4096BYTES UINT32_C(0x00D00000) +#define IMAGE_SCN_ALIGN_8192BYTES UINT32_C(0x00E00000) +#define IMAGE_SCN_ALIGN_MASK UINT32_C(0x00F00000) +#define IMAGE_SCN_ALIGN_SHIFT 20 + +#define IMAGE_SCN_LNK_NRELOC_OVFL UINT32_C(0x01000000) +#define IMAGE_SCN_MEM_DISCARDABLE UINT32_C(0x02000000) +#define IMAGE_SCN_MEM_NOT_CACHED UINT32_C(0x04000000) +#define IMAGE_SCN_MEM_NOT_PAGED UINT32_C(0x08000000) +#define IMAGE_SCN_MEM_SHARED UINT32_C(0x10000000) +#define IMAGE_SCN_MEM_EXECUTE UINT32_C(0x20000000) +#define IMAGE_SCN_MEM_READ UINT32_C(0x40000000) +#define IMAGE_SCN_MEM_WRITE UINT32_C(0x80000000) +/** @} */ + + +/** + * PE image base relocations block header. + * + * This found in IMAGE_DIRECTORY_ENTRY_BASERELOC. Each entry is follow + * immediately by an array of 16-bit words, where the lower 12-bits are used + * for the page offset and the upper 4-bits for the base relocation type + * (IMAGE_REL_BASE_XXX). The block should be padded with + * IMAGE_REL_BASED_ABSOLUTE entries to ensure 32-bit alignment of this header. + */ +typedef struct _IMAGE_BASE_RELOCATION +{ + /** The RVA of the page/block the following ase relocations applies to. */ + uint32_t VirtualAddress; + /** The size of this relocation block, including this header. */ + uint32_t SizeOfBlock; +} IMAGE_BASE_RELOCATION; +AssertCompileSize(IMAGE_BASE_RELOCATION, 8); +typedef IMAGE_BASE_RELOCATION *PIMAGE_BASE_RELOCATION; +typedef IMAGE_BASE_RELOCATION const *PCIMAGE_BASE_RELOCATION; + +/** @name IMAGE_REL_BASED_XXX - PE base relocations. + * Found in the IMAGE_DIRECTORY_ENTRY_BASERELOC data directory. + * @{ */ +#define IMAGE_REL_BASED_ABSOLUTE UINT16_C(0x0) +#define IMAGE_REL_BASED_HIGH UINT16_C(0x1) +#define IMAGE_REL_BASED_LOW UINT16_C(0x2) +#define IMAGE_REL_BASED_HIGHLOW UINT16_C(0x3) +#define IMAGE_REL_BASED_HIGHADJ UINT16_C(0x4) +#define IMAGE_REL_BASED_MIPS_JMPADDR UINT16_C(0x5) +#define IMAGE_REL_BASED_MIPS_JMPADDR16 UINT16_C(0x9) +#define IMAGE_REL_BASED_IA64_IMM64 UINT16_C(0x9) +#define IMAGE_REL_BASED_DIR64 UINT16_C(0xa) +#define IMAGE_REL_BASED_HIGH3ADJ UINT16_C(0xb) +/** @} */ + +/** + * PE export directory entry. + */ +typedef struct _IMAGE_EXPORT_DIRECTORY +{ + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; + uint32_t AddressOfNames; + uint32_t AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY; +AssertCompileSize(IMAGE_EXPORT_DIRECTORY, 40); +typedef IMAGE_EXPORT_DIRECTORY *PIMAGE_EXPORT_DIRECTORY; +typedef IMAGE_EXPORT_DIRECTORY const *PCIMAGE_EXPORT_DIRECTORY; + + +/** + * PE import directory entry. + */ +typedef struct _IMAGE_IMPORT_DESCRIPTOR +{ + union + { + uint32_t Characteristics; + uint32_t OriginalFirstThunk; + } u; + uint32_t TimeDateStamp; + uint32_t ForwarderChain; + uint32_t Name; + uint32_t FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR; +AssertCompileSize(IMAGE_IMPORT_DESCRIPTOR, 20); +typedef IMAGE_IMPORT_DESCRIPTOR *PIMAGE_IMPORT_DESCRIPTOR; +typedef IMAGE_IMPORT_DESCRIPTOR const *PCIMAGE_IMPORT_DESCRIPTOR; + +/** + * Something we currently don't make use of... + */ +typedef struct _IMAGE_IMPORT_BY_NAME +{ + uint16_t Hint; + uint8_t Name[1]; +} IMAGE_IMPORT_BY_NAME; +AssertCompileSize(IMAGE_IMPORT_BY_NAME, 4); +typedef IMAGE_IMPORT_BY_NAME *PIMAGE_IMPORT_BY_NAME; +typedef IMAGE_IMPORT_BY_NAME const *PCIMAGE_IMPORT_BY_NAME; + + +#if 0 +/* The image_thunk_data32/64 structures are not very helpful except for getting RSI. + keep them around till all the code has been converted. */ +typedef struct _IMAGE_THUNK_DATA64 +{ + union + { + uint64_t ForwarderString; + uint64_t Function; + uint64_t Ordinal; + uint64_t AddressOfData; + } u1; +} IMAGE_THUNK_DATA64; +typedef IMAGE_THUNK_DATA64 *PIMAGE_THUNK_DATA64; +typedef IMAGE_THUNK_DATA64 const *PCIMAGE_THUNK_DATA64; + +typedef struct _IMAGE_THUNK_DATA32 +{ + union + { + uint32_t ForwarderString; + uint32_t Function; + uint32_t Ordinal; + uint32_t AddressOfData; + } u1; +} IMAGE_THUNK_DATA32; +typedef IMAGE_THUNK_DATA32 *PIMAGE_THUNK_DATA32; +typedef IMAGE_THUNK_DATA32 const *PCIMAGE_THUNK_DATA32; +#endif + +/** @name PE import directory macros. + * @{ */ +#define IMAGE_ORDINAL_FLAG32 UINT32_C(0x80000000) +#define IMAGE_ORDINAL32(ord) ((ord) & UINT32_C(0xffff)) +#define IMAGE_SNAP_BY_ORDINAL32(ord) (!!((ord) & IMAGE_ORDINAL_FLAG32)) + +#define IMAGE_ORDINAL_FLAG64 UINT64_C(0x8000000000000000) +#define IMAGE_ORDINAL64(ord) ((ord) & UINT32_C(0xffff)) +#define IMAGE_SNAP_BY_ORDINAL64(ord) (!!((ord) & IMAGE_ORDINAL_FLAG64)) +/** @} */ + +/** @name PE Resource directory + * @{ */ +typedef struct _IMAGE_RESOURCE_DIRECTORY +{ + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint16_t NumberOfNamedEntries; + uint16_t NumberOfIdEntries; +} IMAGE_RESOURCE_DIRECTORY; +typedef IMAGE_RESOURCE_DIRECTORY *PIMAGE_RESOURCE_DIRECTORY; +typedef IMAGE_RESOURCE_DIRECTORY const *PCIMAGE_RESOURCE_DIRECTORY; + +typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY +{ + union + { + struct + { + uint32_t NameOffset : 31; + uint32_t NameIsString : 1; /**< IMAGE_RESOURCE_NAME_IS_STRING */ + } s; + uint32_t Name; + uint16_t Id; + } u; + union + { + struct + { + uint32_t OffsetToDirectory : 31; + uint32_t DataIsDirectory : 1; /**< IMAGE_RESOURCE_DATA_IS_DIRECTORY*/ + } s2; + uint32_t OffsetToData; + } u2; +} IMAGE_RESOURCE_DIRECTORY_ENTRY; +typedef IMAGE_RESOURCE_DIRECTORY_ENTRY *PIMAGE_RESOURCE_DIRECTORY_ENTRY; +typedef IMAGE_RESOURCE_DIRECTORY_ENTRY const *PCIMAGE_RESOURCE_DIRECTORY_ENTRY; + +#define IMAGE_RESOURCE_NAME_IS_STRING UINT32_C(0x80000000) +#define IMAGE_RESOURCE_DATA_IS_DIRECTORY UINT32_C(0x80000000) + +typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING +{ + uint16_t Length; + char NameString[1]; +} IMAGE_RESOURCE_DIRECTORY_STRING; +typedef IMAGE_RESOURCE_DIRECTORY_STRING *PIMAGE_RESOURCE_DIRECTORY_STRING; +typedef IMAGE_RESOURCE_DIRECTORY_STRING const *PCIMAGE_RESOURCE_DIRECTORY_STRING; + + +typedef struct _IMAGE_RESOURCE_DIR_STRING_U +{ + uint16_t Length; + RTUTF16 NameString[1]; +} IMAGE_RESOURCE_DIR_STRING_U; +typedef IMAGE_RESOURCE_DIR_STRING_U *PIMAGE_RESOURCE_DIR_STRING_U; +typedef IMAGE_RESOURCE_DIR_STRING_U const *PCIMAGE_RESOURCE_DIR_STRING_U; + + +typedef struct _IMAGE_RESOURCE_DATA_ENTRY +{ + uint32_t OffsetToData; + uint32_t Size; + uint32_t CodePage; + uint32_t Reserved; +} IMAGE_RESOURCE_DATA_ENTRY; +typedef IMAGE_RESOURCE_DATA_ENTRY *PIMAGE_RESOURCE_DATA_ENTRY; +typedef IMAGE_RESOURCE_DATA_ENTRY const *PCIMAGE_RESOURCE_DATA_ENTRY; + +/** @} */ + +/** @name Image exception information + * @{ */ + +/** This structure is used by AMD64 and "Itanic". + * MIPS uses a different one. ARM, SH3, SH4 and PPC on WinCE also uses a different one. */ +typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY +{ + uint32_t BeginAddress; + uint32_t EndAddress; + uint32_t UnwindInfoAddress; +} IMAGE_RUNTIME_FUNCTION_ENTRY; +AssertCompileSize(IMAGE_RUNTIME_FUNCTION_ENTRY, 12); +typedef IMAGE_RUNTIME_FUNCTION_ENTRY *PIMAGE_RUNTIME_FUNCTION_ENTRY; +typedef IMAGE_RUNTIME_FUNCTION_ENTRY const *PCIMAGE_RUNTIME_FUNCTION_ENTRY; + +/** + * An unwind code for AMD64 and ARM64. + * + * @note Also known as UNWIND_CODE or _UNWIND_CODE. + */ +typedef union IMAGE_UNWIND_CODE +{ + struct + { + /** The prolog offset where the change takes effect. + * This means the instruction following the one being described. */ + uint8_t CodeOffset; + /** Unwind opcode. + * For AMD64 see IMAGE_AMD64_UNWIND_OP_CODES. */ + RT_GCC_EXTENSION uint8_t UnwindOp : 4; + /** Opcode specific. */ + RT_GCC_EXTENSION uint8_t OpInfo : 4; + } u; + uint16_t FrameOffset; +} IMAGE_UNWIND_CODE; +AssertCompileSize(IMAGE_UNWIND_CODE, 2); + +/** + * Unwind information for AMD64 and ARM64. + * + * Pointed to by IMAGE_RUNTIME_FUNCTION_ENTRY::UnwindInfoAddress, + * + * @note Also known as UNWIND_INFO or _UNWIND_INFO. + */ +typedef struct IMAGE_UNWIND_INFO +{ + /** Version, currently 1 or 2. The latter if IMAGE_AMD64_UWOP_EPILOG is used. */ + RT_GCC_EXTENSION uint8_t Version : 3; + /** IMAGE_UNW_FLAG_XXX */ + RT_GCC_EXTENSION uint8_t Flags : 5; + /** Size of function prolog. */ + uint8_t SizeOfProlog; + /** Number of opcodes in aOpcodes. */ + uint8_t CountOfCodes; + /** Initial frame register. */ + RT_GCC_EXTENSION uint8_t FrameRegister : 4; + /** Scaled frame register offset. */ + RT_GCC_EXTENSION uint8_t FrameOffset : 4; + /** Unwind opcodes. */ + RT_FLEXIBLE_ARRAY_EXTENSION + IMAGE_UNWIND_CODE aOpcodes[RT_FLEXIBLE_ARRAY]; +} IMAGE_UNWIND_INFO; +AssertCompileMemberOffset(IMAGE_UNWIND_INFO, aOpcodes, 4); +typedef IMAGE_UNWIND_INFO *PIMAGE_UNWIND_INFO; +typedef IMAGE_UNWIND_INFO const *PCIMAGE_UNWIND_INFO; + +/** IMAGE_UNW_FLAGS_XXX - IMAGE_UNWIND_INFO::Flags. + * @{ */ +/** No handler. + * @note Also know as UNW_FLAG_NHANDLER. */ +#define IMAGE_UNW_FLAGS_NHANDLER 0 +/** Have exception handler (RVA after codes, dword aligned.) + * @note Also know as UNW_FLAG_NHANDLER. */ +#define IMAGE_UNW_FLAGS_EHANDLER 1 +/** Have unwind handler (RVA after codes, dword aligned.) + * @note Also know as UNW_FLAG_NHANDLER. */ +#define IMAGE_UNW_FLAGS_UHANDLER 2 +/** Set if not primary unwind info for a function. An + * IMAGE_RUNTIME_FUNCTION_ENTRY giving the chained unwind info follows the + * aOpcodes array at a dword aligned offset. */ +#define IMAGE_UNW_FLAGS_CHAININFO 4 +/** @} */ + +/** + * AMD64 unwind opcodes. + */ +typedef enum IMAGE_AMD64_UNWIND_OP_CODES +{ + /** Push non-volatile register (OpInfo). + * YASM: [pushreg reg] + * MASM: .PUSHREG reg */ + IMAGE_AMD64_UWOP_PUSH_NONVOL = 0, + /** Stack allocation: Size stored in scaled in the next slot if OpInfo == 0, + * otherwise stored unscaled in the next two slots. + * YASM: [allocstack size] + * MASM: .ALLOCSTACK size */ + IMAGE_AMD64_UWOP_ALLOC_LARGE, + /** Stack allocation: OpInfo = size / 8 - 1. + * YASM: [allocstack size] + * MASM: .ALLOCSTACK size */ + IMAGE_AMD64_UWOP_ALLOC_SMALL, + /** Set frame pointer register: RSP + FrameOffset * 16. + * YASM: [setframe reg, offset] + * MASM: .SETFRAME reg, offset + * @code + * LEA RBP, [RSP + 20h] + * [setframe RBP, 20h] + * @endcode */ + IMAGE_AMD64_UWOP_SET_FPREG, + /** Save non-volatile register (OpInfo) on stack (RSP/FP + next slot). + * YASM: [savereg reg, offset] + * MASM: .SAVEREG reg, offset */ + IMAGE_AMD64_UWOP_SAVE_NONVOL, + /** Save non-volatile register (OpInfo) on stack (RSP/FP + next two slots). + * YASM: [savereg reg, offset] + * MASM: .SAVEREG reg, offset */ + IMAGE_AMD64_UWOP_SAVE_NONVOL_FAR, + /** Epilog info, version 2+. + * + * The first time this opcode is used, the CodeOffset gives the size of the + * epilog and bit 0 of the OpInfo field indicates that there is only one + * epilog at the very end of the function. + * + * Subsequent uses of this opcode specifies epilog start offsets relative to + * the end of the function, using CodeOffset for the 8 lower bits and OpInfo + * for bits 8 thru 11. + * + * The compiler seems to stack allocations and register saving opcodes and + * indicates the location mirroring the first IMAGE_AMD64_UWOP_PUSH_NONVOL. */ + IMAGE_AMD64_UWOP_EPILOG, + /** Undefined. */ + IMAGE_AMD64_UWOP_RESERVED_7, + /** Save 128-bit XMM register (OpInfo) on stack (RSP/FP + next slot). + * YASM: [savexmm128 reg, offset] + * MASM: .SAVEXMM128 reg, offset */ + IMAGE_AMD64_UWOP_SAVE_XMM128, + /** Save 128-bit XMM register (OpInfo) on stack (RSP/FP + next two slots). + * YASM: [savexmm128 reg, offset] + * MASM: .SAVEXMM128 reg, offset */ + IMAGE_AMD64_UWOP_SAVE_XMM128_FAR, + /** IRET frame, OpInfo serves as error code indicator. + * YASM: [pushframe with-code] + * MASM: .pushframe with-code */ + IMAGE_AMD64_UWOP_PUSH_MACHFRAME +} IMAGE_AMD64_UNWIND_OP_CODES; +/** @} */ + + + +/** @name Image load config directories + * @{ */ + +/** @since Windows 10 (preview 9879) */ +typedef struct _IMAGE_LOAD_CONFIG_CODE_INTEGRITY +{ + uint16_t Flags; + uint16_t Catalog; + uint32_t CatalogOffset; + uint32_t Reserved; +} IMAGE_LOAD_CONFIG_CODE_INTEGRITY; +AssertCompileSize(IMAGE_LOAD_CONFIG_CODE_INTEGRITY, 12); +typedef IMAGE_LOAD_CONFIG_CODE_INTEGRITY *PIMAGE_LOAD_CONFIG_CODE_INTEGRITY; +typedef IMAGE_LOAD_CONFIG_CODE_INTEGRITY const *PCIMAGE_LOAD_CONFIG_CODE_INTEGRITY; + +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V1 +{ + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint32_t DeCommitFreeBlockThreshold; + uint32_t DeCommitTotalFreeThreshold; + uint32_t LockPrefixTable; + uint32_t MaximumAllocationSize; + uint32_t VirtualMemoryThreshold; + uint32_t ProcessHeapFlags; + uint32_t ProcessAffinityMask; + uint16_t CSDVersion; + uint16_t DependentLoadFlags; + uint32_t EditList; + uint32_t SecurityCookie; +} IMAGE_LOAD_CONFIG_DIRECTORY32_V1; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V1, 0x40); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V1 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V1; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V1 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V1; + +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V2 +{ + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint32_t DeCommitFreeBlockThreshold; + uint32_t DeCommitTotalFreeThreshold; + uint32_t LockPrefixTable; + uint32_t MaximumAllocationSize; + uint32_t VirtualMemoryThreshold; + uint32_t ProcessHeapFlags; + uint32_t ProcessAffinityMask; + uint16_t CSDVersion; + uint16_t DependentLoadFlags; + uint32_t EditList; + uint32_t SecurityCookie; + uint32_t SEHandlerTable; + uint32_t SEHandlerCount; +} IMAGE_LOAD_CONFIG_DIRECTORY32_V2; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V2, 0x48); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V2 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V2; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V2 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V2; + +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V3 +{ + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint32_t DeCommitFreeBlockThreshold; + uint32_t DeCommitTotalFreeThreshold; + uint32_t LockPrefixTable; + uint32_t MaximumAllocationSize; + uint32_t VirtualMemoryThreshold; + uint32_t ProcessHeapFlags; + uint32_t ProcessAffinityMask; + uint16_t CSDVersion; + uint16_t DependentLoadFlags; + uint32_t EditList; + uint32_t SecurityCookie; + uint32_t SEHandlerTable; + uint32_t SEHandlerCount; + uint32_t GuardCFCCheckFunctionPointer; + uint32_t GuardCFDispatchFunctionPointer; + uint32_t GuardCFFunctionTable; + uint32_t GuardCFFunctionCount; + uint32_t GuardFlags; +} IMAGE_LOAD_CONFIG_DIRECTORY32_V3; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V3, 0x5c); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V3 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V3; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V3 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V3; + +/** @since Windows 10 (preview 9879) */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V4 +{ + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint32_t DeCommitFreeBlockThreshold; + uint32_t DeCommitTotalFreeThreshold; + uint32_t LockPrefixTable; + uint32_t MaximumAllocationSize; + uint32_t VirtualMemoryThreshold; + uint32_t ProcessHeapFlags; + uint32_t ProcessAffinityMask; + uint16_t CSDVersion; + uint16_t DependentLoadFlags; + uint32_t EditList; + uint32_t SecurityCookie; + uint32_t SEHandlerTable; + uint32_t SEHandlerCount; + uint32_t GuardCFCCheckFunctionPointer; + uint32_t GuardCFDispatchFunctionPointer; + uint32_t GuardCFFunctionTable; + uint32_t GuardCFFunctionCount; + uint32_t GuardFlags; + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; +} IMAGE_LOAD_CONFIG_DIRECTORY32_V4; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V4, 0x68); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V4 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V4; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V4 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V4; + +/** @since Windows 10 build 14286 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V5 +{ + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint32_t DeCommitFreeBlockThreshold; + uint32_t DeCommitTotalFreeThreshold; + uint32_t LockPrefixTable; + uint32_t MaximumAllocationSize; + uint32_t VirtualMemoryThreshold; + uint32_t ProcessHeapFlags; + uint32_t ProcessAffinityMask; + uint16_t CSDVersion; + uint16_t DependentLoadFlags; + uint32_t EditList; + uint32_t SecurityCookie; + uint32_t SEHandlerTable; + uint32_t SEHandlerCount; + uint32_t GuardCFCCheckFunctionPointer; + uint32_t GuardCFDispatchFunctionPointer; + uint32_t GuardCFFunctionTable; + uint32_t GuardCFFunctionCount; + uint32_t GuardFlags; + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; + uint32_t GuardAddressTakenIatEntryTable; + uint32_t GuardAddressTakenIatEntryCount; + uint32_t GuardLongJumpTargetTable; + uint32_t GuardLongJumpTargetCount; +} IMAGE_LOAD_CONFIG_DIRECTORY32_V5; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V5, 0x78); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V5 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V5; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V5 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V5; + +/** @since Windows 10 build 14383 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V6 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint32_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint32_t DeCommitTotalFreeThreshold; /**< 0x1c */ + uint32_t LockPrefixTable; /**< 0x20 */ + uint32_t MaximumAllocationSize; /**< 0x24 */ + uint32_t VirtualMemoryThreshold; /**< 0x28 */ + uint32_t ProcessHeapFlags; /**< 0x2c */ + uint32_t ProcessAffinityMask; /**< 0x30 */ + uint16_t CSDVersion; /**< 0x34 */ + uint16_t DependentLoadFlags; /**< 0x36 */ + uint32_t EditList; /**< 0x38 */ + uint32_t SecurityCookie; /**< 0x3c */ + uint32_t SEHandlerTable; /**< 0x40 */ + uint32_t SEHandlerCount; /**< 0x44 */ + uint32_t GuardCFCCheckFunctionPointer; /**< 0x48 */ + uint32_t GuardCFDispatchFunctionPointer; /**< 0x4c */ + uint32_t GuardCFFunctionTable; /**< 0x50 */ + uint32_t GuardCFFunctionCount; /**< 0x54 */ + uint32_t GuardFlags; /**< 0x58 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x5c */ + uint32_t GuardAddressTakenIatEntryTable; /**< 0x68 */ + uint32_t GuardAddressTakenIatEntryCount; /**< 0x6c */ + uint32_t GuardLongJumpTargetTable; /**< 0x70 */ + uint32_t GuardLongJumpTargetCount; /**< 0x74 */ + uint32_t DynamicValueRelocTable; /**< 0x78 */ + uint32_t HybridMetadataPointer; /**< 0x7c */ +} IMAGE_LOAD_CONFIG_DIRECTORY32_V6; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V6, 0x80); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V6 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V6; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V6 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V6; + +/** @since Windows 10 build 14901 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V7 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint32_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint32_t DeCommitTotalFreeThreshold; /**< 0x1c */ + uint32_t LockPrefixTable; /**< 0x20 */ + uint32_t MaximumAllocationSize; /**< 0x24 */ + uint32_t VirtualMemoryThreshold; /**< 0x28 */ + uint32_t ProcessHeapFlags; /**< 0x2c */ + uint32_t ProcessAffinityMask; /**< 0x30 */ + uint16_t CSDVersion; /**< 0x34 */ + uint16_t DependentLoadFlags; /**< 0x36 */ + uint32_t EditList; /**< 0x38 */ + uint32_t SecurityCookie; /**< 0x3c */ + uint32_t SEHandlerTable; /**< 0x40 */ + uint32_t SEHandlerCount; /**< 0x44 */ + uint32_t GuardCFCCheckFunctionPointer; /**< 0x48 */ + uint32_t GuardCFDispatchFunctionPointer; /**< 0x4c */ + uint32_t GuardCFFunctionTable; /**< 0x50 */ + uint32_t GuardCFFunctionCount; /**< 0x54 */ + uint32_t GuardFlags; /**< 0x58 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x5c */ + uint32_t GuardAddressTakenIatEntryTable; /**< 0x68 */ + uint32_t GuardAddressTakenIatEntryCount; /**< 0x6c */ + uint32_t GuardLongJumpTargetTable; /**< 0x70 */ + uint32_t GuardLongJumpTargetCount; /**< 0x74 */ + uint32_t DynamicValueRelocTable; /**< 0x78 */ + uint32_t CHPEMetadataPointer; /**< 0x7c Not sure when this was renamed from HybridMetadataPointer. */ + uint32_t GuardRFFailureRoutine; /**< 0x80 */ + uint32_t GuardRFFailureRoutineFunctionPointer; /**< 0x84 */ + uint32_t DynamicValueRelocTableOffset; /**< 0x88 */ + uint16_t DynamicValueRelocTableSection; /**< 0x8c */ + uint16_t Reserved2; /**< 0x8e */ +} IMAGE_LOAD_CONFIG_DIRECTORY32_V7; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V7, 0x90); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V7 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V7; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V7 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V7; + +/** @since Windows 10 build 15002 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V8 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint32_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint32_t DeCommitTotalFreeThreshold; /**< 0x1c */ + uint32_t LockPrefixTable; /**< 0x20 */ + uint32_t MaximumAllocationSize; /**< 0x24 */ + uint32_t VirtualMemoryThreshold; /**< 0x28 */ + uint32_t ProcessHeapFlags; /**< 0x2c */ + uint32_t ProcessAffinityMask; /**< 0x30 */ + uint16_t CSDVersion; /**< 0x34 */ + uint16_t DependentLoadFlags; /**< 0x36 */ + uint32_t EditList; /**< 0x38 */ + uint32_t SecurityCookie; /**< 0x3c */ + uint32_t SEHandlerTable; /**< 0x40 */ + uint32_t SEHandlerCount; /**< 0x44 */ + uint32_t GuardCFCCheckFunctionPointer; /**< 0x48 */ + uint32_t GuardCFDispatchFunctionPointer; /**< 0x4c */ + uint32_t GuardCFFunctionTable; /**< 0x50 */ + uint32_t GuardCFFunctionCount; /**< 0x54 */ + uint32_t GuardFlags; /**< 0x58 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x5c */ + uint32_t GuardAddressTakenIatEntryTable; /**< 0x68 */ + uint32_t GuardAddressTakenIatEntryCount; /**< 0x6c */ + uint32_t GuardLongJumpTargetTable; /**< 0x70 */ + uint32_t GuardLongJumpTargetCount; /**< 0x74 */ + uint32_t DynamicValueRelocTable; /**< 0x78 */ + uint32_t CHPEMetadataPointer; /**< 0x7c Not sure when this was renamed from HybridMetadataPointer. */ + uint32_t GuardRFFailureRoutine; /**< 0x80 */ + uint32_t GuardRFFailureRoutineFunctionPointer; /**< 0x84 */ + uint32_t DynamicValueRelocTableOffset; /**< 0x88 */ + uint16_t DynamicValueRelocTableSection; /**< 0x8c */ + uint16_t Reserved2; /**< 0x8e */ + uint32_t GuardRFVerifyStackPointerFunctionPointer; /**< 0x90 */ + uint32_t HotPatchTableOffset; /**< 0x94 */ +} IMAGE_LOAD_CONFIG_DIRECTORY32_V8; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V8, 0x98); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V8 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V8; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V8 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V8; + +/** @since Windows 10 build 16237 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V9 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint32_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint32_t DeCommitTotalFreeThreshold; /**< 0x1c */ + uint32_t LockPrefixTable; /**< 0x20 */ + uint32_t MaximumAllocationSize; /**< 0x24 */ + uint32_t VirtualMemoryThreshold; /**< 0x28 */ + uint32_t ProcessHeapFlags; /**< 0x2c */ + uint32_t ProcessAffinityMask; /**< 0x30 */ + uint16_t CSDVersion; /**< 0x34 */ + uint16_t DependentLoadFlags; /**< 0x36 */ + uint32_t EditList; /**< 0x38 */ + uint32_t SecurityCookie; /**< 0x3c */ + uint32_t SEHandlerTable; /**< 0x40 */ + uint32_t SEHandlerCount; /**< 0x44 */ + uint32_t GuardCFCCheckFunctionPointer; /**< 0x48 */ + uint32_t GuardCFDispatchFunctionPointer; /**< 0x4c */ + uint32_t GuardCFFunctionTable; /**< 0x50 */ + uint32_t GuardCFFunctionCount; /**< 0x54 */ + uint32_t GuardFlags; /**< 0x58 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x5c */ + uint32_t GuardAddressTakenIatEntryTable; /**< 0x68 */ + uint32_t GuardAddressTakenIatEntryCount; /**< 0x6c */ + uint32_t GuardLongJumpTargetTable; /**< 0x70 */ + uint32_t GuardLongJumpTargetCount; /**< 0x74 */ + uint32_t DynamicValueRelocTable; /**< 0x78 */ + uint32_t CHPEMetadataPointer; /**< 0x7c Not sure when this was renamed from HybridMetadataPointer. */ + uint32_t GuardRFFailureRoutine; /**< 0x80 */ + uint32_t GuardRFFailureRoutineFunctionPointer; /**< 0x84 */ + uint32_t DynamicValueRelocTableOffset; /**< 0x88 */ + uint16_t DynamicValueRelocTableSection; /**< 0x8c */ + uint16_t Reserved2; /**< 0x8e */ + uint32_t GuardRFVerifyStackPointerFunctionPointer; /**< 0x90 */ + uint32_t HotPatchTableOffset; /**< 0x94 */ + uint32_t Reserved3; /**< 0x98 */ + uint32_t EnclaveConfigurationPointer; /**< 0x9c */ +} IMAGE_LOAD_CONFIG_DIRECTORY32_V9; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V9, 0xa0); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V9 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V9; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V9 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V9; + +/** @since Windows 10 build 18362 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V10 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint32_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint32_t DeCommitTotalFreeThreshold; /**< 0x1c */ + uint32_t LockPrefixTable; /**< 0x20 */ + uint32_t MaximumAllocationSize; /**< 0x24 */ + uint32_t VirtualMemoryThreshold; /**< 0x28 */ + uint32_t ProcessHeapFlags; /**< 0x2c */ + uint32_t ProcessAffinityMask; /**< 0x30 */ + uint16_t CSDVersion; /**< 0x34 */ + uint16_t DependentLoadFlags; /**< 0x36 */ + uint32_t EditList; /**< 0x38 */ + uint32_t SecurityCookie; /**< 0x3c */ + uint32_t SEHandlerTable; /**< 0x40 */ + uint32_t SEHandlerCount; /**< 0x44 */ + uint32_t GuardCFCCheckFunctionPointer; /**< 0x48 */ + uint32_t GuardCFDispatchFunctionPointer; /**< 0x4c */ + uint32_t GuardCFFunctionTable; /**< 0x50 */ + uint32_t GuardCFFunctionCount; /**< 0x54 */ + uint32_t GuardFlags; /**< 0x58 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x5c */ + uint32_t GuardAddressTakenIatEntryTable; /**< 0x68 */ + uint32_t GuardAddressTakenIatEntryCount; /**< 0x6c */ + uint32_t GuardLongJumpTargetTable; /**< 0x70 */ + uint32_t GuardLongJumpTargetCount; /**< 0x74 */ + uint32_t DynamicValueRelocTable; /**< 0x78 */ + uint32_t CHPEMetadataPointer; /**< 0x7c Not sure when this was renamed from HybridMetadataPointer. */ + uint32_t GuardRFFailureRoutine; /**< 0x80 */ + uint32_t GuardRFFailureRoutineFunctionPointer; /**< 0x84 */ + uint32_t DynamicValueRelocTableOffset; /**< 0x88 */ + uint16_t DynamicValueRelocTableSection; /**< 0x8c */ + uint16_t Reserved2; /**< 0x8e */ + uint32_t GuardRFVerifyStackPointerFunctionPointer; /**< 0x90 */ + uint32_t HotPatchTableOffset; /**< 0x94 */ + uint32_t Reserved3; /**< 0x98 */ + uint32_t EnclaveConfigurationPointer; /**< 0x9c */ + uint32_t VolatileMetadataPointer; /**< 0xa0 */ +} IMAGE_LOAD_CONFIG_DIRECTORY32_V10; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V10, 0xa4); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V10 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V10; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V10 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V10; + +/** @since Windows 10 build 19564 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V11 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint32_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint32_t DeCommitTotalFreeThreshold; /**< 0x1c */ + uint32_t LockPrefixTable; /**< 0x20 */ + uint32_t MaximumAllocationSize; /**< 0x24 */ + uint32_t VirtualMemoryThreshold; /**< 0x28 */ + uint32_t ProcessHeapFlags; /**< 0x2c */ + uint32_t ProcessAffinityMask; /**< 0x30 */ + uint16_t CSDVersion; /**< 0x34 */ + uint16_t DependentLoadFlags; /**< 0x36 */ + uint32_t EditList; /**< 0x38 */ + uint32_t SecurityCookie; /**< 0x3c */ + uint32_t SEHandlerTable; /**< 0x40 */ + uint32_t SEHandlerCount; /**< 0x44 */ + uint32_t GuardCFCCheckFunctionPointer; /**< 0x48 */ + uint32_t GuardCFDispatchFunctionPointer; /**< 0x4c */ + uint32_t GuardCFFunctionTable; /**< 0x50 */ + uint32_t GuardCFFunctionCount; /**< 0x54 */ + uint32_t GuardFlags; /**< 0x58 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x5c */ + uint32_t GuardAddressTakenIatEntryTable; /**< 0x68 */ + uint32_t GuardAddressTakenIatEntryCount; /**< 0x6c */ + uint32_t GuardLongJumpTargetTable; /**< 0x70 */ + uint32_t GuardLongJumpTargetCount; /**< 0x74 */ + uint32_t DynamicValueRelocTable; /**< 0x78 */ + uint32_t CHPEMetadataPointer; /**< 0x7c Not sure when this was renamed from HybridMetadataPointer. */ + uint32_t GuardRFFailureRoutine; /**< 0x80 */ + uint32_t GuardRFFailureRoutineFunctionPointer; /**< 0x84 */ + uint32_t DynamicValueRelocTableOffset; /**< 0x88 */ + uint16_t DynamicValueRelocTableSection; /**< 0x8c */ + uint16_t Reserved2; /**< 0x8e */ + uint32_t GuardRFVerifyStackPointerFunctionPointer; /**< 0x90 */ + uint32_t HotPatchTableOffset; /**< 0x94 */ + uint32_t Reserved3; /**< 0x98 */ + uint32_t EnclaveConfigurationPointer; /**< 0x9c - virtual address */ + uint32_t VolatileMetadataPointer; /**< 0xa0 */ + uint32_t GuardEHContinuationTable; /**< 0xa4 - virtual address */ + uint32_t GuardEHContinuationCount; /**< 0xa8 */ +} IMAGE_LOAD_CONFIG_DIRECTORY32_V11; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V11, 0xac); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V11 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V11; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V11 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V11; + +/** @since Visual C++ 2019 / RS5_IMAGE_LOAD_CONFIG_DIRECTORY32. */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V12 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint32_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint32_t DeCommitTotalFreeThreshold; /**< 0x1c */ + uint32_t LockPrefixTable; /**< 0x20 */ + uint32_t MaximumAllocationSize; /**< 0x24 */ + uint32_t VirtualMemoryThreshold; /**< 0x28 */ + uint32_t ProcessHeapFlags; /**< 0x2c */ + uint32_t ProcessAffinityMask; /**< 0x30 */ + uint16_t CSDVersion; /**< 0x34 */ + uint16_t DependentLoadFlags; /**< 0x36 */ + uint32_t EditList; /**< 0x38 */ + uint32_t SecurityCookie; /**< 0x3c */ + uint32_t SEHandlerTable; /**< 0x40 */ + uint32_t SEHandlerCount; /**< 0x44 */ + uint32_t GuardCFCCheckFunctionPointer; /**< 0x48 */ + uint32_t GuardCFDispatchFunctionPointer; /**< 0x4c */ + uint32_t GuardCFFunctionTable; /**< 0x50 */ + uint32_t GuardCFFunctionCount; /**< 0x54 */ + uint32_t GuardFlags; /**< 0x58 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x5c */ + uint32_t GuardAddressTakenIatEntryTable; /**< 0x68 */ + uint32_t GuardAddressTakenIatEntryCount; /**< 0x6c */ + uint32_t GuardLongJumpTargetTable; /**< 0x70 */ + uint32_t GuardLongJumpTargetCount; /**< 0x74 */ + uint32_t DynamicValueRelocTable; /**< 0x78 */ + uint32_t CHPEMetadataPointer; /**< 0x7c Not sure when this was renamed from HybridMetadataPointer. */ + uint32_t GuardRFFailureRoutine; /**< 0x80 */ + uint32_t GuardRFFailureRoutineFunctionPointer; /**< 0x84 */ + uint32_t DynamicValueRelocTableOffset; /**< 0x88 */ + uint16_t DynamicValueRelocTableSection; /**< 0x8c */ + uint16_t Reserved2; /**< 0x8e */ + uint32_t GuardRFVerifyStackPointerFunctionPointer; /**< 0x90 */ + uint32_t HotPatchTableOffset; /**< 0x94 */ + uint32_t Reserved3; /**< 0x98 */ + uint32_t EnclaveConfigurationPointer; /**< 0x9c - virtual address */ + uint32_t VolatileMetadataPointer; /**< 0xa0 */ + uint32_t GuardEHContinuationTable; /**< 0xa4 - virtual address */ + uint32_t GuardEHContinuationCount; /**< 0xa8 */ + uint32_t GuardXFGCheckFunctionPointer; /**< 0xac */ + uint32_t GuardXFGDispatchFunctionPointer; /**< 0xb0 */ + uint32_t GuardXFGTableDispatchFunctionPointer; /**< 0xb4 */ +} IMAGE_LOAD_CONFIG_DIRECTORY32_V12; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V12, 0xb8); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V12 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V12; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V12 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V12; + +/** @since Visual C++ 2019 16.x (found in 16.11.9) / RS5_IMAGE_LOAD_CONFIG_DIRECTORY32. */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V13 +{ + uint32_t Size; /**< 0x00 - virtual address */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint32_t DeCommitFreeBlockThreshold; /**< 0x18 - virtual address */ + uint32_t DeCommitTotalFreeThreshold; /**< 0x1c - virtual address */ + uint32_t LockPrefixTable; /**< 0x20 */ + uint32_t MaximumAllocationSize; /**< 0x24 */ + uint32_t VirtualMemoryThreshold; /**< 0x28 - virtual address of pointer variable */ + uint32_t ProcessHeapFlags; /**< 0x2c - virtual address of pointer variable */ + uint32_t ProcessAffinityMask; /**< 0x30 - virtual address */ + uint16_t CSDVersion; /**< 0x34 */ + uint16_t DependentLoadFlags; /**< 0x36 */ + uint32_t EditList; /**< 0x38 */ + uint32_t SecurityCookie; /**< 0x3c - virtual address */ + uint32_t SEHandlerTable; /**< 0x40 */ + uint32_t SEHandlerCount; /**< 0x44 - virtual address */ + uint32_t GuardCFCCheckFunctionPointer; /**< 0x48 */ + uint32_t GuardCFDispatchFunctionPointer; /**< 0x4c - virtual address */ + uint32_t GuardCFFunctionTable; /**< 0x50 */ + uint32_t GuardCFFunctionCount; /**< 0x54 - virtual address */ + uint32_t GuardFlags; /**< 0x58 - virtual address of pointer variable */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x5c */ + uint32_t GuardAddressTakenIatEntryTable; /**< 0x68 - virtual address */ + uint32_t GuardAddressTakenIatEntryCount; /**< 0x6c */ + uint32_t GuardLongJumpTargetTable; /**< 0x70 - virtual address */ + uint32_t GuardLongJumpTargetCount; /**< 0x74 */ + uint32_t DynamicValueRelocTable; /**< 0x78 - virtual address */ + uint32_t CHPEMetadataPointer; /**< 0x7c Not sure when this was renamed from HybridMetadataPointer. */ + uint32_t GuardRFFailureRoutine; /**< 0x80 - virtual address */ + uint32_t GuardRFFailureRoutineFunctionPointer; /**< 0x84 - virtual address of pointer variable */ + uint32_t DynamicValueRelocTableOffset; /**< 0x88 */ + uint16_t DynamicValueRelocTableSection; /**< 0x8c */ + uint16_t Reserved2; /**< 0x8e */ + uint32_t GuardRFVerifyStackPointerFunctionPointer; /**< 0x90 - virtual address of pointer variable */ + uint32_t HotPatchTableOffset; /**< 0x94 */ + uint32_t Reserved3; /**< 0x98 */ + uint32_t EnclaveConfigurationPointer; /**< 0x9c - virtual address of pointer variable */ + uint32_t VolatileMetadataPointer; /**< 0xa0 - virtual address of pointer variable */ + uint32_t GuardEHContinuationTable; /**< 0xa4 - virtual address */ + uint32_t GuardEHContinuationCount; /**< 0xa8 */ + uint32_t GuardXFGCheckFunctionPointer; /**< 0xac - virtual address of pointer variable */ + uint32_t GuardXFGDispatchFunctionPointer; /**< 0xb0 - virtual address of pointer variable */ + uint32_t GuardXFGTableDispatchFunctionPointer; /**< 0xb4 - virtual address of pointer variable */ + uint32_t CastGuardOsDeterminedFailureMode; /**< 0xb8 - virtual address */ +} IMAGE_LOAD_CONFIG_DIRECTORY32_V13; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V13, 0xbc); +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V13 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V13; +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V13 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V13; + +typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V13 IMAGE_LOAD_CONFIG_DIRECTORY32; +typedef PIMAGE_LOAD_CONFIG_DIRECTORY32_V13 PIMAGE_LOAD_CONFIG_DIRECTORY32; +typedef PCIMAGE_LOAD_CONFIG_DIRECTORY32_V13 PCIMAGE_LOAD_CONFIG_DIRECTORY32; + + +/* No _IMAGE_LOAD_CONFIG_DIRECTORY64_V1 exists. */ + +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V2 +{ + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint64_t DeCommitFreeBlockThreshold; + uint64_t DeCommitTotalFreeThreshold; + uint64_t LockPrefixTable; + uint64_t MaximumAllocationSize; + uint64_t VirtualMemoryThreshold; + uint64_t ProcessAffinityMask; + uint32_t ProcessHeapFlags; + uint16_t CSDVersion; + uint16_t DependentLoadFlags; + uint64_t EditList; + uint64_t SecurityCookie; + uint64_t SEHandlerTable; + uint64_t SEHandlerCount; +} IMAGE_LOAD_CONFIG_DIRECTORY64_V2; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V2, 0x70); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V2 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V2; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V2 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V2; + +#pragma pack(4) /* Why not 8 byte alignment, baka microsofties?!? */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V3 +{ + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint64_t DeCommitFreeBlockThreshold; + uint64_t DeCommitTotalFreeThreshold; + uint64_t LockPrefixTable; + uint64_t MaximumAllocationSize; + uint64_t VirtualMemoryThreshold; + uint64_t ProcessAffinityMask; + uint32_t ProcessHeapFlags; + uint16_t CSDVersion; + uint16_t DependentLoadFlags; + uint64_t EditList; + uint64_t SecurityCookie; + uint64_t SEHandlerTable; + uint64_t SEHandlerCount; + uint64_t GuardCFCCheckFunctionPointer; + uint64_t GuardCFDispatchFunctionPointer; + uint64_t GuardCFFunctionTable; + uint64_t GuardCFFunctionCount; + uint32_t GuardFlags; +} IMAGE_LOAD_CONFIG_DIRECTORY64_V3; +#pragma pack() +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V3, 0x94); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V3 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V3; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V3 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V3; + +/** @since Windows 10 (Preview (9879). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V4 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 */ + uint64_t SecurityCookie; /**< 0x58 */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 */ + uint64_t GuardCFFunctionTable; /**< 0x80 */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V4; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V4, 0xa0); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V4 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V4; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V4 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V4; + +/** @since Windows 10 build 14286 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V5 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 */ + uint64_t SecurityCookie; /**< 0x58 */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 */ + uint64_t GuardCFFunctionTable; /**< 0x80 */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ + uint64_t GuardAddressTakenIatEntryTable; /**< 0xa0 */ + uint64_t GuardAddressTakenIatEntryCount; /**< 0xa8 */ + uint64_t GuardLongJumpTargetTable; /**< 0xb0 */ + uint64_t GuardLongJumpTargetCount; /**< 0xb8 */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V5; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V5, 0xc0); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V5 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V5; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V5 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V5; + +/** @since Windows 10 build 14393 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V6 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 */ + uint64_t SecurityCookie; /**< 0x58 */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 */ + uint64_t GuardCFFunctionTable; /**< 0x80 */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ + uint64_t GuardAddressTakenIatEntryTable; /**< 0xa0 */ + uint64_t GuardAddressTakenIatEntryCount; /**< 0xa8 */ + uint64_t GuardLongJumpTargetTable; /**< 0xb0 */ + uint64_t GuardLongJumpTargetCount; /**< 0xb8 */ + uint64_t DynamicValueRelocTable; /**< 0xc0 */ + uint64_t HybridMetadataPointer; /**< 0xc8 */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V6; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V6, 0xd0); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V6 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V6; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V6 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V6; + +/** @since Windows 10 build 14901 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V7 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 */ + uint64_t SecurityCookie; /**< 0x58 */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 */ + uint64_t GuardCFFunctionTable; /**< 0x80 */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ + uint64_t GuardAddressTakenIatEntryTable; /**< 0xa0 */ + uint64_t GuardAddressTakenIatEntryCount; /**< 0xa8 */ + uint64_t GuardLongJumpTargetTable; /**< 0xb0 */ + uint64_t GuardLongJumpTargetCount; /**< 0xb8 */ + uint64_t DynamicValueRelocTable; /**< 0xc0 */ + uint64_t CHPEMetadataPointer; /**< 0xc8 Not sure when this was renamed from HybridMetadataPointer. */ + uint64_t GuardRFFailureRoutine; /**< 0xd0 */ + uint64_t GuardRFFailureRoutineFunctionPointer; /**< 0xd8 */ + uint32_t DynamicValueRelocTableOffset; /**< 0xe0 */ + uint16_t DynamicValueRelocTableSection; /**< 0xe4 */ + uint16_t Reserved2; /**< 0xe6 */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V7; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V7, 0xe8); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V7 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V7; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V7 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V7; + +/** @since Windows 10 build 15002 (or maybe earlier). */ +#pragma pack(4) /* Stupid, stupid microsofties! */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V8 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 */ + uint64_t SecurityCookie; /**< 0x58 */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 */ + uint64_t GuardCFFunctionTable; /**< 0x80 */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ + uint64_t GuardAddressTakenIatEntryTable; /**< 0xa0 */ + uint64_t GuardAddressTakenIatEntryCount; /**< 0xa8 */ + uint64_t GuardLongJumpTargetTable; /**< 0xb0 */ + uint64_t GuardLongJumpTargetCount; /**< 0xb8 */ + uint64_t DynamicValueRelocTable; /**< 0xc0 */ + uint64_t CHPEMetadataPointer; /**< 0xc8 */ + uint64_t GuardRFFailureRoutine; /**< 0xd0 */ + uint64_t GuardRFFailureRoutineFunctionPointer; /**< 0xd8 */ + uint32_t DynamicValueRelocTableOffset; /**< 0xe0 */ + uint16_t DynamicValueRelocTableSection; /**< 0xe4 */ + uint16_t Reserved2; /**< 0xe6 */ + uint64_t GuardRFVerifyStackPointerFunctionPointer; /**< 0xe8 */ + uint32_t HotPatchTableOffset; /**< 0xf0 */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V8; +#pragma pack() +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V8, 0xf4); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V8 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V8; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V8 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V8; + +/** @since Windows 10 build 15002 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V9 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 */ + uint64_t SecurityCookie; /**< 0x58 */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 */ + uint64_t GuardCFFunctionTable; /**< 0x80 */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ + uint64_t GuardAddressTakenIatEntryTable; /**< 0xa0 */ + uint64_t GuardAddressTakenIatEntryCount; /**< 0xa8 */ + uint64_t GuardLongJumpTargetTable; /**< 0xb0 */ + uint64_t GuardLongJumpTargetCount; /**< 0xb8 */ + uint64_t DynamicValueRelocTable; /**< 0xc0 */ + uint64_t CHPEMetadataPointer; /**< 0xc8 */ + uint64_t GuardRFFailureRoutine; /**< 0xd0 */ + uint64_t GuardRFFailureRoutineFunctionPointer; /**< 0xd8 */ + uint32_t DynamicValueRelocTableOffset; /**< 0xe0 */ + uint16_t DynamicValueRelocTableSection; /**< 0xe4 */ + uint16_t Reserved2; /**< 0xe6 */ + uint64_t GuardRFVerifyStackPointerFunctionPointer; /**< 0xe8 */ + uint32_t HotPatchTableOffset; /**< 0xf0 */ + uint32_t Reserved3; /**< 0xf4 */ + uint64_t EnclaveConfigurationPointer; /**< 0xf8 - seen in bcrypt and bcryptprimitives pointing to the string "L". */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V9; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V9, 0x100); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V9 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V9; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V9 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V9; + +/** @since Windows 10 build 18362 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V10 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 */ + uint64_t SecurityCookie; /**< 0x58 */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 */ + uint64_t GuardCFFunctionTable; /**< 0x80 */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ + uint64_t GuardAddressTakenIatEntryTable; /**< 0xa0 */ + uint64_t GuardAddressTakenIatEntryCount; /**< 0xa8 */ + uint64_t GuardLongJumpTargetTable; /**< 0xb0 */ + uint64_t GuardLongJumpTargetCount; /**< 0xb8 */ + uint64_t DynamicValueRelocTable; /**< 0xc0 */ + uint64_t CHPEMetadataPointer; /**< 0xc8 */ + uint64_t GuardRFFailureRoutine; /**< 0xd0 */ + uint64_t GuardRFFailureRoutineFunctionPointer; /**< 0xd8 */ + uint32_t DynamicValueRelocTableOffset; /**< 0xe0 */ + uint16_t DynamicValueRelocTableSection; /**< 0xe4 */ + uint16_t Reserved2; /**< 0xe6 */ + uint64_t GuardRFVerifyStackPointerFunctionPointer; /**< 0xe8 */ + uint32_t HotPatchTableOffset; /**< 0xf0 */ + uint32_t Reserved3; /**< 0xf4 */ + uint64_t EnclaveConfigurationPointer; /**< 0xf8 - seen in bcrypt and bcryptprimitives pointing to the string "L". */ + uint64_t VolatileMetadataPointer; /**< 0x100 */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V10; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V10, 0x108); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V10 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V10; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V10 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V10; + +/** @since Windows 10 build 19534 (or maybe earlier). */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V11 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 */ + uint64_t SecurityCookie; /**< 0x58 */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 */ + uint64_t GuardCFFunctionTable; /**< 0x80 */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ + uint64_t GuardAddressTakenIatEntryTable; /**< 0xa0 */ + uint64_t GuardAddressTakenIatEntryCount; /**< 0xa8 */ + uint64_t GuardLongJumpTargetTable; /**< 0xb0 */ + uint64_t GuardLongJumpTargetCount; /**< 0xb8 */ + uint64_t DynamicValueRelocTable; /**< 0xc0 */ + uint64_t CHPEMetadataPointer; /**< 0xc8 */ + uint64_t GuardRFFailureRoutine; /**< 0xd0 */ + uint64_t GuardRFFailureRoutineFunctionPointer; /**< 0xd8 */ + uint32_t DynamicValueRelocTableOffset; /**< 0xe0 */ + uint16_t DynamicValueRelocTableSection; /**< 0xe4 */ + uint16_t Reserved2; /**< 0xe6 */ + uint64_t GuardRFVerifyStackPointerFunctionPointer; /**< 0xe8 */ + uint32_t HotPatchTableOffset; /**< 0xf0 */ + uint32_t Reserved3; /**< 0xf4 */ + uint64_t EnclaveConfigurationPointer; /**< 0xf8 - seen in bcrypt and bcryptprimitives pointing to the string "L". */ + uint64_t VolatileMetadataPointer; /**< 0x100 */ + uint64_t GuardEHContinuationTable; /**< 0x108 - virtual address */ + uint64_t GuardEHContinuationCount; /**< 0x110 */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V11; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V11, 0x118); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V11 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V11; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V11 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V11; + +/** @since Visual C++ 2019 / RS5_IMAGE_LOAD_CONFIG_DIRECTORY64. */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V12 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 */ + uint64_t SecurityCookie; /**< 0x58 */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 */ + uint64_t GuardCFFunctionTable; /**< 0x80 */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ + uint64_t GuardAddressTakenIatEntryTable; /**< 0xa0 */ + uint64_t GuardAddressTakenIatEntryCount; /**< 0xa8 */ + uint64_t GuardLongJumpTargetTable; /**< 0xb0 */ + uint64_t GuardLongJumpTargetCount; /**< 0xb8 */ + uint64_t DynamicValueRelocTable; /**< 0xc0 */ + uint64_t CHPEMetadataPointer; /**< 0xc8 */ + uint64_t GuardRFFailureRoutine; /**< 0xd0 */ + uint64_t GuardRFFailureRoutineFunctionPointer; /**< 0xd8 */ + uint32_t DynamicValueRelocTableOffset; /**< 0xe0 */ + uint16_t DynamicValueRelocTableSection; /**< 0xe4 */ + uint16_t Reserved2; /**< 0xe6 */ + uint64_t GuardRFVerifyStackPointerFunctionPointer; /**< 0xe8 */ + uint32_t HotPatchTableOffset; /**< 0xf0 */ + uint32_t Reserved3; /**< 0xf4 */ + uint64_t EnclaveConfigurationPointer; /**< 0xf8 - seen in bcrypt and bcryptprimitives pointing to the string "L". */ + uint64_t VolatileMetadataPointer; /**< 0x100 */ + uint64_t GuardEHContinuationTable; /**< 0x108 - virtual address */ + uint64_t GuardEHContinuationCount; /**< 0x110 */ + uint64_t GuardXFGCheckFunctionPointer; /**< 0x118 */ + uint64_t GuardXFGDispatchFunctionPointer; /**< 0x120 */ + uint64_t GuardXFGTableDispatchFunctionPointer; /**< 0x128 */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V12; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V12, 0x130); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V12 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V12; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V12 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V12; + +/** @since Visual C++ 2019 16.x (found in 16.11.9) / RS5_IMAGE_LOAD_CONFIG_DIRECTORY32. */ +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V13 +{ + uint32_t Size; /**< 0x00 */ + uint32_t TimeDateStamp; /**< 0x04 */ + uint16_t MajorVersion; /**< 0x08 */ + uint16_t MinorVersion; /**< 0x0a */ + uint32_t GlobalFlagsClear; /**< 0x0c */ + uint32_t GlobalFlagsSet; /**< 0x10 */ + uint32_t CriticalSectionDefaultTimeout; /**< 0x14 */ + uint64_t DeCommitFreeBlockThreshold; /**< 0x18 */ + uint64_t DeCommitTotalFreeThreshold; /**< 0x20 */ + uint64_t LockPrefixTable; /**< 0x28 - virtual address */ + uint64_t MaximumAllocationSize; /**< 0x30 */ + uint64_t VirtualMemoryThreshold; /**< 0x38 */ + uint64_t ProcessAffinityMask; /**< 0x40 */ + uint32_t ProcessHeapFlags; /**< 0x48 */ + uint16_t CSDVersion; /**< 0x4c */ + uint16_t DependentLoadFlags; /**< 0x4e */ + uint64_t EditList; /**< 0x50 - virtual address */ + uint64_t SecurityCookie; /**< 0x58 - virtual address */ + uint64_t SEHandlerTable; /**< 0x60 */ + uint64_t SEHandlerCount; /**< 0x68 */ + uint64_t GuardCFCCheckFunctionPointer; /**< 0x70 - virtual address of pointer variable */ + uint64_t GuardCFDispatchFunctionPointer; /**< 0x78 - virtual address of pointer variable */ + uint64_t GuardCFFunctionTable; /**< 0x80 - virtual address */ + uint64_t GuardCFFunctionCount; /**< 0x88 */ + uint32_t GuardFlags; /**< 0x90 */ + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; /**< 0x94 */ + uint64_t GuardAddressTakenIatEntryTable; /**< 0xa0 - virtual address */ + uint64_t GuardAddressTakenIatEntryCount; /**< 0xa8 */ + uint64_t GuardLongJumpTargetTable; /**< 0xb0 - virtual address */ + uint64_t GuardLongJumpTargetCount; /**< 0xb8 */ + uint64_t DynamicValueRelocTable; /**< 0xc0 - virtual address */ + uint64_t CHPEMetadataPointer; /**< 0xc8 */ + uint64_t GuardRFFailureRoutine; /**< 0xd0 - virtual address */ + uint64_t GuardRFFailureRoutineFunctionPointer; /**< 0xd8 - virtual address of pointer variable */ + uint32_t DynamicValueRelocTableOffset; /**< 0xe0 */ + uint16_t DynamicValueRelocTableSection; /**< 0xe4 */ + uint16_t Reserved2; /**< 0xe6 */ + uint64_t GuardRFVerifyStackPointerFunctionPointer; /**< 0xe8 - virtual address of pointer variable */ + uint32_t HotPatchTableOffset; /**< 0xf0 */ + uint32_t Reserved3; /**< 0xf4 */ + uint64_t EnclaveConfigurationPointer; /**< 0xf8 - seen in bcrypt and bcryptprimitives pointing to the string "L". */ + uint64_t VolatileMetadataPointer; /**< 0x100 - virtual address of pointer variable */ + uint64_t GuardEHContinuationTable; /**< 0x108 - virtual address */ + uint64_t GuardEHContinuationCount; /**< 0x110 */ + uint64_t GuardXFGCheckFunctionPointer; /**< 0x118 - virtual address of pointer variable */ + uint64_t GuardXFGDispatchFunctionPointer; /**< 0x120 - virtual address of pointer variable */ + uint64_t GuardXFGTableDispatchFunctionPointer; /**< 0x128 - virtual address of pointer variable */ + uint64_t CastGuardOsDeterminedFailureMode; /**< 0x130 - virtual address */ +} IMAGE_LOAD_CONFIG_DIRECTORY64_V13; +AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V13, 0x138); +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V13 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V13; +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V13 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V13; + +typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V13 IMAGE_LOAD_CONFIG_DIRECTORY64; +typedef PIMAGE_LOAD_CONFIG_DIRECTORY64_V13 PIMAGE_LOAD_CONFIG_DIRECTORY64; +typedef PCIMAGE_LOAD_CONFIG_DIRECTORY64_V13 PCIMAGE_LOAD_CONFIG_DIRECTORY64; + +/** @} */ + + +/** + * PE certificate directory. + * + * Found in IMAGE_DIRECTORY_ENTRY_SECURITY. + */ +typedef struct WIN_CERTIFICATE +{ + uint32_t dwLength; + uint16_t wRevision; + uint16_t wCertificateType; + uint8_t bCertificate[8]; +} WIN_CERTIFICATE; +AssertCompileSize(WIN_CERTIFICATE, 16); +typedef WIN_CERTIFICATE *PWIN_CERTIFICATE; +typedef WIN_CERTIFICATE const *PCWIN_CERTIFICATE; + +/** @name WIN_CERT_REVISION_XXX - Certificate data directory revision. + * Used WIN_CERTIFICATE::wRevision found in the IMAGE_DIRECTORY_ENTRY_SECURITY + * data directory. + * @{ */ +#define WIN_CERT_REVISION_1_0 UINT16_C(0x0100) +#define WIN_CERT_REVISION_2_0 UINT16_C(0x0200) +/** @} */ + +/** @name WIN_CERT_TYPE_XXX - Signature type. + * Used by WIN_CERTIFICATE::wCertificateType. + * @{ */ +#define WIN_CERT_TYPE_X509 UINT16_C(1) +#define WIN_CERT_TYPE_PKCS_SIGNED_DATA UINT16_C(2) +#define WIN_CERT_TYPE_RESERVED_1 UINT16_C(3) +#define WIN_CERT_TYPE_TS_STACK_SIGNED UINT16_C(4) +#define WIN_CERT_TYPE_EFI_PKCS115 UINT16_C(0x0ef0) +#define WIN_CERT_TYPE_EFI_GUID UINT16_C(0x0ef1) +/** @} */ + +/** The alignment of the certificate table. + * @remarks Found thru signtool experiments. + * @note There is a copy of this in RTSignTool.cpp. */ +#define WIN_CERTIFICATE_ALIGNMENT UINT32_C(8) + + +/** + * Debug directory. + * + * Found in IMAGE_DIRECTORY_ENTRY_DEBUG. + */ +typedef struct _IMAGE_DEBUG_DIRECTORY +{ + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Type; + uint32_t SizeOfData; + uint32_t AddressOfRawData; + uint32_t PointerToRawData; +} IMAGE_DEBUG_DIRECTORY; +AssertCompileSize(IMAGE_DEBUG_DIRECTORY, 28); +typedef IMAGE_DEBUG_DIRECTORY *PIMAGE_DEBUG_DIRECTORY; +typedef IMAGE_DEBUG_DIRECTORY const *PCIMAGE_DEBUG_DIRECTORY; + +/** @name IMAGE_DEBUG_TYPE_XXX - Debug format types. + * Used by IMAGE_DEBUG_DIRECTORY::Type. + * @{ */ +#define IMAGE_DEBUG_TYPE_UNKNOWN UINT32_C(0x00) +#define IMAGE_DEBUG_TYPE_COFF UINT32_C(0x01) +#define IMAGE_DEBUG_TYPE_CODEVIEW UINT32_C(0x02) +#define IMAGE_DEBUG_TYPE_FPO UINT32_C(0x03) +#define IMAGE_DEBUG_TYPE_MISC UINT32_C(0x04) +#define IMAGE_DEBUG_TYPE_EXCEPTION UINT32_C(0x05) +#define IMAGE_DEBUG_TYPE_FIXUP UINT32_C(0x06) +#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC UINT32_C(0x07) +#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC UINT32_C(0x08) +#define IMAGE_DEBUG_TYPE_BORLAND UINT32_C(0x09) +#define IMAGE_DEBUG_TYPE_RESERVED10 UINT32_C(0x0a) +#define IMAGE_DEBUG_TYPE_CLSID UINT32_C(0x0b) +#define IMAGE_DEBUG_TYPE_VC_FEATURE UINT32_C(0x0c) +#define IMAGE_DEBUG_TYPE_POGO UINT32_C(0x0d) +#define IMAGE_DEBUG_TYPE_ILTCG UINT32_C(0x0e) +#define IMAGE_DEBUG_TYPE_MPX UINT32_C(0x0f) +#define IMAGE_DEBUG_TYPE_REPRO UINT32_C(0x10) +/** @} */ + +/** @name IMAGE_DEBUG_MISC_XXX - Misc debug data type. + * Used by IMAGE_DEBUG_MISC::DataType. + * @{ */ +#define IMAGE_DEBUG_MISC_EXENAME UINT32_C(1) +/** @} */ + + +/** + * The format of IMAGE_DEBUG_TYPE_MISC debug info. + */ +typedef struct _IMAGE_DEBUG_MISC +{ + uint32_t DataType; + uint32_t Length; + uint8_t Unicode; + uint8_t Reserved[3]; + uint8_t Data[1]; +} IMAGE_DEBUG_MISC; +AssertCompileSize(IMAGE_DEBUG_MISC, 16); +typedef IMAGE_DEBUG_MISC *PIMAGE_DEBUG_MISC; +typedef IMAGE_DEBUG_MISC const *PCIMAGE_DEBUG_MISC; + + + +/** + * The header of a .DBG file (NT4). + */ +typedef struct _IMAGE_SEPARATE_DEBUG_HEADER +{ + uint16_t Signature; /**< 0x00 */ + uint16_t Flags; /**< 0x02 */ + uint16_t Machine; /**< 0x04 */ + uint16_t Characteristics; /**< 0x06 */ + uint32_t TimeDateStamp; /**< 0x08 */ + uint32_t CheckSum; /**< 0x0c */ + uint32_t ImageBase; /**< 0x10 */ + uint32_t SizeOfImage; /**< 0x14 */ + uint32_t NumberOfSections; /**< 0x18 */ + uint32_t ExportedNamesSize; /**< 0x1c */ + uint32_t DebugDirectorySize; /**< 0x20 */ + uint32_t SectionAlignment; /**< 0x24 */ + uint32_t Reserved[2]; /**< 0x28 */ +} IMAGE_SEPARATE_DEBUG_HEADER; /* size: 0x30 */ +AssertCompileSize(IMAGE_SEPARATE_DEBUG_HEADER, 0x30); +typedef IMAGE_SEPARATE_DEBUG_HEADER *PIMAGE_SEPARATE_DEBUG_HEADER; +typedef IMAGE_SEPARATE_DEBUG_HEADER const *PCIMAGE_SEPARATE_DEBUG_HEADER; + +/** The signature of a IMAGE_SEPARATE_DEBUG_HEADER. */ +#define IMAGE_SEPARATE_DEBUG_SIGNATURE UINT16_C(0x4944) + + +/** + * The format of IMAGE_DEBUG_TYPE_COFF debug info. + */ +typedef struct _IMAGE_COFF_SYMBOLS_HEADER +{ + uint32_t NumberOfSymbols; + uint32_t LvaToFirstSymbol; + uint32_t NumberOfLinenumbers; + uint32_t LvaToFirstLinenumber; + uint32_t RvaToFirstByteOfCode; + uint32_t RvaToLastByteOfCode; + uint32_t RvaToFirstByteOfData; + uint32_t RvaToLastByteOfData; +} IMAGE_COFF_SYMBOLS_HEADER; +AssertCompileSize(IMAGE_COFF_SYMBOLS_HEADER, 0x20); +typedef IMAGE_COFF_SYMBOLS_HEADER *PIMAGE_COFF_SYMBOLS_HEADER; +typedef IMAGE_COFF_SYMBOLS_HEADER const *PCIMAGE_COFF_SYMBOLS_HEADER; + + +/** + * Line number format of IMAGE_DEBUG_TYPE_COFF debug info. + * + * @remarks This has misaligned members. + */ +#pragma pack(2) +typedef struct _IMAGE_LINENUMBER +{ + union + { + uint32_t VirtualAddress; + uint32_t SymbolTableIndex; + } Type; + uint16_t Linenumber; +} IMAGE_LINENUMBER; +#pragma pack() +AssertCompileSize(IMAGE_LINENUMBER, 6); +typedef IMAGE_LINENUMBER *PIMAGE_LINENUMBER; +typedef IMAGE_LINENUMBER const *PCIMAGE_LINENUMBER; + + +/** The size of a IMAGE_SYMBOL & IMAGE_AUX_SYMBOL structure. */ +#define IMAGE_SIZE_OF_SYMBOL 18 +/** The size of a IMAGE_SYMBOL_EX & IMAGE_AUX_SYMBOL_EX structure. */ +#define IMAGE_SIZE_OF_SYMBOL_EX 20 + +/** + * COFF symbol. + */ +#pragma pack(2) +typedef struct _IMAGE_SYMBOL +{ + union + { + uint8_t ShortName[8]; + struct + { + uint32_t Short; + uint32_t Long; + } Name; + uint32_t LongName[2]; + } N; + + uint32_t Value; + int16_t SectionNumber; + uint16_t Type; + uint8_t StorageClass; + uint8_t NumberOfAuxSymbols; +} IMAGE_SYMBOL; +#pragma pack() +AssertCompileSize(IMAGE_SYMBOL, IMAGE_SIZE_OF_SYMBOL); +typedef IMAGE_SYMBOL *PIMAGE_SYMBOL; +typedef IMAGE_SYMBOL const *PCIMAGE_SYMBOL; + +/** + * COFF auxiliary symbol token defintion (whatever that is). + */ +#pragma pack(2) +typedef struct IMAGE_AUX_SYMBOL_TOKEN_DEF +{ + uint8_t bAuxType; + uint8_t bReserved; + uint32_t SymbolTableIndex; + uint8_t rgbReserved[12]; +} IMAGE_AUX_SYMBOL_TOKEN_DEF; +#pragma pack() +AssertCompileSize(IMAGE_AUX_SYMBOL_TOKEN_DEF, IMAGE_SIZE_OF_SYMBOL); +typedef IMAGE_AUX_SYMBOL_TOKEN_DEF *PIMAGE_AUX_SYMBOL_TOKEN_DEF; +typedef IMAGE_AUX_SYMBOL_TOKEN_DEF const *PCIMAGE_AUX_SYMBOL_TOKEN_DEF; + +/** + * COFF auxiliary symbol. + */ +#pragma pack(1) +typedef union _IMAGE_AUX_SYMBOL +{ + struct + { + uint32_t TagIndex; + union + { + struct + { + uint16_t Linenumber; + uint16_t Size; + } LnSz; + } Misc; + union + { + struct + { + uint32_t PointerToLinenumber; + uint32_t PointerToNextFunction; + } Function; + struct + { + uint16_t Dimension[4]; + } Array; + } FcnAry; + uint16_t TvIndex; + } Sym; + + struct + { + uint8_t Name[IMAGE_SIZE_OF_SYMBOL]; + } File; + + struct + { + uint32_t Length; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t CheckSum; + uint16_t Number; + uint8_t Selection; + uint8_t bReserved; + uint16_t HighNumber; + } Section; + + IMAGE_AUX_SYMBOL_TOKEN_DEF TokenDef; + struct + { + uint32_t crc; + uint8_t rgbReserved[14]; + } CRC; +} IMAGE_AUX_SYMBOL; +#pragma pack() +AssertCompileSize(IMAGE_AUX_SYMBOL, IMAGE_SIZE_OF_SYMBOL); +typedef IMAGE_AUX_SYMBOL *PIMAGE_AUX_SYMBOL; +typedef IMAGE_AUX_SYMBOL const *PCIMAGE_AUX_SYMBOL; + + +/** + * Extended COFF symbol. + */ +typedef struct _IMAGE_SYMBOL_EX +{ + union + { + uint8_t ShortName[8]; + struct + { + uint32_t Short; + uint32_t Long; + } Name; + uint32_t LongName[2]; + } N; + + uint32_t Value; + int32_t SectionNumber; /* The difference from IMAGE_SYMBOL */ + uint16_t Type; + uint8_t StorageClass; + uint8_t NumberOfAuxSymbols; +} IMAGE_SYMBOL_EX; +AssertCompileSize(IMAGE_SYMBOL_EX, IMAGE_SIZE_OF_SYMBOL_EX); +typedef IMAGE_SYMBOL_EX *PIMAGE_SYMBOL_EX; +typedef IMAGE_SYMBOL_EX const *PCIMAGE_SYMBOL_EX; + +/** + * Extended COFF auxiliary symbol. + */ +typedef union _IMAGE_AUX_SYMBOL_EX +{ + struct + { + uint32_t WeakDefaultSymIndex; + uint32_t WeakSearchType; + uint8_t rgbReserved[12]; + } Sym; + + struct + { + uint8_t Name[IMAGE_SIZE_OF_SYMBOL_EX]; + } File; + + struct + { + uint32_t Length; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t CheckSum; + uint16_t Number; + uint8_t Selection; + uint8_t bReserved; + uint16_t HighNumber; + uint8_t rgbReserved[2]; + } Section; + + IMAGE_AUX_SYMBOL_TOKEN_DEF TokenDef; + + struct + { + uint32_t crc; + uint8_t rgbReserved[16]; + } CRC; +} IMAGE_AUX_SYMBOL_EX; +AssertCompileSize(IMAGE_AUX_SYMBOL_EX, IMAGE_SIZE_OF_SYMBOL_EX); +typedef IMAGE_AUX_SYMBOL_EX *PIMAGE_AUX_SYMBOL_EX; +typedef IMAGE_AUX_SYMBOL_EX const *PCIMAGE_AUX_SYMBOL_EX; + +/** @name Special COFF section numbers. + * Used by IMAGE_SYMBOL::SectionNumber and IMAGE_SYMBOL_EX::SectionNumber + * @{ */ +#define IMAGE_SYM_UNDEFINED INT16_C(0) +#define IMAGE_SYM_ABSOLUTE INT16_C(-1) +#define IMAGE_SYM_DEBUG INT16_C(-2) +/** @} */ + +/** @name IMAGE_SYM_CLASS_XXX - COFF symbol storage classes. + * @{ */ +#define IMAGE_SYM_CLASS_END_OF_FUNCTION UINT8_C(0xff) /* -1 */ +#define IMAGE_SYM_CLASS_NULL UINT8_C(0) +#define IMAGE_SYM_CLASS_AUTOMATIC UINT8_C(1) +#define IMAGE_SYM_CLASS_EXTERNAL UINT8_C(2) +#define IMAGE_SYM_CLASS_STATIC UINT8_C(3) +#define IMAGE_SYM_CLASS_REGISTER UINT8_C(4) +#define IMAGE_SYM_CLASS_EXTERNAL_DEF UINT8_C(5) +#define IMAGE_SYM_CLASS_LABEL UINT8_C(6) +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL UINT8_C(7) +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT UINT8_C(8) +#define IMAGE_SYM_CLASS_ARGUMENT UINT8_C(9) +#define IMAGE_SYM_CLASS_STRUCT_TAG UINT8_C(10) +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION UINT8_C(11) +#define IMAGE_SYM_CLASS_UNION_TAG UINT8_C(12) +#define IMAGE_SYM_CLASS_TYPE_DEFINITION UINT8_C(13) +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC UINT8_C(14) +#define IMAGE_SYM_CLASS_ENUM_TAG UINT8_C(15) +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM UINT8_C(16) +#define IMAGE_SYM_CLASS_REGISTER_PARAM UINT8_C(17) +#define IMAGE_SYM_CLASS_BIT_FIELD UINT8_C(18) +#define IMAGE_SYM_CLASS_FAR_EXTERNAL UINT8_C(68) +#define IMAGE_SYM_CLASS_BLOCK UINT8_C(100) +#define IMAGE_SYM_CLASS_FUNCTION UINT8_C(101) +#define IMAGE_SYM_CLASS_END_OF_STRUCT UINT8_C(102) +#define IMAGE_SYM_CLASS_FILE UINT8_C(103) +#define IMAGE_SYM_CLASS_SECTION UINT8_C(104) +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL UINT8_C(105) +#define IMAGE_SYM_CLASS_CLR_TOKEN UINT8_C(107) +/** @} */ + +/** @name IMAGE_SYM_TYPE_XXX - COFF symbol base types + * @{ */ +#define IMAGE_SYM_TYPE_NULL UINT16_C(0x0000) +#define IMAGE_SYM_TYPE_VOID UINT16_C(0x0001) +#define IMAGE_SYM_TYPE_CHAR UINT16_C(0x0002) +#define IMAGE_SYM_TYPE_SHORT UINT16_C(0x0003) +#define IMAGE_SYM_TYPE_INT UINT16_C(0x0004) +#define IMAGE_SYM_TYPE_LONG UINT16_C(0x0005) +#define IMAGE_SYM_TYPE_FLOAT UINT16_C(0x0006) +#define IMAGE_SYM_TYPE_DOUBLE UINT16_C(0x0007) +#define IMAGE_SYM_TYPE_STRUCT UINT16_C(0x0008) +#define IMAGE_SYM_TYPE_UNION UINT16_C(0x0009) +#define IMAGE_SYM_TYPE_ENUM UINT16_C(0x000a) +#define IMAGE_SYM_TYPE_MOE UINT16_C(0x000b) +#define IMAGE_SYM_TYPE_BYTE UINT16_C(0x000c) +#define IMAGE_SYM_TYPE_WORD UINT16_C(0x000d) +#define IMAGE_SYM_TYPE_UINT UINT16_C(0x000e) +#define IMAGE_SYM_TYPE_DWORD UINT16_C(0x000f) +#define IMAGE_SYM_TYPE_PCODE UINT16_C(0x8000) +/** @} */ + +/** @name IMAGE_SYM_DTYPE_XXX - COFF symbol complex types + * @{ */ +#define IMAGE_SYM_DTYPE_NULL UINT16_C(0x0) +#define IMAGE_SYM_DTYPE_POINTER UINT16_C(0x1) +#define IMAGE_SYM_DTYPE_FUNCTION UINT16_C(0x2) +#define IMAGE_SYM_DTYPE_ARRAY UINT16_C(0x3) +/** @} */ + +/** @name COFF Symbol type masks and shift counts. + * @{ */ +#define N_BTMASK UINT16_C(0x000f) +#define N_TMASK UINT16_C(0x0030) +#define N_TMASK1 UINT16_C(0x00c0) +#define N_TMASK2 UINT16_C(0x00f0) +#define N_BTSHFT 4 +#define N_TSHIFT 2 +/** @} */ + +/** @name COFF Symbol type macros. + * @{ */ +#define BTYPE(a_Type) ( (a_Type) & N_BTMASK ) +#define ISPTR(a_Type) ( ((a_Type) & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT) ) +#define ISFCN(a_Type) ( ((a_Type) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT) ) +#define ISARY(a_Type) ( ((a_Type) & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT) ) +#define ISTAG(a_StorageClass) ( (a_StorageClass) == IMAGE_SYM_CLASS_STRUCT_TAG \ + || (a_StorageClass) == IMAGE_SYM_CLASS_UNION_TAG \ + || (a_StorageClass) == IMAGE_SYM_CLASS_ENUM_TAG ) +/** @} */ + + +/** + * COFF relocation table entry. + * + * @note The size of the structure is not a multiple of the largest member + * (uint32_t), so odd relocation table entry members will have + * misaligned uint32_t members. + */ +#pragma pack(1) +typedef struct _IMAGE_RELOCATION +{ + union + { + uint32_t VirtualAddress; + uint32_t RelocCount; + } u; + uint32_t SymbolTableIndex; + uint16_t Type; +} IMAGE_RELOCATION; +#pragma pack() +/** The size of a COFF relocation entry. */ +#define IMAGE_SIZEOF_RELOCATION 10 +AssertCompileSize(IMAGE_RELOCATION, IMAGE_SIZEOF_RELOCATION); +typedef IMAGE_RELOCATION *PIMAGE_RELOCATION; +typedef IMAGE_RELOCATION const *PCIMAGE_RELOCATION; + + +/** @name IMAGE_REL_AMD64_XXX - COFF relocations for AMD64 CPUs. + * Used by IMAGE_RELOCATION::Type. + * @{ */ +#define IMAGE_REL_AMD64_ABSOLUTE UINT16_C(0x0000) +#define IMAGE_REL_AMD64_ADDR64 UINT16_C(0x0001) +#define IMAGE_REL_AMD64_ADDR32 UINT16_C(0x0002) +#define IMAGE_REL_AMD64_ADDR32NB UINT16_C(0x0003) +#define IMAGE_REL_AMD64_REL32 UINT16_C(0x0004) +#define IMAGE_REL_AMD64_REL32_1 UINT16_C(0x0005) +#define IMAGE_REL_AMD64_REL32_2 UINT16_C(0x0006) +#define IMAGE_REL_AMD64_REL32_3 UINT16_C(0x0007) +#define IMAGE_REL_AMD64_REL32_4 UINT16_C(0x0008) +#define IMAGE_REL_AMD64_REL32_5 UINT16_C(0x0009) +#define IMAGE_REL_AMD64_SECTION UINT16_C(0x000a) +#define IMAGE_REL_AMD64_SECREL UINT16_C(0x000b) +#define IMAGE_REL_AMD64_SECREL7 UINT16_C(0x000c) +#define IMAGE_REL_AMD64_TOKEN UINT16_C(0x000d) +#define IMAGE_REL_AMD64_SREL32 UINT16_C(0x000e) +#define IMAGE_REL_AMD64_PAIR UINT16_C(0x000f) +#define IMAGE_REL_AMD64_SSPAN32 UINT16_C(0x0010) +/** @} */ + +/** @name ARM IMAGE_REL_ARM_XXX - COFF relocations for ARM CPUs. + * Used by IMAGE_RELOCATION::Type. + * @{ */ +#define IMAGE_REL_ARM_ABSOLUTE UINT16_C(0x0000) +#define IMAGE_REL_ARM_ADDR32 UINT16_C(0x0001) +#define IMAGE_REL_ARM_ADDR32NB UINT16_C(0x0002) +#define IMAGE_REL_ARM_BRANCH24 UINT16_C(0x0003) +#define IMAGE_REL_ARM_BRANCH11 UINT16_C(0x0004) +#define IMAGE_REL_ARM_TOKEN UINT16_C(0x0005) +#define IMAGE_REL_ARM_BLX24 UINT16_C(0x0008) +#define IMAGE_REL_ARM_BLX11 UINT16_C(0x0009) +#define IMAGE_REL_ARM_SECTION UINT16_C(0x000e) +#define IMAGE_REL_ARM_SECREL UINT16_C(0x000f) +#define IMAGE_REL_ARM_MOV32A UINT16_C(0x0010) +#define IMAGE_REL_ARM_MOV32T UINT16_C(0x0011) +#define IMAGE_REL_ARM_BRANCH20T UINT16_C(0x0012) +#define IMAGE_REL_ARM_BRANCH24T UINT16_C(0x0014) +#define IMAGE_REL_ARM_BLX23T UINT16_C(0x0015) +/** @} */ + +/** @name IMAGE_REL_ARM64_XXX - COFF relocations for ARMv8 CPUs (64-bit). + * Used by IMAGE_RELOCATION::Type. + * @{ */ +#define IMAGE_REL_ARM64_ABSOLUTE UINT16_C(0x0000) +#define IMAGE_REL_ARM64_ADDR32 UINT16_C(0x0001) +#define IMAGE_REL_ARM64_ADDR32NB UINT16_C(0x0002) +#define IMAGE_REL_ARM64_BRANCH26 UINT16_C(0x0003) +#define IMAGE_REL_ARM64_PAGEBASE_REL21 UINT16_C(0x0004) +#define IMAGE_REL_ARM64_REL21 UINT16_C(0x0005) +#define IMAGE_REL_ARM64_PAGEOFFSET_12A UINT16_C(0x0006) +#define IMAGE_REL_ARM64_PAGEOFFSET_12L UINT16_C(0x0007) +#define IMAGE_REL_ARM64_SECREL UINT16_C(0x0008) +#define IMAGE_REL_ARM64_SECREL_LOW12A UINT16_C(0x0009) +#define IMAGE_REL_ARM64_SECREL_HIGH12A UINT16_C(0x000a) +#define IMAGE_REL_ARM64_SECREL_LOW12L UINT16_C(0x000b) +#define IMAGE_REL_ARM64_TOKEN UINT16_C(0x000c) +#define IMAGE_REL_ARM64_SECTION UINT16_C(0x000d) +#define IMAGE_REL_ARM64_ADDR64 UINT16_C(0x000e) +/** @} */ + +/** @name IMAGE_REL_SH3_XXX - COFF relocation for Hitachi SuperH CPUs. + * Used by IMAGE_RELOCATION::Type. + * @{ */ +#define IMAGE_REL_SH3_ABSOLUTE UINT16_C(0x0000) +#define IMAGE_REL_SH3_DIRECT16 UINT16_C(0x0001) +#define IMAGE_REL_SH3_DIRECT32 UINT16_C(0x0002) +#define IMAGE_REL_SH3_DIRECT8 UINT16_C(0x0003) +#define IMAGE_REL_SH3_DIRECT8_WORD UINT16_C(0x0004) +#define IMAGE_REL_SH3_DIRECT8_LONG UINT16_C(0x0005) +#define IMAGE_REL_SH3_DIRECT4 UINT16_C(0x0006) +#define IMAGE_REL_SH3_DIRECT4_WORD UINT16_C(0x0007) +#define IMAGE_REL_SH3_DIRECT4_LONG UINT16_C(0x0008) +#define IMAGE_REL_SH3_PCREL8_WORD UINT16_C(0x0009) +#define IMAGE_REL_SH3_PCREL8_LONG UINT16_C(0x000a) +#define IMAGE_REL_SH3_PCREL12_WORD UINT16_C(0x000b) +#define IMAGE_REL_SH3_STARTOF_SECTION UINT16_C(0x000c) +#define IMAGE_REL_SH3_SIZEOF_SECTION UINT16_C(0x000d) +#define IMAGE_REL_SH3_SECTION UINT16_C(0x000e) +#define IMAGE_REL_SH3_SECREL UINT16_C(0x000f) +#define IMAGE_REL_SH3_DIRECT32_NB UINT16_C(0x0010) +#define IMAGE_REL_SH3_GPREL4_LONG UINT16_C(0x0011) +#define IMAGE_REL_SH3_TOKEN UINT16_C(0x0012) +#define IMAGE_REL_SHM_PCRELPT UINT16_C(0x0013) +#define IMAGE_REL_SHM_REFLO UINT16_C(0x0014) +#define IMAGE_REL_SHM_REFHALF UINT16_C(0x0015) +#define IMAGE_REL_SHM_RELLO UINT16_C(0x0016) +#define IMAGE_REL_SHM_RELHALF UINT16_C(0x0017) +#define IMAGE_REL_SHM_PAIR UINT16_C(0x0018) +#define IMAGE_REL_SHM_NOMODE UINT16_C(0x8000) +/** @} */ + +/** @name IMAGE_REL_PPC_XXX - COFF relocations for IBM PowerPC CPUs. + * Used by IMAGE_RELOCATION::Type. + * @{ */ +#define IMAGE_REL_PPC_ABSOLUTE UINT16_C(0x0000) +#define IMAGE_REL_PPC_ADDR64 UINT16_C(0x0001) +#define IMAGE_REL_PPC_ADDR32 UINT16_C(0x0002) +#define IMAGE_REL_PPC_ADDR24 UINT16_C(0x0003) +#define IMAGE_REL_PPC_ADDR16 UINT16_C(0x0004) +#define IMAGE_REL_PPC_ADDR14 UINT16_C(0x0005) +#define IMAGE_REL_PPC_REL24 UINT16_C(0x0006) +#define IMAGE_REL_PPC_REL14 UINT16_C(0x0007) +#define IMAGE_REL_PPC_ADDR32NB UINT16_C(0x000a) +#define IMAGE_REL_PPC_SECREL UINT16_C(0x000b) +#define IMAGE_REL_PPC_SECTION UINT16_C(0x000c) +#define IMAGE_REL_PPC_SECREL16 UINT16_C(0x000f) +#define IMAGE_REL_PPC_REFHI UINT16_C(0x0010) +#define IMAGE_REL_PPC_REFLO UINT16_C(0x0011) +#define IMAGE_REL_PPC_PAIR UINT16_C(0x0012) +#define IMAGE_REL_PPC_SECRELLO UINT16_C(0x0013) +#define IMAGE_REL_PPC_GPREL UINT16_C(0x0015) +#define IMAGE_REL_PPC_TOKEN UINT16_C(0x0016) +/** @} */ + +/** @name IMAGE_REL_I386_XXX - COFF relocations for x86 CPUs. + * Used by IMAGE_RELOCATION::Type. + * @{ */ +#define IMAGE_REL_I386_ABSOLUTE UINT16_C(0x0000) +#define IMAGE_REL_I386_DIR16 UINT16_C(0x0001) +#define IMAGE_REL_I386_REL16 UINT16_C(0x0002) +#define IMAGE_REL_I386_DIR32 UINT16_C(0x0006) +#define IMAGE_REL_I386_DIR32NB UINT16_C(0x0007) +#define IMAGE_REL_I386_SEG12 UINT16_C(0x0009) +#define IMAGE_REL_I386_SECTION UINT16_C(0x000A) +#define IMAGE_REL_I386_SECREL UINT16_C(0x000B) +#define IMAGE_REL_I386_TOKEN UINT16_C(0x000C) +#define IMAGE_REL_I386_SECREL7 UINT16_C(0x000D) +#define IMAGE_REL_I386_REL32 UINT16_C(0x0014) +/** @} */ + +/** @name IMAGE_REL_IA64_XXX - COFF relocations for "Itanic" CPUs. + * @{ */ +#define IMAGE_REL_IA64_ABSOLUTE UINT16_C(0x0000) +#define IMAGE_REL_IA64_IMM14 UINT16_C(0x0001) +#define IMAGE_REL_IA64_IMM22 UINT16_C(0x0002) +#define IMAGE_REL_IA64_IMM64 UINT16_C(0x0003) +#define IMAGE_REL_IA64_DIR32 UINT16_C(0x0004) +#define IMAGE_REL_IA64_DIR64 UINT16_C(0x0005) +#define IMAGE_REL_IA64_PCREL21B UINT16_C(0x0006) +#define IMAGE_REL_IA64_PCREL21M UINT16_C(0x0007) +#define IMAGE_REL_IA64_PCREL21F UINT16_C(0x0008) +#define IMAGE_REL_IA64_GPREL22 UINT16_C(0x0009) +#define IMAGE_REL_IA64_LTOFF22 UINT16_C(0x000a) +#define IMAGE_REL_IA64_SECTION UINT16_C(0x000b) +#define IMAGE_REL_IA64_SECREL22 UINT16_C(0x000c) +#define IMAGE_REL_IA64_SECREL64I UINT16_C(0x000d) +#define IMAGE_REL_IA64_SECREL32 UINT16_C(0x000e) +#define IMAGE_REL_IA64_DIR32NB UINT16_C(0x0010) +#define IMAGE_REL_IA64_SREL14 UINT16_C(0x0011) +#define IMAGE_REL_IA64_SREL22 UINT16_C(0x0012) +#define IMAGE_REL_IA64_SREL32 UINT16_C(0x0013) +#define IMAGE_REL_IA64_UREL32 UINT16_C(0x0014) +#define IMAGE_REL_IA64_PCREL60X UINT16_C(0x0015) +#define IMAGE_REL_IA64_PCREL60B UINT16_C(0x0016) +#define IMAGE_REL_IA64_PCREL60F UINT16_C(0x0017) +#define IMAGE_REL_IA64_PCREL60I UINT16_C(0x0018) +#define IMAGE_REL_IA64_PCREL60M UINT16_C(0x0019) +#define IMAGE_REL_IA64_IMMGPREL64 UINT16_C(0x001a) +#define IMAGE_REL_IA64_TOKEN UINT16_C(0x001b) +#define IMAGE_REL_IA64_GPREL32 UINT16_C(0x001c) +#define IMAGE_REL_IA64_ADDEND UINT16_C(0x001f) +/** @} */ + +/** @name IMAGE_REL_MIPS_XXX - COFF relocations for MIPS CPUs. + * Used by IMAGE_RELOCATION::Type. + * @{ */ +#define IMAGE_REL_MIPS_ABSOLUTE UINT16_C(0x0000) +#define IMAGE_REL_MIPS_REFHALF UINT16_C(0x0001) +#define IMAGE_REL_MIPS_REFWORD UINT16_C(0x0002) +#define IMAGE_REL_MIPS_JMPADDR UINT16_C(0x0003) +#define IMAGE_REL_MIPS_REFHI UINT16_C(0x0004) +#define IMAGE_REL_MIPS_REFLO UINT16_C(0x0005) +#define IMAGE_REL_MIPS_GPREL UINT16_C(0x0006) +#define IMAGE_REL_MIPS_LITERAL UINT16_C(0x0007) +#define IMAGE_REL_MIPS_SECTION UINT16_C(0x000a) +#define IMAGE_REL_MIPS_SECREL UINT16_C(0x000b) +#define IMAGE_REL_MIPS_SECRELLO UINT16_C(0x000c) +#define IMAGE_REL_MIPS_SECRELHI UINT16_C(0x000d) +#define IMAGE_REL_MIPS_JMPADDR16 UINT16_C(0x0010) +#define IMAGE_REL_MIPS_REFWORDNB UINT16_C(0x0022) +#define IMAGE_REL_MIPS_PAIR UINT16_C(0x0025) +/** @} */ + +/** @name IMAGE_REL_M32R_XXX - COFF relocations for Mitsubishi M32R CPUs. + * Used by IMAGE_RELOCATION::Type. + * @{ */ +#define IMAGE_REL_M32R_ABSOLUTE UINT16_C(0x0000) +#define IMAGE_REL_M32R_ADDR32 UINT16_C(0x0001) +#define IMAGE_REL_M32R_ADDR32NB UINT16_C(0x0002) +#define IMAGE_REL_M32R_ADDR24 UINT16_C(0x0003) +#define IMAGE_REL_M32R_GPREL16 UINT16_C(0x0004) +#define IMAGE_REL_M32R_PCREL24 UINT16_C(0x0005) +#define IMAGE_REL_M32R_PCREL16 UINT16_C(0x0006) +#define IMAGE_REL_M32R_PCREL8 UINT16_C(0x0007) +#define IMAGE_REL_M32R_REFHALF UINT16_C(0x0008) +#define IMAGE_REL_M32R_REFHI UINT16_C(0x0009) +#define IMAGE_REL_M32R_REFLO UINT16_C(0x000a) +#define IMAGE_REL_M32R_PAIR UINT16_C(0x000b) +#define IMAGE_REL_M32R_SECTION UINT16_C(0x000c) +#define IMAGE_REL_M32R_SECREL UINT16_C(0x000d) +#define IMAGE_REL_M32R_TOKEN UINT16_C(0x000e) +/** @} */ + + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_pecoff_h */ + diff --git a/include/iprt/formats/riff.h b/include/iprt/formats/riff.h new file mode 100644 index 00000000..01188b72 --- /dev/null +++ b/include/iprt/formats/riff.h @@ -0,0 +1,247 @@ +/* $Id: riff.h $ */ +/** @file + * IPRT - Resource Interchange File Format (RIFF), WAVE, ++. + */ + +/* + * Copyright (C) 2021-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_riff_h +#define IPRT_INCLUDED_formats_riff_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_riff RIFF & WAVE structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + +/** + * Resource interchange file format (RIFF) file header. + */ +typedef struct RTRIFFHDR +{ + /** The 'RIFF' magic (RTRIFFHDR_MAGIC). */ + uint32_t uMagic; + /** The file size. */ + uint32_t cbFile; + /** The file type. */ + uint32_t uFileType; +} RTRIFFHDR; +AssertCompileSize(RTRIFFHDR, 12); +/** Pointer to a RIFF file header. */ +typedef RTRIFFHDR *PRTRIFFHDR; + +/** Magic value for RTRIFFHDR::uMagic ('RIFF'). */ +#define RTRIFFHDR_MAGIC RT_BE2H_U32_C(0x52494646) + +/** @name RIFF file types (RTRIFFHDR::uFileType) + * @{ */ +/** RIFF file type: WAVE (audio) */ +#define RTRIFF_FILE_TYPE_WAVE RT_BE2H_U32_C(0x57415645) +/** RIFF file type: AVI (video) */ +#define RTRIFF_FILE_TYPE_AVI RT_BE2H_U32_C(0x41564920) +/** @} */ + +/** + * A RIFF chunk. + */ +typedef struct RTRIFFCHUNK +{ + /** The chunk magic (four character code). */ + uint32_t uMagic; + /** The size of the chunk minus this header. */ + uint32_t cbChunk; +} RTRIFFCHUNK; +AssertCompileSize(RTRIFFCHUNK, 8); +/** Pointer to a RIFF chunk. */ +typedef RTRIFFCHUNK *PRTRIFFCHUNK; + +/** + * A RIFF list. + */ +typedef struct RTRIFFLIST +{ + /** The list indicator (RTRIFFLIST_MAGIC). */ + uint32_t uMagic; + /** The size of the chunk minus this header. */ + uint32_t cbChunk; + /** The list type (four character code). */ + uint32_t uListType; +} RTRIFFLIST; +AssertCompileSize(RTRIFFLIST, 12); +/** Pointer to a RIFF list. */ +typedef RTRIFFLIST *PRTRIFFLIST; +/** Magic value for RTRIFFLIST::uMagic ('LIST'). */ +#define RTRIFFLIST_MAGIC RT_BE2H_U32_C(0x4c495354) + +/** Generic 'INFO' list type. */ +#define RTRIFFLIST_TYPE_INFO RT_BE2H_U32_C(0x494e464f) + + +/** + * Wave file format (WAVEFORMATEX w/o cbSize). + * @see RTRIFFWAVEFMTCHUNK. + */ +typedef struct RTRIFFWAVEFMT +{ + /** Audio format tag. */ + uint16_t uFormatTag; + /** Number of channels. */ + uint16_t cChannels; + /** Sample rate. */ + uint32_t uHz; + /** Byte rate (= uHz * cChannels * cBitsPerSample / 8) */ + uint32_t cbRate; + /** Frame size (aka block alignment). */ + uint16_t cbFrame; + /** Number of bits per sample. */ + uint16_t cBitsPerSample; +} RTRIFFWAVEFMT; +AssertCompileSize(RTRIFFWAVEFMT, 16); +/** Pointer to a wave file format structure. */ +typedef RTRIFFWAVEFMT *PRTRIFFWAVEFMT; + +/** + * Extensible wave file format (WAVEFORMATEXTENSIBLE). + * @see RTRIFFWAVEFMTEXTCHUNK. + */ +#pragma pack(4) /* Override the uint64_t effect from RTUUID, so we can safely put it after RTRIFFHDR in a structure. */ +typedef struct RTRIFFWAVEFMTEXT +{ + /** The coreformat structure. */ + RTRIFFWAVEFMT Core; + /** Number of bytes of extra information after the core. */ + uint16_t cbExtra; + /** Number of valid bits per sample. */ + uint16_t cValidBitsPerSample; + /** The channel mask. */ + uint32_t fChannelMask; + /** The GUID of the sub-format. */ + RTUUID SubFormat; +} RTRIFFWAVEFMTEXT; +#pragma pack() +AssertCompileSize(RTRIFFWAVEFMTEXT, 16+2+22); +/** Pointer to an extensible wave file format structure. */ +typedef RTRIFFWAVEFMTEXT *PRTRIFFWAVEFMTEXT; + +/** RTRIFFWAVEFMT::uFormatTag value for PCM (WDK: WAVE_FORMAT_PCM). */ +#define RTRIFFWAVEFMT_TAG_PCM UINT16_C(0x0001) +/** RTRIFFWAVEFMT::uFormatTag value for extensible wave files (WDK: WAVE_FORMAT_EXTENSIBLE). */ +#define RTRIFFWAVEFMT_TAG_EXTENSIBLE UINT16_C(0xfffe) + +/** Typical RTRIFFWAVEFMTEXT::cbExtra value (min). */ +#define RTRIFFWAVEFMTEXT_EXTRA_SIZE UINT16_C(22) + +/** @name Channel IDs for RTRIFFWAVEFMTEXT::fChannelMask. + * @{ */ +#define RTRIFFWAVEFMTEXT_CH_ID_FL RT_BIT_32(0) /**< Front left. */ +#define RTRIFFWAVEFMTEXT_CH_ID_FR RT_BIT_32(1) /**< Front right. */ +#define RTRIFFWAVEFMTEXT_CH_ID_FC RT_BIT_32(2) /**< Front center */ +#define RTRIFFWAVEFMTEXT_CH_ID_LFE RT_BIT_32(3) /**< Low frequency */ +#define RTRIFFWAVEFMTEXT_CH_ID_BL RT_BIT_32(4) /**< Back left. */ +#define RTRIFFWAVEFMTEXT_CH_ID_BR RT_BIT_32(5) /**< Back right. */ +#define RTRIFFWAVEFMTEXT_CH_ID_FLC RT_BIT_32(6) /**< Front left of center. */ +#define RTRIFFWAVEFMTEXT_CH_ID_FLR RT_BIT_32(7) /**< Front right of center. */ +#define RTRIFFWAVEFMTEXT_CH_ID_BC RT_BIT_32(8) /**< Back center. */ +#define RTRIFFWAVEFMTEXT_CH_ID_SL RT_BIT_32(9) /**< Side left. */ +#define RTRIFFWAVEFMTEXT_CH_ID_SR RT_BIT_32(10) /**< Side right. */ +#define RTRIFFWAVEFMTEXT_CH_ID_TC RT_BIT_32(11) /**< Top center. */ +#define RTRIFFWAVEFMTEXT_CH_ID_TFL RT_BIT_32(12) /**< Top front left. */ +#define RTRIFFWAVEFMTEXT_CH_ID_TFC RT_BIT_32(13) /**< Top front center. */ +#define RTRIFFWAVEFMTEXT_CH_ID_TFR RT_BIT_32(14) /**< Top front right. */ +#define RTRIFFWAVEFMTEXT_CH_ID_TBL RT_BIT_32(15) /**< Top back left. */ +#define RTRIFFWAVEFMTEXT_CH_ID_TBC RT_BIT_32(16) /**< Top back center. */ +#define RTRIFFWAVEFMTEXT_CH_ID_TBR RT_BIT_32(17) /**< Top back right. */ +/** @} */ + +/** RTRIFFWAVEFMTEXT::SubFormat UUID string for PCM. */ +#define RTRIFFWAVEFMTEXT_SUBTYPE_PCM "00000001-0000-0010-8000-00aa00389b71" + + +/** + * Wave file format chunk. + */ +typedef struct RTRIFFWAVEFMTCHUNK +{ + /** Chunk header with RTRIFFWAVEFMT_MAGIC as magic. */ + RTRIFFCHUNK Chunk; + /** The wave file format. */ + RTRIFFWAVEFMT Data; +} RTRIFFWAVEFMTCHUNK; +AssertCompileSize(RTRIFFWAVEFMTCHUNK, 8+16); +/** Pointer to a wave file format chunk. */ +typedef RTRIFFWAVEFMTCHUNK *PRTRIFFWAVEFMTCHUNK; +/** Magic value for RTRIFFWAVEFMTCHUNK and RTRIFFWAVEFMTEXTCHUNK ('fmt '). */ +#define RTRIFFWAVEFMT_MAGIC RT_BE2H_U32_C(0x666d7420) + +/** + * Extensible wave file format chunk. + */ +typedef struct RTRIFFWAVEFMTEXTCHUNK +{ + /** Chunk header with RTRIFFWAVEFMT_MAGIC as magic. */ + RTRIFFCHUNK Chunk; + /** The wave file format. */ + RTRIFFWAVEFMTEXT Data; +} RTRIFFWAVEFMTEXTCHUNK; +AssertCompileSize(RTRIFFWAVEFMTEXTCHUNK, 8+16+2+22); +/** Pointer to a wave file format chunk. */ +typedef RTRIFFWAVEFMTEXTCHUNK *PRTRIFFWAVEFMTEXTCHUNK; + + +/** + * Wave file data chunk. + */ +typedef struct RTRIFFWAVEDATACHUNK +{ + /** Chunk header with RTRIFFWAVEFMT_MAGIC as magic. */ + RTRIFFCHUNK Chunk; + /** Variable sized sample data. */ + uint8_t abData[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} RTRIFFWAVEDATACHUNK; + +/** Magic value for RTRIFFWAVEFMT::uMagic ('data'). */ +#define RTRIFFWAVEDATACHUNK_MAGIC RT_BE2H_U32_C(0x64617461) + + +/** Magic value padding chunks ('PAD '). */ +#define RTRIFFPADCHUNK_MAGIC RT_BE2H_U32_C(0x50414420) + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_riff_h */ + diff --git a/include/iprt/formats/tar.h b/include/iprt/formats/tar.h new file mode 100644 index 00000000..a42fb564 --- /dev/null +++ b/include/iprt/formats/tar.h @@ -0,0 +1,298 @@ +/* $Id: tar.h $ */ +/** @file + * IPRT - TAR Virtual Filesystem. + */ + +/* + * Copyright (C) 2010-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_tar_h +#define IPRT_INCLUDED_formats_tar_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/assert.h> + +/** @name RTZIPTARHDRPOSIX::typeflag + * @{ */ +#define RTZIPTAR_TF_OLDNORMAL '\0' /**< Normal disk file, Unix compatible */ +#define RTZIPTAR_TF_NORMAL '0' /**< Normal disk file */ +#define RTZIPTAR_TF_LINK '1' /**< Link to previously dumped file */ +#define RTZIPTAR_TF_SYMLINK '2' /**< Symbolic link */ +#define RTZIPTAR_TF_CHR '3' /**< Character special file */ +#define RTZIPTAR_TF_BLK '4' /**< Block special file */ +#define RTZIPTAR_TF_DIR '5' /**< Directory */ +#define RTZIPTAR_TF_FIFO '6' /**< FIFO special file */ +#define RTZIPTAR_TF_CONTIG '7' /**< Contiguous file */ + +#define RTZIPTAR_TF_X_HDR 'x' /**< Extended header. */ +#define RTZIPTAR_TF_X_GLOBAL 'g' /**< Global extended header. */ + +#define RTZIPTAR_TF_SOLARIS_XHDR 'X' + +#define RTZIPTAR_TF_GNU_DUMPDIR 'D' +#define RTZIPTAR_TF_GNU_LONGLINK 'K' /**< GNU long link header. */ +#define RTZIPTAR_TF_GNU_LONGNAME 'L' /**< GNU long name header. */ +#define RTZIPTAR_TF_GNU_MULTIVOL 'M' +#define RTZIPTAR_TF_GNU_SPARSE 'S' +#define RTZIPTAR_TF_GNU_VOLDHR 'V' +/** @} */ + +/** Maximum length of a tar filename, excluding the terminating '\0'. More + * does not fit into a tar record. */ +#define RTZIPTAR_NAME_MAX 99 + + +/** + * The ancient tar header. + * + * The posix and gnu headers are compatible with the members up to and including + * link name, from there on they differ. + */ +typedef struct RTZIPTARHDRANCIENT +{ + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char typeflag; + char linkname[100]; /**< Was called linkflag. */ + char unused[8+64+16+155+12]; +} RTZIPTARHDRANCIENT; +AssertCompileSize(RTZIPTARHDRANCIENT, 512); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, name, 0); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, mode, 100); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, uid, 108); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, gid, 116); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, size, 124); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, mtime, 136); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, chksum, 148); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, typeflag, 156); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, linkname, 157); +AssertCompileMemberOffset(RTZIPTARHDRANCIENT, unused, 257); + + +/** The uniform standard tape archive format magic value. */ +#define RTZIPTAR_USTAR_MAGIC "ustar" +/** The ustar version string. + * @remarks The terminator character is not part of the field. */ +#define RTZIPTAR_USTAR_VERSION "00" + +/** The GNU magic + version value. */ +#define RTZIPTAR_GNU_MAGIC "ustar " + + +/** + * The posix header (according to SuS). + */ +typedef struct RTZIPTARHDRPOSIX +{ + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char typeflag; + char linkname[100]; + char magic[6]; + char version[2]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char prefix[155]; + char unused[12]; +} RTZIPTARHDRPOSIX; +AssertCompileSize(RTZIPTARHDRPOSIX, 512); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, name, 0); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, mode, 100); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, uid, 108); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, gid, 116); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, size, 124); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, mtime, 136); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, chksum, 148); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, typeflag, 156); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, linkname, 157); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, magic, 257); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, version, 263); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, uname, 265); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, gname, 297); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, devmajor, 329); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, devminor, 337); +AssertCompileMemberOffset(RTZIPTARHDRPOSIX, prefix, 345); + +/** + * GNU sparse data segment descriptor. + */ +typedef struct RTZIPTARGNUSPARSE +{ + char offset[12]; /**< Absolute offset relative to the start of the file. */ + char numbytes[12]; +} RTZIPTARGNUSPARSE; +AssertCompileSize(RTZIPTARGNUSPARSE, 24); +AssertCompileMemberOffset(RTZIPTARGNUSPARSE, offset, 0); +AssertCompileMemberOffset(RTZIPTARGNUSPARSE, numbytes, 12); +/** Pointer to a GNU sparse data segment descriptor. */ +typedef RTZIPTARGNUSPARSE *PRTZIPTARGNUSPARSE; +/** Pointer to a const GNU sparse data segment descriptor. */ +typedef RTZIPTARGNUSPARSE *PCRTZIPTARGNUSPARSE; + +/** + * The GNU header. + */ +typedef struct RTZIPTARHDRGNU +{ + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char typeflag; + char linkname[100]; + char magic[8]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char atime[12]; + char ctime[12]; + char offset[12]; /**< for multi-volume? */ + char longnames[4]; /**< Seems to be unused. */ + char unused[1]; + RTZIPTARGNUSPARSE sparse[4]; + char isextended; /**< More headers about sparse stuff if binary value 1. */ + char realsize[12]; + char unused2[17]; +} RTZIPTARHDRGNU; +AssertCompileSize(RTZIPTARHDRGNU, 512); +AssertCompileMemberOffset(RTZIPTARHDRGNU, name, 0); +AssertCompileMemberOffset(RTZIPTARHDRGNU, mode, 100); +AssertCompileMemberOffset(RTZIPTARHDRGNU, uid, 108); +AssertCompileMemberOffset(RTZIPTARHDRGNU, gid, 116); +AssertCompileMemberOffset(RTZIPTARHDRGNU, size, 124); +AssertCompileMemberOffset(RTZIPTARHDRGNU, mtime, 136); +AssertCompileMemberOffset(RTZIPTARHDRGNU, chksum, 148); +AssertCompileMemberOffset(RTZIPTARHDRGNU, typeflag, 156); +AssertCompileMemberOffset(RTZIPTARHDRGNU, linkname, 157); +AssertCompileMemberOffset(RTZIPTARHDRGNU, magic, 257); +AssertCompileMemberOffset(RTZIPTARHDRGNU, uname, 265); +AssertCompileMemberOffset(RTZIPTARHDRGNU, gname, 297); +AssertCompileMemberOffset(RTZIPTARHDRGNU, devmajor, 329); +AssertCompileMemberOffset(RTZIPTARHDRGNU, devminor, 337); +AssertCompileMemberOffset(RTZIPTARHDRGNU, atime, 345); +AssertCompileMemberOffset(RTZIPTARHDRGNU, ctime, 357); +AssertCompileMemberOffset(RTZIPTARHDRGNU, offset, 369); +AssertCompileMemberOffset(RTZIPTARHDRGNU, longnames, 381); +AssertCompileMemberOffset(RTZIPTARHDRGNU, unused, 385); +AssertCompileMemberOffset(RTZIPTARHDRGNU, sparse, 386); +AssertCompileMemberOffset(RTZIPTARHDRGNU, isextended,482); +AssertCompileMemberOffset(RTZIPTARHDRGNU, realsize, 483); +AssertCompileMemberOffset(RTZIPTARHDRGNU, unused2, 495); + + +/** + * GNU sparse header. + */ +typedef struct RTZIPTARHDRGNUSPARSE +{ + RTZIPTARGNUSPARSE sp[21]; + char isextended; + char unused[7]; +} RTZIPTARHDRGNUSPARSE; +AssertCompileSize(RTZIPTARHDRGNUSPARSE, 512); +AssertCompileMemberOffset(RTZIPTARHDRGNUSPARSE, sp, 0); +AssertCompileMemberOffset(RTZIPTARHDRGNUSPARSE, isextended, 504); +AssertCompileMemberOffset(RTZIPTARHDRGNUSPARSE, unused, 505); + + +/** + * The bits common to posix and GNU. + */ +typedef struct RTZIPTARHDRCOMMON +{ + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char typeflag; + char linkname[100]; + char magic[6]; + char version[2]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char not_common[155+12]; +} RTZIPTARHDRCOMMON; +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, name, RTZIPTARHDRPOSIX, name); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mode, RTZIPTARHDRPOSIX, mode); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uid, RTZIPTARHDRPOSIX, uid); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gid, RTZIPTARHDRPOSIX, gid); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, size, RTZIPTARHDRPOSIX, size); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mtime, RTZIPTARHDRPOSIX, mtime); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, chksum, RTZIPTARHDRPOSIX, chksum); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, typeflag, RTZIPTARHDRPOSIX, typeflag); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, linkname, RTZIPTARHDRPOSIX, linkname); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, magic, RTZIPTARHDRPOSIX, magic); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, version, RTZIPTARHDRPOSIX, version); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uname, RTZIPTARHDRPOSIX, uname); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gname, RTZIPTARHDRPOSIX, gname); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devmajor, RTZIPTARHDRPOSIX, devmajor); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devminor, RTZIPTARHDRPOSIX, devminor); + +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, name, RTZIPTARHDRGNU, name); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mode, RTZIPTARHDRGNU, mode); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uid, RTZIPTARHDRGNU, uid); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gid, RTZIPTARHDRGNU, gid); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, size, RTZIPTARHDRGNU, size); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mtime, RTZIPTARHDRGNU, mtime); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, chksum, RTZIPTARHDRGNU, chksum); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, typeflag, RTZIPTARHDRGNU, typeflag); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, linkname, RTZIPTARHDRGNU, linkname); +AssertCompileMembersAtSameOffset( RTZIPTARHDRCOMMON, magic, RTZIPTARHDRGNU, magic); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uname, RTZIPTARHDRGNU, uname); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gname, RTZIPTARHDRGNU, gname); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devmajor, RTZIPTARHDRGNU, devmajor); +AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devminor, RTZIPTARHDRGNU, devminor); + +#endif /* !IPRT_INCLUDED_formats_tar_h */ + diff --git a/include/iprt/formats/tpm.h b/include/iprt/formats/tpm.h new file mode 100644 index 00000000..342a5220 --- /dev/null +++ b/include/iprt/formats/tpm.h @@ -0,0 +1,313 @@ +/* $Id: tpm.h $ */ +/** @file + * IPRT, TPM common definitions (this is actually a protocol and not a format). + */ + +/* + * Copyright (C) 2021-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_tpm_h +#define IPRT_INCLUDED_formats_tpm_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/asm.h> +#include <iprt/cdefs.h> +#include <iprt/types.h> +#include <iprt/assertcompile.h> +#include <iprt/string.h> + + +/** + * TPM request header (everything big endian). + */ +#pragma pack(1) +typedef struct TPMREQHDR +{ + /** The tag for this request. */ + uint16_t u16Tag; + /** Size of the request in bytes. */ + uint32_t cbReq; + /** The request ordinal to execute. */ + uint32_t u32Ordinal; +} TPMREQHDR; +#pragma pack() +AssertCompileSize(TPMREQHDR, 2 + 4 + 4); +/** Pointer to a TPM request header. */ +typedef TPMREQHDR *PTPMREQHDR; +/** Pointer to a const TPM request header. */ +typedef const TPMREQHDR *PCTPMREQHDR; + + +/** @name TPM 1.2 request tags + * @{ */ +/** Command with no authentication. */ +#define TPM_TAG_RQU_COMMAND UINT16_C(0x00c1) +/** An authenticated command with one authentication handle. */ +#define TPM_TAG_RQU_AUTH1_COMMAND UINT16_C(0x00c2) +/** An authenticated command with two authentication handles. */ +#define TPM_TAG_RQU_AUTH2_COMMAND UINT16_C(0x00c3) +/** @} */ + + +/** @name TPM 2.0 request/response tags + * @{ */ +/** Command with no associated session. */ +#define TPM2_ST_NO_SESSIONS UINT16_C(0x8001) +/** Command with an associated session. */ +#define TPM2_ST_SESSIONS UINT16_C(0x8002) +/** @} */ + + +/** @name TPM 1.2 request ordinals. + * @{ */ +/** Perform a full self test. */ +#define TPM_ORD_SELFTESTFULL UINT32_C(80) +/** Continue the selftest. */ +#define TPM_ORD_CONTINUESELFTEST UINT32_C(83) +/** Return the test result. */ +#define TPM_ORD_GETTESTRESULT UINT32_C(84) +/** Get a capability. */ +#define TPM_ORD_GETCAPABILITY UINT32_C(101) +/** @} */ + + +/** @name TPM 2.0 command codes. + * @{ */ +/** Get a capability. */ +#define TPM2_CC_GET_CAPABILITY UINT32_C(378) +/** @} */ + + +/** @name Defines related to TPM_ORD_GETCAPABILITY. + * @{ */ +/** Return a TPM related property. */ +#define TPM_CAP_PROPERTY UINT32_C(5) + +/** Returns the size of the input buffer. */ +#define TPM_CAP_PROP_INPUT_BUFFER UINT32_C(0x124) + +/** + * TPM_ORD_GETCAPABILITY request. + */ +#pragma pack(1) +typedef struct TPMREQGETCAPABILITY +{ + /** Request header. */ + TPMREQHDR Hdr; + /** The capability group to query. */ + uint32_t u32Cap; + /** Length of the capability. */ + uint32_t u32Length; + /** The sub capability to query. */ + uint32_t u32SubCap; +} TPMREQGETCAPABILITY; +#pragma pack() +/** Pointer to a TPM_ORD_GETCAPABILITY request. */ +typedef TPMREQGETCAPABILITY *PTPMREQGETCAPABILITY; +/** Pointer to a const TPM_ORD_GETCAPABILITY request. */ +typedef const TPMREQGETCAPABILITY *PCTPMREQGETCAPABILITY; +/** @} */ + + +/** @name Defines related to TPM2_CC_GET_CAPABILITY. + * @{ */ +/** Return a TPM related property. */ +#define TPM2_CAP_TPM_PROPERTIES UINT32_C(6) + +/** Returns the size of the input buffer. */ +#define TPM2_PT_INPUT_BUFFER UINT32_C(0x10d) + +/** + * TPM2_CC_GET_CAPABILITY request. + */ +#pragma pack(1) +typedef struct TPM2REQGETCAPABILITY +{ + /** Request header. */ + TPMREQHDR Hdr; + /** The capability group to query. */ + uint32_t u32Cap; + /** Property to query. */ + uint32_t u32Property; + /** Number of values to return. */ + uint32_t u32Count; +} TPM2REQGETCAPABILITY; +#pragma pack() +/** Pointer to a TPM2_CC_GET_CAPABILITY request. */ +typedef TPM2REQGETCAPABILITY *PTPM2REQGETCAPABILITY; +/** Pointer to a const TPM2_CC_GET_CAPABILITY request. */ +typedef const TPM2REQGETCAPABILITY *PCTPM2REQGETCAPABILITY; +/** @} */ + + +/** + * TPM response header (everything big endian). + */ +#pragma pack(1) +typedef struct TPMRESPHDR +{ + /** The tag for this request. */ + uint16_t u16Tag; + /** Size of the response in bytes. */ + uint32_t cbResp; + /** The error code for the response. */ + uint32_t u32ErrCode; +} TPMRESPHDR; +#pragma pack() +AssertCompileSize(TPMRESPHDR, 2 + 4 + 4); +/** Pointer to a TPM response header. */ +typedef TPMRESPHDR *PTPMRESPHDR; +/** Pointer to a const TPM response header. */ +typedef const TPMRESPHDR *PCTPMRESPHDR; + + +/** @name TPM 1.2 response tags + * @{ */ +/** A response from a command with no authentication. */ +#define TPM_TAG_RSP_COMMAND UINT16_C(0x00c4) +/** An authenticated response with one authentication handle. */ +#define TPM_TAG_RSP_AUTH1_COMMAND UINT16_C(0x00c5) +/** An authenticated response with two authentication handles. */ +#define TPM_TAG_RSP_AUTH2_COMMAND UINT16_C(0x00c6) +/** @} */ + + +/** @name TPM status codes. + * @{ */ +#ifndef TPM_SUCCESS +/** Request executed successfully. */ +# define TPM_SUCCESS UINT32_C(0) +#endif +#ifndef TPM_AUTHFAIL +/** Authentication failed. */ +# define TPM_AUTHFAIL UINT32_C(1) +#endif +#ifndef TPM_BADINDEX +/** An index is malformed. */ +# define TPM_BADINDEX UINT32_C(2) +#endif +#ifndef TPM_BAD_PARAMETER +/** A request parameter is invalid. */ +# define TPM_BAD_PARAMETER UINT32_C(3) +#endif +#ifndef TPM_FAIL +/** The TPM failed to execute the request. */ +# define TPM_FAIL UINT32_C(9) +#endif +/** @todo Extend as need arises. */ +/** @} */ + + +/* Some inline helpers to account for the unaligned members of the request and response headers. */ + +/** + * Returns the request tag of the given TPM request header. + * + * @returns TPM request tag in bytes. + * @param pTpmReqHdr Pointer to the TPM request header. + */ +DECLINLINE(uint16_t) RTTpmReqGetTag(PCTPMREQHDR pTpmReqHdr) +{ + return RT_BE2H_U16(pTpmReqHdr->u16Tag); +} + + +/** + * Returns the request size of the given TPM request header. + * + * @returns TPM request size in bytes. + * @param pTpmReqHdr Pointer to the TPM request header. + */ +DECLINLINE(size_t) RTTpmReqGetSz(PCTPMREQHDR pTpmReqHdr) +{ + uint32_t cbReq; + memcpy(&cbReq, &pTpmReqHdr->cbReq, sizeof(pTpmReqHdr->cbReq)); + return RT_BE2H_U32(cbReq); +} + + +/** + * Returns the request ordinal of the given TPM request header. + * + * @returns TPM request ordinal in bytes. + * @param pTpmReqHdr Pointer to the TPM request header. + */ +DECLINLINE(uint32_t) RTTpmReqGetOrdinal(PCTPMREQHDR pTpmReqHdr) +{ + uint32_t u32Ordinal; + memcpy(&u32Ordinal, &pTpmReqHdr->u32Ordinal, sizeof(pTpmReqHdr->u32Ordinal)); + return RT_BE2H_U32(u32Ordinal); +} + + +/** + * Returns the response tag of the given TPM response header. + * + * @returns TPM request tag in bytes. + * @param pTpmRespHdr Pointer to the TPM response header. + */ +DECLINLINE(uint16_t) RTTpmRespGetTag(PCTPMRESPHDR pTpmRespHdr) +{ + return RT_BE2H_U16(pTpmRespHdr->u16Tag); +} + + +/** + * Returns the response size included in the given TPM response header. + * + * @returns TPM response size in bytes. + * @param pTpmRespHdr Pointer to the TPM response header. + */ +DECLINLINE(size_t) RTTpmRespGetSz(PCTPMRESPHDR pTpmRespHdr) +{ + uint32_t cbResp; + memcpy(&cbResp, &pTpmRespHdr->cbResp, sizeof(pTpmRespHdr->cbResp)); + return RT_BE2H_U32(cbResp); +} + + +/** + * Returns the error code of the given TPM response header. + * + * @returns TPM response error code. + * @param pTpmRespHdr Pointer to the TPM response header. + */ +DECLINLINE(uint32_t) RTTpmRespGetErrCode(PCTPMRESPHDR pTpmRespHdr) +{ + uint32_t u32ErrCode; + memcpy(&u32ErrCode, &pTpmRespHdr->u32ErrCode, sizeof(pTpmRespHdr->u32ErrCode)); + return RT_BE2H_U32(u32ErrCode); +} + +#endif /* !IPRT_INCLUDED_formats_tpm_h */ + diff --git a/include/iprt/formats/tracelog.h b/include/iprt/formats/tracelog.h new file mode 100644 index 00000000..c6403d03 --- /dev/null +++ b/include/iprt/formats/tracelog.h @@ -0,0 +1,239 @@ +/* $Id: tracelog.h $ */ +/** @file + * IPRT, Binary trace log format. + */ + +/* + * Copyright (C) 2018-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_tracelog_h +#define IPRT_INCLUDED_formats_tracelog_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/assert.h> +#include <iprt/cdefs.h> +#include <iprt/types.h> + + +/** @defgroup grp_rt_formats_tracelog Binary trace log structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + +/** Size of the record magic in bytes. */ +#define TRACELOG_MAGIC_SZ 8 + +/** + * Trace log identification and options header. + */ +typedef struct TRACELOGHDR +{ + /** Identifiaction magic. */ + uint8_t szMagic[8]; + /** Endianess indicator. */ + uint32_t u32Endianess; + /** File version indicator. */ + uint32_t u32Version; + /** File flags (MBZ for now). */ + uint32_t fFlags; + /** Size of the trace log description in bytes following this header. */ + uint32_t cbStrDesc; + /** Size of a pointer item in bytes. */ + uint8_t cbTypePtr; + /** size of the size_t item in bytes. */ + uint8_t cbTypeSize; + /** Padding to an 4 byte boundary. */ + uint16_t u16Reserved0; + /** Padding to an 8 byte boundary. */ + uint32_t u32Reserved0; + /** Starting timestamp when the log was initialised. */ + uint64_t u64TsStart; + /** Padding to 64byte boundary, reserved for future use. */ + uint64_t au64Reserved[3]; +} TRACELOGHDR; +AssertCompileSize(TRACELOGHDR, 64); +/** Pointer to a trace log header. */ +typedef TRACELOGHDR *PTRACELOGHDR; +/** Pointer to a const trace log header. */ +typedef const TRACELOGHDR *PCTRACELOGHDR; + +/** Magic value for a trace log file (TRACELOG backwards). */ +#define TRACELOG_HDR_MAGIC "GOLECART" +/** Endianess indicator. */ +#define TRACELOG_HDR_ENDIANESS 0xdeadc0de +/** The default version (Higher 16bits major, low 16bits minor version). */ +#define TRACELOG_VERSION RT_MAKE_U32(1, 0) + + +/** + * Trace log event structure descriptor. + */ +typedef struct TRACELOGEVTDESC +{ + /** Event descriptor magic. */ + uint8_t szMagic[8]; + /** Event structure descriptor ID for identification in events later. */ + uint32_t u32Id; + /** Severity class of the event .*/ + uint32_t u32Severity; + /** Size of the identifier string in bytes without terminator. */ + uint32_t cbStrId; + /** Size of the description string in bytes without terminator. */ + uint32_t cbStrDesc; + /** Number of event items following. */ + uint32_t cEvtItems; + /** Padding to end the descriptor on a 32 byte boundary. */ + uint32_t au32Padding0; +} TRACELOGEVTDESC; +AssertCompileSize(TRACELOGEVTDESC, 32); +/** Pointer to a trace log event structure descriptor. */ +typedef TRACELOGEVTDESC *PTRACELOGEVTDESC; +/** Pointer to a const trace log event structure descriptor. */ +typedef const TRACELOGEVTDESC *PCTRACELOGEVTDESC; + +/** Event descriptor magic. */ +#define TRACELOG_EVTDESC_MAGIC "\0CSEDTVE" + +/** Severity: Informational event*/ +#define TRACELOG_EVTDESC_SEVERITY_INFO UINT32_C(0) +/** Severity: Warning event*/ +#define TRACELOG_EVTDESC_SEVERITY_WARNING UINT32_C(1) +/** Severity: Error event*/ +#define TRACELOG_EVTDESC_SEVERITY_ERROR UINT32_C(2) +/** Severity: Fatal event*/ +#define TRACELOG_EVTDESC_SEVERITY_FATAL UINT32_C(3) +/** Severity: Debug event*/ +#define TRACELOG_EVTDESC_SEVERITY_DEBUG UINT32_C(4) + + +/** + * Trace log event item descriptor. + */ +typedef struct TRACELOGEVTITEMDESC +{ + /** Event item descriptor magic. */ + uint8_t szMagic[8]; + /** Size of the item name string in bytes without terminator. */ + uint32_t cbStrName; + /** Size of the optional description string in bytes without terminator. */ + uint32_t cbStrDesc; + /** Item type */ + uint32_t u32Type; + /** Size of the raw data type if static throughout. */ + uint32_t cbRawData; + /** Padding to end the descriptor on a 32 byte boundary. */ + uint32_t au32Padding0[2]; +} TRACELOGEVTITEMDESC; +AssertCompileSize(TRACELOGEVTITEMDESC, 32); +/** Pointer to a trace log event item descriptor. */ +typedef TRACELOGEVTITEMDESC *PTRACELOGEVTITEMDESC; +/** Pointer to a const trace log event item descriptor. */ +typedef const TRACELOGEVTITEMDESC *PCTRACELOGEVTITEMDESC; + +/** Event item descriptor magic. */ +#define TRACELOG_EVTITEMDESC_MAGIC "CSEDMETI" +/** Boolean type. */ +#define TRACELOG_EVTITEMDESC_TYPE_BOOL UINT32_C(1) +/** Unsigned 8bit integer type. */ +#define TRACELOG_EVTITEMDESC_TYPE_UINT8 UINT32_C(2) +/** Signed 8bit integer type. */ +#define TRACELOG_EVTITEMDESC_TYPE_INT8 UINT32_C(3) +/** Unsigned 16bit integer type. */ +#define TRACELOG_EVTITEMDESC_TYPE_UINT16 UINT32_C(4) +/** Signed 16bit integer type. */ +#define TRACELOG_EVTITEMDESC_TYPE_INT16 UINT32_C(5) +/** Unsigned 32bit integer type. */ +#define TRACELOG_EVTITEMDESC_TYPE_UINT32 UINT32_C(6) +/** Signed 32bit integer type. */ +#define TRACELOG_EVTITEMDESC_TYPE_INT32 UINT32_C(7) +/** Unsigned 64bit integer type. */ +#define TRACELOG_EVTITEMDESC_TYPE_UINT64 UINT32_C(8) +/** Signed 64bit integer type. */ +#define TRACELOG_EVTITEMDESC_TYPE_INT64 UINT32_C(9) +/** 32bit floating point type. */ +#define TRACELOG_EVTITEMDESC_TYPE_FLOAT32 UINT32_C(10) +/** 64bit floating point type. */ +#define TRACELOG_EVTITEMDESC_TYPE_FLOAT64 UINT32_C(11) +/** Raw binary data type. */ +#define TRACELOG_EVTITEMDESC_TYPE_RAWDATA UINT32_C(12) +/** Pointer data type. */ +#define TRACELOG_EVTITEMDESC_TYPE_POINTER UINT32_C(13) +/** size_t data type. */ +#define TRACELOG_EVTITEMDESC_TYPE_SIZE UINT32_C(14) + +/** + * Trace log event marker. + */ +typedef struct TRACELOGEVT +{ + /** Event marker magic. */ + uint8_t szMagic[8]; + /** Trace log sequence number to identify the event uniquely. */ + uint64_t u64SeqNo; + /** Timestamp for the marker (resolution is infered from the header). */ + uint64_t u64Ts; + /** Event group ID for grouping different events together - for no grouped event. */ + uint64_t u64EvtGrpId; + /** Parent group ID this event originated from. */ + uint64_t u64EvtParentGrpId; + /** Overall number of bytes for the event data following including static and possibly variable data. */ + uint32_t cbEvtData; + /** Number of size_t sized raw data size indicators before the raw event data follows. */ + uint32_t cRawEvtDataSz; + /** Event flags. */ + uint32_t fFlags; + /** Event structure descriptor ID to use for structuring the event data. */ + uint32_t u32EvtDescId; + /** Reserved for future use. */ + uint64_t u64Reserved0; +} TRACELOGEVT; +AssertCompileSize(TRACELOGEVT, 64); +/** Pointer to a trace log event marker. */ +typedef TRACELOGEVT *PTRACELOGEVT; +/** Pointer to a const trace log event marker. */ +typedef const TRACELOGEVT *PCTRACELOGEVT; + +/** Event marker descriptor magic. */ +#define TRACELOG_EVT_MAGIC "\0RKRMTVE" +/** Flag indicating this is the start of an event group and all subsequent events + * with the same group ID belong to the same group. */ +#define TRACELOG_EVT_F_GRP_START RT_BIT_32(0) +/** Flag indicating this is the end of an event group which was started earlier. */ +#define TRACELOG_EVT_F_GRP_END RT_BIT_32(1) +/** Combination of valid flags. */ +#define TRACELOG_EVT_F_VALID (TRACELOG_EVT_F_GRP_START | TRACELOG_EVT_F_GRP_END) + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_tracelog_h */ + diff --git a/include/iprt/formats/udf.h b/include/iprt/formats/udf.h new file mode 100644 index 00000000..78ddcd54 --- /dev/null +++ b/include/iprt/formats/udf.h @@ -0,0 +1,2232 @@ +/* $Id: udf.h $ */ +/** @file + * IPRT, Universal Disk Format (UDF). + */ + +/* + * Copyright (C) 2017-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_udf_h +#define IPRT_INCLUDED_formats_udf_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> +#include <iprt/formats/iso9660.h> + + +/** @defgroup grp_rt_formats_udf Universal Disk Format (UDF) structures and definitions + * @ingroup grp_rt_formats + * + * References: + * - https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-167.pdf + * - http://www.osta.org/specs/pdf/udf260.pdf + * - http://wiki.osdev.org/UDF + * - https://sites.google.com/site/udfintro/ + * + * @{ + */ + +/** + * UDF d-character string (@ecma167{1,7.2.12,25}). + * + * This is mainly to mark what's d-strings and what's not. + */ +typedef char UDFDSTRING; +/** Pointer to an UDF dstring. */ +typedef UDFDSTRING *PUDFDSTRING; +/** Pointer to a const UDF dstring. */ +typedef UDFDSTRING const *PCUDFDSTRING; + +/** + * UDF extent allocation descriptor (AD) (@ecma167{3,7.1,42}). + */ +typedef struct UDFEXTENTAD +{ + /** Extent length in bytes. */ + uint32_t cb; + /** Extent offset (logical sector number). + * If @a cb is zero, this is also zero. */ + uint32_t off; +} UDFEXTENTAD; +AssertCompileSize(UDFEXTENTAD, 8); +/** Pointer to an UDF extent descriptor. */ +typedef UDFEXTENTAD *PUDFEXTENTAD; +/** Pointer to a const UDF extent descriptor. */ +typedef UDFEXTENTAD const *PCUDFEXTENTAD; + + +/** + * UDF logical block address (@ecma167{4,7.1,73}). + */ +#pragma pack(2) +typedef struct UDFLBADDR +{ + /** Logical block number, relative to the start of the given partition. */ + uint32_t off; + /** Partition reference number. */ + uint16_t uPartitionNo; +} UDFLBADDR; +#pragma pack() +AssertCompileSize(UDFLBADDR, 6); +/** Pointer to an UDF logical block address. */ +typedef UDFLBADDR *PUDFLBADDR; +/** Pointer to a const UDF logical block address. */ +typedef UDFLBADDR const *PCUDFLBADDR; + + +/** @name UDF_AD_TYPE_XXX - Allocation descriptor types. + * + * Used by UDFSHORTAD::uType, UDFLONGAD::uType and UDFEXTAD::uType. + * + * See @ecma167{4,14.14.1.1,116}. + * + * @{ */ +/** Recorded and allocated. + * Also used for zero length descriptors. */ +#define UDF_AD_TYPE_RECORDED_AND_ALLOCATED 0 +/** Allocated but not recorded. */ +#define UDF_AD_TYPE_ONLY_ALLOCATED 1 +/** Not recorded nor allocated. */ +#define UDF_AD_TYPE_FREE 2 +/** Go figure. */ +#define UDF_AD_TYPE_NEXT 3 +/** @} */ + +/** + * UDF short allocation descriptor (@ecma167{4,14.14.1,116}). + */ +typedef struct UDFSHORTAD +{ +#ifdef RT_BIG_ENDIAN + /** Extent type (UDF_AD_TYPE_XXX). */ + uint32_t uType : 2; + /** Extent length in bytes, top 2 bits . */ + uint32_t cb : 30; +#else + /** Extent length in bytes. */ + uint32_t cb : 30; + /** Extent type (UDF_AD_TYPE_XXX). */ + uint32_t uType : 2; +#endif + /** Extent offset (logical sector number). */ + uint32_t off; +} UDFSHORTAD; +AssertCompileSize(UDFSHORTAD, 8); +/** Pointer to an UDF short allocation descriptor. */ +typedef UDFSHORTAD *PUDFSHORTAD; +/** Pointer to a const UDF short allocation descriptor. */ +typedef UDFSHORTAD const *PCUDFSHORTAD; + +/** + * UDF long allocation descriptor (@ecma167{4,14.14.2,116}). + */ +#pragma pack(2) +typedef struct UDFLONGAD +{ +#ifdef RT_BIG_ENDIAN + /** Extent type (UDF_AD_TYPE_XXX). */ + uint32_t uType : 2; + /** Extent length in bytes, top 2 bits . */ + uint32_t cb : 30; +#else + /** Extent length in bytes. */ + uint32_t cb : 30; + /** Extent type (UDF_AD_TYPE_XXX). */ + uint32_t uType : 2; +#endif + /** Extent location. */ + UDFLBADDR Location; + /** Implementation use area. */ + union + { + /** Generic view. */ + uint8_t ab[6]; + /** Used in FIDs. + * See @udf260{2.3.10.1,66}, @udf260{2.3.4.3,58}. + */ + struct + { + /** Flags (UDF_AD_IMP_USE_FLAGS_XXX). */ + uint16_t fFlags; + /** Unique ID. */ + uint32_t idUnique; + } Fid; + } ImplementationUse; +} UDFLONGAD; +#pragma pack() +AssertCompileSize(UDFLONGAD, 16); +/** Pointer to an UDF long allocation descriptor. */ +typedef UDFLONGAD *PUDFLONGAD; +/** Pointer to a const UDF long allocation descriptor. */ +typedef UDFLONGAD const *PCUDFLONGAD; + +/** @name UDF_AD_IMP_USE_FLAGS_XXX - UDFLONGAD::ImplementationUse::Fid::fFlags values + * See @udf260{2.3.10.1,66}. + * @{ */ +/** Set if erased and the extend is of the type UDF_AD_TYPE_ONLY_ALLOCATED. */ +#define UDF_AD_IMP_USE_FLAGS_ERASED UINT16_C(0x0001) +/** Valid mask. */ +#define UDF_AD_IMP_USE_FLAGS_VALID_MASK UINT16_C(0x0001) +/** @} */ + +/** + * UDF extended allocation descriptor (@ecma167{4,14.14.3,117}). + */ +typedef struct UDFEXTAD +{ +#ifdef RT_BIG_ENDIAN + /** 0x00: Extent type (UDF_AD_TYPE_XXX). */ + uint32_t uType : 2; + /** 0x00: Extent length in bytes, top 2 bits . */ + uint32_t cb : 30; + /** 0x04: Reserved, MBZ. */ + uint32_t uReserved : 2; + /** 0x04: Number of bytes recorded. */ + uint32_t cbRecorded : 30; +#else + /** 0x00: Extent length in bytes. */ + uint32_t cb : 30; + /** 0x00: Extent type (UDF_AD_TYPE_XXX). */ + uint32_t uType : 2; + /** 0x04: Number of bytes recorded. */ + uint32_t cbRecorded : 30; + /** 0x04: Reserved, MBZ. */ + uint32_t uReserved : 2; +#endif + /** 0x08: Number of bytes of information (from first byte). */ + uint32_t cbInformation; + /** 0x0c: Extent location. */ + UDFLBADDR Location; + /** 0x12: Implementation use area. */ + uint8_t abImplementationUse[2]; +} UDFEXTAD; +AssertCompileSize(UDFEXTAD, 20); +/** Pointer to an UDF extended allocation descriptor. */ +typedef UDFEXTAD *PUDFEXTAD; +/** Pointer to a const UDF extended allocation descriptor. */ +typedef UDFEXTAD const *PCUDFEXTAD; + + +/** + * UDF timestamp (@ecma167{1,7.3,25}, @udf260{2.1.4,19}). + */ +typedef struct UDFTIMESTAMP +{ +#ifdef RT_BIG_ENDIAN + /** 0x00: Type (UDFTIMESTAMP_T_XXX). */ + RT_GCC_EXTENSION uint16_t fType : 4; + /** 0x00: Time zone offset in minutes. + * For EST this will be -300, whereas for CET it will be 60. */ + RT_GCC_EXTENSION int16_t offUtcInMin : 12; +#else + /** 0x00: Time zone offset in minutes. + * For EST this will be -300, whereas for CET it will be 60. */ + RT_GCC_EXTENSION int16_t offUtcInMin : 12; + /** 0x00: Type (UDFTIMESTAMP_T_XXX). */ + RT_GCC_EXTENSION uint16_t fType : 4; +#endif + /** 0x02: The year. */ + int16_t iYear; + /** 0x04: Month of year (1-12). */ + uint8_t uMonth; + /** 0x05: Day of month (1-31). */ + uint8_t uDay; + /** 0x06: Hour of day (0-23). */ + uint8_t uHour; + /** 0x07: Minute of hour (0-59). */ + uint8_t uMinute; + /** 0x08: Second of minute (0-60 if type 2, otherwise 0-59). */ + uint8_t uSecond; + /** 0x09: Number of Centiseconds (0-99). */ + uint8_t cCentiseconds; + /** 0x0a: Number of hundreds of microseconds (0-99). Unit is 100us. */ + uint8_t cHundredsOfMicroseconds; + /** 0x0b: Number of microseconds (0-99). */ + uint8_t cMicroseconds; +} UDFTIMESTAMP; +AssertCompileSize(UDFTIMESTAMP, 12); +/** Pointer to an UDF timestamp. */ +typedef UDFTIMESTAMP *PUDFTIMESTAMP; +/** Pointer to a const UDF timestamp. */ +typedef UDFTIMESTAMP const *PCUDFTIMESTAMP; + +/** @name UDFTIMESTAMP_T_XXX + * @{ */ +/** Local time. */ +#define UDFTIMESTAMP_T_LOCAL 1 +/** @} */ + +/** No time zone specified. */ +#define UDFTIMESTAMP_NO_TIME_ZONE (-2047) + + +/** + * UDF character set specficiation (@ecma167{1,7.2.1,21}, @udf260{2.1.2,18}). + */ +typedef struct UDFCHARSPEC +{ + /** The character set type (UDF_CHAR_SET_TYPE_XXX) */ + uint8_t uType; + /** Character set information. */ + uint8_t abInfo[63]; +} UDFCHARSPEC; +AssertCompileSize(UDFCHARSPEC, 64); +/** Pointer to UDF character set specification. */ +typedef UDFCHARSPEC *PUDFCHARSPEC; +/** Pointer to const UDF character set specification. */ +typedef UDFCHARSPEC const *PCUDFCHARSPEC; + +/** @name UDF_CHAR_SET_TYPE_XXX - Character set types. + * @{ */ +/** CS0: By agreement between the medium producer and consumer. + * See UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE. */ +#define UDF_CHAR_SET_TYPE_BY_AGREEMENT UINT8_C(0x00) +/** CS1: ASCII (ECMA-6) with all or part of the specified graphic characters. */ +#define UDF_CHAR_SET_TYPE_ASCII UINT8_C(0x01) +/** CS5: Latin-1 (ECMA-94) with all graphical characters. */ +#define UDF_CHAR_SET_TYPE_LATIN_1 UINT8_C(0x05) +/* there are more defined here, but they are mostly useless, since UDF only uses CS0. */ + +/** The CS0 definition used by the UDF specification. */ +#define UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE UDF_CHAR_SET_TYPE_BY_AGREEMENT +/** String to put in the UDFCHARSEPC::abInfo field for UDF CS0. */ +#define UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO "OSTA Compressed Unicode" +/** @} */ + + +/** + * UDF entity identifier (@ecma167{1,7.4,26}, @udf260{2.1.5,20}). + */ +typedef struct UDFENTITYID +{ + /** 0x00: Flags (UDFENTITYID_FLAGS_XXX). */ + uint8_t fFlags; + /** 0x01: Identifier string (see UDF_ENTITY_ID_XXX). */ + char achIdentifier[23]; + /** 0x18: Identifier suffix. */ + union + { + /** Domain ID suffix. */ + struct + { + uint16_t uUdfRevision; + uint8_t fDomain; + uint8_t abReserved[5]; + } Domain; + + /** UDF ID suffix. */ + struct + { + uint16_t uUdfRevision; + uint8_t bOsClass; + uint8_t idOS; + uint8_t abReserved[4]; + } Udf; + + + /** Implementation ID suffix. */ + struct + { + uint8_t bOsClass; + uint8_t idOS; + uint8_t achImplUse[6]; + } Implementation; + + /** Application ID suffix / generic. */ + uint8_t abApplication[8]; + } Suffix; +} UDFENTITYID; +AssertCompileSize(UDFENTITYID, 32); +/** Pointer to UDF entity identifier. */ +typedef UDFENTITYID *PUDFENTITYID; +/** Pointer to const UDF entity identifier. */ +typedef UDFENTITYID const *PCUDFENTITYID; + +/** @name UDF_ENTITY_ID_XXX - UDF identifier strings + * + * See @udf260{2.1.5.2,21}. + * + * @{ */ +/** Implementation use volume descriptor, implementation ID field. + * UDF ID suffix. */ +#define UDF_ENTITY_ID_IUVD_IMPLEMENTATION "*UDF LV Info" + +/** Partition descriptor, partition contents field, set to indicate UDF + * (ECMA-167 3rd edition). Application ID suffix. */ +#define UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF "+NSR03" +/** Partition descriptor, partition contents field, set to indicate ISO-9660 + * (ECMA-119). Application ID suffix. */ +#define UDF_ENTITY_ID_PD_PARTITION_CONTENTS_ISO9660 "+CD001" +/** Partition descriptor, partition contents field, set to indicate ECMA-168. + * Application ID suffix. */ +#define UDF_ENTITY_ID_PD_PARTITION_CONTENTS_CDW "+CDW02" +/** Partition descriptor, partition contents field, set to indicate FAT + * (ECMA-107). Application ID suffix. */ +#define UDF_ENTITY_ID_PD_PARTITION_CONTENTS_FAT "+FDC01" + +/** Logical volume descriptor, domain ID field. + * Domain ID suffix. */ +#define UDF_ENTITY_ID_LVD_DOMAIN "*OSTA UDF Compliant" + +/** File set descriptor, domain ID field. + * Domain ID suffix. */ +#define UDF_ENTITY_FSD_LVD_DOMAIN "*OSTA UDF Compliant" + +/** UDF implementation use extended attribute, implementation ID field, set + * to free EA space. UDF ID suffix. */ +#define UDF_ENTITY_ID_IUEA_FREE_EA_SPACE "*UDF FreeEASpace" +/** UDF implementation use extended attribute, implementation ID field, set + * to DVD copyright management information. UDF ID suffix. */ +#define UDF_ENTITY_ID_IUEA_DVD_CGMS_INFO "*UDF DVD CGMS Info" +/** UDF implementation use extended attribute, implementation ID field, set + * to OS/2 extended attribute length. UDF ID suffix. */ +#define UDF_ENTITY_ID_IUEA_OS2_EA_LENGTH "*UDF OS/2 EALength" +/** UDF implementation use extended attribute, implementation ID field, set + * to Machintosh OS volume information. UDF ID suffix. */ +#define UDF_ENTITY_ID_IUEA_MAC_VOLUME_INFO "*UDF Mac VolumeInfo" +/** UDF implementation use extended attribute, implementation ID field, set + * to Machintosh Finder Info. UDF ID suffix. */ +#define UDF_ENTITY_ID_IUEA_MAC_FINDER_INFO "*UDF Mac FinderInfo" +/** UDF implementation use extended attribute, implementation ID field, set + * to OS/400 extended directory information. UDF ID suffix. */ +#define UDF_ENTITY_ID_IUEA_OS400_DIR_INFO "*UDF OS/400 DirInfo" + +/** UDF application use extended attribute, application ID field, set + * to free application use EA space. UDF ID suffix. */ +#define UDF_ENTITY_ID_AUEA_FREE_EA_SPACE "*UDF FreeAppEASpace" + +/** Virtual partition map, partition type field. + * UDF ID suffix. */ +#define UDF_ENTITY_ID_VPM_PARTITION_TYPE "*UDF Virtual Partition" + +/** Sparable partition map, partition type field. + * UDF ID suffix. */ +#define UDF_ENTITY_ID_SPM_PARTITION_TYPE "*UDF Sparable Partition" + +/** Metadata partition map, partition type field. + * UDF ID suffix. */ +#define UDF_ENTITY_ID_MPM_PARTITION_TYPE "*UDF Metadata Partition" + +/** Sparing table, sparing identifier field. + * UDF ID suffix. */ +#define UDF_ENTITY_ID_ST_SPARING "*UDF Sparting Table" + +/** @} */ + + +/** + * UDF descriptor tag (@ecma167{3,7.2,42}, @udf260{2.2.1,26}). + */ +typedef struct UDFTAG +{ + /** Tag identifier (UDF_TAG_ID_XXX). */ + uint16_t idTag; + /** Descriptor version. */ + uint16_t uVersion; + /** Tag checksum. + * Sum of each byte in the structure with this field as zero. */ + uint8_t uChecksum; + /** Reserved, MBZ. */ + uint8_t bReserved; + /** Tag serial number. */ + uint16_t uTagSerialNo; + /** Descriptor CRC. */ + uint16_t uDescriptorCrc; + /** Descriptor CRC length. */ + uint16_t cbDescriptorCrc; + /** The tag location (logical sector number). */ + uint32_t offTag; +} UDFTAG; +AssertCompileSize(UDFTAG, 16); +/** Pointer to an UDF descriptor tag. */ +typedef UDFTAG *PUDFTAG; +/** Pointer to a const UDF descriptor tag. */ +typedef UDFTAG const *PCUDFTAG; + +/** @name UDF_TAG_ID_XXX - UDF descriptor tag IDs. + * @{ */ +#define UDF_TAG_ID_PRIMARY_VOL_DESC UINT16_C(0x0001) /**< See UDFPRIMARYVOLUMEDESC */ +#define UDF_TAG_ID_ANCHOR_VOLUME_DESC_PTR UINT16_C(0x0002) /**< See UDFANCHORVOLUMEDESCPTR */ +#define UDF_TAG_ID_VOLUME_DESC_PTR UINT16_C(0x0003) /**< See UDFVOLUMEDESCPTR */ +#define UDF_TAG_ID_IMPLEMENTATION_USE_VOLUME_DESC UINT16_C(0x0004) /**< See UDFIMPLEMENTATIONUSEVOLUMEDESC */ +#define UDF_TAG_ID_PARTITION_DESC UINT16_C(0x0005) /**< See UDFPARTITIONDESC */ +#define UDF_TAG_ID_LOGICAL_VOLUME_DESC UINT16_C(0x0006) /**< See UDFLOGICALVOLUMEDESC */ +#define UDF_TAG_ID_UNALLOCATED_SPACE_DESC UINT16_C(0x0007) /**< See UDFUNALLOCATEDSPACEDESC */ +#define UDF_TAG_ID_TERMINATING_DESC UINT16_C(0x0008) /**< See UDFTERMINATINGDESC */ +#define UDF_TAG_ID_LOGICAL_VOLUME_INTEGRITY_DESC UINT16_C(0x0009) /**< See UDFLOGICALVOLINTEGRITYDESC */ +#define UDF_TAG_ID_FILE_SET_DESC UINT16_C(0x0100) /**< See UDFFILESETDESC */ +#define UDF_TAG_ID_FILE_ID_DESC UINT16_C(0x0101) /**< See UDFFILEIDDESC */ +#define UDF_TAG_ID_ALLOCATION_EXTENT_DESC UINT16_C(0x0102) /**< See UDFALLOCATIONEXTENTDESC */ +#define UDF_TAG_ID_INDIRECT_ENTRY UINT16_C(0x0103) /**< See UDFINDIRECTENTRY */ +#define UDF_TAG_ID_TERMINAL_ENTRY UINT16_C(0x0104) /**< See UDFTERMINALENTRY */ +#define UDF_TAG_ID_FILE_ENTRY UINT16_C(0x0105) /**< See UDFFILEENTRY */ +#define UDF_TAG_ID_EXTENDED_ATTRIB_HDR_DESC UINT16_C(0x0106) /**< See UDFEXTATTRIBHDRDESC */ +#define UDF_TAG_ID_UNALLOCATED_SPACE_ENTRY UINT16_C(0x0107) /**< See UDFUNALLOCATEDSPACEENTRY */ +#define UDF_TAG_ID_SPACE_BITMAP_DESC UINT16_C(0x0108) /**< See UDFSPACEBITMAPDESC */ +#define UDF_TAG_ID_PARTITION_INTEGERITY_DESC UINT16_C(0x0109) /**< See UDFPARTITIONINTEGRITYDESC */ +#define UDF_TAG_ID_EXTENDED_FILE_ENTRY UINT16_C(0x010a) /**< See UDFEXFILEENTRY */ +/** @} */ + + +/** + * UDF primary volume descriptor (PVD) (@ecma167{3,10.1,50}, + * @udf260{2.2.2,27}). + */ +typedef struct UDFPRIMARYVOLUMEDESC +{ + /** 0x000: The descriptor tag (UDF_TAG_ID_PRIMARY_VOL_DESC). */ + UDFTAG Tag; + /** 0x010: Volume descriptor sequence number. */ + uint32_t uVolumeDescSeqNo; + /** 0x014: Primary volume descriptor number. */ + uint32_t uPrimaryVolumeDescNo; + /** 0x018: Volume identifier (dstring). */ + UDFDSTRING achVolumeID[32]; + /** 0x038: Volume sequence number. */ + uint16_t uVolumeSeqNo; + /** 0x03a: Maximum volume sequence number. */ + uint16_t uMaxVolumeSeqNo; + /** 0x03c: Interchange level. */ + uint16_t uInterchangeLevel; + /** 0x03e: Maximum interchange level. */ + uint16_t uMaxInterchangeLevel; + /** 0x040: Character set bitmask (aka list). Each bit correspond to a + * character set number. */ + uint32_t fCharacterSets; + /** 0x044: Maximum character set bitmask (aka list). */ + uint32_t fMaxCharacterSets; + /** 0x048: Volume set identifier (dstring). This starts with 16 unique + * characters, the first 8 being the hex representation of a time value. */ + UDFDSTRING achVolumeSetID[128]; + /** 0x0c8: Descriptor character set. + * For achVolumeSetID and achVolumeID. */ + UDFCHARSPEC DescCharSet; + /** 0x108: Explanatory character set. + * For VolumeAbstract and VolumeCopyrightNotice data. */ + UDFCHARSPEC ExplanatoryCharSet; + /** 0x148: Volume abstract. */ + UDFEXTENTAD VolumeAbstract; + /** 0x150: Volume copyright notice. */ + UDFEXTENTAD VolumeCopyrightNotice; + /** 0x158: Application identifier ("*Application ID"). */ + UDFENTITYID idApplication; + /** 0x178: Recording date and time. */ + UDFTIMESTAMP RecordingTimestamp; + /** 0x184: Implementation identifier ("*Developer ID"). */ + UDFENTITYID idImplementation; + /** 0x1a4: Implementation use. */ + uint8_t abImplementationUse[64]; + /** 0x1e4: Predecessor volume descriptor sequence location. */ + uint32_t offPredecessorVolDescSeq; + /** 0x1e8: Flags (UDF_PVD_FLAGS_XXX). */ + uint16_t fFlags; + /** 0x1ea: Reserved. */ + uint8_t abReserved[22]; +} UDFPRIMARYVOLUMEDESC; +AssertCompileSize(UDFPRIMARYVOLUMEDESC, 512); +/** Pointer to a UDF primary volume descriptor. */ +typedef UDFPRIMARYVOLUMEDESC *PUDFPRIMARYVOLUMEDESC; +/** Pointer to a const UDF primary volume descriptor. */ +typedef UDFPRIMARYVOLUMEDESC const *PCUDFPRIMARYVOLUMEDESC; + +/** @name UDF_PVD_FLAGS_XXX - Flags for UDFPRIMARYVOLUMEDESC::fFlags. + * @{ */ +/** Indicates that the volume set ID is common to all members of the set. */ +#define UDF_PVD_FLAGS_COMMON_VOLUME_SET_ID UINT16_C(0x0001) +/** @} */ + + +/** + * UDF anchor volume descriptor pointer (AVDP) (@ecma167{3,10.2,53}, + * @udf260{2.2.3,29}). + * + * This is stored at least two of these locations: + * - logical sector 256 + * - logical sector N - 256. + * - logical sector N. + */ +typedef struct UDFANCHORVOLUMEDESCPTR +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_ANCHOR_VOLUME_DESC_PTR). */ + UDFTAG Tag; + /** 0x10: The extent descripting the main volume descriptor sequence. */ + UDFEXTENTAD MainVolumeDescSeq; + /** 0x18: Location of the backup descriptor sequence. */ + UDFEXTENTAD ReserveVolumeDescSeq; + /** 0x20: Reserved, probably must be zeros. */ + uint8_t abReserved[0x1e0]; +} UDFANCHORVOLUMEDESCPTR; +AssertCompileSize(UDFANCHORVOLUMEDESCPTR, 512); +/** Pointer to UDF anchor volume descriptor pointer. */ +typedef UDFANCHORVOLUMEDESCPTR *PUDFANCHORVOLUMEDESCPTR; +/** Pointer to const UDF anchor volume descriptor pointer. */ +typedef UDFANCHORVOLUMEDESCPTR const *PCUDFANCHORVOLUMEDESCPTR; + + +/** + * UDF volume descriptor pointer (VDP) (@ecma167{3,10.3,53}). + */ +typedef struct UDFVOLUMEDESCPTR +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_VOLUME_DESC_PTR). */ + UDFTAG Tag; + /** 0x10: Volume descriptor sequence number. */ + uint32_t uVolumeDescSeqNo; + /** 0x14: Location of the next volume descriptor sequence. */ + UDFEXTENTAD NextVolumeDescSeq; + /** 0x1c: Reserved, probably must be zeros. */ + uint8_t abReserved[484]; +} UDFVOLUMEDESCPTR; +AssertCompileSize(UDFVOLUMEDESCPTR, 512); +/** Pointer to UDF volume descriptor pointer. */ +typedef UDFVOLUMEDESCPTR *PUDFVOLUMEDESCPTR; +/** Pointer to const UDF volume descriptor pointer. */ +typedef UDFVOLUMEDESCPTR const *PCUDFVOLUMEDESCPTR; + + +/** + * UDF implementation use volume descriptor (IUVD) (@ecma167{3,10.4,55}, + * @udf260{2.2.7,35}). + */ +typedef struct UDFIMPLEMENTATIONUSEVOLUMEDESC +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_IMPLEMENTATION_USE_VOLUME_DESC). */ + UDFTAG Tag; + /** 0x10: Volume descriptor sequence number. */ + uint32_t uVolumeDescSeqNo; + /** 0x14: The implementation identifier (UDF_ENTITY_ID_IUVD_IMPLEMENTATION). */ + UDFENTITYID idImplementation; + /** 0x34: The implementation use area. */ + union + { + /** Generic view. */ + uint8_t ab[460]; + /** Logical volume information (@udf260{2.2.7.2,35}). */ + struct + { + /** 0x034: The character set used in this sub-structure. */ + UDFCHARSPEC Charset; + /** 0x074: Logical volume identifier. */ + UDFDSTRING achVolumeID[128]; + /** 0x0f4: Info string \#1. */ + UDFDSTRING achInfo1[36]; + /** 0x118: Info string \#2. */ + UDFDSTRING achInfo2[36]; + /** 0x13c: Info string \#3. */ + UDFDSTRING achInfo3[36]; + /** 0x160: The implementation identifier ("*Developer ID"). */ + UDFENTITYID idImplementation; + /** 0x180: Additional use bytes. */ + uint8_t abUse[128]; + } Lvi; + } ImplementationUse; +} UDFIMPLEMENTATIONUSEVOLUMEDESC; +AssertCompileSize(UDFIMPLEMENTATIONUSEVOLUMEDESC, 512); +AssertCompileMemberOffset(UDFIMPLEMENTATIONUSEVOLUMEDESC, ImplementationUse.Lvi.Charset, 0x034); +AssertCompileMemberOffset(UDFIMPLEMENTATIONUSEVOLUMEDESC, ImplementationUse.Lvi.achVolumeID, 0x074); +AssertCompileMemberOffset(UDFIMPLEMENTATIONUSEVOLUMEDESC, ImplementationUse.Lvi.achInfo1, 0x0f4); +AssertCompileMemberOffset(UDFIMPLEMENTATIONUSEVOLUMEDESC, ImplementationUse.Lvi.achInfo2, 0x118); +AssertCompileMemberOffset(UDFIMPLEMENTATIONUSEVOLUMEDESC, ImplementationUse.Lvi.achInfo3, 0x13c); +AssertCompileMemberOffset(UDFIMPLEMENTATIONUSEVOLUMEDESC, ImplementationUse.Lvi.idImplementation, 0x160); +/** Pointer to an UDF implementation use volume descriptor. */ +typedef UDFIMPLEMENTATIONUSEVOLUMEDESC *PUDFIMPLEMENTATIONUSEVOLUMEDESC; +/** Pointer to a const UDF implementation use volume descriptor. */ +typedef UDFIMPLEMENTATIONUSEVOLUMEDESC const *PCUDFIMPLEMENTATIONUSEVOLUMEDESC; + + +/** + * UDF partition header descriptor (@ecma167{4,14.3,90}, @udf260{2.3.3,56}). + * + * This is found in UDFPARTITIONDESC::ContentsUse. + */ +typedef struct UDFPARTITIONHDRDESC +{ + /** 0x00: Unallocated space table location. Zero length means no table. */ + UDFSHORTAD UnallocatedSpaceTable; + /** 0x08: Unallocated space bitmap location. Zero length means no bitmap. */ + UDFSHORTAD UnallocatedSpaceBitmap; + /** 0x10: Partition integrity table location. Zero length means no table. */ + UDFSHORTAD PartitionIntegrityTable; + /** 0x18: Freed space table location. Zero length means no table. */ + UDFSHORTAD FreedSpaceTable; + /** 0x20: Freed space bitmap location. Zero length means no bitmap. */ + UDFSHORTAD FreedSpaceBitmap; + /** 0x28: Reserved, MBZ. */ + uint8_t abReserved[88]; +} UDFPARTITIONHDRDESC; +AssertCompileSize(UDFPARTITIONHDRDESC, 128); +AssertCompileMemberOffset(UDFPARTITIONHDRDESC, PartitionIntegrityTable, 0x10); +AssertCompileMemberOffset(UDFPARTITIONHDRDESC, abReserved, 0x28); +/** Pointer to an UDF partition header descriptor. */ +typedef UDFPARTITIONHDRDESC *PUDFPARTITIONHDRDESC; +/** Pointer to a const UDF partition header descriptor. */ +typedef UDFPARTITIONHDRDESC const *PCUDFPARTITIONHDRDESC; + + +/** + * UDF partition descriptor (PD) (@ecma167{3,10.5,55}, @udf260{2.2.14,51}). + */ +typedef struct UDFPARTITIONDESC +{ + /** 0x000: The descriptor tag (UDF_TAG_ID_PARTITION_DESC). */ + UDFTAG Tag; + /** 0x010: Volume descriptor sequence number. */ + uint32_t uVolumeDescSeqNo; + /** 0x014: The partition flags (UDF_PARTITION_FLAGS_XXX). */ + uint16_t fFlags; + /** 0x016: The partition number. */ + uint16_t uPartitionNo; + /** 0x018: Partition contents (UDF_ENTITY_ID_PD_PARTITION_CONTENTS_XXX). */ + UDFENTITYID PartitionContents; + /** 0x038: partition contents use (depends on the PartitionContents field). */ + union + { + /** Generic view. */ + uint8_t ab[128]; + /** UDF partition header descriptor (UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF). */ + UDFPARTITIONHDRDESC Hdr; + } ContentsUse; + /** 0x0b8: Access type (UDF_PART_ACCESS_TYPE_XXX). */ + uint32_t uAccessType; + /** 0x0bc: Partition starting location (logical sector number). */ + uint32_t offLocation; + /** 0x0c0: Partition length in sectors. */ + uint32_t cSectors; + /** 0x0c4: Implementation identifier ("*Developer ID"). */ + UDFENTITYID idImplementation; + /** 0x0e4: Implementation use bytes. */ + union + { + /** Generic view. */ + uint8_t ab[128]; + } ImplementationUse; + /** 0x164: Reserved. */ + uint8_t abReserved[156]; +} UDFPARTITIONDESC; +AssertCompileSize(UDFPARTITIONDESC, 512); +/** Pointer to an UDF partitions descriptor. */ +typedef UDFPARTITIONDESC *PUDFPARTITIONDESC; +/** Pointer to a const UDF partitions descriptor. */ +typedef const UDFPARTITIONDESC *PCUDFPARTITIONDESC; + +/** @name UDF_PART_ACCESS_TYPE_XXX - UDF partition access types + * + * See @ecma167{3,10.5.7,57}, @udf260{2.2.14.2,51}. + * + * @{ */ +/** Access not specified by this field. */ +#define UDF_PART_ACCESS_TYPE_NOT_SPECIFIED UINT32_C(0x00000000) +/** Read only: No writes. */ +#define UDF_PART_ACCESS_TYPE_READ_ONLY UINT32_C(0x00000001) +/** Write once: Sectors can only be written once. */ +#define UDF_PART_ACCESS_TYPE_WRITE_ONCE UINT32_C(0x00000002) +/** Rewritable: Logical sectors may require preprocessing before writing. */ +#define UDF_PART_ACCESS_TYPE_REWRITABLE UINT32_C(0x00000003) +/** Overwritable: No restrictions on writing. */ +#define UDF_PART_ACCESS_TYPE_OVERWRITABLE UINT32_C(0x00000004) +/** @} */ + + +/** + * Logical volume descriptor (LVD) (@ecma167{3,10.6,58}, @udf260{2.2.4,30}). + * + * @note Variable length. + */ +typedef struct UDFLOGICALVOLUMEDESC +{ + /** 0x000: The descriptor tag (UDF_TAG_ID_LOGICAL_VOLUME_DESC). */ + UDFTAG Tag; + /** 0x010: Volume descriptor sequence number. */ + uint32_t uVolumeDescSeqNo; + /** 0x014: Character set used in the achLogicalVolumeID field. */ + UDFCHARSPEC DescCharSet; + /** 0x054: The logical volume ID (label). */ + UDFDSTRING achLogicalVolumeID[128]; + /** 0x0d4: Logical block size (in bytes). */ + uint32_t cbLogicalBlock; + /** 0x0d8: Domain identifier (UDF_ENTITY_ID_LVD_DOMAIN). */ + UDFENTITYID idDomain; + /** 0x0f8: Logical volume contents use. */ + union + { + /** Byte view. */ + uint8_t ab[16]; + /** The extent containing the file set descriptor. */ + UDFLONGAD FileSetDescriptor; + } ContentsUse; + /** 0x108: Map table length (in bytes). */ + uint32_t cbMapTable; + /** 0x10c: Number of partition maps. */ + uint32_t cPartitionMaps; + /** 0x110: Implementation identifier ("*Developer ID"). */ + UDFENTITYID idImplementation; + /** 0x130: Implementation use. */ + union + { + /** Byte view. */ + uint8_t ab[128]; + } ImplementationUse; + /** 0x1b0: Integrity sequence extent. Can be zero if cPartitionMaps is zero. */ + UDFEXTENTAD IntegritySeqExtent; + /** 0x1b8: Partition maps (length given by @a cbMapTable), data format is + * defined by UDFPARTMAPHDR, UDFPARTMAPTYPE1 and UDFPARTMAPTYPE2. */ + RT_FLEXIBLE_ARRAY_EXTENSION + uint8_t abPartitionMaps[RT_FLEXIBLE_ARRAY]; +} UDFLOGICALVOLUMEDESC; +AssertCompileMemberOffset(UDFLOGICALVOLUMEDESC, abPartitionMaps, 0x1b8); +/** Pointer to an UDF logical volume descriptor. */ +typedef UDFLOGICALVOLUMEDESC *PUDFLOGICALVOLUMEDESC; +/** Pointer to a const UDF logical volume descriptor. */ +typedef UDFLOGICALVOLUMEDESC const *PCUDFLOGICALVOLUMEDESC; + +/** + * Partition map header (UDFLOGICALVOLUMEDESC::abPartitionMaps). + */ +typedef struct UDFPARTMAPHDR +{ + /** 0x00: The partition map type. */ + uint8_t bType; + /** 0x01: The partition map length (header included). */ + uint8_t cb; +} UDFPARTMAPHDR; +AssertCompileSize(UDFPARTMAPHDR, 2); +/** Pointer to a partition map header. */ +typedef UDFPARTMAPHDR *PUDFPARTMAPHDR; +/** Pointer to a const partition map header. */ +typedef UDFPARTMAPHDR const *PCUDFPARTMAPHDR; + +/** + * Partition map type 1 (UDFLOGICALVOLUMEDESC::abPartitionMaps). + */ +typedef struct UDFPARTMAPTYPE1 +{ + /** 0x00: Header (uType=1, cb=6). */ + UDFPARTMAPHDR Hdr; + /** 0x02: Volume sequence number. */ + uint16_t uVolumeSeqNo; + /** 0x04: Partition number. */ + uint16_t uPartitionNo; +} UDFPARTMAPTYPE1; +AssertCompileSize(UDFPARTMAPTYPE1, 6); +/** Pointer to a type 1 partition map. */ +typedef UDFPARTMAPTYPE1 *PUDFPARTMAPTYPE1; +/** Pointer to a const type 1 partition map. */ +typedef UDFPARTMAPTYPE1 const *PCUDFPARTMAPTYPE1; + +/** + * Partition map type 2 (UDFLOGICALVOLUMEDESC::abPartitionMaps). + */ +typedef struct UDFPARTMAPTYPE2 +{ + /** 0x00: Header (uType=2, cb=64). */ + UDFPARTMAPHDR Hdr; + /** 0x02: Reserved \#1. */ + uint16_t uReserved1; + /** 0x04: Partition ID type (UDF_ENTITY_ID_VPM_PARTITION_TYPE, + * UDF_ENTITY_ID_SPM_PARTITION_TYPE, or UDF_ENTITY_ID_MPM_PARTITION_TYPE). */ + UDFENTITYID idPartitionType; + /** 0x24: Volume sequence number. */ + uint16_t uVolumeSeqNo; + /** 0x26: Partition number. */ + uint16_t uPartitionNo; + /** 0x28: Data specific to the partition ID type. */ + union + { + /** 0x28: Generic view. */ + uint8_t ab[24]; + + /** UDF_ENTITY_ID_VPM_PARTITION_TYPE. */ + struct + { + /** 0x28: Reserved. */ + uint8_t abReserved2[24]; + } Vpm; + + /** UDF_ENTITY_ID_SPM_PARTITION_TYPE. */ + struct + { + /** 0x28: Packet length in blocks. */ + uint16_t cBlocksPerPacket; + /** 0x2a: Number of sparing tables. */ + uint8_t cSparingTables; + /** 0x2b: Reserved padding byte. */ + uint8_t bReserved2; + /** 0x2c: The size of each sparing table. */ + uint32_t cbSparingTable; + /** 0x30: The sparing table locations (logical block). */ + uint32_t aoffSparingTables[4]; + } Spm; + + /** UDF_ENTITY_ID_MPM_PARTITION_TYPE. */ + struct + { + /** 0x28: Metadata file entry location (logical block). */ + uint32_t offMetadataFile; + /** 0x2c: Metadata mirror file entry location (logical block). */ + uint32_t offMetadataMirrorFile; + /** 0x30: Metadata bitmap file entry location (logical block). */ + uint32_t offMetadataBitmapFile; + /** 0x34: The metadata allocation unit (logical blocks) */ + uint32_t cBlocksAllocationUnit; + /** 0x38: The metadata allocation unit alignment (logical blocks). */ + uint16_t cBlocksAlignmentUnit; + /** 0x3a: Flags, UDFPARTMAPMETADATA_F_XXX. */ + uint8_t fFlags; + /** 0x3b: Reserved. */ + uint8_t abReserved2[5]; + } Mpm; + } u; +} UDFPARTMAPTYPE2; +AssertCompileSize(UDFPARTMAPTYPE2, 64); +/** Pointer to a type 2 partition map. */ +typedef UDFPARTMAPTYPE2 *PUDFPARTMAPTYPE2; +/** Pointer to a const type 2 partition map. */ +typedef UDFPARTMAPTYPE2 const *PCUDFPARTMAPTYPE2; + +/** @name UDFPARTMAPMETADATA_F_XXX + * @{ */ +/** Indicates that the metadata is mirrored too, not just the file entry. */ +#define UDFPARTMAPMETADATA_F_DATA_MIRRORED UINT8_C(1) +/** @} */ + + +/** + * UDF unallocated space descriptor (USD) (@ecma167{3,10.8,61}, @udf260{2.2.5,32}). + * + * @note Variable length. + */ +typedef struct UDFUNALLOCATEDSPACEDESC +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_UNALLOCATED_SPACE_DESC). */ + UDFTAG Tag; + /** 0x10: Volume descriptor sequence number. */ + uint32_t uVolumeDescSeqNo; + /** 0x14: Number of allocation descriptors in the array below. */ + uint32_t cAllocationDescriptors; + /** 0x18: Allocation descriptors (variable length). */ + RT_FLEXIBLE_ARRAY_EXTENSION + UDFEXTENTAD aAllocationDescriptors[RT_FLEXIBLE_ARRAY]; +} UDFUNALLOCATEDSPACEDESC; +AssertCompileMemberOffset(UDFUNALLOCATEDSPACEDESC, aAllocationDescriptors, 0x18); +/** Pointer to an UDF unallocated space descriptor. */ +typedef UDFUNALLOCATEDSPACEDESC *PUDFUNALLOCATEDSPACEDESC; +/** Pointer to a const UDF unallocated space descriptor. */ +typedef UDFUNALLOCATEDSPACEDESC const *PCUDFUNALLOCATEDSPACEDESC; + + +/** + * UDF terminating descriptor (@ecma167{3,10.9,62}, @ecma167{4,14.2,62}). + */ +typedef struct UDFTERMINATINGDESC +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_TERMINATING_DESC). */ + UDFTAG Tag; + /** 0x10: Reserved, MBZ. */ + uint8_t abReserved[496]; +} UDFTERMINATINGDESC; +/** Pointer to an UDF terminating descriptor. */ +typedef UDFTERMINATINGDESC *PUDFTERMINATINGDESC; +/** Pointer to a const UDF terminating descriptor. */ +typedef UDFTERMINATINGDESC const *PCUDFTERMINATINGDESC; + + +/** + * UDF logical volume integrity descriptor (LVID) (@ecma167{3,10.10,62}, + * @udf260{2.2.6,32}). + */ +typedef struct UDFLOGICALVOLINTEGRITYDESC +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_TERMINATING_DESC). */ + UDFTAG Tag; + /** 0x10: Recording timestamp. */ + UDFTIMESTAMP RecordingTimestamp; + /** 0x1c: Integrity type (UDF_LVID_TYPE_XXX). */ + uint32_t uIntegrityType; + /** 0x20: The next integrity extent. */ + UDFEXTENTAD NextIntegrityExtent; + /** 0x28: Number of partitions. */ + uint32_t cPartitions; + /** 0x2c: Length of implementation use. */ + uint32_t cbImplementationUse; + /** + * There are two tables each @a cPartitions in size. The first is the free + * space table. The second the size table. + * + * Following these tables there are @a cbImplementationUse bytes of space for + * the implementation to use. + */ + RT_FLEXIBLE_ARRAY_EXTENSION + uint32_t aTables[RT_FLEXIBLE_ARRAY]; +} UDFLOGICALVOLINTEGRITYDESC; +AssertCompileMemberOffset(UDFLOGICALVOLINTEGRITYDESC, cbImplementationUse, 0x2c); +AssertCompileMemberOffset(UDFLOGICALVOLINTEGRITYDESC, aTables, 0x30); +/** Pointer to an UDF logical volume integrity descriptor. */ +typedef UDFLOGICALVOLINTEGRITYDESC *PUDFLOGICALVOLINTEGRITYDESC; +/** Pointer to a const UDF logical volume integrity descriptor. */ +typedef UDFLOGICALVOLINTEGRITYDESC const *PCUDFLOGICALVOLINTEGRITYDESC; + +/** @name UDF_LVID_TYPE_XXX - Integirty types. + * @{ */ +#define UDF_LVID_TYPE_OPEN UINT32_C(0x00000000) +#define UDF_LVID_TYPE_CLOSE UINT32_C(0x00000001) +/** @} */ + +/** + * UDF file set descriptor (FSD) (@ecma167{4,14.1,86}, @udf260{2.3.2,54}). + */ +typedef struct UDFFILESETDESC +{ + /** 0x000: The descriptor tag (UDF_TAG_ID_FILE_SET_DESC). */ + UDFTAG Tag; + /** 0x010: Recording timestamp. */ + UDFTIMESTAMP RecordingTimestamp; + /** 0x01c: Interchange level. */ + uint16_t uInterchangeLevel; + /** 0x01e: Maximum interchange level. */ + uint16_t uMaxInterchangeLevel; + /** 0x020: Character set bitmask (aka list). Each bit correspond to a + * character set number. */ + uint32_t fCharacterSets; + /** 0x024: Maximum character set bitmask (aka list). */ + uint32_t fMaxCharacterSets; + /** 0x028: File set number. */ + uint32_t uFileSetNo; + /** 0x02c: File set descriptor number. */ + uint32_t uFileSetDescNo; + /** 0x030: Logical volume identifier character set. */ + UDFCHARSPEC LogicalVolumeIDCharSet; + /** 0x070: Logical volume identifier string. */ + UDFDSTRING achLogicalVolumeID[128]; + /** 0x0e0: File set character set. */ + UDFCHARSPEC FileSetCharSet; + /** 0x130: Identifier string for this file set. */ + UDFDSTRING achFileSetID[32]; + /** 0x150: Names a root file containing copyright info. Optional. */ + UDFDSTRING achCopyrightFile[32]; + /** 0x170: Names a root file containing an abstract for the file set. Optional. */ + UDFDSTRING achAbstractFile[32]; + /** 0x190: Root directory information control block location (ICB). + * An ICB is a sequence made up of UDF_TAG_ID_FILE_ENTRY, + * UDF_TAG_ID_INDIRECT_ENTRY, and UDF_TAG_ID_TERMINAL_ENTRY descriptors. */ + UDFLONGAD RootDirIcb; + /** 0x1a0: Domain identifier (UDF_ENTITY_FSD_LVD_DOMAIN). Optional. */ + UDFENTITYID idDomain; + /** 0x1c0: Next location with file set descriptors location, 0 if none. */ + UDFLONGAD NextExtent; + /** 0x1d0: Location of the system stream directory associated with the + * file set. Optional. */ + UDFLONGAD SystemStreamDirIcb; + /** 0x1e0: Reserved, MBZ. */ + uint8_t abReserved[32]; +} UDFFILESETDESC; +AssertCompileSize(UDFFILESETDESC, 512); +/** Pointer to an UDF file set descriptor. */ +typedef UDFFILESETDESC *PUDFFILESETDESC; +/** Pointer to a const UDF file set descriptor. */ +typedef UDFFILESETDESC const *PCUDFFILESETDESC; + + +/** + * UDF file identifier descriptor (FID) (@ecma167{4,14.4,91}, @udf260{2.3.4,57}). + */ +typedef struct UDFFILEIDDESC +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_FILE_ID_DESC). */ + UDFTAG Tag; + /** 0x10: File version number (1..32767). Always set to 1. */ + uint16_t uVersion; + /** 0x12: File characteristics (UDF_FILE_FLAGS_XXX). */ + uint8_t fFlags; + /** 0x13: File identifier (name) length. */ + uint8_t cbName; + /** 0x14: Location of an information control block describing the file. + * Can be null if marked deleted. The implementation defined part of + * this contains additional flags and a unique ID. */ + UDFLONGAD Icb; + /** 0x24: Length of implementation use field (in bytes). This can be zero. + * + * It can be used to prevent the following FID from spanning a block + * boundrary, in which case it will be 32 bytes or more, and the it will + * start with an UDFENTITYID identifying who last wrote it. + * + * The latter padding fun is a requirement from write-once media. */ + uint16_t cbImplementationUse; + /** 0x26: Two variable sized fields followed by padding to make the + * actual structure size 4 byte aligned. The first field in an + * implementation use field with length given by @a cbImplementationUse. + * After that is a d-string field with the name of the file, length + * specified by @a cbName. */ + RT_FLEXIBLE_ARRAY_EXTENSION + uint8_t abImplementationUse[RT_FLEXIBLE_ARRAY]; +} UDFFILEIDDESC; +AssertCompileMemberOffset(UDFFILEIDDESC, fFlags, 0x12); +AssertCompileMemberOffset(UDFFILEIDDESC, cbName, 0x13); +AssertCompileMemberOffset(UDFFILEIDDESC, Icb, 0x14); +AssertCompileMemberOffset(UDFFILEIDDESC, abImplementationUse, 0x26); +/** Pointer to an UDF file set descriptor */ +typedef UDFFILEIDDESC *PUDFFILEIDDESC; +/** Pointer to a const UDF file set descriptor */ +typedef UDFFILEIDDESC const *PCUDFFILEIDDESC; + +/** Get the pointer to the name field. */ +#define UDFFILEIDDESC_2_NAME(a_pFid) ((uint8_t const *)(&(a_pFid)->abImplementationUse[(a_pFid)->cbImplementationUse])) +/** Calculates the total size the size of a record. */ +#define UDFFILEIDDESC_CALC_SIZE_EX(cbImplementationUse, cbName) \ + RT_ALIGN_32((uint32_t)RT_UOFFSETOF(UDFFILEIDDESC, abImplementationUse) + cbImplementationUse + cbName, 4) +/** Gets the actual size of a record. */ +#define UDFFILEIDDESC_GET_SIZE(a_pFid) UDFFILEIDDESC_CALC_SIZE_EX((a_pFid)->cbImplementationUse, (a_pFid)->cbName) + +/** @name UDF_FILE_FLAGS_XXX + * @{ */ +/** Existence - Hide the file from the user. */ +#define UDF_FILE_FLAGS_HIDDEN UINT8_C(0x01) +/** Directory - Indicates a directory as apposed to some kind of file or symlink or something (0). */ +#define UDF_FILE_FLAGS_DIRECTORY UINT8_C(0x02) +/** Deleted - Indicate that the file has been deleted. Assoicated descriptors may still be valid, though. */ +#define UDF_FILE_FLAGS_DELETED UINT8_C(0x04) +/** Parent - Indicate the ICB field refers to the parent directory (or maybe + * a file in case of streaming directory). */ +#define UDF_FILE_FLAGS_PARENT UINT8_C(0x08) +/** Metadata - Zero means user data, one means implementation specific metadata. + * Only allowed used in stream directory. */ +#define UDF_FILE_FLAGS_METADATA UINT8_C(0x10) +/** Reserved bits that should be zer. */ +#define UDF_FILE_FLAGS_RESERVED_MASK UINT8_C(0xe0) +/** @} */ + + +/** + * UDF allocation extent descriptor (@ecma167{4,14.5,93}, @udf260{2.3.11,67}). + */ +typedef struct UDFALLOCATIONEXTENTDESC +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_ALLOCATION_EXTENT_DESC). */ + UDFTAG Tag; + /** 0x10: Previous allocation extent location (logical block in current + * partition). */ + uint32_t offPrevExtent; + /** 0x14: Size of the following allocation descriptors (in bytes). */ + uint32_t cbAllocDescs; + /** 0x18: Allocation descriptors. */ + union + { + UDFSHORTAD aShortADs[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; + UDFLONGAD aLongADs[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; + UDFEXTAD aExtADs[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; + } u; +} UDFALLOCATIONEXTENTDESC; +AssertCompileMemberOffset(UDFALLOCATIONEXTENTDESC, u, 0x18); +/** Pointer to an UDF allocation extent descriptor. */ +typedef UDFALLOCATIONEXTENTDESC *PUDFALLOCATIONEXTENTDESC; +/** Pointer to a const UDF allocation extent descriptor. */ +typedef UDFALLOCATIONEXTENTDESC const *PCUDFALLOCATIONEXTENTDESC; + +/** + * UDF information control block tag (@ecma167{4,14.6,93}, @udf260{2.3.5,60}). + */ +typedef struct UDFICBTAG +{ + /** 0x00: Number of direct entries in this ICB prior to this one. */ + uint32_t cEntiresBeforeThis; + /** 0x04: ICB hierarchy building strategy type (UDF_ICB_STRATEGY_TYPE_XXX). */ + uint16_t uStrategyType; + /** 0x06: Type specific parameters. */ + uint8_t abStrategyParams[2]; + /** 0x08: Max number of direct and indirect entries that MAY be recorded in this ICB. */ + uint16_t cMaxEntries; + /** 0x0a: Reserved, MBZ. */ + uint8_t bReserved; + /** 0x0b: File type (UDF_FILE_TYPE_XXX). */ + uint8_t bFileType; + /** 0x0c: Parent ICB location. */ + UDFLBADDR ParentIcb; + /** 0x12: Parent ICB location (UDF_ICB_FLAGS_XXX). */ + uint16_t fFlags; +} UDFICBTAG; +AssertCompileSize(UDFICBTAG, 20); +typedef UDFICBTAG *PUDFICBTAG; +typedef UDFICBTAG const *PCUDFICBTAG; + +/** @name UDF_ICB_STRATEGY_TYPE_XXX - ICB hierarchy building strategies + * + * See @ecma167{4,14.6.2,94}, @udf260{6.6,121} + * + * @{ */ +/** Strategy not specified. */ +#define UDF_ICB_STRATEGY_TYPE_NOT_SPECIFIED UINT16_C(0x0000) +/** See @ecma167{4,A.2,129}. */ +#define UDF_ICB_STRATEGY_TYPE_1 UINT16_C(0x0001) +/** See @ecma167{4,A.3,131}. */ +#define UDF_ICB_STRATEGY_TYPE_2 UINT16_C(0x0002) +/** See @ecma167{4,A.4,131}. */ +#define UDF_ICB_STRATEGY_TYPE_3 UINT16_C(0x0003) +/** See @ecma167{4,A.5,131}. */ +#define UDF_ICB_STRATEGY_TYPE_4 UINT16_C(0x0004) +/** Defined by the UDF spec, see @udf260{6.6,121}. */ +#define UDF_ICB_STRATEGY_TYPE_4096 UINT16_C(0x1000) +/** @} */ + +/** @name UDF_ICB_FLAGS_XXX - ICB flags + * + * See @ecma167{4,14.6.8,95}, @udf260{2.3.5.4,61} + * + * @{ */ +/** Using UDFSHORTAD. */ +#define UDF_ICB_FLAGS_AD_TYPE_SHORT UINT16_C(0x0000) +/** Using UDFLONGAD. */ +#define UDF_ICB_FLAGS_AD_TYPE_LONG UINT16_C(0x0001) +/** Using UDFEXTAD. */ +#define UDF_ICB_FLAGS_AD_TYPE_EXTENDED UINT16_C(0x0002) +/** File content is embedded in the allocation descriptor area. */ +#define UDF_ICB_FLAGS_AD_TYPE_EMBEDDED UINT16_C(0x0003) +/** Allocation type mask. */ +#define UDF_ICB_FLAGS_AD_TYPE_MASK UINT16_C(0x0007) +/** Set on directories that are sorted (according to @ecma167{4,8.6.1,78}). + * @note Directories are never sorted in UDF. */ +#define UDF_ICB_FLAGS_SORTED_DIRECTORY UINT16_C(0x0008) +/** Not relocatable. */ +#define UDF_ICB_FLAGS_NON_RELOCATABLE UINT16_C(0x0010) +/** Indicate that the file needs backing up (DOS attribute). */ +#define UDF_ICB_FLAGS_ARCHIVE UINT16_C(0x0020) +/** Set UID bit (UNIX). */ +#define UDF_ICB_FLAGS_SET_UID UINT16_C(0x0040) +/** Set GID bit (UNIX). */ +#define UDF_ICB_FLAGS_SET_GID UINT16_C(0x0080) +/** Set sticky bit (UNIX). */ +#define UDF_ICB_FLAGS_STICKY UINT16_C(0x0100) +/** Extents are contiguous. */ +#define UDF_ICB_FLAGS_CONTIGUOUS UINT16_C(0x0200) +/** System bit, reserved for implementation use. */ +#define UDF_ICB_FLAGS_SYSTEM UINT16_C(0x0400) +/** Data has been transformed in some way. + * @note UDF shall not set this bit. */ +#define UDF_ICB_FLAGS_TRANSFORMED UINT16_C(0x0800) +/** Directory may contain multi-versioned files. + * @note UDF shall not set this bit. */ +#define UDF_ICB_FLAGS_MULTI_VERSIONS UINT16_C(0x1000) +/** Is a stream in a stream directory. */ +#define UDF_ICB_FLAGS_STREAM UINT16_C(0x2000) +/** Reserved mask. */ +#define UDF_ICB_FLAGS_RESERVED_MASK UINT16_C(0xc000) +/** @} */ + +/** @name UDF_FILE_TYPE_XXX - File types + * + * See @ecma167{4,14.6.6,94}, @udf260{2.3.5.2,60} + * + * @{ */ +#define UDF_FILE_TYPE_NOT_SPECIFIED UINT8_C(0x00) /**< Not specified by this field. */ +#define UDF_FILE_TYPE_UNALLOCATED_SPACE_ENTRY UINT8_C(0x01) +#define UDF_FILE_TYPE_PARTITION_INTEGRITY_ENTRY UINT8_C(0x02) +#define UDF_FILE_TYPE_INDIRECT_ENTRY UINT8_C(0x03) +#define UDF_FILE_TYPE_DIRECTORY UINT8_C(0x04) +#define UDF_FILE_TYPE_REGULAR_FILE UINT8_C(0x05) +#define UDF_FILE_TYPE_BLOCK_DEVICE UINT8_C(0x06) +#define UDF_FILE_TYPE_CHARACTER_DEVICE UINT8_C(0x07) +#define UDF_FILE_TYPE_EXTENDED_ATTRIBUTES UINT8_C(0x08) +#define UDF_FILE_TYPE_FIFO UINT8_C(0x09) +#define UDF_FILE_TYPE_SOCKET UINT8_C(0x0a) +#define UDF_FILE_TYPE_TERMINAL_ENTRY UINT8_C(0x0b) +#define UDF_FILE_TYPE_SYMBOLIC_LINK UINT8_C(0x0c) +#define UDF_FILE_TYPE_STREAM_DIRECTORY UINT8_C(0x0d) +#define UDF_FILE_TYPE_VAT UINT8_C(0xf8) +#define UDF_FILE_TYPE_REAL_TIME_FILE UINT8_C(0xf9) +#define UDF_FILE_TYPE_METADATA_FILE UINT8_C(0xfa) +#define UDF_FILE_TYPE_METADATA_MIRROR_FILE UINT8_C(0xfb) +#define UDF_FILE_TYPE_METADATA_BITMAP_FILE UINT8_C(0xfc) +/** @} */ + + +/** + * UDF ICB header (derived structure). + */ +typedef struct UDFICBHDR +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_INDIRECT_ENTRY). */ + UDFTAG Tag; + /** 0x10: ICB Tag. */ + UDFICBTAG IcbTag; +} UDFICBHDR; +AssertCompileSize(UDFICBHDR, 36); +/** Pointer to an UDF ICB header. */ +typedef UDFICBHDR *PUDFICBHDR; +/** Pointer to a const UDF ICB header. */ +typedef UDFICBHDR const *PCUDFICBHDR; + + +/** + * UDF indirect entry (@ecma167{4,14.7,96}). + */ +typedef struct UDFINDIRECTENTRY +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_INDIRECT_ENTRY). */ + UDFTAG Tag; + /** 0x10: ICB Tag. */ + UDFICBTAG IcbTag; + /** 0x24: Indirect ICB location. */ + UDFLONGAD IndirectIcb; +} UDFINDIRECTENTRY; +AssertCompileSize(UDFINDIRECTENTRY, 52); +/** Pointer to an UDF indirect entry. */ +typedef UDFINDIRECTENTRY *PUDFINDIRECTENTRY; +/** Pointer to a const UDF indirect entry. */ +typedef UDFINDIRECTENTRY const *PCUDFINDIRECTENTRY; + + +/** + * UDF terminal entry (@ecma167{4,14.8,97}). + */ +typedef struct UDFTERMINALENTRY +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_TERMINAL_ENTRY). */ + UDFTAG Tag; + /** 0x10: ICB Tag (UDF_FILE_TYPE_TERMINAL_ENTRY). */ + UDFICBTAG IcbTag; +} UDFTERMINALENTRY; +AssertCompileSize(UDFTERMINALENTRY, 36); +/** Pointer to an UDF terminal entry. */ +typedef UDFTERMINALENTRY *PUDFTERMINALENTRY; +/** Pointer to a const UDF terminal entry. */ +typedef UDFTERMINALENTRY const *PCUDFTERMINALENTRY; + + +/** + * UDF file entry (FE) (@ecma167{4,14.8,97}, @udf260{2.3.6,62}). + * + * @note Total length shall not exceed one logical block. + */ +typedef struct UDFFILEENTRY +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_FILE_ENTRY). */ + UDFTAG Tag; + /** 0x10: ICB Tag. */ + UDFICBTAG IcbTag; + /** 0x24: User ID (UNIX). */ + uint32_t uid; + /** 0x28: Group ID (UNIX). */ + uint32_t gid; + /** 0x2c: Permission (UDF_PERM_XXX). */ + uint32_t fPermissions; + /** 0x30: Number hard links. */ + uint16_t cHardlinks; + /** 0x32: Record format (UDF_REC_FMT_XXX). */ + uint8_t uRecordFormat; + /** 0x33: Record format (UDF_REC_ATTR_XXX). */ + uint8_t fRecordDisplayAttribs; + /** 0x34: Record length (in bytes). + * @note Must be zero according to the UDF specification. */ + uint32_t cbRecord; + /** 0x38: Information length in bytes (file size). */ + uint64_t cbData; + /** 0x40: Number of logical blocks allocated (for file data). */ + uint64_t cLogicalBlocks; + /** 0x48: Time of last access (prior to recording the file entry). */ + UDFTIMESTAMP AccessTime; + /** 0x54: Time of last data modification. */ + UDFTIMESTAMP ModificationTime; + /** 0x60: Time of last attribute/status modification. */ + UDFTIMESTAMP ChangeTime; + /** 0x6c: Checkpoint number (defaults to 1). */ + uint32_t uCheckpoint; + /** 0x70: Extended attribute information control block location. */ + UDFLONGAD ExtAttribIcb; + /** 0x80: Implementation identifier ("*Developer ID"). */ + UDFENTITYID idImplementation; + /** 0xa0: Unique ID. */ + uint64_t INodeId; + /** 0xa8: Length of extended attributes in bytes, multiple of four. */ + uint32_t cbExtAttribs; + /** 0xac: Length of allocation descriptors in bytes, multiple of four. */ + uint32_t cbAllocDescs; + /** 0xb0: Two variable sized fields. First @a cbExtAttribs bytes of extended + * attributes, then @a cbAllocDescs bytes of allocation descriptors. */ + RT_FLEXIBLE_ARRAY_EXTENSION + uint8_t abExtAttribs[RT_FLEXIBLE_ARRAY]; +} UDFFILEENTRY; +AssertCompileMemberOffset(UDFFILEENTRY, abExtAttribs, 0xb0); +/** Pointer to an UDF file entry. */ +typedef UDFFILEENTRY *PUDFFILEENTRY; +/** Pointer to a const UDF file entry. */ +typedef UDFFILEENTRY const *PCUDFFILEENTRY; + +/** @name UDF_PERM_XXX - UDFFILEENTRY::fPermissions + * See @ecma167{4,14.9.5,99}. + * @{ */ +#define UDF_PERM_OTH_EXEC UINT32_C(0x00000001) +#define UDF_PERM_OTH_WRITE UINT32_C(0x00000002) +#define UDF_PERM_OTH_READ UINT32_C(0x00000004) +#define UDF_PERM_OTH_ATTRIB UINT32_C(0x00000008) +#define UDF_PERM_OTH_DELETE UINT32_C(0x00000010) +#define UDF_PERM_OTH_MASK UINT32_C(0x0000001f) + +#define UDF_PERM_GRP_EXEC UINT32_C(0x00000020) +#define UDF_PERM_GRP_WRITE UINT32_C(0x00000040) +#define UDF_PERM_GRP_READ UINT32_C(0x00000080) +#define UDF_PERM_GRP_ATTRIB UINT32_C(0x00000100) +#define UDF_PERM_GRP_DELETE UINT32_C(0x00000200) +#define UDF_PERM_GRP_MASK UINT32_C(0x000003e0) + +#define UDF_PERM_USR_EXEC UINT32_C(0x00000400) +#define UDF_PERM_USR_WRITE UINT32_C(0x00000800) +#define UDF_PERM_USR_READ UINT32_C(0x00001000) +#define UDF_PERM_USR_ATTRIB UINT32_C(0x00002000) +#define UDF_PERM_USR_DELETE UINT32_C(0x00004000) +#define UDF_PERM_USR_MASK UINT32_C(0x00007c00) + +#define UDF_PERM_USR_RESERVED_MASK UINT32_C(0xffff8000) +/** @} */ + +/** @name UDF_REC_FMT_XXX - Record format. + * See @ecma167{4,14.9.7,100}. + * @{ */ +/** Not record format specified. + * @note The only allowed value according to the UDF specification. */ +#define UDF_REC_FMT_NOT_SPECIFIED UINT8_C(0x00) +/** @} */ + +/** @name UDF_REC_ATTR_XXX - Record display attributes. + * See @ecma167{4,14.9.8,100}. + * @{ */ +/** Manner of record display not specified. + * @note The only allowed value according to the UDF specification. */ +#define UDF_REC_ATTR_NOT_SPECIFIED UINT8_C(0x00) +/** @} */ + + +/** + * UDF extended attribute header descriptor (@ecma167{4,14.10.1,102}, + * @udf260{3.3.4,79}). + */ +typedef struct UDFEXTATTRIBHDRDESC +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_EXTENDED_ATTRIB_HDR_DESC). */ + UDFTAG Tag; + /** 0x10: Implementation attributes location (byte offset) into the EA space. + * This typically set to UINT32_MAX if not present, though any value larger + * than the EA space will do. */ + uint32_t offImplementationAttribs; + /** 0x14: Application attributes location (byte offset) into the EA space. + * This typically set to UINT32_MAX if not present, though any value larger + * than the EA space will do. */ + uint32_t offApplicationAttribs; +} UDFEXTATTRIBHDRDESC; +AssertCompileSize(UDFEXTATTRIBHDRDESC, 24); +/** Pointer to an UDF extended attribute header descriptor. */ +typedef UDFEXTATTRIBHDRDESC *PUDFEXTATTRIBHDRDESC; +/** Pointer to a const UDF extended attribute header descriptor. */ +typedef UDFEXTATTRIBHDRDESC const *PCUDFEXTATTRIBHDRDESC; + +/** + * UDF character set info EA data (@ecma167{4,14.10.3,104}). + * + * Not needed by UDF. + */ +typedef struct UDFEADATACHARSETINFO +{ + /** 0x00/0x0c: The length of the escape sequences (in bytes). */ + uint32_t cbEscSeqs; + /** 0x04/0x10: The character set type (UDF_CHAR_SET_TYPE_XXX). */ + uint8_t bType; + /** 0x05/0x11: Escape sequences. */ + uint8_t abEscSeqs[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} UDFEADATACHARSETINFO; +/** Pointer to UDF character set info EA data. */ +typedef UDFEADATACHARSETINFO *PUDFEADATACHARSETINFO; +/** Pointer to const UDF character set info EA data. */ +typedef UDFEADATACHARSETINFO const *PCUDFEADATACHARSETINFO; +/** UDFGEA::uAttribType value for UDFEADATACHARSETINFO.*/ +#define UDFEADATACHARSETINFO_ATTRIB_TYPE UINT32_C(0x00000001) +/** UDFGEA::uAttribSubtype value for UDFEADATACHARSETINFO. */ +#define UDFEADATACHARSETINFO_ATTRIB_SUBTYPE UINT32_C(0x00000001) + +/** + * UDF alternate permissions EA data (@ecma167{4,14.10.4,105}, @udf260{3.3.4.2,80}). + * @note Not recorded according to the UDF specification. + */ +typedef struct UDFEADATAALTPERM +{ + /** 0x00/0x0c: Alternative owner ID. */ + uint16_t idOwner; + /** 0x02/0x0e: Alternative group ID. */ + uint16_t idGroup; + /** 0x04/0x10: Alternative permissions. */ + uint16_t fPermission; +} UDFEADATAALTPERM; +/** Pointer to UDF alternative permissions EA data. */ +typedef UDFEADATAALTPERM *PUDFEADATAALTPERM; +/** Pointer to const UDF alternative permissions EA data. */ +typedef UDFEADATAALTPERM const *PCUDFEADATAALTPERM; +/** UDFGEA::uAttribType value for UDFEADATAALTPERM. */ +#define UDFEADATAALTPERM_ATTRIB_TYPE UINT32_C(0x00000003) +/** UDFGEA::uAttribSubtype value for UDFEADATAALTPERM. */ +#define UDFEADATAALTPERM_ATTRIB_SUBTYPE UINT32_C(0x00000001) + +/** + * UDF file times EA data (@ecma167{4,14.10.5,108}, @udf260{3.3.4.3,80}). + * (This is a bit reminiscent of ISO9660RRIPTF.) + */ +typedef struct UDFEADATAFILETIMES +{ + /** 0x00/0x0c: Timestamp length. */ + uint32_t cbTimestamps; + /** 0x04/0x10: Indicates which timestamps are present + * (UDF_FILE_TIMES_EA_F_XXX). */ + uint32_t fFlags; + /** 0x08/0x14: Timestamps. */ + UDFTIMESTAMP aTimestamps[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} UDFEADATAFILETIMES; +/** Pointer to UDF file times EA data. */ +typedef UDFEADATAFILETIMES *PUDFEADATAFILETIMES; +/** Pointer to const UDF file times EA data. */ +typedef UDFEADATAFILETIMES const *PCUDFEADATAFILETIMES; +/** UDFGEA::uAttribType value for UDFEADATAFILETIMES. */ +#define UDFEADATAFILETIMES_ATTRIB_TYPE UINT32_C(0x00000005) +/** UDFGEA::uAttribSubtype value for UDFEADATAFILETIMES. */ +#define UDFEADATAFILETIMES_ATTRIB_SUBTYPE UINT32_C(0x00000001) + +/** @name UDF_FILE_TIMES_EA_F_XXX - File times existence flags. + * See @ecma167{4,14.10.5.6,109} + * @{ */ +#define UDF_FILE_TIMES_EA_F_BIRTH UINT8_C(0x01) /**< Birth (creation) timestamp is recorded. */ +#define UDF_FILE_TIMES_EA_F_DELETE UINT8_C(0x04) /**< Deletion timestamp is recorded. */ +#define UDF_FILE_TIMES_EA_F_EFFECTIVE UINT8_C(0x08) /**< Effective timestamp is recorded. */ +#define UDF_FILE_TIMES_EA_F_BACKUP UINT8_C(0x20) /**< Backup timestamp is recorded. */ +#define UDF_FILE_TIMES_EA_F_RESERVED_MASK UINT8_C(0xd2) +/** @} */ + +/** + * UDF information times EA data (@ecma167{4,14.10.6,109}). + */ +typedef struct UDFEADATAINFOTIMES +{ + /** 0x00/0x0c: Timestamp length. */ + uint32_t cbTimestamps; + /** 0x04/0x10: Indicates which timestamps are present + * (UDF_INFO_TIMES_EA_F_XXX). */ + uint32_t fFlags; + /** 0x08/0x14: Timestamps. */ + UDFTIMESTAMP aTimestamps[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} UDFEADATAINFOTIMES; +/** Pointer to UDF information times EA data. */ +typedef UDFEADATAINFOTIMES *PUDFEADATAINFOTIMES; +/** Pointer to const UDF information times EA data. */ +typedef UDFEADATAINFOTIMES const *PCUDFEADATAINFOTIMES; +/** UDFGEA::uAttribType value for UDFEADATAINFOTIMES. */ +#define UDFEADATAINFOTIMES_ATTRIB_TYPE UINT32_C(0x00000006) +/** UDFGEA::uAttribSubtype value for UDFEADATAINFOTIMES. */ +#define UDFEADATAINFOTIMES_ATTRIB_SUBTYPE UINT32_C(0x00000001) + +/** @name UDF_INFO_TIMES_EA_F_XXX - Information times existence flags. + * See @ecma167{4,14.10.6.6,110} + * @{ */ +#define UDF_INFO_TIMES_EA_F_BIRTH UINT8_C(0x01) /**< Birth (creation) timestamp is recorded. */ +#define UDF_INFO_TIMES_EA_F_MODIFIED UINT8_C(0x02) /**< Last (data) modified timestamp is recorded. */ +#define UDF_INFO_TIMES_EA_F_EXPIRE UINT8_C(0x04) /**< Expiration (deletion) timestamp is recorded. */ +#define UDF_INFO_TIMES_EA_F_EFFECTIVE UINT8_C(0x08) /**< Effective timestamp is recorded. */ +#define UDF_INFO_TIMES_EA_F_RESERVED_MASK UINT8_C(0xf0) +/** @} */ + +/** + * UDF device specification EA data (@ecma167{4,14.10.7,110}, @udf260{3.3.4.4,81}). + */ +typedef struct UDFEADATADEVICESPEC +{ + /** 0x00/0x0c: Length of implementation use field. */ + uint32_t cbImplementationUse; + /** 0x04/0x10: Major device number. */ + uint32_t uMajorDeviceNo; + /** 0x08/0x14: Minor device number. */ + uint32_t uMinorDeviceNo; + /** 0x0c/0x18: Implementation use field (variable length). + * UDF specficiation expects UDFENTITYID with a "*Developer ID" as first part + * here. */ + uint8_t abImplementationUse[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} UDFEADATADEVICESPEC; +/** Pointer to UDF device specification EA data. */ +typedef UDFEADATADEVICESPEC *PUDFEADATADEVICESPEC; +/** Pointer to const UDF device specification EA data. */ +typedef UDFEADATADEVICESPEC const *PCUDFEADATADEVICESPEC; +/** UDFGEA::uAttribType value for UDFEADATADEVICESPEC. */ +#define UDFEADATADEVICESPEC_ATTRIB_TYPE UINT32_C(0x0000000c) +/** UDFGEA::uAttribSubtype value for UDFEADATADEVICESPEC. */ +#define UDFEADATADEVICESPEC_ATTRIB_SUBTYPE UINT32_C(0x00000001) + +/** + * UDF free EA space payload for implementation and application use EAs + * (@udf260{3.3.4.5.1.1,82}, @udf260{3.3.4.6.1.1,88}). + * + * UDFEADATAIMPLUSE::idImplementation is UDF_ENTITY_ID_IUEA_FREE_EA_SPACE. + * UDFEADATAAPPUSE::idImplementation is UDF_ENTITY_ID_AUEA_FREE_EA_SPACE. + */ +typedef struct UDFFREEEASPACE +{ + /** 0x00/0x30: Header checksum. + * @note 16-bit checksum of UDFGEA up thru u.ImplUse.idImplementation. */ + uint16_t uChecksum; + /** 0x02/0x32: Free space. */ + uint8_t abFree[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; +} UDFFREEEASPACE; +/** Pointer to UDF free EA space impl/app use payload. */ +typedef UDFFREEEASPACE *PUDFFREEEASPACE; +/** Pointer to const UDF free EA space impl/app use payload. */ +typedef UDFFREEEASPACE const *PCUDFFREEEASPACE; + +/** + * UDF DVD copyright management information implementation use EA payload + * (@udf260{3.3.4.5.1.2,83}). + * + * UDFEADATAIMPLUSE::idImplementation is UDF_ENTITY_ID_IUEA_DVD_CGMS_INFO. + */ +typedef struct UDFIUEADVDCGMSINFO +{ + /** 0x00/0x30: Header checksum. + * @note 16-bit checksum of UDFGEA up thru u.ImplUse.idImplementation. */ + uint16_t uChecksum; + /** 0x02/0x32: The CGMS information (whatever that is). */ + uint8_t bInfo; + /** 0x03/0x33: Data structure type (whatever that is). */ + uint8_t bType; + /** 0x04/0x34: Production system information, probably dependend on the + * values of previous fields. */ + uint8_t abProtSysInfo[4]; +} UDFIUEADVDCGMSINFO; +/** Pointer to UDF DVD copyright management information implementation use EA payload. */ +typedef UDFIUEADVDCGMSINFO *PUDFIUEADVDCGMSINFO; +/** Pointer to const UDF DVD copyright management information implementation use EA payload. */ +typedef UDFIUEADVDCGMSINFO const *PCUDFIUEADVDCGMSINFO; + +/** + * UDF OS/2 EA length implementation use EA payload (@udf260{3.3.4.5.3.1,84}). + * + * UDFEADATAIMPLUSE::idImplementation is UDF_ENTITY_ID_IUEA_OS2_EA_LENGTH. + */ +#pragma pack(2) +typedef struct UDFIUEAOS2EALENGTH +{ + /** 0x00/0x30: Header checksum. + * @note 16-bit checksum of UDFGEA up thru u.ImplUse.idImplementation. */ + uint16_t uChecksum; + /** 0x02/0x32: The CGMS information (whatever that is). */ + uint32_t cbEAs; +} UDFIUEAOS2EALENGTH; +#pragma pack() +AssertCompileMemberOffset(UDFIUEAOS2EALENGTH, cbEAs, 2); +/** Pointer to UDF OS/2 EA length implementation use EA payload. */ +typedef UDFIUEAOS2EALENGTH *PUDFIUEAOS2EALENGTH; +/** Pointer to const UDF OS/2 EA length implementation use EA payload. */ +typedef UDFIUEAOS2EALENGTH const *PCUDFIUEAOS2EALENGTH; + +/** + * UDF Mac volume info implementation use EA payload (@udf260{3.3.4.5.4.1,84}). + * + * UDFEADATAIMPLUSE::idImplementation is UDF_ENTITY_ID_IUEA_MAC_VOLUME_INFO. + */ +#pragma pack(2) +typedef struct UDFIUEAMACVOLINFO +{ + /** 0x00/0x30: Header checksum. + * @note 16-bit checksum of UDFGEA up thru u.ImplUse.idImplementation. */ + uint16_t uChecksum; + /** 0x02/0x32: Last modification time. */ + UDFTIMESTAMP LastModificationTime; + /** 0x0e/0x3e: Last backup time. */ + UDFTIMESTAMP LastBackupTime; + /** 0x1a/0x4e: Volume finder information. */ + uint32_t au32FinderInfo[8]; +} UDFIUEAMACVOLINFO; +#pragma pack() +AssertCompileMemberOffset(UDFIUEAMACVOLINFO, au32FinderInfo, 0x1a); +/** Pointer to UDF Mac volume info implementation use EA payload. */ +typedef UDFIUEAMACVOLINFO *PUDFIUEAMACVOLINFO; +/** Pointer to const UDF Mac volume info implementation use EA payload. */ +typedef UDFIUEAMACVOLINFO const *PCUDFIUEAMACVOLINFO; + +/** + * UDF point for use in Mac EAs (@udf260{3.3.4.5.4.2,86}). + */ +typedef struct UDFMACPOINT +{ + /** X coordinate. */ + int16_t x; + /** Y coordinate. */ + int16_t y; +} UDFMACPOINT; + +/** + * UDF rectangle for using Mac EAs (@udf260{3.3.4.5.4.2,86}). + */ +typedef struct UDFMACRECT +{ + /** top Y coordinate. */ + int16_t yTop; + /** left X coordinate. */ + int16_t xLeft; + /** bottom Y coordinate. (exclusive?) */ + int16_t yBottom; + /** right X coordinate. (exclusive?) */ + int16_t xRight; +} UDFMACRECT; + +/** + * UDF finder directory info for Mac EAs (@udf260{3.3.4.5.4.2,86}). + */ +typedef struct UDFMACFDINFO +{ + UDFMACRECT FrRect; + int16_t FrFlags; + UDFMACPOINT FrLocation; + int16_t FrView; +} UDFMACFDINFO; +AssertCompileSize(UDFMACFDINFO, 16); + +/** + * UDF finder directory extended info for Mac EAs (@udf260{3.3.4.5.4.2,86}). + */ +typedef struct UDFMACFDXINFO +{ + UDFMACPOINT FrScroll; + int32_t FrOpenChain; + uint8_t FrScript; + uint8_t FrXFlags; + uint16_t FrComment; + uint32_t FrPutAway; +} UDFMACFDXINFO; +AssertCompileSize(UDFMACFDXINFO, 16); + +/** + * UDF Mac finder info implementation use EA payload (@udf260{3.3.4.5.4.1,84}), + * directory edition. + * + * UDFEADATAIMPLUSE::idImplementation is UDF_ENTITY_ID_IUEA_MAC_FINDER_INFO. + */ +typedef struct UDFIUEAMACFINDERINFODIR +{ + /** 0x00/0x30: Header checksum. + * @note 16-bit checksum of UDFGEA up thru u.ImplUse.idImplementation. */ + uint16_t uChecksum; + /** 0x02/0x32: Explicit alignment padding, MBZ. */ + uint16_t uPadding; + /** 0x04/0x34: Parent directory ID. */ + uint32_t idParentDir; + /** 0x08/0x38: Dir information. */ + UDFMACFDINFO DirInfo; + /** 0x18/0x48: Dir extended information. */ + UDFMACFDXINFO DirExInfo; +} UDFIUEAMACFINDERINFODIR; +AssertCompileMemberOffset(UDFIUEAMACFINDERINFODIR, DirInfo, 0x08); +AssertCompileMemberOffset(UDFIUEAMACFINDERINFODIR, DirExInfo, 0x18); +AssertCompileSize(UDFIUEAMACFINDERINFODIR, 0x28); +/** Pointer to UDF Mac finder info for dir implementation use EA payload. */ +typedef UDFIUEAMACFINDERINFODIR *PUDFIUEAMACFINDERINFODIR; +/** Pointer to const UDF Mac finder info for dir implementation use EA payload. */ +typedef UDFIUEAMACFINDERINFODIR const *PCUDFIUEAMACFINDERINFODIR; + +/** + * UDF finder file info for Mac EAs (@udf260{3.3.4.5.4.2,86}). + */ +typedef struct UDFMACFFINFO +{ + uint32_t FrType; + uint32_t FrCreator; + uint16_t FrFlags; + UDFMACPOINT FrLocation; + int16_t FrFldr; +} UDFMACFFINFO; +AssertCompileSize(UDFMACFFINFO, 16); + +/** + * UDF finder file extended info for Mac EAs (@udf260{3.3.4.5.4.2,86}). + */ +typedef struct UDFMACFFXINFO +{ + int16_t FrIconID; + uint8_t FdUnused[6]; + uint8_t FrScript; + uint8_t FrXFlags; + uint16_t FrComment; + uint32_t FrPutAway; +} UDFMACFFXINFO; +AssertCompileSize(UDFMACFFXINFO, 16); + +/** + * UDF Mac finder info implementation use EA payload (@udf260{3.3.4.5.4.1,84}), + * file edition. + * + * UDFEADATAIMPLUSE::idImplementation is UDF_ENTITY_ID_IUEA_MAC_FINDER_INFO. + */ +typedef struct UDFIUEAMACFINDERINFOFILE +{ + /** 0x00/0x30: Header checksum. + * @note 16-bit checksum of UDFGEA up thru u.ImplUse.idImplementation. */ + uint16_t uChecksum; + /** 0x02/0x32: Explicit alignment padding, MBZ. */ + uint16_t uPadding; + /** 0x04/0x34: Parent directory ID. */ + uint32_t idParentDir; + /** 0x08/0x38: File information. */ + UDFMACFFINFO FileInfo; + /** 0x18/0x48: File extended information. */ + UDFMACFFXINFO FileExInfo; + /** 0x28/0x58: The size of the fork data (in bytes). */ + uint32_t cbForkData; + /** 0x2c/0x5c: The size of the fork allocation (in bytes). */ + uint32_t cbForkAlloc; +} UDFIUEAMACFINDERINFOFILE; +AssertCompileMemberOffset(UDFIUEAMACFINDERINFOFILE, FileInfo, 0x08); +AssertCompileMemberOffset(UDFIUEAMACFINDERINFOFILE, FileExInfo, 0x18); +AssertCompileMemberOffset(UDFIUEAMACFINDERINFOFILE, cbForkData, 0x28); +AssertCompileSize(UDFIUEAMACFINDERINFOFILE, 0x30); +/** Pointer to UDF Mac finder info for file implementation use EA payload. */ +typedef UDFIUEAMACFINDERINFOFILE *PUDFIUEAMACFINDERINFOFILE; +/** Pointer to const UDF Mac finder info for file implementation use EA payload. */ +typedef UDFIUEAMACFINDERINFOFILE const *PCUDFIUEAMACFINDERINFOFILE; + +/** + * UDF OS/400 directory info implementation use EA payload (@udf260{3.3.4.5.6.1,87}) + * + * UDFEADATAIMPLUSE::idImplementation is UDF_ENTITY_ID_IUEA_OS400_DIR_INFO. + */ +typedef struct UDFIUEAOS400DIRINFO +{ + /** 0x00/0x30: Header checksum. + * @note 16-bit checksum of UDFGEA up thru u.ImplUse.idImplementation. */ + uint16_t uChecksum; + /** 0x02/0x32: Explicit alignment padding, MBZ. */ + uint16_t uPadding; + /** 0x04/0x34: The directory info, format documented elsewhere. */ + uint8_t abDirInfo[44]; +} UDFIUEAOS400DIRINFO; +AssertCompileSize(UDFIUEAOS400DIRINFO, 0x30); +/** Pointer to UDF Mac finder info for file implementation use EA payload. */ +typedef UDFIUEAOS400DIRINFO *PUDFIUEAOS400DIRINFO; +/** Pointer to const UDF Mac finder info for file implementation use EA payload. */ +typedef UDFIUEAOS400DIRINFO const *PCUDFIUEAOS400DIRINFO; + + +/** + * UDF implementation use EA data (@ecma167{4,14.10.8,111}, @udf260{3.3.4.5,82}). + */ +typedef struct UDFEADATAIMPLUSE +{ + /** 0x00/0x0c: Length uData in bytes. */ + uint32_t cbData; + /** 0x04/0x10: Implementation identifier (UDF_ENTITY_ID_IUEA_XXX). */ + UDFENTITYID idImplementation; + /** 0x24/0x30: Implementation use field (variable length). */ + union + { + /** Generic byte view. */ + uint8_t abData[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; + /** Free EA space (UDF_ENTITY_ID_IUEA_FREE_EA_SPACE). */ + UDFFREEEASPACE FreeEaSpace; + /** DVD copyright management information (UDF_ENTITY_ID_IUEA_DVD_CGMS_INFO). */ + UDFIUEADVDCGMSINFO DvdCgmsInfo; + /** OS/2 EA length (UDF_ENTITY_ID_IUEA_OS2_EA_LENGTH). */ + UDFIUEAOS2EALENGTH Os2EaLength; + /** Mac volume info (UDF_ENTITY_ID_IUEA_MAC_VOLUME_INFO). */ + UDFIUEAMACVOLINFO MacVolInfo; + /** Mac finder info, directory edition (UDF_ENTITY_ID_IUEA_MAC_FINDER_INFO). */ + UDFIUEAMACFINDERINFODIR MacFinderInfoDir; + /** Mac finder info, file edition (UDF_ENTITY_ID_IUEA_MAC_FINDER_INFO). */ + UDFIUEAMACFINDERINFOFILE MacFinderInfoFile; + /** OS/400 directory info (UDF_ENTITY_ID_IUEA_OS400_DIR_INFO). */ + UDFIUEAOS400DIRINFO Os400DirInfo; + } u; +} UDFEADATAIMPLUSE; +/** Pointer to UDF implementation use EA data. */ +typedef UDFEADATAIMPLUSE *PUDFEADATAIMPLUSE; +/** Pointer to const UDF implementation use EA data. */ +typedef UDFEADATAIMPLUSE const *PCUDFEADATAIMPLUSE; +/** UDFGEA::uAttribType value for UDFEADATAIMPLUSE. */ +#define UDFEADATAIMPLUSE_ATTRIB_TYPE UINT32_C(0x00000800) +/** UDFGEA::uAttribSubtype value for UDFEADATAIMPLUSE. */ +#define UDFEADATAIMPLUSE_ATTRIB_SUBTYPE UINT32_C(0x00000001) + +/** + * UDF application use EA data (@ecma167{4,14.10.9,112}, @udf260{3.3.4.6,88}). + */ +typedef struct UDFEADATAAPPUSE +{ + /** 0x0c: Length uData in bytes. */ + uint32_t cbData; + /** 0x10: Application identifier (UDF_ENTITY_ID_AUEA_FREE_EA_SPACE). */ + UDFENTITYID idApplication; + /** 0x30: Application use field (variable length). */ + union + { + /** Generic byte view. */ + uint8_t ab[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; + /** Free EA space (UDF_ENTITY_ID_AUEA_FREE_EA_SPACE). */ + UDFFREEEASPACE FreeEaSpace; + } uData; +} UDFEADATAAPPUSE; +/** Pointer to UDF application use EA data. */ +typedef UDFEADATAAPPUSE *PUDFEADATAAPPUSE; +/** Pointer to const UDF application use EA data. */ +typedef UDFEADATAAPPUSE const *PCUDFEADATAAPPUSE; +/** UDFGEA::uAttribType value for UDFEADATAAPPUSE. */ +#define UDFEADATAAPPUSE_ATTRIB_TYPE UINT32_C(0x00010000) +/** UDFGEA::uAttribSubtype value for UDFEADATAAPPUSE. */ +#define UDFEADATAAPPUSE_ATTRIB_SUBTYPE UINT32_C(0x00000001) + +/** + * UDF generic extended attribute (@ecma167{4,14.10.2,103}). + */ +typedef struct UDFGEA +{ + /** 0x00: Attribute type (UDFXXX_ATTRIB_TYPE). */ + uint32_t uAttribType; + /** 0x04: Attribute subtype (UDFXXX_ATTRIB_SUBTYPE). */ + uint8_t uAttribSubtype; + /** 0x05: Reserved padding bytes, MBZ. */ + uint8_t abReserved[3]; + /** 0x08: Size of the whole extended attribute. + * Multiple of four is recommended. */ + uint32_t cbAttrib; + /** 0x0c: Attribute data union. */ + union + { + /** Generic byte view (variable size). */ + uint8_t abData[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; + /** Character set information (@ecma167{4,14.10.3,104}). */ + UDFEADATACHARSETINFO CharSetInfo; + /** Alternate permissions (@ecma167{4,14.10.4,105}, @udf260{3.3.4.2,80}). + * @note Not recorded according to the UDF specification. */ + UDFEADATAALTPERM AltPerm; + /** File times (@ecma167{4,14.10.5,108}, @udf260{3.3.4.3,80}). + * (This is a bit reminiscent of ISO9660RRIPTF.) */ + UDFEADATAFILETIMES FileTimes; + /** Information times (@ecma167{4,14.10.6,109}). */ + UDFEADATAINFOTIMES InfoTimes; + /** Device specification (@ecma167{4,14.10.7,110}, @udf260{3.3.4.4,81}). */ + UDFEADATADEVICESPEC DeviceSpec; + /** Implementation use (@ecma167{4,14.10.8,111}, @udf260{3.3.4.5,82}). */ + UDFEADATAIMPLUSE ImplUse; + /** Application use (@ecma167{4,14.10.9,112}, @udf260{3.3.4.6,88}). */ + UDFEADATAAPPUSE AppUse; + } u; +} UDFGEA; +AssertCompileMemberOffset(UDFGEA, u, 0x0c); +/** Pointer to a UDF extended attribute. */ +typedef UDFGEA *PUDFGEA; +/** Pointer to a const UDF extended attribute. */ +typedef UDFGEA const *PCUDFGEA; + + +/** + * UDF unallocated space entry (@ecma167{4,14.11,113}, @udf260{2.3.7,64}). + * + * @note Total length shall not exceed one logical block. + */ +typedef struct UDFUNALLOCATEDSPACEENTRY +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_UNALLOCATED_SPACE_ENTRY). */ + UDFTAG Tag; + /** 0x10: ICB Tag. */ + UDFICBTAG IcbTag; + /** 0x24: Size of the allocation desciptors in bytes. */ + uint32_t cbAllocDescs; + /** 0x28: Allocation desciptors, type given by IcbTag::fFlags. */ + union + { + UDFSHORTAD aShortADs[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; + UDFLONGAD aLongADs[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; + UDFEXTAD aExtADs[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; + UDFEXTENTAD SingleAD; + } u; +} UDFUNALLOCATEDSPACEENTRY; +AssertCompileMemberOffset(UDFUNALLOCATEDSPACEENTRY, u, 0x28); +/** Pointer to an UDF unallocated space entry. */ +typedef UDFUNALLOCATEDSPACEENTRY *PUDFUNALLOCATEDSPACEENTRY; +/** Pointer to a const UDF unallocated space entry. */ +typedef UDFUNALLOCATEDSPACEENTRY const *PCUDFUNALLOCATEDSPACEENTRY; + + +/** + * UDF space bitmap descriptor (SBD) (@ecma167{4,14.12,114}, @udf260{2.3.8,65}). + */ +typedef struct UDFSPACEBITMAPDESC +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_SPACE_BITMAP_DESC). */ + UDFTAG Tag; + /** 0x10: Number of bits in the bitmap. */ + uint32_t cBits; + /** 0x14: The bitmap size in bytes. */ + uint32_t cbBitmap; + /** 0x18: The bitmap. */ + RT_FLEXIBLE_ARRAY_EXTENSION + uint8_t abBitmap[RT_FLEXIBLE_ARRAY]; +} UDFSPACEBITMAPDESC; +AssertCompileMemberOffset(UDFSPACEBITMAPDESC, abBitmap, 0x18); +/** Pointer to an UDF space bitmap descriptor. */ +typedef UDFSPACEBITMAPDESC *PUDFSPACEBITMAPDESC; +/** Pointer to a const UDF space bitmap descriptor. */ +typedef UDFSPACEBITMAPDESC const *PCUDFSPACEBITMAPDESC; + + +/** + * UDF partition integrity descriptor (@ecma167{4,14.3,115}, @udf260{2.3.9,65}). + * + * @note Not needed by UDF. + */ +typedef struct UDFPARTITIONINTEGRITYDESC +{ + /** 0x000: The descriptor tag (UDF_TAG_ID_PARTITION_INTEGERITY_DESC). */ + UDFTAG Tag; + /** 0x010: ICB Tag. */ + UDFICBTAG IcbTag; + /** 0x024: Recording timestamp. */ + UDFTIMESTAMP RecordingTimestamp; + /** 0x030: Interity type (UDF_PARTITION_INTEGRITY_TYPE_XXX). */ + uint8_t bType; + /** 0x031: Reserved. */ + uint8_t abReserved[175]; + /** 0x0e0: Implementation identifier. */ + UDFENTITYID idImplementation; + /** 0x100: Implementation use data. */ + RT_FLEXIBLE_ARRAY_EXTENSION + uint8_t abImplementationUse[RT_FLEXIBLE_ARRAY]; +} UDFPARTITIONINTEGRITYDESC; +AssertCompileMemberOffset(UDFPARTITIONINTEGRITYDESC, abImplementationUse, 0x100); +/** Pointer to an UDF partition integrity descriptor. */ +typedef UDFPARTITIONINTEGRITYDESC *PUDFPARTITIONINTEGRITYDESC; +/** Pointer to a const UDF partition integrity descriptor. */ +typedef UDFPARTITIONINTEGRITYDESC const *PCUDFPARTITIONINTEGRITYDESC; + + +/** + * UDF extended file entry (EFE) (@ecma167{4,14.17,120}, @udf260{3.3.5,83}). + * + * @note Total length shall not exceed one logical block. + */ +typedef struct UDFEXFILEENTRY +{ + /** 0x00: The descriptor tag (UDF_TAG_ID_EXTENDED_FILE_ENTRY). */ + UDFTAG Tag; + /** 0x10: ICB Tag. */ + UDFICBTAG IcbTag; + /** 0x24: User ID (UNIX). */ + uint32_t uid; + /** 0x28: Group ID (UNIX). */ + uint32_t gid; + /** 0x2c: Permission (UDF_PERM_XXX). */ + uint32_t fPermissions; + /** 0x30: Number hard links. */ + uint16_t cHardlinks; + /** 0x32: Record format (UDF_REC_FMT_XXX). */ + uint8_t uRecordFormat; + /** 0x33: Record format (UDF_REC_FMT_XXX). */ + uint8_t fRecordDisplayAttribs; + /** 0x34: Record length (in bytes). + * @note Must be zero according to the UDF specification. */ + uint32_t cbRecord; + /** 0x38: Information length in bytes (file size). */ + uint64_t cbData; + /** 0x40: The size of all streams. Same as cbData if no additional streams. */ + uint64_t cbObject; + /** 0x48: Number of logical blocks allocated (for file data). */ + uint64_t cLogicalBlocks; + /** 0x50: Time of last access (prior to recording the file entry). */ + UDFTIMESTAMP AccessTime; + /** 0x5c: Time of last data modification. */ + UDFTIMESTAMP ModificationTime; + /** 0x68: Birth (creation) time. */ + UDFTIMESTAMP BirthTime; + /** 0x74: Time of last attribute/status modification. */ + UDFTIMESTAMP ChangeTime; + /** 0x80: Checkpoint number (defaults to 1). */ + uint32_t uCheckpoint; + /** 0x84: Reserved, MBZ. */ + uint32_t uReserved; + /** 0x88: Extended attribute information control block location. */ + UDFLONGAD ExtAttribIcb; + /** 0x98: Stream directory information control block location. */ + UDFLONGAD StreamDirIcb; + /** 0xa8: Implementation identifier (UDF_ENTITY_ID_FE_IMPLEMENTATION). */ + UDFENTITYID idImplementation; + /** 0xc8: Unique ID. */ + uint64_t INodeId; + /** 0xd0: Length of extended attributes in bytes, multiple of four. */ + uint32_t cbExtAttribs; + /** 0xd4: Length of allocation descriptors in bytes, multiple of four. */ + uint32_t cbAllocDescs; + /** 0xd8: Two variable sized fields. First @a cbExtAttribs bytes of extended + * attributes, then @a cbAllocDescs bytes of allocation descriptors. */ + RT_FLEXIBLE_ARRAY_EXTENSION + uint8_t abExtAttribs[RT_FLEXIBLE_ARRAY]; +} UDFEXFILEENTRY; +AssertCompileMemberOffset(UDFEXFILEENTRY, abExtAttribs, 0xd8); +/** Pointer to an UDF extended file entry. */ +typedef UDFEXFILEENTRY *PUDFEXFILEENTRY; +/** Pointer to a const UDF extended file entry. */ +typedef UDFEXFILEENTRY const *PCUDFEXFILEENTRY; + + + +/** @name UDF Volume Recognition Sequence (VRS) + * + * The recognition sequence usually follows the CD001 descriptor sequence at + * sector 16 and is there to indicate that the medium (also) contains a UDF file + * system and which standards are involved. + * + * See @ecma167{2,8,31}, @ecma167{2,9,32}, @udf260{2.1.7,25}. + * + * @{ */ + +/** The type value used for all the extended UDF volume descriptors + * (ISO9660VOLDESCHDR::bDescType). */ +#define UDF_EXT_VOL_DESC_TYPE 0 +/** The version value used for all the extended UDF volume descriptors + * (ISO9660VOLDESCHDR::bDescVersion). */ +#define UDF_EXT_VOL_DESC_VERSION 1 + +/** Standard ID for UDFEXTVOLDESCBEGIN. */ +#define UDF_EXT_VOL_DESC_STD_ID_BEGIN "BEA01" +/** Standard ID for UDFEXTVOLDESCTERM. */ +#define UDF_EXT_VOL_DESC_STD_ID_TERM "TEA01" +/** Standard ID for UDFEXTVOLDESCNSR following ECMA-167 2nd edition. */ +#define UDF_EXT_VOL_DESC_STD_ID_NSR_02 "NSR02" +/** Standard ID for UDFEXTVOLDESCNSR following ECMA-167 3rd edition. */ +#define UDF_EXT_VOL_DESC_STD_ID_NSR_03 "NSR03" +/** Standard ID for UDFEXTVOLDESCBOOT. */ +#define UDF_EXT_VOL_DESC_STD_ID_BOOT "BOOT2" + + +/** + * Begin UDF extended volume descriptor area (@ecma167{2,9.2,33}). + */ +typedef struct UDFEXTVOLDESCBEGIN +{ + /** The volume descriptor header. + * The standard identifier is UDF_EXT_VOL_DESC_STD_ID_BEGIN. */ + ISO9660VOLDESCHDR Hdr; + /** Zero payload. */ + uint8_t abZero[2041]; +} UDFEXTVOLDESCBEGIN; +AssertCompileSize(UDFEXTVOLDESCBEGIN, 2048); +/** Pointer to an UDF extended volume descriptor indicating the start of the + * extended descriptor area. */ +typedef UDFEXTVOLDESCBEGIN *PUDFEXTVOLDESCBEGIN; +/** Pointer to a const UDF extended volume descriptor indicating the start of + * the extended descriptor area. */ +typedef UDFEXTVOLDESCBEGIN const *PCUDFEXTVOLDESCBEGIN; + + +/** + * Terminate UDF extended volume descriptor area (@ecma167{2,9.3,33}). + */ +typedef struct UDFEXTVOLDESCTERM +{ + /** The volume descriptor header. + * The standard identifier is UDF_EXT_VOL_DESC_STD_ID_TERM. */ + ISO9660VOLDESCHDR Hdr; + /** Zero payload. */ + uint8_t abZero[2041]; +} UDFEXTVOLDESCTERM; +AssertCompileSize(UDFEXTVOLDESCTERM, 2048); +/** Pointer to an UDF extended volume descriptor indicating the end of the + * extended descriptor area. */ +typedef UDFEXTVOLDESCTERM *PUDFEXTVOLDESCTERM; +/** Pointer to a const UDF extended volume descriptor indicating the end of + * the extended descriptor area. */ +typedef UDFEXTVOLDESCTERM const *PCUDFEXTVOLDESCTERM; + + +/** + * UDF NSR extended volume descriptor (@ecma167{3,9.1,50}). + * + * This gives the ECMA standard version. + */ +typedef struct UDFEXTVOLDESCNSR +{ + /** The volume descriptor header. + * The standard identifier is UDF_EXT_VOL_DESC_STD_ID_NSR_02, or + * UDF_EXT_VOL_DESC_STD_ID_NSR_03. */ + ISO9660VOLDESCHDR Hdr; + /** Zero payload. */ + uint8_t abZero[2041]; +} UDFEXTVOLDESCNSR; +AssertCompileSize(UDFEXTVOLDESCNSR, 2048); +/** Pointer to an extended volume descriptor giving the UDF standard version. */ +typedef UDFEXTVOLDESCNSR *PUDFEXTVOLDESCNSR; +/** Pointer to a const extended volume descriptor giving the UDF standard version. */ +typedef UDFEXTVOLDESCNSR const *PCUDFEXTVOLDESCNSR; + + +/** + * UDF boot extended volume descriptor (@ecma167{2,9.4,34}). + * + * @note Probably entirely unused. + */ +typedef struct UDFEXTVOLDESCBOOT +{ + /** 0x00: The volume descriptor header. + * The standard identifier is UDF_EXT_VOL_DESC_STD_ID_BOOT. */ + ISO9660VOLDESCHDR Hdr; + /** 0x07: Reserved/alignment, MBZ. */ + uint8_t bReserved1; + /** 0x08: The architecture type. */ + UDFENTITYID ArchType; + /** 0x28: The boot identifier. */ + UDFENTITYID idBoot; + /** 0x48: Logical sector number of load the boot loader from. */ + uint32_t offBootExtent; + /** 0x4c: Number of bytes to load. */ + uint32_t cbBootExtent; + /** 0x50: The load address (in memory). */ + uint64_t uLoadAddress; + /** 0x58: The start address (in memory). */ + uint64_t uStartAddress; + /** 0x60: The descriptor creation timestamp. */ + UDFTIMESTAMP CreationTimestamp; + /** 0x6c: Flags. */ + uint16_t fFlags; + /** 0x6e: Reserved, MBZ. */ + uint8_t abReserved2[32]; + /** 0x8e: Implementation use. */ + uint8_t abBootUse[1906]; +} UDFEXTVOLDESCBOOT; +AssertCompileSize(UDFEXTVOLDESCBOOT, 2048); +/** Pointer to a boot extended volume descriptor. */ +typedef UDFEXTVOLDESCBOOT *PUDFEXTVOLDESCBOOT; +/** Pointer to a const boot extended volume descriptor. */ +typedef UDFEXTVOLDESCBOOT const *PCUDFEXTVOLDESCBOOT; + +/** @} */ + + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_udf_h */ + diff --git a/include/iprt/formats/wim.h b/include/iprt/formats/wim.h new file mode 100644 index 00000000..063fcbfa --- /dev/null +++ b/include/iprt/formats/wim.h @@ -0,0 +1,160 @@ +/** @file + * IPRT - Windows Imaging (WIM) format. + */ + +/* + * Copyright (C) 2022-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_wim_h +#define IPRT_INCLUDED_formats_wim_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> +#include <iprt/uuid.h> + + +/** @defgroup grp_rt_formats_win Windows Imaging (WIM) format + * @ingroup grp_rt_formats + * + * Specification: + * http://download.microsoft.com/download/f/e/f/fefdc36e-392d-4678-9e4e-771ffa2692ab/Windows%20Imaging%20File%20Format.rtf + * + * @{ */ + + +/** + * A short WIM resource entry. + * + * This is a simplified version of the specs. + */ +typedef struct RESHDRDISKSHORT +{ + /** 0x00 - The compressed size. */ + RT_GCC_EXTENSION + uint64_t cb : 56; + /** 0x07 - Flags, RESHDR_FLAGS_XXX. */ + RT_GCC_EXTENSION + uint64_t bFlags : 8; + /** 0x08 - Offset. + * @note This is signed in the specficiation... */ + uint64_t off; + /** 0x10 - The uncompressed original size. + * @note This is signed in the specficiation... */ + uint64_t cbOriginal; +} RESHDRDISKSHORT; +AssertCompileSize(RESHDRDISKSHORT, 0x18); +/** Pointer to a short WIM resource entry. */ +typedef RESHDRDISKSHORT *PRESHDRDISKSHORT; +/** Pointer to a const short WIM resource entry. */ +typedef RESHDRDISKSHORT *PCRESHDRDISKSHORT; + +/** @name RESHDR_FLAGS_XXX + * @{ */ +#define RESHDR_FLAGS_FREE UINT8_C(0x01) +#define RESHDR_FLAGS_METADATA UINT8_C(0x02) +#define RESHDR_FLAGS_COMPRESSED UINT8_C(0x04) +#define RESHDR_FLAGS_SPANNED UINT8_C(0x08) +/** @} */ + +/** + * WIM file header, version 1. + * + * The field names have been normalized to our coding style. + */ +#pragma pack(4) +typedef struct WIMHEADERV1 +{ + /** 0x00 - Magic value WIMHEADER_MAGIC. */ + char szMagic[8]; + /** 0x08 - The size of this header structure. */ + uint32_t cbHeader; + /** 0x0c - The header version structure. */ + uint32_t uVersion; + /** 0x10 - Flags. */ + uint32_t fFlags; + /** 0x14 - ??. */ + uint32_t cbCompression; + /** 0x18 - Unique identifier. */ + RTUUID WIMGuid; + /** 0x28 - Part number in spanned (split) wim set. Unsplit use part number 1. */ + uint16_t idxPartNumber; + /** 0x2a - Total number of parts in spanned set. */ + uint16_t cTotalParts; + /** 0x2c - Number of images in the archive. */ + uint32_t cImages; + /** 0x30 - Resource lookup table offset & size. */ + RESHDRDISKSHORT OffsetTable; + /** 0x48 - XML data offset & size. */ + RESHDRDISKSHORT XmlData; + /** 0x60 - Boot metadata offset & size. */ + RESHDRDISKSHORT BootMetadata; + /** 0x78 - Bootable image index, zero if no bootable image. */ + uint32_t idxBoot; + /** 0x7c - Integrity data offset & size. + * @note Misaligned! */ + RESHDRDISKSHORT Integrity; + /** 0x94 - Reserved */ + uint8_t abUnused[60]; +} WIMHEADERV1; +#pragma pack() +AssertCompileSize(WIMHEADERV1, 0xd0); +/** Pointer to a XAR header. */ +typedef WIMHEADERV1 *PWIMHEADERV1; +/** Pointer to a const XAR header. */ +typedef WIMHEADERV1 const *PCWIMHEADERV1; + +/** The WIMHEADERV1::szMagic value. */ +#define WIMHEADER_MAGIC "MSWIM\0\0" +AssertCompile(sizeof(WIMHEADER_MAGIC) == 8); + +/** @name WIMHEADER_FLAGS_XXX - WINHEADERV1::fFlags. + * @note Specfication names these FLAG_HEADER_XXX. + * @{ */ +#define WIMHEADER_FLAGS_RESERVED RT_BIT_32(0) +#define WIMHEADER_FLAGS_COMPRESSION RT_BIT_32(1) +#define WIMHEADER_FLAGS_READONLY RT_BIT_32(2) +#define WIMHEADER_FLAGS_SPANNED RT_BIT_32(3) +#define WIMHEADER_FLAGS_RESOURCE_ONLY RT_BIT_32(4) +#define WIMHEADER_FLAGS_METADATA_ONLY RT_BIT_32(5) +#define WIMHEADER_FLAGS_WRITE_IN_PROGRESS RT_BIT_32(5) +#define WIMHEADER_FLAGS_RP_FIX RT_BIT_32(6) +#define WIMHEADER_FLAGS_COMPRESS_RESERVED RT_BIT_32(16) +#define WIMHEADER_FLAGS_COMPRESS_XPRESS RT_BIT_32(17) +#define WIMHEADER_FLAGS_COMPRESS_LZX RT_BIT_32(18) +/** @} */ + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_wim_h */ + diff --git a/include/iprt/formats/xar.h b/include/iprt/formats/xar.h new file mode 100644 index 00000000..c5cc0526 --- /dev/null +++ b/include/iprt/formats/xar.h @@ -0,0 +1,90 @@ +/** @file + * IPRT - Extensible Archiver (XAR) format. + */ + +/* + * Copyright (C) 2013-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_xar_h +#define IPRT_INCLUDED_formats_xar_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_xar Extensible Archive (XAR) format + * @ingroup grp_rt_formats + * + * @{ */ + +#pragma pack(4) /* Misdesigned header, not 8-byte aligned size. */ +typedef struct XARHEADER +{ + /** The magic number 'xar!' (XAR_HEADER_MAGIC). */ + uint32_t u32Magic; + /** The size of this header structure. */ + uint16_t cbHeader; + /** The header version structure. */ + uint16_t uVersion; + /** The size of the compressed table of content (TOC). */ + uint64_t cbTocCompressed; + /** The size of the table of context (TOC) when not compressed. */ + uint64_t cbTocUncompressed; + /** Which cryptographic hash function is used (XAR_HASH_XXX). */ + uint32_t uHashFunction; +} XARHEADER; +#pragma pack() +AssertCompileSize(XARHEADER, 28); +/** Pointer to a XAR header. */ +typedef XARHEADER *PXARHEADER; +/** Pointer to a const XAR header. */ +typedef XARHEADER const *PCXARHEADER; + +/** XAR magic value (on disk endian). */ +#define XAR_HEADER_MAGIC RT_H2LE_U32(RT_MAKE_U32_FROM_U8('x', 'a', 'r', '!')) +/** The current header version value (host endian). */ +#define XAR_HEADER_VERSION 1 + +/** @name XAR hashing functions. + * @{ */ +#define XAR_HASH_NONE 0 +#define XAR_HASH_SHA1 1 +#define XAR_HASH_MD5 2 +#define XAR_HASH_MAX 2 +/** @} */ + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_xar_h */ + diff --git a/include/iprt/formats/xfs.h b/include/iprt/formats/xfs.h new file mode 100644 index 00000000..6e5b3025 --- /dev/null +++ b/include/iprt/formats/xfs.h @@ -0,0 +1,721 @@ +/* $Id: xfs.h $ */ +/** @file + * IPRT, XFS format. + */ + +/* + * Copyright (C) 2018-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_formats_xfs_h +#define IPRT_INCLUDED_formats_xfs_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/assertcompile.h> + + +/** @defgroup grp_rt_formats_xfs XFS filesystem structures and definitions + * @ingroup grp_rt_formats + * @{ + */ + +/* + * The filesystem structures were retrieved from: + * http://xfs.org/docs/xfsdocs-xml-dev/XFS_Filesystem_Structure//tmp/en-US/html/index.html and + * https://elixir.bootlin.com/linux/v4.9/source/fs/xfs/libxfs/xfs_format.h and + * https://righteousit.wordpress.com/ + */ + +/** XFS superblock offset from the beginning of the volume, this is constant. */ +#define XFS_SB_OFFSET UINT64_C(0) + +/** @name Common XFS types as defined in the spec. + * @{ */ +/** Unsigned 64 bit absolute inode number. */ +typedef uint64_t XFSINO; +/** Signed 64 bit file offset. */ +typedef int64_t XFSFOFF; +/** Signed 64 bit disk address. */ +typedef int64_t XFSDADDR; +/** Unsinged 32 bit allocation group (AG) number. */ +typedef uint32_t XFSAGNUMBER; +/** Unsigned 32 bit AG relative block number. */ +typedef uint32_t XFSAGBLOCK; +/** Unsigned 32 bit extent length in blocks. */ +typedef uint32_t XFSEXTLEN; +/** Signed 32 bit number of extents in a file. */ +typedef int32_t XFSEXTNUM; +/** Unsigned 32 bit block number for directories and extended attributes. */ +typedef uint32_t XFSDABLK; +/** Unsigned 32 bit hash of a directory file name or extended attribute name. */ +typedef uint32_t XFSDAHASH; +/** Unsigned 64 bit filesystem block number combining AG number and block offset into the AG. */ +typedef uint64_t XFSDFSBNO; +/** Unsigned 64 bit raw filesystem block number. */ +typedef uint64_t XFSDRFSBNO; +/** Unsigned 64 bit extent number in the real-time device. */ +typedef uint64_t XFSDRTBNO; +/** Unsigned 64 bit block offset int oa file. */ +typedef uint64_t XFSDFILOFF; +/** Unsigned 64 bit block count for a file. */ +typedef uint64_t XFSDFILBLKS; +/** @} */ + +/** + * XFS superblock. + */ +#pragma pack(1) +typedef struct XFSSUPERBLOCK +{ + /** 0x00: Magic number to identify the superblock. */ + uint32_t u32Magic; + /** 0x04: Size of smallest allocation unit in bytes. */ + uint32_t cbBlock; + /** 0x04: Number of blocks available for data and metadata. */ + XFSDRFSBNO cBlocks; + /** 0x0c: Number of block in the real-time device. */ + XFSDRFSBNO cBlocksRtDev; + /** 0x14: Number of extents on real-time device. */ + XFSDRTBNO cExtentsRtDev; + /** 0x1c: UUID of the filesystem. */ + uint8_t abUuid[16]; + /** 0x2c: First block of the filesystem journal. */ + XFSDFSBNO uBlockJournal; + /** 0x34: Inode number of the root directory. */ + XFSINO uInodeRoot; + /** Inode for the real-time extent bitmap. */ + XFSINO uInodeBitmapRtExt; + /** Inode for the real-time bitmap summary. */ + XFSINO uInodeBitmapSummary; + /** Extent size on the real-time device in blocks. */ + XFSAGBLOCK cRtExtent; + /** Size of an AG in blocks. */ + XFSAGBLOCK cAgBlocks; + /** Number of AGs in hte filesystem. */ + XFSAGNUMBER cAg; + /** Number of real-time bitmap blocks. */ + XFSEXTLEN cRtBitmapBlocks; + /** Number of blocks for the journal. */ + XFSEXTLEN cJournalBlocks; + /** Version number (actually flag bitmaps of features). */ + uint16_t fVersion; + /** Sector size of the underlying medium. */ + uint16_t cbSector; + /** Size of an inode in bytes. */ + uint16_t cbInode; + /** Number of inodes stored in one block. */ + uint16_t cInodesPerBlock; + /** Name of the filesystem. */ + char achFsName[12]; + /** Block size as log2 (number of bits to shift left). */ + uint8_t cBlockSzLog; + /** Sector size as log2 (number of bits to shift left). */ + uint8_t cSectorSzLog; + /** Inode size as log2 (number of bits to shift left). */ + uint8_t cInodeSzLog; + /** Number of inodes per block as log2. */ + uint8_t cInodesPerBlockLog; + /** Number of AG blocks as log2 (number of bits to shift left). */ + uint8_t cAgBlocksLog; + /** Number of extent blocks as log2. */ + uint8_t cExtentsRtDevLog; + /** Flag when the filesystem is in the process of being created. */ + uint8_t fInProgress; + /** Maximum percentage of the filesystem usable for inodes. */ + uint8_t cInodeMaxPct; + /** Global number of inodes allocated (only mainted on the first superblock). */ + uint64_t cInodesGlobal; + /** Global number of free inodes (only mainted on the first superblock). */ + uint64_t cInodesGlobalFree; + /** Global count of free data blocks on the filesystem (only mainted on the first superblock). */ + uint64_t cBlocksFree; + /** Global count of free extents on the real-time device (only mainted on the first superblock). */ + uint64_t cExtentsRtFree; + /** Inode containing the user quotas. */ + XFSINO uInodeQuotaUsr; + /** Inode containing the group/project quotas. */ + XFSINO uInodeQuotaGrp; + /** Quota flags. */ + uint16_t fQuotaFlags; + /** Misc flags. */ + uint8_t fFlagsMisc; + /** Reserved MBZ. */ + uint8_t uSharedVn; + /** Number of filesystem blocks for the inode chunk alignment. */ + XFSEXTLEN cBlocksInodeAlignment; + /** Raid stripe size in blocks. */ + uint32_t cBlocksRaidStripe; + /** Raid width in number of blocks. */ + uint32_t cBlocksRaidWidth; + /** Multiplier for determining the allocation size for directory blocks as log2. */ + uint8_t cDirBlockAllocLog; + /** Sub volume sector size as log2 if an external journal device is used. */ + uint8_t cLogDevSubVolSectorSzLog; + /** Sector size of the device an external journal is stored as log2. */ + uint16_t cLogDevSectorSzLog; + /** Log devices stripe size. */ + uint32_t cLogDevRaidStripe; + /** Additional features which may be active. */ + uint32_t fFeatures2; + /** Padding. */ + uint32_t u32Padding0; + /** From here follow data only available from version 5 and later. */ + /** Read/Write feature flags. */ + uint32_t fFeaturesRw; + /** Read-only feature flags. */ + uint32_t fFeaturesRo; + /** Read/Write incompatible feature flags. */ + uint32_t fFeaturesIncompatRw; + /** Read/Write incompatible feature flags for the journal. */ + uint32_t fFeaturesJrnlIncompatRw; + /** CRC32 checksum for the superblock. */ + uint32_t u32Chksum; + /** Sparse inode alignment. */ + uint32_t u32SparseInodeAlignment; + /** Project quota inode. */ + XFSINO uInodeProjectQuota; + /** Log sequence number of last superblock update. */ + uint64_t uJrnlSeqSbUpdate; + /** UUID used when INCOMPAT_META_UUID is used. */ + uint8_t abUuidMeta[16]; + /** Inode if INCOMPATMETA_RMAPBT is used. */ + XFSINO uInodeRm; +} XFSSUPERBLOCK; +#pragma pack() +AssertCompileSize(XFSSUPERBLOCK, 272); +/** Pointer to an XFS superblock. */ +typedef XFSSUPERBLOCK *PXFSSUPERBLOCK; +/** Pointer to a const XFS superblock. */ +typedef const XFSSUPERBLOCK *PCXFSSUPERBLOCK; + +/** XFS superblock magic. */ +#define XFS_SB_MAGIC RT_MAKE_U32_FROM_U8('B', 'S', 'F', 'X') + +/** @name XFS_SB_VERSION_F_XXX - Version/Feature flags. + * @{ */ +/** Retrieves the version part of the field. */ +#define XFS_SB_VERSION_GET(a_fVersion) ((a_fVersion) & 0xf) +/** Version number for filesystem 5.3, 6.0.1 and 6.1. */ +#define XFS_SB_VERSION_1 1 +/** Version number for filesystem 6.2 - attributes. */ +#define XFS_SB_VERSION_2 2 +/** Version number for filesystem 6.2 - new inode version. */ +#define XFS_SB_VERSION_3 3 +/** Version number for filesystem 6.2+ - new bitmask version. */ +#define XFS_SB_VERSION_4 4 +/** Introduced checksums in the metadata. */ +#define XFS_SB_VERSION_5 5 +/** Extended attributes are used for at least one inode. */ +#define XFS_SB_VERSION_F_ATTR RT_BIT_32(4) +/** At least one inode use 32-bit nlink values. */ +#define XFS_SB_VERSION_F_NLINK RT_BIT_32(5) +/** Quotas are enabled on the filesystem. */ +#define XFS_SB_VERSION_F_QUOTA RT_BIT_32(6) +/** Set if XFSSUPERBLOCK::cBlocksInodeAlignment is used. */ +#define XFS_SB_VERSION_F_ALIGN RT_BIT_32(7) +/** Set if XFSSUPERBLOCK::cBlocksRaidStripe and XFSSUPERBLOCK::cBlocksRaidWidth are used. */ +#define XFS_SB_VERSION_F_DALIGN RT_BIT_32(8) +/** Set if XFSSUPERBLOCK::uSharedVn is used. */ +#define XFS_SB_VERSION_F_SHARED RT_BIT_32(9) +/** Version 2 journaling is used. */ +#define XFS_SB_VERSION_F_LOGV2 RT_BIT_32(10) +/** Set if sector size is not 512 bytes. */ +#define XFS_SB_VERSION_F_SECTOR RT_BIT_32(11) +/** Set if unwritten extents are used (always set). */ +#define XFS_SB_VERSION_F_EXTFLG RT_BIT_32(12) +/** Version 2 directories are used (always set). */ +#define XFS_SB_VERSION_F_DIRV2 RT_BIT_32(13) +/** Set if XFSSUPERBLOCK::fFeatures2 is used. */ +#define XFS_SB_VERSION_F_FEAT2 RT_BIT_32(14) +/** @} */ + +/** @name XFS_SB_QUOTA_F_XXX - Quota flags + * @{ */ +/** User quota accounting enabled. */ +#define XFS_SB_QUOTA_F_USR_ACCT RT_BIT(0) +/** User quotas are enforced. */ +#define XFS_SB_QUOTA_F_USR_ENFD RT_BIT(1) +/** User quotas have been checked and updated on disk. */ +#define XFS_SB_QUOTA_F_USR_CHKD RT_BIT(2) +/** Project quota accounting is enabled. */ +#define XFS_SB_QUOTA_F_PROJ_ACCT RT_BIT(3) +/** Other quotas are enforced. */ +#define XFS_SB_QUOTA_F_OTH_ENFD RT_BIT(4) +/** Other quotas have been checked and updated on disk. */ +#define XFS_SB_QUOTA_F_OTH_CHKD RT_BIT(5) +/** Group quota accounting enabled. */ +#define XFS_SB_QUOTA_F_GRP_ACCT RT_BIT(6) +/** @} */ + +/** @name XFS_SB_FEATURES2_F_XXX - Additional features + * @{ */ +/** Global counters are lazy and are only updated when the filesystem is cleanly unmounted. */ +#define XFS_SB_FEATURES2_F_LAZYSBCOUNT RT_BIT_32(1) +/** Extended attributes version 2. */ +#define XFS_SB_FEATURES2_F_ATTR2 RT_BIT_32(3) +/** Parent pointers, inodes must have an extended attribute pointing to the parent inode. */ +#define XFS_SB_FEATURES2_F_PARENT RT_BIT_32(4) +/** @} */ + + +/** + * XFS AG free space block. + */ +typedef struct XFSAGF +{ + /** Magic number. */ + uint32_t u32Magic; + /** Header version number. */ + uint32_t uVersion; + /** AG number for the sector. */ + uint32_t uSeqNo; + /** Length of the AG in filesystem blocks. */ + uint32_t cLengthBlocks; + /** Block numbers for the roots of the free space B+trees. */ + uint32_t auRoots[3]; + /** Depths of the free space B+trees. */ + uint32_t acLvls[3]; + /** Index of the first free list block. */ + uint32_t idxFreeListFirst; + /** Index of the last free list block. */ + uint32_t idxFreeListLast; + /** Number of blocks in the free list. */ + uint32_t cFreeListBlocks; + /** Current number of free blocks in the AG. */ + uint32_t cFreeBlocks; + /** Longest number of contiguous free blocks in the AG. */ + uint32_t cFreeBlocksLongest; + /** Number of blocks used for the free space B+-trees. */ + uint32_t cBlocksBTrees; + /** UUID of filesystem the AG belongs to. */ + uint8_t abUuid[16]; + /** Number of blocks used for the reverse map. */ + uint32_t cBlocksRevMap; + /** Number of blocks used for the refcount B+-tree. */ + uint32_t cBlocksRefcountBTree; + /** Block number for the refcount tree root. */ + uint32_t uRootRefcount; + /** Depth of the refcount B+-tree. */ + uint32_t cLvlRefcount; + /** Reserved contiguous space for future extensions. */ + uint64_t au64Rsvd[14]; + /** Last write sequence number. */ + uint64_t uSeqNoLastWrite; + /** CRC of the AGF. */ + uint32_t uChkSum; + /** Padding to 64 bit alignment. */ + uint32_t uAlignment0; +} XFSAGF; +/** Pointer to a AG free space block. */ +typedef XFSAGF *PXFSAGF; +/** Poiner to a const AG free space block. */ +typedef const XFSAGF *PCXFSAGF; + +/** AGF magic. */ +#define XFS_AGF_MAGIC RT_MAKE_U32_FROM_U8('F', 'G', 'A', 'X') +/** The current valid AGF version. */ +#define XFS_AGF_VERSION 1 + + +/** + * XFS AG inode information. + */ +typedef struct XFSAGI +{ + /** Magic number. */ + uint32_t u32Magic; + /** Header version number. */ + uint32_t uVersion; + /** AG number for the sector. */ + uint32_t uSeqNo; + /** Length of the AG in filesystem blocks. */ + uint32_t cLengthBlocks; + /** Count of allocated inodes. */ + uint32_t cInodesAlloc; + /** Block number of the inode tree root. */ + uint32_t uRootInode; + /** Depth of the inode B+-tree. */ + uint32_t cLvlsInode; + /** Newest allocated inode. */ + uint32_t uInodeNew; + /** Last directory inode chunk. */ + uint32_t uInodeDir; + /** Hash table of unlinked but still referenced inodes. */ + uint32_t au32HashUnlinked[64]; + /** UUID of filesystem. */ + uint8_t abUuid[16]; + /** CRC of the AGI. */ + uint32_t uChkSum; + /** Padding. */ + uint32_t uAlignment0; + /** Last write sequence number. */ + uint64_t uSeqNoLastWrite; + /** Block number of the free inode tree. */ + uint32_t uRootFreeInode; + /** Depth of the free inode B+-tree. */ + uint32_t cLvlsFreeInode; +} XFSAGI; +/** Pointer to a AG inode information. */ +typedef XFSAGI *PXFSAGI; +/** Pointer to a const AG inode information. */ +typedef const XFSAGI *PCXFSAGI; + +/** AGI magic. */ +#define XFS_AGI_MAGIC RT_MAKE_U32_FROM_U8('I', 'G', 'A', 'X') +/** The current valid AGI version. */ +#define XFS_AGI_VERSION 1 + + +/** + * XFS timestamp structure. + */ +typedef struct XFSTIMESTAMP +{ + /** 0x00: The second part of the timestamp since the epoch. */ + int32_t cSecEpoch; + /** 0x04: Nanosecond part of the timestamp. */ + int32_t cNanoSec; +} XFSTIMESTAMP; +/** Pointer to a XFS timestamp. */ +typedef XFSTIMESTAMP *PXFSTIMESTAMP; +/** Poiner to a const CFS timestamp. */ +typedef const XFSTIMESTAMP *PCXFSTIMESTAMP; + + +/** + * The inode core structure. + */ +typedef struct XFSINODECORE +{ + /** 0x00: Magic value. */ + uint16_t u16Magic; + /** 0x02: File mode and access bits (XFS_INODE_MODE_XXX). */ + uint16_t fMode; + /** 0x04: Inode version. */ + int8_t iVersion; + /** 0x05: The format of the data fork. */ + int8_t enmFormat; + /** 0x06: Number of links to this inode from directories for v1 inodes. */ + uint16_t cOnLinks; + /** 0x08: Owners UID. */ + uint32_t uUid; + /** 0x0c: Owners GID. */ + uint32_t uGid; + /** 0x10: The number of links to this inode for v2 inodes. */ + uint32_t cLinks; + /** 0x14: Project ID for v2 inodes (not used for v1, low 16bits). */ + uint16_t uProjIdLow; + /** 0x16: Project ID for v2 inodes (not used for v1, high 16bits). */ + uint16_t uProjIdHigh; + /** 0x18: Padding. */ + uint8_t abPad0[6]; + /** 0x1e: Flush counter. */ + uint16_t cFlush; + /** 0x20: Last accessed timestamp. */ + XFSTIMESTAMP TsLastAccessed; + /** 0x28: Last modified timestamp. */ + XFSTIMESTAMP TsLastModified; + /** 0x30: Inode created/modified timestamp. */ + XFSTIMESTAMP TsCreatedModified; + /** 0x38: Number of bytes in the file. */ + uint64_t cbInode; + /** 0x40: Number of direct and B-Tree blocks used for the forks. */ + uint64_t cBlocks; + /** 0x48: Minimum extent size for the inode. */ + uint32_t cExtentBlocksMin; + /** 0x4c: Number of extents in the data fork. */ + uint32_t cExtentsData; + /** 0x50: Number of extents in the attribute fork. */ + uint16_t cExtentsAttr; + /** 0x52: Offset of the attribute fork from the start of the inode. */ + uint8_t offAttrFork; + /** 0x53: Attribute fork format. */ + int8_t enmFormatAttr; + /** 0x54: DMIG event mask. */ + uint32_t fEvtMaskDmig; + /** 0x58: DMIG state info. */ + uint16_t uStateDmig; + /** 0x5a: Inode flags. */ + uint16_t fFlags; + /** 0x5c: Generation number. */ + uint32_t cGeneration; + /** 0x60: AGI unlinked list pointer. */ + uint32_t offBlockUnlinkedNext; + /** The following fields are for v3 inodes only. */ + /** 0x64: The CRC of the inode. */ + uint32_t uChkSum; + /** 0x68: Number of attribute changes. */ + uint64_t cAttrChanges; + /** 0x70: Last flush sequence number. */ + uint64_t uFlushSeqNo; + /** 0x78: Additional flags. */ + uint64_t fFlags2; + /** 0x80: Basic COW extent size. */ + uint32_t cExtentCowMin; + /** 0x84: Padding for future expansion. */ + uint8_t abPad1[12]; + /** 0x90: Inode creation timestamp. */ + XFSTIMESTAMP TsCreation; + /** 0x98: The inode number. */ + uint64_t uInode; + /** 0x100: Filesystem UUID the inode belongs to. */ + uint8_t abUuid[16]; +} XFSINODECORE; +AssertCompileSizeAlignment(XFSINODECORE, 8); +/** Pointer to a inode core. */ +typedef XFSINODECORE *PXFSINODECORE; +/** Pointer to a const inode core. */ +typedef const XFSINODECORE *PCXFSINODECORE; + +/** Inode magic. */ +#define XFS_INODE_MAGIC RT_MAKE_U16_FROM_U8('N', 'I') + +/** @name XFS_INODE_MODE_XXX - File mode + * @{ */ +/** Others can execute the file. */ +#define XFS_INODE_MODE_EXEC_OTHER RT_BIT(0) +/** Others can write to the file. */ +#define XFS_INODE_MODE_WRITE_OTHER RT_BIT(1) +/** Others can read the file. */ +#define XFS_INODE_MODE_READ_OTHER RT_BIT(2) +/** Members of the same group can execute the file. */ +#define XFS_INODE_MODE_EXEC_GROUP RT_BIT(3) +/** Members of the same group can write to the file. */ +#define XFS_INODE_MODE_WRITE_GROUP RT_BIT(4) +/** Members of the same group can read the file. */ +#define XFS_INODE_MODE_READ_GROUP RT_BIT(5) +/** Owner can execute the file. */ +#define XFS_INODE_MODE_EXEC_OWNER RT_BIT(6) +/** Owner can write to the file. */ +#define XFS_INODE_MODE_WRITE_OWNER RT_BIT(7) +/** Owner can read the file. */ +#define XFS_INODE_MODE_READ_OWNER RT_BIT(8) +/** Sticky file mode. */ +#define XFS_INODE_MODE_STICKY RT_BIT(9) +/** File is set GID. */ +#define XFS_INODE_MODE_SET_GROUP_ID RT_BIT(10) +/** File is set UID. */ +#define XFS_INODE_MODE_SET_USER_ID RT_BIT(11) +/** @} */ + +/** @name XFS_INODE_MODE_TYPE_XXX - File type + * @{ */ +/** Inode represents a FIFO. */ +#define XFS_INODE_MODE_TYPE_FIFO UINT16_C(0x1000) +/** Inode represents a character device. */ +#define XFS_INODE_MODE_TYPE_CHAR UINT16_C(0x2000) +/** Inode represents a directory. */ +#define XFS_INODE_MODE_TYPE_DIR UINT16_C(0x4000) +/** Inode represents a block device. */ +#define XFS_INODE_MODE_TYPE_BLOCK UINT16_C(0x6000) +/** Inode represents a regular file. */ +#define XFS_INODE_MODE_TYPE_REGULAR UINT16_C(0x8000) +/** Inode represents a symlink. */ +#define XFS_INODE_MODE_TYPE_SYMLINK UINT16_C(0xa000) +/** Inode represents a socket. */ +#define XFS_INODE_MODE_TYPE_SOCKET UINT16_C(0xc000) +/** Returns the inode type from the combined mode field. */ +#define XFS_INODE_MODE_TYPE_GET_TYPE(a_Mode) ((a_Mode) & 0xf000) +/** @} */ + +/** @name XFS_INODE_FORMAT_XXX - Inode data fork format. + * @{ */ +/** Device node data. */ +#define XFS_INODE_FORMAT_DEV 0 +/** Inline data. */ +#define XFS_INODE_FORMAT_LOCAL 1 +/** Array of extent descriptors. */ +#define XFS_INODE_FORMAT_EXTENTS 2 +/** Data fork contains root of B-Tree. */ +#define XFS_INODE_FORMAT_BTREE 3 +/** Data fork contains UUID. */ +#define XFS_INODE_FORMAT_UUID 4 +/** @} */ + +/** @name XFS_INODE_F_XXX - Inode flags. + * @{ */ +/** File data blocks are stored in the real-time device area. */ +#define XFS_INODE_F_RTDEV RT_BIT(0) +/** File space has been pre-allocated. */ +#define XFS_INODE_F_PREALLOC RT_BIT(1) +/** Use new real-time bitmap format. */ +#define XFS_INODE_F_NEWRTBITMAP RT_BIT(2) +/** Inode is immutable. */ +#define XFS_INODE_F_IMMUTABLE RT_BIT(3) +/** Inode is append only. */ +#define XFS_INODE_F_APPEND RT_BIT(4) +/** Inode is written synchronously. */ +#define XFS_INODE_F_SYNC RT_BIT(5) +/** The last accessed timestamp is not updated. */ +#define XFS_INODE_F_NOATIME RT_BIT(6) +/** The inode is not dumpable via dump(1). */ +#define XFS_INODE_F_NODUMP RT_BIT(7) +/** Create with real-time bit set. */ +#define XFS_INODE_F_RTINHERIT RT_BIT(8) +/** Create with parents project ID. */ +#define XFS_INODE_F_PROJIDINHERIT RT_BIT(9) +/** Deny symlink creation. */ +#define XFS_INODE_F_NOSYMLINKS RT_BIT(10) +/** Inode extent size allocator hint. */ +#define XFS_INODE_F_EXTSIZEHINT RT_BIT(11) +/** Inode extent size is inherited. */ +#define XFS_INODE_F_EXTSIZEINHERIT RT_BIT(12) +/** Do not defrag/reorganize the inode. */ +#define XFS_INODE_F_NODEFRAG RT_BIT(13) +/** Use filestream allocator. */ +#define XFS_INODE_F_FILESTREAM RT_BIT(14) +/** @} */ + +/** @name XFS_INODE_F2_XXX - Inode flags number 2 (XFSINODECORE::fFlags2). + * @{ */ +/** Use DAX for the inode. */ +#define XFS_INODE_F2_DAX RT_BIT_64(0) +/** Blocks use reference counting for sharing. */ +#define XFS_INODE_F2_REFLINK RT_BIT_64(1) +/** Inode COW extent size hint is valid. */ +#define XFS_INODE_F2_COWEXTSIZEHINT RT_BIT_64(2) +/** @} */ + + +/** + * Inode B-Tree record. + */ +typedef struct XFSINODEBTREEREC +{ + /** 0x00: Starting inode number. */ + uint32_t uInodeStart; + /** 0x04: Version dependent data. */ + union + { + /** Full (old) version. */ + struct + { + /** 0x04: Number of free inodes. */ + uint32_t cInodesFree; + } Full; + /** Sparse (new) version. */ + struct + { + /** 0x04: Hole mask for sparse chunks. */ + uint16_t bmHoles; + /** 0x06: Total number of inodes. */ + uint8_t cInodes; + /** 0x07: Number of free inodes. */ + uint8_t cInodesFree; + } Sparse; + } u; + /** 0x08: Free inode mask. */ + uint64_t bmInodesFree; +} XFSINODEBTREEREC; +/** Pointer to an inode B-Tree record. */ +typedef XFSINODEBTREEREC *PXFSINODEBTREEREC; +/** Pointer to a const inode B-Tree record. */ +typedef const XFSINODEBTREEREC *PCXFSINODEBTREEREC; + + +/** + * XFS B+Tree root header. + */ +typedef struct XFSBTREEROOTHDR +{ + /** 0x00: Tree level. */ + uint16_t iLvl; + /** 0x02: Number of records. */ + uint16_t cRecs; +} XFSBTREEROOTHDR; +/** Pointer to a B+Tree root header */ +typedef XFSBTREEROOTHDR *PXFSBTREEROOTHDR; +/** Pointer to a const B+Tree root header. */ +typedef const XFSBTREEROOTHDR *PCXFSBTREEROOTHDR; + + +/** + * XFS B+Tree intermediate/leave node header. + */ +typedef struct XFSBTREENODEHDR +{ + /** 0x00: Magic identifying the node. */ + uint32_t u32Magic; + /** 0x04: Tree level. */ + uint16_t iLvl; + /** 0x06: Number of records. */ + uint16_t cRecs; + /** 0x08: Block number of the left sibling. */ + uint64_t uSibLeft; + /** 0x10: Block number of the right sibling. */ + uint64_t uSibRight; +} XFSBTREENODEHDR; +/** Pointer to a B+Tree intermediate/leave node header. */ +typedef XFSBTREENODEHDR *PXFSBTREENODEHDR; +/** Pointer to a const B+Tree intermediate/leave node header. */ +typedef const XFSBTREENODEHDR *PCXFSBTREENODEHDR; + +/** @name XFS_BTREENODEHDR_XXX - B+Tree node related defines. + * @{ */ +/** Magic for the tree node header. */ +#define XFS_BTREENODEHDR_MAGIC RT_MAKE_U32_FROM_U8('P', 'A', 'M', 'B') +/** @} */ + + +/** + * XFS Extent. + */ +typedef struct XFSEXTENT +{ + /** 0x00: Low 64 bits. */ + uint64_t u64Low; + /** 0x08: High 64 bits. */ + uint64_t u64High; +} XFSEXTENT; +/** Pointer to an XFS extent. */ +typedef XFSEXTENT *PXFSEXTENT; +/** Pointer to a const XFS extent. */ +typedef const XFSEXTENT *PCXFSEXTENT; + +/** @name XFS_EXTENT_XXX - Extent related getters. + * @{ */ +/** Returns whether the extent is allocated but unwritten (true) or a normal extent (false). */ +#define XFS_EXTENT_IS_UNWRITTEN(a_pExtent) (RT_BOOL((a_pExtent)->u64High & RT_BIT_64(63))) +/** Returns the number of blocks the extent covers. */ +#define XFS_EXTENT_GET_BLOCK_COUNT(a_pExtent) ((a_pExtent)->u64Low & UINT64_C(0x1fffff)) +/** Returns the absolute block number where the data is stored on the disk. */ +#define XFS_EXTENT_GET_DISK_BLOCK(a_pExtent) ( (((a_pExtent)->u64High & UINT64_C(0x1ff)) << 42) \ + | (((a_pExtent)->u64Low & UINT64_C(0xffffffffffe00000)) >> 21)) +/** Returns the logical inode block offset. */ +#define XFS_EXTENT_GET_LOGICAL_BLOCK(a_pExtent) (((a_pExtent)->u64High & UINT64_C(0x7ffffffffffffe00)) >> 9) +/** @} */ + +/** @} */ + +#endif /* !IPRT_INCLUDED_formats_xfs_h */ + |