summaryrefslogtreecommitdiffstats
path: root/include/iprt/formats
diff options
context:
space:
mode:
Diffstat (limited to 'include/iprt/formats')
-rw-r--r--include/iprt/formats/Makefile.kup0
-rw-r--r--include/iprt/formats/asn1.h97
-rw-r--r--include/iprt/formats/codeview.h860
-rw-r--r--include/iprt/formats/dwarf.h532
-rw-r--r--include/iprt/formats/dwarf.mac461
-rw-r--r--include/iprt/formats/elf-amd64.h131
-rw-r--r--include/iprt/formats/elf-common.h340
-rw-r--r--include/iprt/formats/elf-i386.h134
-rw-r--r--include/iprt/formats/elf.h88
-rw-r--r--include/iprt/formats/elf32.h190
-rw-r--r--include/iprt/formats/elf64.h189
-rw-r--r--include/iprt/formats/ext.h988
-rw-r--r--include/iprt/formats/fat.h749
-rw-r--r--include/iprt/formats/hfs.h680
-rw-r--r--include/iprt/formats/iso9660.h1504
-rw-r--r--include/iprt/formats/lx.h506
-rw-r--r--include/iprt/formats/mach-o.h773
-rw-r--r--include/iprt/formats/mz.h67
-rw-r--r--include/iprt/formats/mz.mac56
-rw-r--r--include/iprt/formats/ntfs.h770
-rw-r--r--include/iprt/formats/omf.h250
-rw-r--r--include/iprt/formats/pe.mac722
-rw-r--r--include/iprt/formats/pecoff.h2171
-rw-r--r--include/iprt/formats/tracelog.h229
-rw-r--r--include/iprt/formats/udf.h2214
-rw-r--r--include/iprt/formats/xar.h80
-rw-r--r--include/iprt/formats/xfs.h639
27 files changed, 15420 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/asn1.h b/include/iprt/formats/asn1.h
new file mode 100644
index 00000000..3bae997c
--- /dev/null
+++ b/include/iprt/formats/asn1.h
@@ -0,0 +1,97 @@
+/** @file
+ * IPRT - Abstract Syntax Notation One (ASN.1) Definitions.
+ */
+
+/*
+ * Copyright (C) 2014-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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/codeview.h b/include/iprt/formats/codeview.h
new file mode 100644
index 00000000..5ae95002
--- /dev/null
+++ b/include/iprt/formats/codeview.h
@@ -0,0 +1,860 @@
+/** @file
+ * IPRT - Microsoft CodeView Debug Information.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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/dwarf.h b/include/iprt/formats/dwarf.h
new file mode 100644
index 00000000..f6e820d4
--- /dev/null
+++ b/include/iprt/formats/dwarf.h
@@ -0,0 +1,532 @@
+/** @file
+ * IPRT - DWARF constants.
+ *
+ * @note dwarf.mac is generated from this file by running 'kmk incs' in the root.
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..fbf2dcda
--- /dev/null
+++ b/include/iprt/formats/dwarf.mac
@@ -0,0 +1,461 @@
+;; @file
+; IPRT - DWARF constants.
+;
+; Automatically generated by various.sed. DO NOT EDIT!
+;
+
+;
+; Copyright (C) 2006-2019 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; The contents of this file may alternatively be used under the terms
+; of the Common Development and Distribution License Version 1.0
+; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+; VirtualBox OSE 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.
+;
+
+%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/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..8f9dd860
--- /dev/null
+++ b/include/iprt/formats/elf-common.h
@@ -0,0 +1,340 @@
+/*-
+ * 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. */
+
+/* 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
+
+/* 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..a5311cb7
--- /dev/null
+++ b/include/iprt/formats/elf.h
@@ -0,0 +1,88 @@
+/* $Id: elf.h $ */
+/** @file
+ * ELF types, current architecture.
+ */
+
+/*
+ * Copyright (C) 2010-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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)
+# 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..2d9d69e8
--- /dev/null
+++ b/include/iprt/formats/elf32.h
@@ -0,0 +1,190 @@
+/* $Id: elf32.h $ */
+/** @file
+ * IPRT - ELF 32-bit header.
+ */
+
+/*
+ * Copyright (C) 2010-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..c618cda6
--- /dev/null
+++ b/include/iprt/formats/elf64.h
@@ -0,0 +1,189 @@
+/* $Id: elf64.h $ */
+/** @file
+ * IPRT - ELF 64-bit header.
+ */
+
+/*
+ * Copyright (C) 2010-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..068012cd
--- /dev/null
+++ b/include/iprt/formats/ext.h
@@ -0,0 +1,988 @@
+/* $Id: ext.h $ */
+/** @file
+ * IPRT, Ext2/3/4 format.
+ */
+
+/*
+ * Copyright (C) 2012-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..7addb0e5
--- /dev/null
+++ b/include/iprt/formats/fat.h
@@ -0,0 +1,749 @@
+/* $Id: fat.h $ */
+/** @file
+ * IPRT, File Allocation Table (FAT).
+ */
+
+/*
+ * Copyright (C) 2017-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..687a75e2
--- /dev/null
+++ b/include/iprt/formats/hfs.h
@@ -0,0 +1,680 @@
+/** @file
+ * IPRT - Hierarchical File System (HFS).
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..4d05e4f6
--- /dev/null
+++ b/include/iprt/formats/iso9660.h
@@ -0,0 +1,1504 @@
+/* $Id: iso9660.h $ */
+/** @file
+ * IPRT, ISO 9660 File System
+ */
+
+/*
+ * Copyright (C) 2017-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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). */
+ 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. */
+ 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 historically 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..95c8b479
--- /dev/null
+++ b/include/iprt/formats/lx.h
@@ -0,0 +1,506 @@
+/* $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
+
+#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)
+/** @} */
+
+
+/** @name 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
+/** @} */
+
+/** @} */
+
+
+/** @name 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);
+
+
+/** @name 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..c21ca2d1
--- /dev/null
+++ b/include/iprt/formats/mach-o.h
@@ -0,0 +1,773 @@
+/* $Id: mach-o.h $ */
+/** @file
+ * IPRT - Mach-O Structures and Constants.
+ */
+
+/*
+ * Copyright (C) 2011-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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_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_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_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;
+ int32_t cputype;
+ int32_t cpusubtype;
+ uint32_t filetype;
+ uint32_t ncmds;
+ uint32_t sizeofcmds;
+ uint32_t flags;
+ uint32_t reserved;
+} mach_header_64_t;
+
+/* 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_VALID_FLAGS UINT32_C(0x01ffffff)
+
+
+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)
+#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)
+
+/* 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. */
+ 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 */
+ uint32_t cmdsize; /**< Size of this structure. */
+ 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 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..c0ca9766
--- /dev/null
+++ b/include/iprt/formats/mz.h
@@ -0,0 +1,67 @@
+/* $Id: mz.h $ */
+/** @file
+ * IPRT, MZ Executable Header.
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..d5c3206f
--- /dev/null
+++ b/include/iprt/formats/mz.mac
@@ -0,0 +1,56 @@
+;; @file
+; IPRT - MZ (DOS Executable Header) definitions for YASM/NASM.
+;
+
+;
+; Copyright (C) 2006-2019 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; The contents of this file may alternatively be used under the terms
+; of the Common Development and Distribution License Version 1.0
+; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+; VirtualBox OSE 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.
+;
+
+%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..eaa1bdbe
--- /dev/null
+++ b/include/iprt/formats/ntfs.h
@@ -0,0 +1,770 @@
+/* $Id: ntfs.h $ */
+/** @file
+ * IPRT, NT File System (NTFS).
+ */
+
+/*
+ * Copyright (C) 2017-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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. */
+ 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. */
+ 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..fb6f1ff8
--- /dev/null
+++ b/include/iprt/formats/omf.h
@@ -0,0 +1,250 @@
+/* $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-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..8ec3cb33
--- /dev/null
+++ b/include/iprt/formats/pe.mac
@@ -0,0 +1,722 @@
+;; @file
+; IPRT - Windows PE definitions for YASM/NASM.
+;
+
+;
+; Copyright (C) 2006-2019 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; The contents of this file may alternatively be used under the terms
+; of the Common Development and Distribution License Version 1.0
+; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+; VirtualBox OSE 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.
+;
+
+%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..a4711b89
--- /dev/null
+++ b/include/iprt/formats/pecoff.h
@@ -0,0 +1,2171 @@
+/* $Id: pecoff.h $ */
+/** @file
+ * IPRT - Windows NT PE & COFF Structures and Constants.
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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. */
+ 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 Aslo know as UNW_FLAG_NHANDLER. */
+#define IMAGE_UNW_FLAGS_NHANDLER 0
+/** Have exception handler (RVA after codes, dword aligned.)
+ * @note Aslo know as UNW_FLAG_NHANDLER. */
+#define IMAGE_UNW_FLAGS_EHANDLER 1
+/** Have unwind handler (RVA after codes, dword aligned.)
+ * @note Aslo 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 AddressOfSomeUnicodeString; /**< 0x98 - 64-bit version has this member about here. not sure about location yet. */
+ uint32_t Reserved3QuestionMark; /**< 0x9a - Did they 8-byte pad the structure or is AddressOfSomeUnicodeString 64-bit? */
+} 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;
+
+typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V9 IMAGE_LOAD_CONFIG_DIRECTORY32;
+typedef PIMAGE_LOAD_CONFIG_DIRECTORY32_V9 PIMAGE_LOAD_CONFIG_DIRECTORY32;
+typedef PCIMAGE_LOAD_CONFIG_DIRECTORY32_V9 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 AddressOfSomeUnicodeString; /**< 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;
+
+typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V9 IMAGE_LOAD_CONFIG_DIRECTORY64;
+typedef PIMAGE_LOAD_CONFIG_DIRECTORY64_V9 PIMAGE_LOAD_CONFIG_DIRECTORY64;
+typedef PCIMAGE_LOAD_CONFIG_DIRECTORY64_V9 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. */
+#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/tracelog.h b/include/iprt/formats/tracelog.h
new file mode 100644
index 00000000..756a7945
--- /dev/null
+++ b/include/iprt/formats/tracelog.h
@@ -0,0 +1,229 @@
+/* $Id: tracelog.h $ */
+/** @file
+ * IPRT, Binary trace log format.
+ */
+
+/*
+ * Copyright (C) 2018-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..06a59b00
--- /dev/null
+++ b/include/iprt/formats/udf.h
@@ -0,0 +1,2214 @@
+/* $Id: udf.h $ */
+/** @file
+ * IPRT, Universal Disk Format (UDF).
+ */
+
+/*
+ * Copyright (C) 2017-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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. */
+ 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). */
+ 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.
+ */
+ 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. */
+ 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. */
+ 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. */
+ 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. */
+ 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. */
+ 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/xar.h b/include/iprt/formats/xar.h
new file mode 100644
index 00000000..a20c40be
--- /dev/null
+++ b/include/iprt/formats/xar.h
@@ -0,0 +1,80 @@
+/** @file
+ * IPRT - Extensible Archiver (XAR) format.
+ */
+
+/*
+ * Copyright (C) 2013-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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..84496b62
--- /dev/null
+++ b/include/iprt/formats/xfs.h
@@ -0,0 +1,639 @@
+/* $Id: xfs.h $ */
+/** @file
+ * IPRT, XFS format.
+ */
+
+/*
+ * Copyright (C) 2018-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#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 exten 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;
+
+
+/** @} */
+
+#endif /* !IPRT_INCLUDED_formats_xfs_h */
+