mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
patterns/includes: Update standard library and patterns to support the new bitfields (#102)
* Add `current_bit_offset()` and `read_bits(...)` to `std::mem` * Replace deprecated BitfieldOrder enum values with new clearer names This adds new options named `MostToLeastSignificant` and `LeastToMostSignificant` to replace the old `LeftToRight` and `RightToLeft` names. These names should be much clearer about what they affect and how. * Throw errors when `std::core::(get|set)_bitfield_order()` are called * Update all patterns to work with the new bitfield behaviors
This commit is contained in:
@@ -10,11 +10,21 @@
|
||||
namespace std::core {
|
||||
|
||||
/**
|
||||
The default ordering of bitfield members
|
||||
The layout order of each field after byte-endianness has been handled.
|
||||
|
||||
`LeftToRight` and `RightToLeft` are deprecated in favor of the clearer `MostToLeastSignificant` and `LeastToMostSignificant` names.
|
||||
*/
|
||||
enum BitfieldOrder : u8 {
|
||||
/**
|
||||
@warning deprecated
|
||||
*/
|
||||
LeftToRight = 0,
|
||||
RightToLeft = 1
|
||||
/**
|
||||
@warning deprecated
|
||||
*/
|
||||
RightToLeft = 1,
|
||||
MostToLeastSignificant = 0,
|
||||
LeastToMostSignificant = 1
|
||||
};
|
||||
|
||||
|
||||
@@ -56,19 +66,17 @@ namespace std::core {
|
||||
|
||||
|
||||
/**
|
||||
Sets the default bitfield order.
|
||||
@param order The new default bitfield order
|
||||
@warning Removed in 1.28.0
|
||||
*/
|
||||
fn set_bitfield_order(BitfieldOrder order) {
|
||||
builtin::std::core::set_bitfield_order(u32(order));
|
||||
builtin::std::error("Runtime default bitfield order is no longer supported.\nConsider using `be` or `le` on your bitfield variables,\nor attach attribute `bitfield_order` to the bitfield.");
|
||||
};
|
||||
|
||||
/**
|
||||
Gets thee current default bitfield order
|
||||
@return The currently set default bitfield order
|
||||
@warning Removed in 1.28.0
|
||||
*/
|
||||
fn get_bitfield_order() {
|
||||
return builtin::std::core::get_bitfield_order();
|
||||
builtin::std::error("Runtime default bitfield order is no longer supported.\nConsider using `be` or `le` on your bitfield variables,\nor attach attribute `bitfield_order` to the bitfield.");
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -113,6 +113,27 @@ namespace std::mem {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Gets the current bit offset within the current byte that a bitfield will read.
|
||||
*/
|
||||
fn current_bit_offset() {
|
||||
return builtin::std::mem::current_bit_offset();
|
||||
};
|
||||
|
||||
/**
|
||||
Reads a number of bits from the specified bit offset within the specified byte
|
||||
@param byteOffset The byte offset within the data
|
||||
@param bitOffset The bit offset to start the read at within the current byte
|
||||
@param bitSize The total number of bits to read
|
||||
@return A u128 containing the value read
|
||||
*/
|
||||
fn read_bits(u128 byteOffset, u128 bitOffset, u64 bitSize) {
|
||||
byteOffset += bitOffset >> 3;
|
||||
bitOffset = bitOffset & 0x7;
|
||||
return builtin::std::mem::read_bits(byteOffset, bitOffset, bitSize);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Creates a new custom section with the given name
|
||||
@param name The name of the section
|
||||
|
||||
@@ -1,209 +1,209 @@
|
||||
#pragma MIME application/x-coff
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
enum Machine : u16 {
|
||||
Unknown = 0x0000,
|
||||
AM33 = 0x01D3,
|
||||
AMD64 = 0x8664,
|
||||
ARM = 0x01C0,
|
||||
ARM64 = 0xAA64,
|
||||
ARMNT = 0x01C4,
|
||||
EBC = 0x0EBC,
|
||||
I386 = 0x014C,
|
||||
IA64 = 0x0200,
|
||||
LOONGARCH32 = 0x6232,
|
||||
LOONGARCH64 = 0x6264,
|
||||
M32R = 0x9041,
|
||||
MIPS16 = 0x0226,
|
||||
MIPSFPU = 0x0366,
|
||||
MIPSFPU16 = 0x0466,
|
||||
POWERPC = 0x01F0,
|
||||
POWERPCFP = 0x01F0,
|
||||
R4000 = 0x0166,
|
||||
RISCV32 = 0x5032,
|
||||
RISCV64 = 0x5064,
|
||||
RISCV128 = 0x5128,
|
||||
SH3 = 0x01A2,
|
||||
SH3DSP = 0x01A3,
|
||||
SH4 = 0x01A6,
|
||||
SH5 = 0x01A8,
|
||||
THUMB = 0x01C2,
|
||||
WCEMIPSV2 = 0x0169
|
||||
};
|
||||
|
||||
bitfield Characteristics {
|
||||
relocsStripped : 1;
|
||||
executableImage : 1;
|
||||
lineNumsStripped : 1;
|
||||
localSymsStripped : 1;
|
||||
aggressiveWsTrim : 1;
|
||||
largeAddressAware : 1;
|
||||
padding : 1;
|
||||
bytesReversedLo : 1;
|
||||
_32BitMachine : 1;
|
||||
debugStripped : 1;
|
||||
removableRunFromSwap : 1;
|
||||
netRunFromSwap : 1;
|
||||
system : 1;
|
||||
dll : 1;
|
||||
upSystemOnly : 1;
|
||||
bytesReversedHi : 1;
|
||||
} [[right_to_left]];
|
||||
|
||||
enum Type : u16 {
|
||||
Null = 0,
|
||||
Void = 1,
|
||||
Char = 2,
|
||||
Short = 3,
|
||||
Int = 4,
|
||||
Long = 5,
|
||||
Float = 6,
|
||||
Double = 7,
|
||||
Struct = 8,
|
||||
Union = 9,
|
||||
Enum = 10,
|
||||
MOE = 11,
|
||||
Byte = 12,
|
||||
Word = 13,
|
||||
UInt = 14,
|
||||
DWord = 15
|
||||
};
|
||||
|
||||
enum StorageClass : u8 {
|
||||
EndOfFunction = 0xFF,
|
||||
Null = 0,
|
||||
Automatic = 1,
|
||||
External = 2,
|
||||
Static = 3,
|
||||
Register = 4,
|
||||
ExternalDef = 5,
|
||||
Label = 6,
|
||||
UndefinedLabel = 7,
|
||||
MemberOfStruct = 8,
|
||||
Argument = 9,
|
||||
StructTag = 10,
|
||||
MemberOfUnion = 11,
|
||||
UnionTag = 12,
|
||||
TypeDefinition = 13,
|
||||
UndefinedStatic = 14,
|
||||
EnumTag = 15,
|
||||
MemberOfEnum = 16,
|
||||
RegisterParam = 17,
|
||||
BitField = 18,
|
||||
Block = 100,
|
||||
Function = 101,
|
||||
EndOfStruct = 102,
|
||||
File = 103,
|
||||
Section = 104,
|
||||
WeakExternal = 105,
|
||||
CLRToken = 107
|
||||
};
|
||||
|
||||
struct AuxSymbol {
|
||||
u8 data[18];
|
||||
};
|
||||
|
||||
u32 countedSymbols = 0;
|
||||
struct SymbolTable {
|
||||
char name[8];
|
||||
u32 value;
|
||||
u16 sectionNumber;
|
||||
Type type;
|
||||
StorageClass storageClass;
|
||||
u8 numberOfAuxSymbols;
|
||||
|
||||
countedSymbols += 1 + numberOfAuxSymbols;
|
||||
|
||||
AuxSymbol auxSymbols[numberOfAuxSymbols];
|
||||
|
||||
if (countedSymbols >= parent.header.numberOfSymbols)
|
||||
break;
|
||||
};
|
||||
|
||||
struct String {
|
||||
char value[];
|
||||
};
|
||||
|
||||
struct StringTable {
|
||||
u32 size;
|
||||
String strings[while($ < addressof(size) + size)];
|
||||
};
|
||||
|
||||
bitfield SectionFlags {
|
||||
padding : 3;
|
||||
typeNoPad : 1;
|
||||
padding : 1;
|
||||
cntCode : 1;
|
||||
initializedData : 1;
|
||||
uninitializedData : 1;
|
||||
lnkOther : 1;
|
||||
lnkInfo : 1;
|
||||
padding : 1;
|
||||
lnkRemove : 1;
|
||||
lnkCOMDAT : 1;
|
||||
padding : 2;
|
||||
gprel : 1;
|
||||
padding : 1;
|
||||
memPurgeable : 1;
|
||||
memLocked : 1;
|
||||
memPreload : 1;
|
||||
alignment : 4 [[format("format_alignment")]];
|
||||
lnkNrelocOvfl : 1;
|
||||
memDiscardable : 1;
|
||||
memNotCached : 1;
|
||||
memNotPaged : 1;
|
||||
memShared : 1;
|
||||
memExecute : 1;
|
||||
memRead : 1;
|
||||
memWrite : 1;
|
||||
} [[right_to_left]];
|
||||
|
||||
fn format_alignment(u8 alignment) {
|
||||
return 1 << alignment;
|
||||
};
|
||||
|
||||
struct Relocations {
|
||||
u32 virtualAddress;
|
||||
u32 symbolTableIndex;
|
||||
Type type;
|
||||
};
|
||||
|
||||
struct Section {
|
||||
char name[8];
|
||||
type::Size<u32> virtualSize;
|
||||
u32 virtualAddress;
|
||||
type::Size<u32> sizeOfRawData;
|
||||
u32 pointerToRawData;
|
||||
u32 pointerToRelocations;
|
||||
u32 pointerToLineNumbers;
|
||||
u16 numberOfRelocations;
|
||||
u16 numberOfLineNumbers;
|
||||
SectionFlags characteristics;
|
||||
|
||||
u8 rawData[sizeOfRawData] @ pointerToRawData [[sealed]];
|
||||
Relocations relocations[numberOfRelocations] @ pointerToRelocations;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
Machine machine;
|
||||
u16 numberOfSections;
|
||||
type::time32_t timeDateStamp;
|
||||
u32 pointerToSymbolTable;
|
||||
u32 numberOfSymbols;
|
||||
u16 sizeOfOptionalHeader;
|
||||
Characteristics characteristics;
|
||||
};
|
||||
|
||||
|
||||
struct COFF {
|
||||
Header header;
|
||||
|
||||
Section sectionTable[header.numberOfSections];
|
||||
|
||||
SymbolTable symbolTable[header.numberOfSymbols] @ header.pointerToSymbolTable;
|
||||
StringTable stringTable @ addressof(symbolTable) + sizeof(symbolTable);
|
||||
};
|
||||
|
||||
COFF coff @ 0x00;
|
||||
#pragma MIME application/x-coff
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
enum Machine : u16 {
|
||||
Unknown = 0x0000,
|
||||
AM33 = 0x01D3,
|
||||
AMD64 = 0x8664,
|
||||
ARM = 0x01C0,
|
||||
ARM64 = 0xAA64,
|
||||
ARMNT = 0x01C4,
|
||||
EBC = 0x0EBC,
|
||||
I386 = 0x014C,
|
||||
IA64 = 0x0200,
|
||||
LOONGARCH32 = 0x6232,
|
||||
LOONGARCH64 = 0x6264,
|
||||
M32R = 0x9041,
|
||||
MIPS16 = 0x0226,
|
||||
MIPSFPU = 0x0366,
|
||||
MIPSFPU16 = 0x0466,
|
||||
POWERPC = 0x01F0,
|
||||
POWERPCFP = 0x01F0,
|
||||
R4000 = 0x0166,
|
||||
RISCV32 = 0x5032,
|
||||
RISCV64 = 0x5064,
|
||||
RISCV128 = 0x5128,
|
||||
SH3 = 0x01A2,
|
||||
SH3DSP = 0x01A3,
|
||||
SH4 = 0x01A6,
|
||||
SH5 = 0x01A8,
|
||||
THUMB = 0x01C2,
|
||||
WCEMIPSV2 = 0x0169
|
||||
};
|
||||
|
||||
bitfield Characteristics {
|
||||
relocsStripped : 1;
|
||||
executableImage : 1;
|
||||
lineNumsStripped : 1;
|
||||
localSymsStripped : 1;
|
||||
aggressiveWsTrim : 1;
|
||||
largeAddressAware : 1;
|
||||
padding : 1;
|
||||
bytesReversedLo : 1;
|
||||
_32BitMachine : 1;
|
||||
debugStripped : 1;
|
||||
removableRunFromSwap : 1;
|
||||
netRunFromSwap : 1;
|
||||
system : 1;
|
||||
dll : 1;
|
||||
upSystemOnly : 1;
|
||||
bytesReversedHi : 1;
|
||||
};
|
||||
|
||||
enum Type : u16 {
|
||||
Null = 0,
|
||||
Void = 1,
|
||||
Char = 2,
|
||||
Short = 3,
|
||||
Int = 4,
|
||||
Long = 5,
|
||||
Float = 6,
|
||||
Double = 7,
|
||||
Struct = 8,
|
||||
Union = 9,
|
||||
Enum = 10,
|
||||
MOE = 11,
|
||||
Byte = 12,
|
||||
Word = 13,
|
||||
UInt = 14,
|
||||
DWord = 15
|
||||
};
|
||||
|
||||
enum StorageClass : u8 {
|
||||
EndOfFunction = 0xFF,
|
||||
Null = 0,
|
||||
Automatic = 1,
|
||||
External = 2,
|
||||
Static = 3,
|
||||
Register = 4,
|
||||
ExternalDef = 5,
|
||||
Label = 6,
|
||||
UndefinedLabel = 7,
|
||||
MemberOfStruct = 8,
|
||||
Argument = 9,
|
||||
StructTag = 10,
|
||||
MemberOfUnion = 11,
|
||||
UnionTag = 12,
|
||||
TypeDefinition = 13,
|
||||
UndefinedStatic = 14,
|
||||
EnumTag = 15,
|
||||
MemberOfEnum = 16,
|
||||
RegisterParam = 17,
|
||||
BitField = 18,
|
||||
Block = 100,
|
||||
Function = 101,
|
||||
EndOfStruct = 102,
|
||||
File = 103,
|
||||
Section = 104,
|
||||
WeakExternal = 105,
|
||||
CLRToken = 107
|
||||
};
|
||||
|
||||
struct AuxSymbol {
|
||||
u8 data[18];
|
||||
};
|
||||
|
||||
u32 countedSymbols = 0;
|
||||
struct SymbolTable {
|
||||
char name[8];
|
||||
u32 value;
|
||||
u16 sectionNumber;
|
||||
Type type;
|
||||
StorageClass storageClass;
|
||||
u8 numberOfAuxSymbols;
|
||||
|
||||
countedSymbols += 1 + numberOfAuxSymbols;
|
||||
|
||||
AuxSymbol auxSymbols[numberOfAuxSymbols];
|
||||
|
||||
if (countedSymbols >= parent.header.numberOfSymbols)
|
||||
break;
|
||||
};
|
||||
|
||||
struct String {
|
||||
char value[];
|
||||
};
|
||||
|
||||
struct StringTable {
|
||||
u32 size;
|
||||
String strings[while($ < addressof(size) + size)];
|
||||
};
|
||||
|
||||
bitfield SectionFlags {
|
||||
padding : 3;
|
||||
typeNoPad : 1;
|
||||
padding : 1;
|
||||
cntCode : 1;
|
||||
initializedData : 1;
|
||||
uninitializedData : 1;
|
||||
lnkOther : 1;
|
||||
lnkInfo : 1;
|
||||
padding : 1;
|
||||
lnkRemove : 1;
|
||||
lnkCOMDAT : 1;
|
||||
padding : 2;
|
||||
gprel : 1;
|
||||
padding : 1;
|
||||
memPurgeable : 1;
|
||||
memLocked : 1;
|
||||
memPreload : 1;
|
||||
alignment : 4 [[format("format_alignment")]];
|
||||
lnkNrelocOvfl : 1;
|
||||
memDiscardable : 1;
|
||||
memNotCached : 1;
|
||||
memNotPaged : 1;
|
||||
memShared : 1;
|
||||
memExecute : 1;
|
||||
memRead : 1;
|
||||
memWrite : 1;
|
||||
};
|
||||
|
||||
fn format_alignment(u8 alignment) {
|
||||
return 1 << alignment;
|
||||
};
|
||||
|
||||
struct Relocations {
|
||||
u32 virtualAddress;
|
||||
u32 symbolTableIndex;
|
||||
Type type;
|
||||
};
|
||||
|
||||
struct Section {
|
||||
char name[8];
|
||||
type::Size<u32> virtualSize;
|
||||
u32 virtualAddress;
|
||||
type::Size<u32> sizeOfRawData;
|
||||
u32 pointerToRawData;
|
||||
u32 pointerToRelocations;
|
||||
u32 pointerToLineNumbers;
|
||||
u16 numberOfRelocations;
|
||||
u16 numberOfLineNumbers;
|
||||
SectionFlags characteristics;
|
||||
|
||||
u8 rawData[sizeOfRawData] @ pointerToRawData [[sealed]];
|
||||
Relocations relocations[numberOfRelocations] @ pointerToRelocations;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
Machine machine;
|
||||
u16 numberOfSections;
|
||||
type::time32_t timeDateStamp;
|
||||
u32 pointerToSymbolTable;
|
||||
u32 numberOfSymbols;
|
||||
u16 sizeOfOptionalHeader;
|
||||
Characteristics characteristics;
|
||||
};
|
||||
|
||||
|
||||
struct COFF {
|
||||
Header header;
|
||||
|
||||
Section sectionTable[header.numberOfSections];
|
||||
|
||||
SymbolTable symbolTable[header.numberOfSymbols] @ header.pointerToSymbolTable;
|
||||
StringTable stringTable @ addressof(symbolTable) + sizeof(symbolTable);
|
||||
};
|
||||
|
||||
COFF coff @ 0x00;
|
||||
|
||||
@@ -22,14 +22,14 @@ namespace old_binary {
|
||||
using SwappedU32 = u32 [[transform("old_binary::swap_32bit"), format("old_binary::swap_32bit")]];
|
||||
|
||||
bitfield Mode {
|
||||
file_type : 4;
|
||||
suid : 1;
|
||||
sgid : 1;
|
||||
sticky : 1;
|
||||
r : 3;
|
||||
w : 3;
|
||||
x : 3;
|
||||
} [[left_to_right]];
|
||||
w : 3;
|
||||
r : 3;
|
||||
sticky : 1;
|
||||
sgid : 1;
|
||||
suid : 1;
|
||||
file_type : 4;
|
||||
};
|
||||
|
||||
struct CpioHeader {
|
||||
type::Oct<u16> magic;
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
#pragma MIME application/x-object
|
||||
#pragma MIME application/x-sharedlib
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
using EI_ABIVERSION = u8;
|
||||
using Elf32_Addr = u32;
|
||||
using Elf32_BaseAddr = u32;
|
||||
@@ -458,37 +460,37 @@ enum VER_NEED : Elf32_Half {
|
||||
};
|
||||
|
||||
bitfield SYMINFO_FLG {
|
||||
padding : 10;
|
||||
NOEXTDIRECT : 1;
|
||||
DIRECTBIND : 1;
|
||||
LAZYLOAD : 1;
|
||||
COPY : 1;
|
||||
RESERVED : 1;
|
||||
DIRECT : 1;
|
||||
} [[left_to_right]];
|
||||
RESERVED : 1;
|
||||
COPY : 1;
|
||||
LAZYLOAD : 1;
|
||||
DIRECTBIND : 1;
|
||||
NOEXTDIRECT : 1;
|
||||
padding : 10;
|
||||
};
|
||||
|
||||
bitfield ST {
|
||||
ST_BIND : 4;
|
||||
ST_TYPE : 4;
|
||||
} [[left_to_right]];
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
bitfield SHF {
|
||||
MASKPROC : 4;
|
||||
MASKOS : 8;
|
||||
UNKNOWN : 8;
|
||||
COMPRESSED : 1;
|
||||
TLS : 1;
|
||||
GROUP : 1;
|
||||
OS_NONCONFORMING : 1;
|
||||
LINK_ORDER : 1;
|
||||
INFO_LINK : 1;
|
||||
STRINGS : 1;
|
||||
MERGE : 1;
|
||||
padding : 1;
|
||||
EXECINSTR : 1;
|
||||
ALLOC : 1;
|
||||
WRITE : 1;
|
||||
} [[left_to_right]];
|
||||
ALLOC : 1;
|
||||
EXECINSTR : 1;
|
||||
padding : 1;
|
||||
MERGE : 1;
|
||||
STRINGS : 1;
|
||||
INFO_LINK : 1;
|
||||
LINK_ORDER : 1;
|
||||
OS_NONCONFORMING : 1;
|
||||
GROUP : 1;
|
||||
TLS : 1;
|
||||
COMPRESSED : 1;
|
||||
UNKNOWN : 8;
|
||||
MASKOS : 8;
|
||||
MASKPROC : 4;
|
||||
};
|
||||
|
||||
bitfield ELF32_R_INFO {
|
||||
SYM : 8;
|
||||
@@ -501,13 +503,13 @@ bitfield ELF64_R_INFO {
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield PF {
|
||||
MASKPROC : 4;
|
||||
MASKOS : 4;
|
||||
padding : 17;
|
||||
R : 1;
|
||||
W : 1;
|
||||
X : 1;
|
||||
} [[left_to_right]];
|
||||
W : 1;
|
||||
R : 1;
|
||||
padding : 17;
|
||||
MASKOS : 4;
|
||||
MASKPROC : 4;
|
||||
};
|
||||
|
||||
struct E_IDENT {
|
||||
char EI_MAG[4];
|
||||
|
||||
@@ -1,321 +1,323 @@
|
||||
#include <std/sys.pat>
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
#pragma endian big
|
||||
|
||||
u32 sampleSize;
|
||||
u32 bitsPerSample;
|
||||
|
||||
// METADATA
|
||||
|
||||
enum BLOCK_TYPE : u8 {
|
||||
STREAMINFO = 0,
|
||||
PADDING = 1,
|
||||
APPLICATION = 2,
|
||||
SEEKTABLE = 3,
|
||||
VORBIS_COMMENT = 4,
|
||||
CUESHEET = 5,
|
||||
PICTURE = 6,
|
||||
|
||||
INVALID = 127
|
||||
};
|
||||
|
||||
bitfield METADATA_BLOCK_HEADER {
|
||||
lastMetadataBlock : 1;
|
||||
blockType : 7;
|
||||
length : 24;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield STREAMINFO_FLAGS {
|
||||
sampleRate : 20;
|
||||
numChannels : 3 [[format("format_channels")]];
|
||||
bitsPerSample : 5;
|
||||
numSamplesInStream : 36;
|
||||
} [[inline, left_to_right]];
|
||||
|
||||
fn format_channels(u8 value) {
|
||||
return value + 1;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_STREAMINFO {
|
||||
u16 minBlockSize, maxBlockSize;
|
||||
u24 minFrameSize, maxFrameSize;
|
||||
STREAMINFO_FLAGS flags;
|
||||
u128 md5Signature;
|
||||
|
||||
bitsPerSample = flags.bitsPerSample;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_PADDING {
|
||||
padding[parent.header.length];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_APPLICATION {
|
||||
char applicationID[4];
|
||||
u8 applicationData[parent.header.length - sizeof(applicationID)];
|
||||
};
|
||||
|
||||
struct SEEKPOINT {
|
||||
u64 sampleNumber;
|
||||
u64 byteOffset;
|
||||
u16 numSamples;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_SEEKTABLE {
|
||||
SEEKPOINT seekPoints[parent.header.length / 18];
|
||||
};
|
||||
|
||||
struct VORBIS_USER_COMMENT {
|
||||
le u32 length;
|
||||
char comment[length];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_VORBIS_COMMENT {
|
||||
le u32 vendorLength;
|
||||
u8 vendor[vendorLength];
|
||||
|
||||
le u32 userCommentListLength;
|
||||
VORBIS_USER_COMMENT userCommentList[userCommentListLength];
|
||||
};
|
||||
|
||||
bitfield TRACK_FLAGS {
|
||||
audioTrack : 1;
|
||||
preEmphasis : 1;
|
||||
padding : 6;
|
||||
} [[inline]];
|
||||
|
||||
struct CUESHEET_TRACK_INDEX {
|
||||
u64 sampleOffset;
|
||||
u8 indexPointNumber;
|
||||
padding[3];
|
||||
};
|
||||
|
||||
struct CUESHEET_TRACK {
|
||||
u64 trackOffset;
|
||||
u8 trackNumber;
|
||||
char trackISRC[12];
|
||||
TRACK_FLAGS flags;
|
||||
padding[13];
|
||||
u8 numTrackIndexPoints;
|
||||
CUESHEET_TRACK_INDEX indexes[numTrackIndexPoints];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_CUESHEET {
|
||||
char mediaCatalogNumber[128];
|
||||
u64 numLeadInSamples;
|
||||
bool isCD;
|
||||
padding[258];
|
||||
u8 numTracks;
|
||||
CUESHEET_TRACK tracks[numTracks];
|
||||
};
|
||||
|
||||
enum PICTURE_TYPE : u32 {
|
||||
Other = 0,
|
||||
FileIcon = 1,
|
||||
OtherFileIcon = 2,
|
||||
CoverFront = 3,
|
||||
CoverBack = 4,
|
||||
LeafletPage = 5,
|
||||
Media = 6,
|
||||
LeadArtist = 7,
|
||||
Artist = 8,
|
||||
Conductor = 9,
|
||||
Band = 10,
|
||||
Composer = 11,
|
||||
Lyricist = 12,
|
||||
RecordingLocation = 13,
|
||||
DuringRecording = 14,
|
||||
DuringPerformance = 15,
|
||||
MovieScreenCapture = 16,
|
||||
ABrightColoredFish = 17,
|
||||
Illustration = 18,
|
||||
BandLogoType = 19,
|
||||
PublisherLogoType = 20
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_PICTURE {
|
||||
PICTURE_TYPE pictureType;
|
||||
u32 mimeTypeLength;
|
||||
char mimeType[mineTypeLength];
|
||||
u32 descriptionLength;
|
||||
char description[descriptionLength];
|
||||
u32 width, height;
|
||||
u32 colorDepth;
|
||||
u32 colorCount;
|
||||
u32 pictureDataLength;
|
||||
u8 pictureData[pictureDataLength];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// FRAME DATA
|
||||
// TODO: THIS IS INCOMPLETE / NOT WORKING CURRENTLY
|
||||
|
||||
bitfield FRAME_HEADER_FLAGS {
|
||||
syncCode : 14;
|
||||
padding : 1;
|
||||
blockingStrategy : 1;
|
||||
blockSize : 4;
|
||||
sampleRate : 4;
|
||||
channelAssignment : 4;
|
||||
sampleSize : 3;
|
||||
padding : 1;
|
||||
} [[inline]];
|
||||
|
||||
struct FRAME_HEADER {
|
||||
FRAME_HEADER_FLAGS flags;
|
||||
|
||||
sampleSize = flags.sampleSize;
|
||||
|
||||
if (flags.blockingStrategy)
|
||||
char16 sampleNumber[7];
|
||||
else
|
||||
char16 frameNumber[6];
|
||||
|
||||
if (flags.blockSize == 0b0110)
|
||||
u8 blockSize;
|
||||
else if (flags.blockSize == 0b0111)
|
||||
u16 blockSize;
|
||||
|
||||
if (flags.sampleRate == 0b1100)
|
||||
u8 sampleRate;
|
||||
else if (flags.sampleRate == 0b1101 || flags.sampleRate == 0b1110)
|
||||
u16 sampleRate;
|
||||
|
||||
u8 crc8;
|
||||
};
|
||||
|
||||
struct FRAME_FOOTER {
|
||||
u16 crc16;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_HEADER {
|
||||
padding : 1;
|
||||
type : 6;
|
||||
wastedBits : 1;
|
||||
};
|
||||
|
||||
fn getBitsPerSample() {
|
||||
if (sampleSize == 0b000)
|
||||
return bitsPerSample;
|
||||
else if (sampleSize == 0b001)
|
||||
return 8;
|
||||
else if (sampleSize == 0b010)
|
||||
return 12;
|
||||
else if (sampleSize == 0b100)
|
||||
return 16;
|
||||
else if (sampleSize == 0b101)
|
||||
return 20;
|
||||
else if (sampleSize == 0b110)
|
||||
return 24;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_CONSTANT {
|
||||
value : getBitsPerSample();
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_VERBATIM {
|
||||
value : getBitsPerSample() * parent.parent.header.flags.blockSize;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_FIXED_VALUE {
|
||||
value : getBitsPerSample() * (parent.parent.header.type & 0b111);
|
||||
codingMethod : 2;
|
||||
} [[inline]];
|
||||
|
||||
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE {
|
||||
partitionOrder : 4;
|
||||
riceParameter : 4;
|
||||
if (riceParameter == 0b1111)
|
||||
bitsPerSample : 5;
|
||||
} [[right_to_left]];
|
||||
|
||||
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 {
|
||||
partitionOrder : 4;
|
||||
riceParameter : 5;
|
||||
if (riceParameter == 0b11111)
|
||||
bitsPerSample : 5;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct RESIDUAL {
|
||||
if (parent.value.codingMethod == 0b00)
|
||||
RESIDUAL_CODING_METHOD_PARTITIONED_RICE rice;
|
||||
else if (parent.value.codingMethod == 0b01)
|
||||
RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 rice;
|
||||
|
||||
|
||||
if ((parent.parent.header.type & 0b111) == 0b000)
|
||||
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize - (parent.parent.header.type & 0b111))) / 8];
|
||||
else if (std::core::array_index() != 0)
|
||||
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder))) / 8];
|
||||
else
|
||||
u8 samples[(getBitsPerSample() * ((parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder)) - (parent.parent.header.type & 0b111))) / 8];
|
||||
};
|
||||
|
||||
struct SUBFRAME_FIXED {
|
||||
SUBFRAME_FIXED_VALUE value;
|
||||
RESIDUAL residual;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_LPC_VALUE {
|
||||
warmUpSamples : getBitsPerSample() * ((parent.header.type & 0b011111) + 1);
|
||||
quantizedLinearPredictorCoefficient : 4;
|
||||
quantizedLinearPredictorCoefficientShift : 5;
|
||||
predictorCoefficients : quantizedLinearPredictorCoefficient * ((parent.header.type & 0b011111) + 1);
|
||||
} [[inline]];
|
||||
|
||||
struct SUBFRAME_LPC {
|
||||
SUBFRAME_LPC_VALUE value;
|
||||
RESIDUAL residual;
|
||||
};
|
||||
|
||||
|
||||
struct SUBFRAME {
|
||||
SUBFRAME_HEADER header;
|
||||
|
||||
if (header.type == 0b00000)
|
||||
SUBFRAME_CONSTANT constant;
|
||||
else if (header.type == 0b000001)
|
||||
SUBFRAME_VERBATIM verbatim;
|
||||
else if ((header.type >> 3) == 0b001 && (header.type & 0b111) <= 4)
|
||||
SUBFRAME_FIXED fixed;
|
||||
else if (header.type == 0b100000)
|
||||
SUBFRAME_LPC lpc;
|
||||
};
|
||||
|
||||
struct FRAME {
|
||||
FRAME_HEADER header;
|
||||
SUBFRAME subframes[parent.metadata[0].data.flags.numChannels + 1];
|
||||
FRAME_FOOTER footer;
|
||||
};
|
||||
|
||||
|
||||
struct METADATA_BLOCK {
|
||||
METADATA_BLOCK_HEADER header;
|
||||
if (header.lastMetadataBlock)
|
||||
break;
|
||||
|
||||
if (header.blockType == BLOCK_TYPE::STREAMINFO)
|
||||
METADATA_BLOCK_STREAMINFO data;
|
||||
else if (header.blockType == BLOCK_TYPE::PADDING)
|
||||
METADATA_BLOCK_PADDING data;
|
||||
else if (header.blockType == BLOCK_TYPE::APPLICATION)
|
||||
METADATA_BLOCK_APPLICATION data;
|
||||
else if (header.blockType == BLOCK_TYPE::VORBIS_COMMENT)
|
||||
METADATA_BLOCK_VORBIS_COMMENT data;
|
||||
else if (header.blockType == BLOCK_TYPE::CUESHEET)
|
||||
METADATA_BLOCK_CUESHEET data;
|
||||
else if (header.blockType == BLOCK_TYPE::PICTURE)
|
||||
METADATA_BLOCK_PICTURE data;
|
||||
else
|
||||
std::error("Invalid metadata block type!");
|
||||
};
|
||||
|
||||
struct STREAM {
|
||||
char magic[4];
|
||||
METADATA_BLOCK metadata[while(true)];
|
||||
//FRAME frames[while(!std::mem::eof())];
|
||||
};
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
#pragma endian big
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
u32 sampleSize;
|
||||
u32 bitsPerSample;
|
||||
|
||||
// METADATA
|
||||
|
||||
enum BLOCK_TYPE : u8 {
|
||||
STREAMINFO = 0,
|
||||
PADDING = 1,
|
||||
APPLICATION = 2,
|
||||
SEEKTABLE = 3,
|
||||
VORBIS_COMMENT = 4,
|
||||
CUESHEET = 5,
|
||||
PICTURE = 6,
|
||||
|
||||
INVALID = 127
|
||||
};
|
||||
|
||||
bitfield METADATA_BLOCK_HEADER {
|
||||
lastMetadataBlock : 1;
|
||||
blockType : 7;
|
||||
length : 24;
|
||||
};
|
||||
|
||||
bitfield STREAMINFO_FLAGS {
|
||||
sampleRate : 20;
|
||||
numChannels : 3 [[format("format_channels")]];
|
||||
bitsPerSample : 5;
|
||||
numSamplesInStream : 36;
|
||||
} [[inline]];
|
||||
|
||||
fn format_channels(u8 value) {
|
||||
return value + 1;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_STREAMINFO {
|
||||
u16 minBlockSize, maxBlockSize;
|
||||
u24 minFrameSize, maxFrameSize;
|
||||
STREAMINFO_FLAGS flags;
|
||||
u128 md5Signature;
|
||||
|
||||
bitsPerSample = flags.bitsPerSample;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_PADDING {
|
||||
padding[parent.header.length];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_APPLICATION {
|
||||
char applicationID[4];
|
||||
u8 applicationData[parent.header.length - sizeof(applicationID)];
|
||||
};
|
||||
|
||||
struct SEEKPOINT {
|
||||
u64 sampleNumber;
|
||||
u64 byteOffset;
|
||||
u16 numSamples;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_SEEKTABLE {
|
||||
SEEKPOINT seekPoints[parent.header.length / 18];
|
||||
};
|
||||
|
||||
struct VORBIS_USER_COMMENT {
|
||||
le u32 length;
|
||||
char comment[length];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_VORBIS_COMMENT {
|
||||
le u32 vendorLength;
|
||||
u8 vendor[vendorLength];
|
||||
|
||||
le u32 userCommentListLength;
|
||||
VORBIS_USER_COMMENT userCommentList[userCommentListLength];
|
||||
};
|
||||
|
||||
bitfield TRACK_FLAGS {
|
||||
audioTrack : 1;
|
||||
preEmphasis : 1;
|
||||
} [[inline,bitfield_order(BitfieldOrder::LeastToMostSignificant, 8)]];
|
||||
|
||||
struct CUESHEET_TRACK_INDEX {
|
||||
u64 sampleOffset;
|
||||
u8 indexPointNumber;
|
||||
padding[3];
|
||||
};
|
||||
|
||||
struct CUESHEET_TRACK {
|
||||
u64 trackOffset;
|
||||
u8 trackNumber;
|
||||
char trackISRC[12];
|
||||
TRACK_FLAGS flags;
|
||||
padding[13];
|
||||
u8 numTrackIndexPoints;
|
||||
CUESHEET_TRACK_INDEX indexes[numTrackIndexPoints];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_CUESHEET {
|
||||
char mediaCatalogNumber[128];
|
||||
u64 numLeadInSamples;
|
||||
bool isCD;
|
||||
padding[258];
|
||||
u8 numTracks;
|
||||
CUESHEET_TRACK tracks[numTracks];
|
||||
};
|
||||
|
||||
enum PICTURE_TYPE : u32 {
|
||||
Other = 0,
|
||||
FileIcon = 1,
|
||||
OtherFileIcon = 2,
|
||||
CoverFront = 3,
|
||||
CoverBack = 4,
|
||||
LeafletPage = 5,
|
||||
Media = 6,
|
||||
LeadArtist = 7,
|
||||
Artist = 8,
|
||||
Conductor = 9,
|
||||
Band = 10,
|
||||
Composer = 11,
|
||||
Lyricist = 12,
|
||||
RecordingLocation = 13,
|
||||
DuringRecording = 14,
|
||||
DuringPerformance = 15,
|
||||
MovieScreenCapture = 16,
|
||||
ABrightColoredFish = 17,
|
||||
Illustration = 18,
|
||||
BandLogoType = 19,
|
||||
PublisherLogoType = 20
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_PICTURE {
|
||||
PICTURE_TYPE pictureType;
|
||||
u32 mimeTypeLength;
|
||||
char mimeType[mineTypeLength];
|
||||
u32 descriptionLength;
|
||||
char description[descriptionLength];
|
||||
u32 width, height;
|
||||
u32 colorDepth;
|
||||
u32 colorCount;
|
||||
u32 pictureDataLength;
|
||||
u8 pictureData[pictureDataLength];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// FRAME DATA
|
||||
// TODO: THIS IS INCOMPLETE / NOT WORKING CURRENTLY
|
||||
|
||||
bitfield FRAME_HEADER_FLAGS {
|
||||
syncCode : 14;
|
||||
padding : 1;
|
||||
blockingStrategy : 1;
|
||||
blockSize : 4;
|
||||
sampleRate : 4;
|
||||
channelAssignment : 4;
|
||||
sampleSize : 3;
|
||||
} [[inline,bitfield_order(BitfieldOrder::LeastToMostSignificant, 32)]];
|
||||
|
||||
struct FRAME_HEADER {
|
||||
FRAME_HEADER_FLAGS flags;
|
||||
|
||||
sampleSize = flags.sampleSize;
|
||||
|
||||
if (flags.blockingStrategy)
|
||||
char16 sampleNumber[7];
|
||||
else
|
||||
char16 frameNumber[6];
|
||||
|
||||
if (flags.blockSize == 0b0110)
|
||||
u8 blockSize;
|
||||
else if (flags.blockSize == 0b0111)
|
||||
u16 blockSize;
|
||||
|
||||
if (flags.sampleRate == 0b1100)
|
||||
u8 sampleRate;
|
||||
else if (flags.sampleRate == 0b1101 || flags.sampleRate == 0b1110)
|
||||
u16 sampleRate;
|
||||
|
||||
u8 crc8;
|
||||
};
|
||||
|
||||
struct FRAME_FOOTER {
|
||||
u16 crc16;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_HEADER {
|
||||
padding : 1;
|
||||
type : 6;
|
||||
wastedBits : 1;
|
||||
};
|
||||
|
||||
fn getBitsPerSample() {
|
||||
if (sampleSize == 0b000)
|
||||
return bitsPerSample;
|
||||
else if (sampleSize == 0b001)
|
||||
return 8;
|
||||
else if (sampleSize == 0b010)
|
||||
return 12;
|
||||
else if (sampleSize == 0b100)
|
||||
return 16;
|
||||
else if (sampleSize == 0b101)
|
||||
return 20;
|
||||
else if (sampleSize == 0b110)
|
||||
return 24;
|
||||
else
|
||||
std::error(std::format("Invalid sample size {}.", sampleSize));
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_CONSTANT {
|
||||
value : getBitsPerSample();
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_VERBATIM {
|
||||
value : getBitsPerSample() * parent.parent.header.flags.blockSize;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_FIXED_VALUE {
|
||||
value : getBitsPerSample() * (parent.parent.header.type & 0b111);
|
||||
codingMethod : 2;
|
||||
} [[inline]];
|
||||
|
||||
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE {
|
||||
partitionOrder : 4;
|
||||
riceParameter : 4;
|
||||
if (riceParameter == 0b1111)
|
||||
bitsPerSample : 5;
|
||||
};
|
||||
|
||||
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 {
|
||||
partitionOrder : 4;
|
||||
riceParameter : 5;
|
||||
if (riceParameter == 0b11111)
|
||||
bitsPerSample : 5;
|
||||
};
|
||||
|
||||
struct RESIDUAL {
|
||||
if (parent.value.codingMethod == 0b00)
|
||||
RESIDUAL_CODING_METHOD_PARTITIONED_RICE rice;
|
||||
else if (parent.value.codingMethod == 0b01)
|
||||
RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 rice;
|
||||
|
||||
|
||||
if ((parent.parent.header.type & 0b111) == 0b000)
|
||||
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize - (parent.parent.header.type & 0b111))) / 8];
|
||||
else if (std::core::array_index() != 0)
|
||||
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder))) / 8];
|
||||
else
|
||||
u8 samples[(getBitsPerSample() * ((parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder)) - (parent.parent.header.type & 0b111))) / 8];
|
||||
};
|
||||
|
||||
struct SUBFRAME_FIXED {
|
||||
SUBFRAME_FIXED_VALUE value;
|
||||
RESIDUAL residual;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_LPC_VALUE {
|
||||
warmUpSamples : getBitsPerSample() * ((parent.header.type & 0b011111) + 1);
|
||||
quantizedLinearPredictorCoefficient : 4;
|
||||
quantizedLinearPredictorCoefficientShift : 5;
|
||||
predictorCoefficients : quantizedLinearPredictorCoefficient * ((parent.header.type & 0b011111) + 1);
|
||||
} [[inline]];
|
||||
|
||||
struct SUBFRAME_LPC {
|
||||
SUBFRAME_LPC_VALUE value;
|
||||
RESIDUAL residual;
|
||||
};
|
||||
|
||||
|
||||
struct SUBFRAME {
|
||||
SUBFRAME_HEADER header;
|
||||
|
||||
if (header.type == 0b00000)
|
||||
SUBFRAME_CONSTANT constant;
|
||||
else if (header.type == 0b000001)
|
||||
SUBFRAME_VERBATIM verbatim;
|
||||
else if ((header.type >> 3) == 0b001 && (header.type & 0b111) <= 4)
|
||||
SUBFRAME_FIXED fixed;
|
||||
else if (header.type == 0b100000)
|
||||
SUBFRAME_LPC lpc;
|
||||
};
|
||||
|
||||
struct FRAME {
|
||||
FRAME_HEADER header;
|
||||
SUBFRAME subframes[parent.metadata[0].data.flags.numChannels + 1];
|
||||
FRAME_FOOTER footer;
|
||||
};
|
||||
|
||||
|
||||
struct METADATA_BLOCK {
|
||||
METADATA_BLOCK_HEADER header;
|
||||
if (header.lastMetadataBlock)
|
||||
break;
|
||||
|
||||
if (header.blockType == BLOCK_TYPE::STREAMINFO)
|
||||
METADATA_BLOCK_STREAMINFO data;
|
||||
else if (header.blockType == BLOCK_TYPE::PADDING)
|
||||
METADATA_BLOCK_PADDING data;
|
||||
else if (header.blockType == BLOCK_TYPE::APPLICATION)
|
||||
METADATA_BLOCK_APPLICATION data;
|
||||
else if (header.blockType == BLOCK_TYPE::VORBIS_COMMENT)
|
||||
METADATA_BLOCK_VORBIS_COMMENT data;
|
||||
else if (header.blockType == BLOCK_TYPE::CUESHEET)
|
||||
METADATA_BLOCK_CUESHEET data;
|
||||
else if (header.blockType == BLOCK_TYPE::PICTURE)
|
||||
METADATA_BLOCK_PICTURE data;
|
||||
else
|
||||
std::error("Invalid metadata block type!");
|
||||
};
|
||||
|
||||
struct STREAM {
|
||||
char magic[4];
|
||||
METADATA_BLOCK metadata[while(true)];
|
||||
//FRAME frames[while(!std::mem::eof())];
|
||||
};
|
||||
|
||||
STREAM stream @ 0x00;
|
||||
@@ -13,7 +13,7 @@ bitfield CHS {
|
||||
h : 8;
|
||||
s : 6;
|
||||
c : 10;
|
||||
} [[right_to_left, format("chs_formatter")]];
|
||||
} [[format("chs_formatter")]];
|
||||
|
||||
fn chs_formatter(CHS chs) {
|
||||
return std::format("({:X}, {:X}, {:X}) | 0x{:X}", chs.c, chs.h, chs.s, (chs.c * 16 + chs.h) * 63 + (chs.s - 1));
|
||||
|
||||
@@ -1,77 +1,79 @@
|
||||
#pragma MIME application/gzip
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/size.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
bitfield Flags {
|
||||
FTEXT : 1;
|
||||
FHCRC : 1;
|
||||
FEXTRA : 1;
|
||||
FNAME : 1;
|
||||
FCOMMENT : 1;
|
||||
padding : 3;
|
||||
} [[right_to_left]];
|
||||
|
||||
bitfield ExtraFlags {
|
||||
padding : 1;
|
||||
maximumCompression : 1;
|
||||
fastestCompression : 1;
|
||||
padding : 5;
|
||||
};
|
||||
|
||||
enum CompressionMethod : u8 {
|
||||
Reserved = 0 ... 7,
|
||||
Deflate = 8
|
||||
};
|
||||
|
||||
enum OperatingSystemID : u8 {
|
||||
FATFileSystem = 0x00,
|
||||
Amiga = 0x01,
|
||||
VMS = 0x02,
|
||||
Unix = 0x03,
|
||||
VM_CMS = 0x04,
|
||||
AtariTOS = 0x05,
|
||||
HPFSFileSystem = 0x06,
|
||||
Macintosh = 0x07,
|
||||
ZSystem = 0x08,
|
||||
CP_M = 0x09,
|
||||
TOPS_20 = 0x0A,
|
||||
NTFSFileSystem = 0x0B,
|
||||
QDOS = 0x0C,
|
||||
AcordRISCOS = 0x0D,
|
||||
Unknown = 0xFF
|
||||
};
|
||||
|
||||
struct GZip {
|
||||
u16 signature;
|
||||
CompressionMethod compressionMethod;
|
||||
Flags flags;
|
||||
type::time32_t modificationTime;
|
||||
ExtraFlags extraFlags;
|
||||
OperatingSystemID operatingSystemId;
|
||||
|
||||
if (flags.FEXTRA) {
|
||||
u16 extraLength;
|
||||
u8 extraField[extraLength];
|
||||
}
|
||||
|
||||
if (flags.FNAME) {
|
||||
char originalFileName[];
|
||||
}
|
||||
|
||||
if (flags.FCOMMENT) {
|
||||
char comment[];
|
||||
}
|
||||
|
||||
if (flags.FHCRC) {
|
||||
u16 crc16;
|
||||
}
|
||||
|
||||
u8 data[while($ < std::mem::size() - 8)] [[sealed]];
|
||||
|
||||
u32 crc32;
|
||||
type::Size<u32> isize;
|
||||
};
|
||||
|
||||
#pragma MIME application/gzip
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/size.pat>
|
||||
#include <std/core.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
bitfield Flags {
|
||||
FTEXT : 1;
|
||||
FHCRC : 1;
|
||||
FEXTRA : 1;
|
||||
FNAME : 1;
|
||||
FCOMMENT : 1;
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 8)]];
|
||||
|
||||
bitfield ExtraFlags {
|
||||
padding : 1;
|
||||
maximumCompression : 1;
|
||||
fastestCompression : 1;
|
||||
padding : 5;
|
||||
};
|
||||
|
||||
enum CompressionMethod : u8 {
|
||||
Reserved = 0 ... 7,
|
||||
Deflate = 8
|
||||
};
|
||||
|
||||
enum OperatingSystemID : u8 {
|
||||
FATFileSystem = 0x00,
|
||||
Amiga = 0x01,
|
||||
VMS = 0x02,
|
||||
Unix = 0x03,
|
||||
VM_CMS = 0x04,
|
||||
AtariTOS = 0x05,
|
||||
HPFSFileSystem = 0x06,
|
||||
Macintosh = 0x07,
|
||||
ZSystem = 0x08,
|
||||
CP_M = 0x09,
|
||||
TOPS_20 = 0x0A,
|
||||
NTFSFileSystem = 0x0B,
|
||||
QDOS = 0x0C,
|
||||
AcordRISCOS = 0x0D,
|
||||
Unknown = 0xFF
|
||||
};
|
||||
|
||||
struct GZip {
|
||||
u16 signature;
|
||||
CompressionMethod compressionMethod;
|
||||
Flags flags;
|
||||
type::time32_t modificationTime;
|
||||
ExtraFlags extraFlags;
|
||||
OperatingSystemID operatingSystemId;
|
||||
|
||||
if (flags.FEXTRA) {
|
||||
u16 extraLength;
|
||||
u8 extraField[extraLength];
|
||||
}
|
||||
|
||||
if (flags.FNAME) {
|
||||
char originalFileName[];
|
||||
}
|
||||
|
||||
if (flags.FCOMMENT) {
|
||||
char comment[];
|
||||
}
|
||||
|
||||
if (flags.FHCRC) {
|
||||
u16 crc16;
|
||||
}
|
||||
|
||||
u8 data[while($ < std::mem::size() - 8)] [[sealed]];
|
||||
|
||||
u32 crc32;
|
||||
type::Size<u32> isize;
|
||||
};
|
||||
|
||||
GZip gzip @ 0x00;
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma endian big
|
||||
#pragma bitfield_order left_to_right
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#pragma endian big
|
||||
#pragma MIME application/x-java-applet
|
||||
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
// The Java documentations use the number of bytes instead of the number of bits for its type names
|
||||
using u1 = u8;
|
||||
using u2 = u16;
|
||||
@@ -206,7 +209,7 @@ bitfield access_flags_method {
|
||||
padding : 1; // 0x2000
|
||||
padding : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]];
|
||||
|
||||
bitfield access_flags_field {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
@@ -225,7 +228,7 @@ bitfield access_flags_field {
|
||||
padding : 1; // 0x2000
|
||||
ACC_ENUM : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]];
|
||||
|
||||
bitfield access_flags_class {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
@@ -244,7 +247,7 @@ bitfield access_flags_class {
|
||||
ACC_ANNOTATION : 1; // 0x2000
|
||||
ACC_ENUM : 1; // 0x4000
|
||||
ACC_MODULE : 1; // 0x8000
|
||||
};
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]];
|
||||
|
||||
struct attribute_info {
|
||||
u2 attribute_name_info;
|
||||
|
||||
@@ -1,459 +1,462 @@
|
||||
#pragma MIME application/x-ms-shortcut
|
||||
|
||||
#include <type/guid.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
bitfield LinkFlags {
|
||||
HasLinkTargetIDList : 1;
|
||||
HasLinkInfo : 1;
|
||||
HasName : 1;
|
||||
HasRelativePath : 1;
|
||||
HasWorkingDir : 1;
|
||||
HasArguments : 1;
|
||||
HasIconLocation : 1;
|
||||
IsUnicode : 1;
|
||||
ForceNoLinkInfo : 1;
|
||||
HasExpString : 1;
|
||||
RunInSeparateProcess : 1;
|
||||
padding : 1;
|
||||
HasDarwinID : 1;
|
||||
RunAsUser : 1;
|
||||
HasExpIcon : 1;
|
||||
NoPidlAlias : 1;
|
||||
padding : 1;
|
||||
RunWithShimLayer : 1;
|
||||
ForceNoLinkTrack : 1;
|
||||
EnableTargetMetadata : 1;
|
||||
DisableLinkPathTracking : 1;
|
||||
DisableKnownFolderTracking : 1;
|
||||
DisableKnownFolderAlias : 1;
|
||||
AllowLinkToLink : 1;
|
||||
UnaliasOnSave : 1;
|
||||
PreferEnvironmentPath : 1;
|
||||
KeepLocalIDListForUNCTarget : 1;
|
||||
padding : 5;
|
||||
} [[right_to_left]];
|
||||
|
||||
bitfield FileAttributesFlags {
|
||||
FILE_ATTRIBUTE_READONLY : 1;
|
||||
FILE_ATTRIBUTE_HIDDEN : 1;
|
||||
FILE_ATTRIBUTE_SYSTEM : 1;
|
||||
padding : 1;
|
||||
FILE_ATTRIBUTE_DIRECTORY : 1;
|
||||
FILE_ATTRIBUTE_ARCHIVE : 1;
|
||||
padding : 1;
|
||||
FILE_ATTRIBUTE_NORMAL : 1;
|
||||
FILE_ATTRIBUTE_TEMPORARY : 1;
|
||||
FILE_ATTRIBUTE_SPARSE_FILE : 1;
|
||||
FILE_ATTRIBUTE_REPARSE_POINT : 1;
|
||||
FILE_ATTRIBUTE_COMPRESSED : 1;
|
||||
FILE_ATTRIBUTE_OFFLINE : 1;
|
||||
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED : 1;
|
||||
FILE_ATTRIBUTE_ENCRYPTED : 1;
|
||||
padding : 17;
|
||||
} [[right_to_left]];
|
||||
|
||||
bitfield ModifierKeys {
|
||||
HOTKEYF_SHIFT : 1;
|
||||
HOTKEYF_CONTROL : 1;
|
||||
HOTKEYF_ALT : 1;
|
||||
padding : 5;
|
||||
} [[right_to_left]];
|
||||
|
||||
enum Keys : u8 {
|
||||
KEY_NONE = 0x00,
|
||||
KEY_0 = 0x30,
|
||||
KEY_1 = 0x31,
|
||||
KEY_2 = 0x32,
|
||||
KEY_3 = 0x33,
|
||||
KEY_4 = 0x34,
|
||||
KEY_5 = 0x35,
|
||||
KEY_6 = 0x36,
|
||||
KEY_7 = 0x37,
|
||||
KEY_8 = 0x38,
|
||||
KEY_9 = 0x39,
|
||||
KEY_A = 0x41,
|
||||
KEY_B = 0x42,
|
||||
KEY_C = 0x43,
|
||||
KEY_D = 0x44,
|
||||
KEY_E = 0x45,
|
||||
KEY_F = 0x46,
|
||||
KEY_G = 0x47,
|
||||
KEY_H = 0x48,
|
||||
KEY_I = 0x49,
|
||||
KEY_J = 0x4A,
|
||||
KEY_K = 0x4B,
|
||||
KEY_L = 0x4C,
|
||||
KEY_M = 0x4D,
|
||||
KEY_N = 0x4E,
|
||||
KEY_O = 0x4F,
|
||||
KEY_P = 0x50,
|
||||
KEY_Q = 0x51,
|
||||
KEY_R = 0x52,
|
||||
KEY_S = 0x53,
|
||||
KEY_T = 0x54,
|
||||
KEY_U = 0x55,
|
||||
KEY_V = 0x56,
|
||||
KEY_W = 0x57,
|
||||
KEY_X = 0x58,
|
||||
KEY_Y = 0x59,
|
||||
KEY_Z = 0x5A,
|
||||
|
||||
VK_F1 = 0x70,
|
||||
VK_F2 = 0x71,
|
||||
VK_F3 = 0x72,
|
||||
VK_F4 = 0x73,
|
||||
VK_F5 = 0x74,
|
||||
VK_F6 = 0x75,
|
||||
VK_F7 = 0x76,
|
||||
VK_F8 = 0x77,
|
||||
VK_F9 = 0x78,
|
||||
VK_F10 = 0x79,
|
||||
VK_F11 = 0x7A,
|
||||
VK_F12 = 0x7B,
|
||||
VK_F13 = 0x7C,
|
||||
VK_F14 = 0x7D,
|
||||
VK_F15 = 0x7E,
|
||||
VK_F16 = 0x7F,
|
||||
VK_F17 = 0x80,
|
||||
VK_F18 = 0x81,
|
||||
VK_F19 = 0x82,
|
||||
VK_F20 = 0x83,
|
||||
VK_F21 = 0x84,
|
||||
VK_F22 = 0x85,
|
||||
VK_F23 = 0x86,
|
||||
VK_F24 = 0x87,
|
||||
VK_NUMLOCK = 0x90,
|
||||
VK_SCROLL = 0x91,
|
||||
};
|
||||
|
||||
struct HotKeyFlags {
|
||||
Keys Key;
|
||||
ModifierKeys ModifierKeys;
|
||||
};
|
||||
|
||||
struct FILETIME {
|
||||
u32 dwLowDateTime;
|
||||
u32 dwHighDateTime;
|
||||
};
|
||||
|
||||
enum SHOWWINDOW_FLAGS : u32 {
|
||||
SW_SHOWNORMAL = 0x00000001,
|
||||
SW_SHOWMAXIMIZED = 0x00000003,
|
||||
SW_SHOWMINNOACTIVE = 0x00000007
|
||||
};
|
||||
|
||||
struct ShellLinkHeader {
|
||||
type::Size32 HeaderSize;
|
||||
type::GUID LinkCLSID;
|
||||
LinkFlags LinkFlags;
|
||||
FileAttributesFlags FileAttributes;
|
||||
FILETIME CreationTime, AccessTime, WriteTime;
|
||||
type::Size32 FileSize;
|
||||
u32 IconIndex;
|
||||
SHOWWINDOW_FLAGS ShowCommand;
|
||||
HotKeyFlags HotKey;
|
||||
padding[2];
|
||||
padding[4];
|
||||
padding[4];
|
||||
};
|
||||
|
||||
struct ItemID {
|
||||
type::Size16 ItemIDSize;
|
||||
|
||||
if (ItemIDSize == 0x00)
|
||||
break;
|
||||
else
|
||||
u8 Data[ItemIDSize - sizeof(ItemIDSize)];
|
||||
};
|
||||
|
||||
struct IDList {
|
||||
ItemID ItemIDList[while(true)];
|
||||
};
|
||||
|
||||
struct LinkTargetIDList {
|
||||
type::Size16 IDListSize;
|
||||
IDList IDList[while($ < (addressof(IDListSize) + IDListSize))];
|
||||
};
|
||||
|
||||
bitfield LinkInfoFlags {
|
||||
VolumeIDAndLocalBasePath : 1;
|
||||
CommonNetworkRelativeLinkAndPathSuffix : 1;
|
||||
padding : 30;
|
||||
};
|
||||
|
||||
enum DriveType : u32 {
|
||||
DRIVE_UNKNOWN = 0x00000000,
|
||||
DRIVE_NO_ROOT_DIR = 0x00000001,
|
||||
DRIVE_REMOVABLE = 0x00000002,
|
||||
DRIVE_FIXED = 0x00000003,
|
||||
DRIVE_REMOTE = 0x00000004,
|
||||
DRIVE_CDROM = 0x00000005,
|
||||
DRIVE_RAMDISK = 0x00000006
|
||||
};
|
||||
|
||||
struct VolumeID {
|
||||
type::Size32 VolumeIDSize;
|
||||
DriveType DriveType;
|
||||
u32 DriveSerialNumber;
|
||||
u32 VolumeLabelOffset;
|
||||
if (VolumeLabelOffset == 0x14)
|
||||
u32 VolumeLabelOffsetUnicode;
|
||||
char Data[VolumeIDSize - ($ - addressof(this))];
|
||||
};
|
||||
|
||||
bitfield CommonNetworkRelativeLinkFlags {
|
||||
ValidDevice : 1;
|
||||
ValidNetType : 1;
|
||||
padding : 30;
|
||||
} [[right_to_left]];
|
||||
|
||||
enum NetworkProviderType : u32 {
|
||||
WNNC_NET_AVID = 0x001A0000,
|
||||
WNNC_NET_DOCUSPACE = 0x001B0000,
|
||||
WNNC_NET_MANGOSOFT = 0x001C0000,
|
||||
WNNC_NET_SERNET = 0x001D0000,
|
||||
WNNC_NET_RIVERFRONT1 = 0x001E0000,
|
||||
WNNC_NET_RIVERFRONT2 = 0x001F0000,
|
||||
WNNC_NET_DECORB = 0x00200000,
|
||||
WNNC_NET_PROTSTOR = 0x00210000,
|
||||
WNNC_NET_FJ_REDIR = 0x00220000,
|
||||
WNNC_NET_DISTINCT = 0x00230000,
|
||||
WNNC_NET_TWINS = 0x00240000,
|
||||
WNNC_NET_RDR2SAMPLE = 0x00250000,
|
||||
WNNC_NET_CSC = 0x00260000,
|
||||
WNNC_NET_3IN1 = 0x00270000,
|
||||
WNNC_NET_EXTENDNET = 0x00290000,
|
||||
WNNC_NET_STAC = 0x002A0000,
|
||||
WNNC_NET_FOXBAT = 0x002B0000,
|
||||
WNNC_NET_YAHOO = 0x002C0000,
|
||||
WNNC_NET_EXIFS = 0x002D0000,
|
||||
WNNC_NET_DAV = 0x002E0000,
|
||||
WNNC_NET_KNOWARE = 0x002F0000,
|
||||
WNNC_NET_OBJECT_DIRE = 0x00300000,
|
||||
WNNC_NET_MASFAX = 0x00310000,
|
||||
WNNC_NET_HOB_NFS = 0x00320000,
|
||||
WNNC_NET_SHIVA = 0x00330000,
|
||||
WNNC_NET_IBMAL = 0x00340000,
|
||||
WNNC_NET_LOCK = 0x00350000,
|
||||
WNNC_NET_TERMSRV = 0x00360000,
|
||||
WNNC_NET_SRT = 0x00370000,
|
||||
WNNC_NET_QUINCY = 0x00380000,
|
||||
WNNC_NET_OPENAFS = 0x00390000,
|
||||
WNNC_NET_AVID1 = 0x003A0000,
|
||||
WNNC_NET_DFS = 0x003B0000,
|
||||
WNNC_NET_KWNP = 0x003C0000,
|
||||
WNNC_NET_ZENWORKS = 0x003D0000,
|
||||
WNNC_NET_DRIVEONWEB = 0x003E0000,
|
||||
WNNC_NET_VMWARE = 0x003F0000,
|
||||
WNNC_NET_RSFX = 0x00400000,
|
||||
WNNC_NET_MFILES = 0x00410000,
|
||||
WNNC_NET_MS_NFS = 0x00420000,
|
||||
WNNC_NET_GOOGLE = 0x00430000
|
||||
};
|
||||
|
||||
struct CommonNetworkRelativeLink {
|
||||
type::Size32 CommonNetworkRelativeLinkSize;
|
||||
CommonNetworkRelativeLinkFlags CommonNetworkRelativeLinkFlags;
|
||||
u32 NetNameOffset;
|
||||
u32 DeviceNameOffset;
|
||||
NetworkProviderType NetworkProviderType;
|
||||
|
||||
if (NetNameOffset > 0x14) {
|
||||
u32 NetNameOffsetUnicode;
|
||||
u32 DeviceNameOffsetUnicode;
|
||||
}
|
||||
|
||||
char NetName[];
|
||||
char DeviceName[];
|
||||
|
||||
if (NetNameOffset > 0x14) {
|
||||
char16 NetNameUnicode[];
|
||||
char16 DeviceNameUnicode[];
|
||||
}
|
||||
};
|
||||
|
||||
struct LinkInfo {
|
||||
type::Size32 LinkInfoSize;
|
||||
type::Size32 LinkInfoHeaderSize;
|
||||
LinkInfoFlags LinkInfoFlags;
|
||||
u32 VolumeIDOffset;
|
||||
u32 LocalBasePathOffset;
|
||||
u32 CommonNetworkRelativeLinkOffset;
|
||||
u32 CommonPathSuffixOffset;
|
||||
|
||||
if (LinkInfoHeaderSize >= 0x24) {
|
||||
u32 LocalBasePathOffsetUnicode;
|
||||
u32 CommonPathSuffixOffsetUnicode;
|
||||
}
|
||||
|
||||
if (LinkInfoFlags.VolumeIDAndLocalBasePath) {
|
||||
VolumeID VolumeID;
|
||||
char LocalBasePath[];
|
||||
}
|
||||
|
||||
if (LinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix)
|
||||
CommonNetworkRelativeLink CommonNetworkRelativeLink;
|
||||
|
||||
char CommonPathSuffix[];
|
||||
|
||||
if (LinkInfoHeaderSize >= 0x24) {
|
||||
if (LinkInfoFlags.VolumeIDAndLocalBasePath)
|
||||
char16 LocalBasePathUnicode[];
|
||||
char16 CommonPathSuffixUnicode[];
|
||||
}
|
||||
};
|
||||
|
||||
struct String {
|
||||
u16 CountCharacters;
|
||||
char16 String[CountCharacters];
|
||||
};
|
||||
|
||||
struct StringData {
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasName)
|
||||
String NAME_STRING;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasRelativePath)
|
||||
String RELATIVE_PATH;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasWorkingDir)
|
||||
String WORKING_DIR;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasArguments)
|
||||
String COMMAND_LINE_ARGUMENTS;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasIconLocation)
|
||||
String ICON_LOCATION;
|
||||
};
|
||||
|
||||
bitfield FillAttributes {
|
||||
FOREGROUND_BLUE : 1;
|
||||
FOREGROUND_GREEN : 1;
|
||||
FOREGROUND_RED : 1;
|
||||
FOREGROUND_INTENSITY : 1;
|
||||
|
||||
BACKGROUND_BLUE : 1;
|
||||
BACKGROUND_GREEN : 1;
|
||||
BACKGROUND_RED : 1;
|
||||
BACKGROUND_INTENSITY : 1;
|
||||
|
||||
padding : 8;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct ConsoleDataBlock {
|
||||
FillAttributes FillAttributes;
|
||||
FillAttributes PopupFillAttributes;
|
||||
u16 ScreenBufferSizeX, ScreenBufferSizeY;
|
||||
u16 WindowSizeX, WindowSizeY;
|
||||
u16 WindowOriginX, WindowOriginY;
|
||||
padding[4];
|
||||
padding[4];
|
||||
u32 FontSize;
|
||||
u32 FontFamily;
|
||||
u32 FontWeight;
|
||||
char16 FaceName[32];
|
||||
u32 CursorSize;
|
||||
u32 FullScreen;
|
||||
u32 QuickEdit;
|
||||
u32 InsertMode;
|
||||
u32 AutoPosition;
|
||||
u32 HistoryBufferSize;
|
||||
u32 NumberOfHistoryBuffers;
|
||||
u32 HistoryNoDup;
|
||||
u32 ColorTable[16];
|
||||
};
|
||||
|
||||
struct ConsoleFEDataBlock {
|
||||
u32 CodePage;
|
||||
};
|
||||
|
||||
struct DarwinDataBlock {
|
||||
char DarwinDataAnsi[260];
|
||||
char16 DarwinDataUnicode[260];
|
||||
};
|
||||
|
||||
struct EnvironmentVariableDataBlock {
|
||||
char TargetAnsi[260];
|
||||
char16 TargetUnicode[260];
|
||||
};
|
||||
|
||||
struct IconEnvironmentDataBlock {
|
||||
char TargetAnsi[260];
|
||||
char16 TargetUnicode[260];
|
||||
};
|
||||
|
||||
struct KnownFolderDataBlock {
|
||||
type::GUID KnownFolderID;
|
||||
u32 Offset;
|
||||
};
|
||||
|
||||
struct PropertyStoreDataBlock {
|
||||
u8 Bytes[parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)];
|
||||
std::warning("PropertyStoreDataBlock is not yet implemented!");
|
||||
};
|
||||
|
||||
struct ShimDataBlock {
|
||||
char16 LayerName[(parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)) / sizeof(char16)];
|
||||
};
|
||||
|
||||
struct SpecialFolderDataBlock {
|
||||
u32 SpecialFolderID;
|
||||
u32 Offset;
|
||||
};
|
||||
|
||||
struct TrackerDataBlock {
|
||||
type::Size32 Length;
|
||||
u32 Version;
|
||||
char MachineID[16];
|
||||
type::GUID Droid[2];
|
||||
type::GUID DroidBirth[2];
|
||||
};
|
||||
|
||||
struct VistaAndAboveIDListDataBlock {
|
||||
IDList IDList;
|
||||
};
|
||||
|
||||
struct ExtraDataBlock {
|
||||
type::Size32 BlockSize;
|
||||
|
||||
if (BlockSize < 0x04)
|
||||
break;
|
||||
else {
|
||||
u32 BlockSignature;
|
||||
|
||||
if (BlockSignature == 0xA000'0002)
|
||||
ConsoleDataBlock CONSOLE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0004)
|
||||
ConsoleFEDataBlock CONSOLE_FE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0006)
|
||||
DarwinDataBlock DARWIN_PROPS;
|
||||
else if (BlockSignature == 0xA000'0001)
|
||||
EnvironmentVariableDataBlock ENVIRONMENT_PROPS;
|
||||
else if (BlockSignature == 0xA000'0007)
|
||||
IconEnvironmentDataBlock ICON_ENVIRONMENT_PROPS;
|
||||
else if (BlockSignature == 0xA000'000B)
|
||||
KnownFolderDataBlock KNOWN_FOLDER_PROPS;
|
||||
else if (BlockSignature == 0xA000'0009)
|
||||
PropertyStoreDataBlock PROPERTY_STORE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0008)
|
||||
ShimDataBlock SHIM_PROPS;
|
||||
else if (BlockSignature == 0xA000'0005)
|
||||
SpecialFolderDataBlock SPECIAL_FOLDER_PROPS;
|
||||
else if (BlockSignature == 0xA000'0003)
|
||||
TrackerDataBlock TRACKER_PROPS;
|
||||
else if (BlockSignature == 0xA000'000C)
|
||||
VistaAndAboveIDListDataBlock VISTA_AND_ABOVE_IDLIST_PROPS;
|
||||
}
|
||||
};
|
||||
|
||||
struct ExtraData {
|
||||
ExtraDataBlock ExtraDataBlock[while(true)];
|
||||
};
|
||||
|
||||
struct LNK {
|
||||
ShellLinkHeader ShellLinkHeader;
|
||||
if (ShellLinkHeader.LinkFlags.HasLinkTargetIDList)
|
||||
LinkTargetIDList LinkTargetIDList;
|
||||
if (ShellLinkHeader.LinkFlags.HasLinkInfo)
|
||||
LinkInfo LinkInfo;
|
||||
StringData StringData;
|
||||
ExtraData ExtraData;
|
||||
};
|
||||
|
||||
LNK lnk @ 0x00;
|
||||
#pragma MIME application/x-ms-shortcut
|
||||
|
||||
#include <std/core.pat>
|
||||
#include <type/guid.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
bitfield LinkFlags {
|
||||
HasLinkTargetIDList : 1;
|
||||
HasLinkInfo : 1;
|
||||
HasName : 1;
|
||||
HasRelativePath : 1;
|
||||
HasWorkingDir : 1;
|
||||
HasArguments : 1;
|
||||
HasIconLocation : 1;
|
||||
IsUnicode : 1;
|
||||
ForceNoLinkInfo : 1;
|
||||
HasExpString : 1;
|
||||
RunInSeparateProcess : 1;
|
||||
padding : 1;
|
||||
HasDarwinID : 1;
|
||||
RunAsUser : 1;
|
||||
HasExpIcon : 1;
|
||||
NoPidlAlias : 1;
|
||||
padding : 1;
|
||||
RunWithShimLayer : 1;
|
||||
ForceNoLinkTrack : 1;
|
||||
EnableTargetMetadata : 1;
|
||||
DisableLinkPathTracking : 1;
|
||||
DisableKnownFolderTracking : 1;
|
||||
DisableKnownFolderAlias : 1;
|
||||
AllowLinkToLink : 1;
|
||||
UnaliasOnSave : 1;
|
||||
PreferEnvironmentPath : 1;
|
||||
KeepLocalIDListForUNCTarget : 1;
|
||||
padding : 5;
|
||||
};
|
||||
|
||||
bitfield FileAttributesFlags {
|
||||
FILE_ATTRIBUTE_READONLY : 1;
|
||||
FILE_ATTRIBUTE_HIDDEN : 1;
|
||||
FILE_ATTRIBUTE_SYSTEM : 1;
|
||||
padding : 1;
|
||||
FILE_ATTRIBUTE_DIRECTORY : 1;
|
||||
FILE_ATTRIBUTE_ARCHIVE : 1;
|
||||
padding : 1;
|
||||
FILE_ATTRIBUTE_NORMAL : 1;
|
||||
FILE_ATTRIBUTE_TEMPORARY : 1;
|
||||
FILE_ATTRIBUTE_SPARSE_FILE : 1;
|
||||
FILE_ATTRIBUTE_REPARSE_POINT : 1;
|
||||
FILE_ATTRIBUTE_COMPRESSED : 1;
|
||||
FILE_ATTRIBUTE_OFFLINE : 1;
|
||||
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED : 1;
|
||||
FILE_ATTRIBUTE_ENCRYPTED : 1;
|
||||
padding : 17;
|
||||
};
|
||||
|
||||
bitfield ModifierKeys {
|
||||
HOTKEYF_SHIFT : 1;
|
||||
HOTKEYF_CONTROL : 1;
|
||||
HOTKEYF_ALT : 1;
|
||||
padding : 5;
|
||||
};
|
||||
|
||||
enum Keys : u8 {
|
||||
KEY_NONE = 0x00,
|
||||
KEY_0 = 0x30,
|
||||
KEY_1 = 0x31,
|
||||
KEY_2 = 0x32,
|
||||
KEY_3 = 0x33,
|
||||
KEY_4 = 0x34,
|
||||
KEY_5 = 0x35,
|
||||
KEY_6 = 0x36,
|
||||
KEY_7 = 0x37,
|
||||
KEY_8 = 0x38,
|
||||
KEY_9 = 0x39,
|
||||
KEY_A = 0x41,
|
||||
KEY_B = 0x42,
|
||||
KEY_C = 0x43,
|
||||
KEY_D = 0x44,
|
||||
KEY_E = 0x45,
|
||||
KEY_F = 0x46,
|
||||
KEY_G = 0x47,
|
||||
KEY_H = 0x48,
|
||||
KEY_I = 0x49,
|
||||
KEY_J = 0x4A,
|
||||
KEY_K = 0x4B,
|
||||
KEY_L = 0x4C,
|
||||
KEY_M = 0x4D,
|
||||
KEY_N = 0x4E,
|
||||
KEY_O = 0x4F,
|
||||
KEY_P = 0x50,
|
||||
KEY_Q = 0x51,
|
||||
KEY_R = 0x52,
|
||||
KEY_S = 0x53,
|
||||
KEY_T = 0x54,
|
||||
KEY_U = 0x55,
|
||||
KEY_V = 0x56,
|
||||
KEY_W = 0x57,
|
||||
KEY_X = 0x58,
|
||||
KEY_Y = 0x59,
|
||||
KEY_Z = 0x5A,
|
||||
|
||||
VK_F1 = 0x70,
|
||||
VK_F2 = 0x71,
|
||||
VK_F3 = 0x72,
|
||||
VK_F4 = 0x73,
|
||||
VK_F5 = 0x74,
|
||||
VK_F6 = 0x75,
|
||||
VK_F7 = 0x76,
|
||||
VK_F8 = 0x77,
|
||||
VK_F9 = 0x78,
|
||||
VK_F10 = 0x79,
|
||||
VK_F11 = 0x7A,
|
||||
VK_F12 = 0x7B,
|
||||
VK_F13 = 0x7C,
|
||||
VK_F14 = 0x7D,
|
||||
VK_F15 = 0x7E,
|
||||
VK_F16 = 0x7F,
|
||||
VK_F17 = 0x80,
|
||||
VK_F18 = 0x81,
|
||||
VK_F19 = 0x82,
|
||||
VK_F20 = 0x83,
|
||||
VK_F21 = 0x84,
|
||||
VK_F22 = 0x85,
|
||||
VK_F23 = 0x86,
|
||||
VK_F24 = 0x87,
|
||||
VK_NUMLOCK = 0x90,
|
||||
VK_SCROLL = 0x91,
|
||||
};
|
||||
|
||||
struct HotKeyFlags {
|
||||
Keys Key;
|
||||
ModifierKeys ModifierKeys;
|
||||
};
|
||||
|
||||
struct FILETIME {
|
||||
u32 dwLowDateTime;
|
||||
u32 dwHighDateTime;
|
||||
};
|
||||
|
||||
enum SHOWWINDOW_FLAGS : u32 {
|
||||
SW_SHOWNORMAL = 0x00000001,
|
||||
SW_SHOWMAXIMIZED = 0x00000003,
|
||||
SW_SHOWMINNOACTIVE = 0x00000007
|
||||
};
|
||||
|
||||
struct ShellLinkHeader {
|
||||
type::Size32 HeaderSize;
|
||||
type::GUID LinkCLSID;
|
||||
LinkFlags LinkFlags;
|
||||
FileAttributesFlags FileAttributes;
|
||||
FILETIME CreationTime, AccessTime, WriteTime;
|
||||
type::Size32 FileSize;
|
||||
u32 IconIndex;
|
||||
SHOWWINDOW_FLAGS ShowCommand;
|
||||
HotKeyFlags HotKey;
|
||||
padding[2];
|
||||
padding[4];
|
||||
padding[4];
|
||||
};
|
||||
|
||||
struct ItemID {
|
||||
type::Size16 ItemIDSize;
|
||||
|
||||
if (ItemIDSize == 0x00)
|
||||
break;
|
||||
else
|
||||
u8 Data[ItemIDSize - sizeof(ItemIDSize)];
|
||||
};
|
||||
|
||||
struct IDList {
|
||||
ItemID ItemIDList[while(true)];
|
||||
};
|
||||
|
||||
struct LinkTargetIDList {
|
||||
type::Size16 IDListSize;
|
||||
IDList IDList[while($ < (addressof(IDListSize) + IDListSize))];
|
||||
};
|
||||
|
||||
bitfield LinkInfoFlags {
|
||||
VolumeIDAndLocalBasePath : 1;
|
||||
CommonNetworkRelativeLinkAndPathSuffix : 1;
|
||||
padding : 30;
|
||||
};
|
||||
|
||||
enum DriveType : u32 {
|
||||
DRIVE_UNKNOWN = 0x00000000,
|
||||
DRIVE_NO_ROOT_DIR = 0x00000001,
|
||||
DRIVE_REMOVABLE = 0x00000002,
|
||||
DRIVE_FIXED = 0x00000003,
|
||||
DRIVE_REMOTE = 0x00000004,
|
||||
DRIVE_CDROM = 0x00000005,
|
||||
DRIVE_RAMDISK = 0x00000006
|
||||
};
|
||||
|
||||
struct VolumeID {
|
||||
type::Size32 VolumeIDSize;
|
||||
DriveType DriveType;
|
||||
u32 DriveSerialNumber;
|
||||
u32 VolumeLabelOffset;
|
||||
if (VolumeLabelOffset == 0x14)
|
||||
u32 VolumeLabelOffsetUnicode;
|
||||
char Data[VolumeIDSize - ($ - addressof(this))];
|
||||
};
|
||||
|
||||
bitfield CommonNetworkRelativeLinkFlags {
|
||||
ValidDevice : 1;
|
||||
ValidNetType : 1;
|
||||
padding : 30;
|
||||
};
|
||||
|
||||
enum NetworkProviderType : u32 {
|
||||
WNNC_NET_AVID = 0x001A0000,
|
||||
WNNC_NET_DOCUSPACE = 0x001B0000,
|
||||
WNNC_NET_MANGOSOFT = 0x001C0000,
|
||||
WNNC_NET_SERNET = 0x001D0000,
|
||||
WNNC_NET_RIVERFRONT1 = 0x001E0000,
|
||||
WNNC_NET_RIVERFRONT2 = 0x001F0000,
|
||||
WNNC_NET_DECORB = 0x00200000,
|
||||
WNNC_NET_PROTSTOR = 0x00210000,
|
||||
WNNC_NET_FJ_REDIR = 0x00220000,
|
||||
WNNC_NET_DISTINCT = 0x00230000,
|
||||
WNNC_NET_TWINS = 0x00240000,
|
||||
WNNC_NET_RDR2SAMPLE = 0x00250000,
|
||||
WNNC_NET_CSC = 0x00260000,
|
||||
WNNC_NET_3IN1 = 0x00270000,
|
||||
WNNC_NET_EXTENDNET = 0x00290000,
|
||||
WNNC_NET_STAC = 0x002A0000,
|
||||
WNNC_NET_FOXBAT = 0x002B0000,
|
||||
WNNC_NET_YAHOO = 0x002C0000,
|
||||
WNNC_NET_EXIFS = 0x002D0000,
|
||||
WNNC_NET_DAV = 0x002E0000,
|
||||
WNNC_NET_KNOWARE = 0x002F0000,
|
||||
WNNC_NET_OBJECT_DIRE = 0x00300000,
|
||||
WNNC_NET_MASFAX = 0x00310000,
|
||||
WNNC_NET_HOB_NFS = 0x00320000,
|
||||
WNNC_NET_SHIVA = 0x00330000,
|
||||
WNNC_NET_IBMAL = 0x00340000,
|
||||
WNNC_NET_LOCK = 0x00350000,
|
||||
WNNC_NET_TERMSRV = 0x00360000,
|
||||
WNNC_NET_SRT = 0x00370000,
|
||||
WNNC_NET_QUINCY = 0x00380000,
|
||||
WNNC_NET_OPENAFS = 0x00390000,
|
||||
WNNC_NET_AVID1 = 0x003A0000,
|
||||
WNNC_NET_DFS = 0x003B0000,
|
||||
WNNC_NET_KWNP = 0x003C0000,
|
||||
WNNC_NET_ZENWORKS = 0x003D0000,
|
||||
WNNC_NET_DRIVEONWEB = 0x003E0000,
|
||||
WNNC_NET_VMWARE = 0x003F0000,
|
||||
WNNC_NET_RSFX = 0x00400000,
|
||||
WNNC_NET_MFILES = 0x00410000,
|
||||
WNNC_NET_MS_NFS = 0x00420000,
|
||||
WNNC_NET_GOOGLE = 0x00430000
|
||||
};
|
||||
|
||||
struct CommonNetworkRelativeLink {
|
||||
type::Size32 CommonNetworkRelativeLinkSize;
|
||||
CommonNetworkRelativeLinkFlags CommonNetworkRelativeLinkFlags;
|
||||
u32 NetNameOffset;
|
||||
u32 DeviceNameOffset;
|
||||
NetworkProviderType NetworkProviderType;
|
||||
|
||||
if (NetNameOffset > 0x14) {
|
||||
u32 NetNameOffsetUnicode;
|
||||
u32 DeviceNameOffsetUnicode;
|
||||
}
|
||||
|
||||
char NetName[];
|
||||
char DeviceName[];
|
||||
|
||||
if (NetNameOffset > 0x14) {
|
||||
char16 NetNameUnicode[];
|
||||
char16 DeviceNameUnicode[];
|
||||
}
|
||||
};
|
||||
|
||||
struct LinkInfo {
|
||||
type::Size32 LinkInfoSize;
|
||||
type::Size32 LinkInfoHeaderSize;
|
||||
LinkInfoFlags LinkInfoFlags;
|
||||
u32 VolumeIDOffset;
|
||||
u32 LocalBasePathOffset;
|
||||
u32 CommonNetworkRelativeLinkOffset;
|
||||
u32 CommonPathSuffixOffset;
|
||||
|
||||
if (LinkInfoHeaderSize >= 0x24) {
|
||||
u32 LocalBasePathOffsetUnicode;
|
||||
u32 CommonPathSuffixOffsetUnicode;
|
||||
}
|
||||
|
||||
if (LinkInfoFlags.VolumeIDAndLocalBasePath) {
|
||||
VolumeID VolumeID;
|
||||
char LocalBasePath[];
|
||||
}
|
||||
|
||||
if (LinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix)
|
||||
CommonNetworkRelativeLink CommonNetworkRelativeLink;
|
||||
|
||||
char CommonPathSuffix[];
|
||||
|
||||
if (LinkInfoHeaderSize >= 0x24) {
|
||||
if (LinkInfoFlags.VolumeIDAndLocalBasePath)
|
||||
char16 LocalBasePathUnicode[];
|
||||
char16 CommonPathSuffixUnicode[];
|
||||
}
|
||||
};
|
||||
|
||||
struct String {
|
||||
u16 CountCharacters;
|
||||
char16 String[CountCharacters];
|
||||
};
|
||||
|
||||
struct StringData {
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasName)
|
||||
String NAME_STRING;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasRelativePath)
|
||||
String RELATIVE_PATH;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasWorkingDir)
|
||||
String WORKING_DIR;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasArguments)
|
||||
String COMMAND_LINE_ARGUMENTS;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasIconLocation)
|
||||
String ICON_LOCATION;
|
||||
};
|
||||
|
||||
bitfield FillAttributes {
|
||||
FOREGROUND_BLUE : 1;
|
||||
FOREGROUND_GREEN : 1;
|
||||
FOREGROUND_RED : 1;
|
||||
FOREGROUND_INTENSITY : 1;
|
||||
|
||||
BACKGROUND_BLUE : 1;
|
||||
BACKGROUND_GREEN : 1;
|
||||
BACKGROUND_RED : 1;
|
||||
BACKGROUND_INTENSITY : 1;
|
||||
|
||||
padding : 8;
|
||||
};
|
||||
|
||||
struct ConsoleDataBlock {
|
||||
FillAttributes FillAttributes;
|
||||
FillAttributes PopupFillAttributes;
|
||||
u16 ScreenBufferSizeX, ScreenBufferSizeY;
|
||||
u16 WindowSizeX, WindowSizeY;
|
||||
u16 WindowOriginX, WindowOriginY;
|
||||
padding[4];
|
||||
padding[4];
|
||||
u32 FontSize;
|
||||
u32 FontFamily;
|
||||
u32 FontWeight;
|
||||
char16 FaceName[32];
|
||||
u32 CursorSize;
|
||||
u32 FullScreen;
|
||||
u32 QuickEdit;
|
||||
u32 InsertMode;
|
||||
u32 AutoPosition;
|
||||
u32 HistoryBufferSize;
|
||||
u32 NumberOfHistoryBuffers;
|
||||
u32 HistoryNoDup;
|
||||
u32 ColorTable[16];
|
||||
};
|
||||
|
||||
struct ConsoleFEDataBlock {
|
||||
u32 CodePage;
|
||||
};
|
||||
|
||||
struct DarwinDataBlock {
|
||||
char DarwinDataAnsi[260];
|
||||
char16 DarwinDataUnicode[260];
|
||||
};
|
||||
|
||||
struct EnvironmentVariableDataBlock {
|
||||
char TargetAnsi[260];
|
||||
char16 TargetUnicode[260];
|
||||
};
|
||||
|
||||
struct IconEnvironmentDataBlock {
|
||||
char TargetAnsi[260];
|
||||
char16 TargetUnicode[260];
|
||||
};
|
||||
|
||||
struct KnownFolderDataBlock {
|
||||
type::GUID KnownFolderID;
|
||||
u32 Offset;
|
||||
};
|
||||
|
||||
struct PropertyStoreDataBlock {
|
||||
u8 Bytes[parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)];
|
||||
std::warning("PropertyStoreDataBlock is not yet implemented!");
|
||||
};
|
||||
|
||||
struct ShimDataBlock {
|
||||
char16 LayerName[(parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)) / sizeof(char16)];
|
||||
};
|
||||
|
||||
struct SpecialFolderDataBlock {
|
||||
u32 SpecialFolderID;
|
||||
u32 Offset;
|
||||
};
|
||||
|
||||
struct TrackerDataBlock {
|
||||
type::Size32 Length;
|
||||
u32 Version;
|
||||
char MachineID[16];
|
||||
type::GUID Droid[2];
|
||||
type::GUID DroidBirth[2];
|
||||
};
|
||||
|
||||
struct VistaAndAboveIDListDataBlock {
|
||||
IDList IDList;
|
||||
};
|
||||
|
||||
struct ExtraDataBlock {
|
||||
type::Size32 BlockSize;
|
||||
|
||||
if (BlockSize < 0x04)
|
||||
break;
|
||||
else {
|
||||
u32 BlockSignature;
|
||||
|
||||
if (BlockSignature == 0xA000'0002)
|
||||
ConsoleDataBlock CONSOLE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0004)
|
||||
ConsoleFEDataBlock CONSOLE_FE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0006)
|
||||
DarwinDataBlock DARWIN_PROPS;
|
||||
else if (BlockSignature == 0xA000'0001)
|
||||
EnvironmentVariableDataBlock ENVIRONMENT_PROPS;
|
||||
else if (BlockSignature == 0xA000'0007)
|
||||
IconEnvironmentDataBlock ICON_ENVIRONMENT_PROPS;
|
||||
else if (BlockSignature == 0xA000'000B)
|
||||
KnownFolderDataBlock KNOWN_FOLDER_PROPS;
|
||||
else if (BlockSignature == 0xA000'0009)
|
||||
PropertyStoreDataBlock PROPERTY_STORE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0008)
|
||||
ShimDataBlock SHIM_PROPS;
|
||||
else if (BlockSignature == 0xA000'0005)
|
||||
SpecialFolderDataBlock SPECIAL_FOLDER_PROPS;
|
||||
else if (BlockSignature == 0xA000'0003)
|
||||
TrackerDataBlock TRACKER_PROPS;
|
||||
else if (BlockSignature == 0xA000'000C)
|
||||
VistaAndAboveIDListDataBlock VISTA_AND_ABOVE_IDLIST_PROPS;
|
||||
}
|
||||
};
|
||||
|
||||
struct ExtraData {
|
||||
ExtraDataBlock ExtraDataBlock[while(true)];
|
||||
};
|
||||
|
||||
struct LNK {
|
||||
ShellLinkHeader ShellLinkHeader;
|
||||
if (ShellLinkHeader.LinkFlags.HasLinkTargetIDList)
|
||||
LinkTargetIDList LinkTargetIDList;
|
||||
if (ShellLinkHeader.LinkFlags.HasLinkInfo)
|
||||
LinkInfo LinkInfo;
|
||||
StringData StringData;
|
||||
ExtraData ExtraData;
|
||||
};
|
||||
|
||||
LNK lnk @ 0x00;
|
||||
|
||||
@@ -1,383 +1,383 @@
|
||||
#pragma MIME application/x-mach-binary
|
||||
|
||||
#include <type/size.pat>
|
||||
|
||||
enum Magic : u32 {
|
||||
_32BitMagic = 0xFEEDFACE,
|
||||
_64BitMagic = 0xFEEDFACF
|
||||
};
|
||||
|
||||
enum CpuType : u32 {
|
||||
VAX = 1,
|
||||
ROMP = 2,
|
||||
BS32032 = 4,
|
||||
BS32332 = 5,
|
||||
MC680x0 = 6,
|
||||
I386 = 7,
|
||||
X86_64 = CpuType::I386 | 0x100'0000,
|
||||
MIPS = 8,
|
||||
NS32532 = 9,
|
||||
HPPA = 11,
|
||||
ARM = 12,
|
||||
MC88000 = 13,
|
||||
SPARC = 14,
|
||||
I860 = be u32(15),
|
||||
I860_LITTLE = 16,
|
||||
RS6000 = 17,
|
||||
MC980000 = 18,
|
||||
POWERPC = 18,
|
||||
POWERPC64 = CpuType::POWERPC | 0x100'0000,
|
||||
VEO = 255
|
||||
};
|
||||
|
||||
enum SubCpuTypeVAX : u24 {
|
||||
ALL = 0,
|
||||
VAX780 = 1,
|
||||
VAX785 = 2,
|
||||
VAX750 = 3,
|
||||
VAX730 = 4,
|
||||
UVAXI = 5,
|
||||
UVAXII = 6,
|
||||
VAX8200 = 7,
|
||||
VAX8500 = 8,
|
||||
VAX8600 = 9,
|
||||
VAX8650 = 10,
|
||||
VAX8800 = 11,
|
||||
UVAXIII = 12
|
||||
};
|
||||
|
||||
enum SubCpuTypeROMP : u24 {
|
||||
ALL = 0,
|
||||
PC = 1,
|
||||
APC = 2,
|
||||
_135 = 3
|
||||
};
|
||||
|
||||
enum SubCpuType32XXX : u24 {
|
||||
ALL = 0,
|
||||
MMAX_DPC = 1,
|
||||
SQT = 2,
|
||||
MMAX_APC_FPU = 3,
|
||||
MMAX_APC_FPA = 4,
|
||||
MMAX_XPC = 5
|
||||
};
|
||||
|
||||
enum SubCpuTypeI386 : u24 {
|
||||
_386 = 3,
|
||||
_486 = 4,
|
||||
_486SX = SubCpuTypeI386::_486 + 128,
|
||||
_586 = 5,
|
||||
IntelPentium = 5 + (0 << 4),
|
||||
IntelPentiumPro = 6 + (1 << 4),
|
||||
IntelPentiumIIM3 = 6 + (3 << 4),
|
||||
IntelPentiumIIM5 = 6 + (5 << 4),
|
||||
IntelPentium4 = 10 + (0 << 4),
|
||||
};
|
||||
|
||||
enum SubCpuTypeMips : u24 {
|
||||
ALL = 0,
|
||||
R2300 = 1,
|
||||
R2600 = 2,
|
||||
R2800 = 3,
|
||||
R2000a = 4
|
||||
};
|
||||
|
||||
enum SubCpuType680x0 : u24 {
|
||||
ALL = 1,
|
||||
MC68030 = 1,
|
||||
MC68040 = 2,
|
||||
MC68030_Only = 3
|
||||
};
|
||||
|
||||
enum SubCpuTypeHPPA : u24 {
|
||||
ALL = 0,
|
||||
_7100 = 0,
|
||||
_7100LC = 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeARM : u24 {
|
||||
ALL = 0,
|
||||
A500_ARCH = 1,
|
||||
A500 = 2,
|
||||
A440 = 3,
|
||||
M4 = 4,
|
||||
V4T = 5,
|
||||
V6 = 6,
|
||||
V5TEJ = 7,
|
||||
XSCALE = 8,
|
||||
V7 = 9,
|
||||
V7F = 10, /* Cortex A9 */
|
||||
V7S = 11, /* Swift */
|
||||
V7K = 12 /* Kirkwood40 */
|
||||
};
|
||||
|
||||
enum SubCpuTypeMC88000 : u24 {
|
||||
ALL = 0,
|
||||
MMAX_JPC = 1,
|
||||
MC88100 = 1,
|
||||
MC88110 = 2
|
||||
};
|
||||
|
||||
enum SubCpuTypeMC98000 : u24 {
|
||||
ALL = 0,
|
||||
MC98601 = 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeI860 : u24 {
|
||||
ALL = 0,
|
||||
_860 = 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeI860Little : u24 {
|
||||
ALL = 0 ... 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeRS6000 : u24 {
|
||||
ALL = 0 ... 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeSparc : u24 {
|
||||
ALL = 0,
|
||||
_260 = 1,
|
||||
_110 = 2
|
||||
};
|
||||
|
||||
enum SubCpuTypePowerPC : u24 {
|
||||
ALL = 0,
|
||||
_601 = 1,
|
||||
_602 = 2,
|
||||
_603 = 3,
|
||||
_603e = 4,
|
||||
_603ev = 5,
|
||||
_604 = 6,
|
||||
_604e = 7,
|
||||
_620 = 8,
|
||||
_750 = 9,
|
||||
_7400 = 10,
|
||||
_7450 = 11,
|
||||
_970 = 100
|
||||
};
|
||||
|
||||
enum SubCpuTypeVEO : u24 {
|
||||
_1 = 1,
|
||||
_2 = 2,
|
||||
_3 = 3,
|
||||
_4 = 4,
|
||||
ALL = SubCpuTypeVEO::_2
|
||||
};
|
||||
|
||||
bitfield Capabilities {
|
||||
padding : 7;
|
||||
lib64 : 1;
|
||||
} [[right_to_left]];
|
||||
|
||||
enum FileType : u32 {
|
||||
Object = 1,
|
||||
Execute = 2,
|
||||
FVMLib = 3,
|
||||
Core = 4,
|
||||
Preload = 5,
|
||||
DyLib = 6,
|
||||
DyLinker = 7,
|
||||
Bundle = 8,
|
||||
DyLibStub = 9,
|
||||
DSym = 10,
|
||||
KExtBundle = 11,
|
||||
};
|
||||
|
||||
bitfield Flags {
|
||||
noUndefs : 1;
|
||||
incrLink : 1;
|
||||
dyldLink : 1;
|
||||
binDatLoad : 1;
|
||||
prebound : 1;
|
||||
splitSegs : 1;
|
||||
lazyInit : 1;
|
||||
twoLevel : 1;
|
||||
forceFlat : 1;
|
||||
noMultiDefs : 1;
|
||||
noFixPrebinding : 1;
|
||||
prebindable : 1;
|
||||
allModsBound : 1;
|
||||
subSectionsViaSymbols : 1;
|
||||
canonical : 1;
|
||||
weakDefines : 1;
|
||||
bindsToWeak : 1;
|
||||
allowStackExecution : 1;
|
||||
rootSafe : 1;
|
||||
setuidSafe : 1;
|
||||
noReexportedDylibs : 1;
|
||||
pie : 1;
|
||||
deadStrippableDylib : 1;
|
||||
hasTlvDescriptors : 1;
|
||||
noHeapExecution : 1;
|
||||
appExtensionSafe : 1;
|
||||
nlistOutOfSyncWithDyldinof : 1;
|
||||
simSupport : 1;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct Header {
|
||||
Magic magic;
|
||||
CpuType cpuType;
|
||||
if (cpuType == CpuType::VAX) SubCpuTypeVAX subCpuType;
|
||||
else if (cpuType == CpuType::ROMP) SubCpuTypeROMP subCpuType;
|
||||
else if (cpuType == CpuType::BS32032 || cpuType == CpuType::BS32332 || cpuType == CpuType::NS32532) SubCpuType32XXX subCpuType;
|
||||
else if (cpuType == CpuType::I386 || cpuType == CpuType::X86_64) SubCpuTypeI386 subCpuType;
|
||||
else if (cpuType == CpuType::MIPS) SubCpuTypeMips subCpuType;
|
||||
else if (cpuType == CpuType::HPPA) SubCpuTypeHPPA subCpuType;
|
||||
else if (cpuType == CpuType::ARM) SubCpuTypeARM subCpuType;
|
||||
else if (cpuType == CpuType::MC88000) SubCpuTypeMC88000 subCpuType;
|
||||
else if (cpuType == CpuType::MC98000) SubCpuTypeMC98000 subCpuType;
|
||||
else if (cpuType == CpuType::I860 || cpuType == CpuType::I860_LITTLE) SubCpuTypeI860 subCpuType;
|
||||
else if (cpuType == CpuType::SPARC) SubCpuTypeSparc subCpuType;
|
||||
else if (cpuType == CpuType::POWERPC || cpuType == CpuType::POWERPC64) SubCpuTypePowerPC subCpuType;
|
||||
else if (cpuType == CpuType::VEO) SubCpuTypeVEO subCpuType;
|
||||
else u24 subCpuType;
|
||||
Capabilities capabilities;
|
||||
FileType fileType;
|
||||
u32 numCommands;
|
||||
type::Size<u32> sizeOfCommands;
|
||||
Flags flags;
|
||||
|
||||
if (magic == Magic::_64BitMagic) padding[sizeof(u32)];
|
||||
};
|
||||
|
||||
enum Command : u32 {
|
||||
ReqDyLd = 0x8000'0000,
|
||||
|
||||
Segment = 0x01,
|
||||
SymTab = 0x02,
|
||||
SymSeg = 0x03,
|
||||
Thread = 0x04,
|
||||
UnixThread = 0x05,
|
||||
LoadFVMLib = 0x06,
|
||||
IdFVMLib = 0x07,
|
||||
Ident = 0x08,
|
||||
FVMFile = 0x09,
|
||||
PrePage = 0x0A,
|
||||
DySymTab = 0x0B,
|
||||
LoadDyLib = 0x0C,
|
||||
IdDyLib = 0x0D,
|
||||
LoadDyLinker = 0x0E,
|
||||
IdDyLinker = 0x0F,
|
||||
PreboundDyLib = 0x10,
|
||||
Routines = 0x11,
|
||||
SubFramework = 0x12,
|
||||
SubUmbrella = 0x13,
|
||||
SubClient = 0x14,
|
||||
SubLibrary = 0x15,
|
||||
TwoLevelHints = 0x16,
|
||||
PrebindCksum = 0x17,
|
||||
LoadWeakDyLib = 0x18 | Command::ReqDyLd,
|
||||
Segment64 = 0x19,
|
||||
Routines64 = 0x1A,
|
||||
UUID = 0x1B,
|
||||
RPath = 0x1C | 0x8000'0000,
|
||||
CodeSignature = 0x1D,
|
||||
SegmentSplitInfo = 0x1E,
|
||||
ReExportDyLib = 0x1F | Command::ReqDyLd,
|
||||
LazyLoadDyLib = 0x20,
|
||||
EncryptionInfo = 0x21,
|
||||
DyLdInfo = 0x22,
|
||||
DyLdInfoOnly = 0x22 | Command::ReqDyLd,
|
||||
LoadUpwardDyLib = 0x23 | Command::ReqDyLd,
|
||||
VersionMinMacOSX = 0x24,
|
||||
VersionMinIPhoneOS = 0x25,
|
||||
FunctionStarts = 0x26,
|
||||
DyLdEnvironment = 0x27,
|
||||
Main = 0x28 | Command::ReqDyLd,
|
||||
DataInCode = 0x29,
|
||||
SourceVersion = 0x2A,
|
||||
DyLibCodeSignDRS = 0x2B
|
||||
};
|
||||
|
||||
struct CommandUUID {
|
||||
u128 uuid;
|
||||
};
|
||||
|
||||
struct Section {
|
||||
char sectionName[16];
|
||||
char segmentName[16];
|
||||
u32 address;
|
||||
type::Size<u32> size;
|
||||
u32 offset;
|
||||
u32 align;
|
||||
u32 reloff;
|
||||
u32 numRelocs;
|
||||
u32 flags;
|
||||
padding[8];
|
||||
|
||||
if (offset > 0)
|
||||
u8 data[size] @ offset [[sealed]];
|
||||
};
|
||||
|
||||
struct CommandSegment {
|
||||
char segmentName[16];
|
||||
u32 vmAddress;
|
||||
type::Size<u32> vmSize;
|
||||
u32 fileOffset;
|
||||
type::Size<u32> fileSize;
|
||||
u32 maxProtection;
|
||||
u32 initProtection;
|
||||
u32 numSections;
|
||||
u32 flags;
|
||||
|
||||
Section sections[numSections];
|
||||
|
||||
if (fileOffset > 0)
|
||||
u8 data[fileSize] @ fileOffset [[sealed]];
|
||||
};
|
||||
|
||||
struct Section64 {
|
||||
char sectionName[16];
|
||||
char segmentName[16];
|
||||
u64 address;
|
||||
type::Size<u64> size;
|
||||
u32 offset;
|
||||
u32 align;
|
||||
u32 reloff;
|
||||
u32 numRelocs;
|
||||
u32 flags;
|
||||
padding[12];
|
||||
|
||||
if (offset > 0)
|
||||
u8 data[size] @ offset [[sealed]];
|
||||
};
|
||||
|
||||
struct CommandSegment64 {
|
||||
char segmentName[16];
|
||||
u64 vmAddress;
|
||||
type::Size<u64> vmSize;
|
||||
u64 fileOffset;
|
||||
type::Size<u64> fileSize;
|
||||
u32 maxProtection;
|
||||
u32 initProtection;
|
||||
u32 numSections;
|
||||
u32 flags;
|
||||
|
||||
Section64 sections[numSections];
|
||||
|
||||
if (fileOffset > 0)
|
||||
u8 data[fileSize] @ fileOffset [[sealed]];
|
||||
};
|
||||
|
||||
struct LoadCommand {
|
||||
Command command;
|
||||
type::Size<u32> commandSize;
|
||||
|
||||
if (command == Command::UUID)
|
||||
CommandUUID data;
|
||||
else if (command == Command::Segment)
|
||||
CommandSegment data;
|
||||
else if (command == Command::Segment64)
|
||||
CommandSegment64 data;
|
||||
else
|
||||
u8 data[commandSize - 8] [[sealed]];
|
||||
};
|
||||
|
||||
struct MachO {
|
||||
Header header;
|
||||
LoadCommand loadCommands[header.numCommands];
|
||||
};
|
||||
|
||||
#pragma MIME application/x-mach-binary
|
||||
|
||||
#include <type/size.pat>
|
||||
|
||||
enum Magic : u32 {
|
||||
_32BitMagic = 0xFEEDFACE,
|
||||
_64BitMagic = 0xFEEDFACF
|
||||
};
|
||||
|
||||
enum CpuType : u32 {
|
||||
VAX = 1,
|
||||
ROMP = 2,
|
||||
BS32032 = 4,
|
||||
BS32332 = 5,
|
||||
MC680x0 = 6,
|
||||
I386 = 7,
|
||||
X86_64 = CpuType::I386 | 0x100'0000,
|
||||
MIPS = 8,
|
||||
NS32532 = 9,
|
||||
HPPA = 11,
|
||||
ARM = 12,
|
||||
MC88000 = 13,
|
||||
SPARC = 14,
|
||||
I860 = be u32(15),
|
||||
I860_LITTLE = 16,
|
||||
RS6000 = 17,
|
||||
MC980000 = 18,
|
||||
POWERPC = 18,
|
||||
POWERPC64 = CpuType::POWERPC | 0x100'0000,
|
||||
VEO = 255
|
||||
};
|
||||
|
||||
enum SubCpuTypeVAX : u24 {
|
||||
ALL = 0,
|
||||
VAX780 = 1,
|
||||
VAX785 = 2,
|
||||
VAX750 = 3,
|
||||
VAX730 = 4,
|
||||
UVAXI = 5,
|
||||
UVAXII = 6,
|
||||
VAX8200 = 7,
|
||||
VAX8500 = 8,
|
||||
VAX8600 = 9,
|
||||
VAX8650 = 10,
|
||||
VAX8800 = 11,
|
||||
UVAXIII = 12
|
||||
};
|
||||
|
||||
enum SubCpuTypeROMP : u24 {
|
||||
ALL = 0,
|
||||
PC = 1,
|
||||
APC = 2,
|
||||
_135 = 3
|
||||
};
|
||||
|
||||
enum SubCpuType32XXX : u24 {
|
||||
ALL = 0,
|
||||
MMAX_DPC = 1,
|
||||
SQT = 2,
|
||||
MMAX_APC_FPU = 3,
|
||||
MMAX_APC_FPA = 4,
|
||||
MMAX_XPC = 5
|
||||
};
|
||||
|
||||
enum SubCpuTypeI386 : u24 {
|
||||
_386 = 3,
|
||||
_486 = 4,
|
||||
_486SX = SubCpuTypeI386::_486 + 128,
|
||||
_586 = 5,
|
||||
IntelPentium = 5 + (0 << 4),
|
||||
IntelPentiumPro = 6 + (1 << 4),
|
||||
IntelPentiumIIM3 = 6 + (3 << 4),
|
||||
IntelPentiumIIM5 = 6 + (5 << 4),
|
||||
IntelPentium4 = 10 + (0 << 4),
|
||||
};
|
||||
|
||||
enum SubCpuTypeMips : u24 {
|
||||
ALL = 0,
|
||||
R2300 = 1,
|
||||
R2600 = 2,
|
||||
R2800 = 3,
|
||||
R2000a = 4
|
||||
};
|
||||
|
||||
enum SubCpuType680x0 : u24 {
|
||||
ALL = 1,
|
||||
MC68030 = 1,
|
||||
MC68040 = 2,
|
||||
MC68030_Only = 3
|
||||
};
|
||||
|
||||
enum SubCpuTypeHPPA : u24 {
|
||||
ALL = 0,
|
||||
_7100 = 0,
|
||||
_7100LC = 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeARM : u24 {
|
||||
ALL = 0,
|
||||
A500_ARCH = 1,
|
||||
A500 = 2,
|
||||
A440 = 3,
|
||||
M4 = 4,
|
||||
V4T = 5,
|
||||
V6 = 6,
|
||||
V5TEJ = 7,
|
||||
XSCALE = 8,
|
||||
V7 = 9,
|
||||
V7F = 10, /* Cortex A9 */
|
||||
V7S = 11, /* Swift */
|
||||
V7K = 12 /* Kirkwood40 */
|
||||
};
|
||||
|
||||
enum SubCpuTypeMC88000 : u24 {
|
||||
ALL = 0,
|
||||
MMAX_JPC = 1,
|
||||
MC88100 = 1,
|
||||
MC88110 = 2
|
||||
};
|
||||
|
||||
enum SubCpuTypeMC98000 : u24 {
|
||||
ALL = 0,
|
||||
MC98601 = 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeI860 : u24 {
|
||||
ALL = 0,
|
||||
_860 = 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeI860Little : u24 {
|
||||
ALL = 0 ... 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeRS6000 : u24 {
|
||||
ALL = 0 ... 1
|
||||
};
|
||||
|
||||
enum SubCpuTypeSparc : u24 {
|
||||
ALL = 0,
|
||||
_260 = 1,
|
||||
_110 = 2
|
||||
};
|
||||
|
||||
enum SubCpuTypePowerPC : u24 {
|
||||
ALL = 0,
|
||||
_601 = 1,
|
||||
_602 = 2,
|
||||
_603 = 3,
|
||||
_603e = 4,
|
||||
_603ev = 5,
|
||||
_604 = 6,
|
||||
_604e = 7,
|
||||
_620 = 8,
|
||||
_750 = 9,
|
||||
_7400 = 10,
|
||||
_7450 = 11,
|
||||
_970 = 100
|
||||
};
|
||||
|
||||
enum SubCpuTypeVEO : u24 {
|
||||
_1 = 1,
|
||||
_2 = 2,
|
||||
_3 = 3,
|
||||
_4 = 4,
|
||||
ALL = SubCpuTypeVEO::_2
|
||||
};
|
||||
|
||||
bitfield Capabilities {
|
||||
padding : 7;
|
||||
lib64 : 1;
|
||||
};
|
||||
|
||||
enum FileType : u32 {
|
||||
Object = 1,
|
||||
Execute = 2,
|
||||
FVMLib = 3,
|
||||
Core = 4,
|
||||
Preload = 5,
|
||||
DyLib = 6,
|
||||
DyLinker = 7,
|
||||
Bundle = 8,
|
||||
DyLibStub = 9,
|
||||
DSym = 10,
|
||||
KExtBundle = 11,
|
||||
};
|
||||
|
||||
bitfield Flags {
|
||||
noUndefs : 1;
|
||||
incrLink : 1;
|
||||
dyldLink : 1;
|
||||
binDatLoad : 1;
|
||||
prebound : 1;
|
||||
splitSegs : 1;
|
||||
lazyInit : 1;
|
||||
twoLevel : 1;
|
||||
forceFlat : 1;
|
||||
noMultiDefs : 1;
|
||||
noFixPrebinding : 1;
|
||||
prebindable : 1;
|
||||
allModsBound : 1;
|
||||
subSectionsViaSymbols : 1;
|
||||
canonical : 1;
|
||||
weakDefines : 1;
|
||||
bindsToWeak : 1;
|
||||
allowStackExecution : 1;
|
||||
rootSafe : 1;
|
||||
setuidSafe : 1;
|
||||
noReexportedDylibs : 1;
|
||||
pie : 1;
|
||||
deadStrippableDylib : 1;
|
||||
hasTlvDescriptors : 1;
|
||||
noHeapExecution : 1;
|
||||
appExtensionSafe : 1;
|
||||
nlistOutOfSyncWithDyldinof : 1;
|
||||
simSupport : 1;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
Magic magic;
|
||||
CpuType cpuType;
|
||||
if (cpuType == CpuType::VAX) SubCpuTypeVAX subCpuType;
|
||||
else if (cpuType == CpuType::ROMP) SubCpuTypeROMP subCpuType;
|
||||
else if (cpuType == CpuType::BS32032 || cpuType == CpuType::BS32332 || cpuType == CpuType::NS32532) SubCpuType32XXX subCpuType;
|
||||
else if (cpuType == CpuType::I386 || cpuType == CpuType::X86_64) SubCpuTypeI386 subCpuType;
|
||||
else if (cpuType == CpuType::MIPS) SubCpuTypeMips subCpuType;
|
||||
else if (cpuType == CpuType::HPPA) SubCpuTypeHPPA subCpuType;
|
||||
else if (cpuType == CpuType::ARM) SubCpuTypeARM subCpuType;
|
||||
else if (cpuType == CpuType::MC88000) SubCpuTypeMC88000 subCpuType;
|
||||
else if (cpuType == CpuType::MC98000) SubCpuTypeMC98000 subCpuType;
|
||||
else if (cpuType == CpuType::I860 || cpuType == CpuType::I860_LITTLE) SubCpuTypeI860 subCpuType;
|
||||
else if (cpuType == CpuType::SPARC) SubCpuTypeSparc subCpuType;
|
||||
else if (cpuType == CpuType::POWERPC || cpuType == CpuType::POWERPC64) SubCpuTypePowerPC subCpuType;
|
||||
else if (cpuType == CpuType::VEO) SubCpuTypeVEO subCpuType;
|
||||
else u24 subCpuType;
|
||||
Capabilities capabilities;
|
||||
FileType fileType;
|
||||
u32 numCommands;
|
||||
type::Size<u32> sizeOfCommands;
|
||||
Flags flags;
|
||||
|
||||
if (magic == Magic::_64BitMagic) padding[sizeof(u32)];
|
||||
};
|
||||
|
||||
enum Command : u32 {
|
||||
ReqDyLd = 0x8000'0000,
|
||||
|
||||
Segment = 0x01,
|
||||
SymTab = 0x02,
|
||||
SymSeg = 0x03,
|
||||
Thread = 0x04,
|
||||
UnixThread = 0x05,
|
||||
LoadFVMLib = 0x06,
|
||||
IdFVMLib = 0x07,
|
||||
Ident = 0x08,
|
||||
FVMFile = 0x09,
|
||||
PrePage = 0x0A,
|
||||
DySymTab = 0x0B,
|
||||
LoadDyLib = 0x0C,
|
||||
IdDyLib = 0x0D,
|
||||
LoadDyLinker = 0x0E,
|
||||
IdDyLinker = 0x0F,
|
||||
PreboundDyLib = 0x10,
|
||||
Routines = 0x11,
|
||||
SubFramework = 0x12,
|
||||
SubUmbrella = 0x13,
|
||||
SubClient = 0x14,
|
||||
SubLibrary = 0x15,
|
||||
TwoLevelHints = 0x16,
|
||||
PrebindCksum = 0x17,
|
||||
LoadWeakDyLib = 0x18 | Command::ReqDyLd,
|
||||
Segment64 = 0x19,
|
||||
Routines64 = 0x1A,
|
||||
UUID = 0x1B,
|
||||
RPath = 0x1C | 0x8000'0000,
|
||||
CodeSignature = 0x1D,
|
||||
SegmentSplitInfo = 0x1E,
|
||||
ReExportDyLib = 0x1F | Command::ReqDyLd,
|
||||
LazyLoadDyLib = 0x20,
|
||||
EncryptionInfo = 0x21,
|
||||
DyLdInfo = 0x22,
|
||||
DyLdInfoOnly = 0x22 | Command::ReqDyLd,
|
||||
LoadUpwardDyLib = 0x23 | Command::ReqDyLd,
|
||||
VersionMinMacOSX = 0x24,
|
||||
VersionMinIPhoneOS = 0x25,
|
||||
FunctionStarts = 0x26,
|
||||
DyLdEnvironment = 0x27,
|
||||
Main = 0x28 | Command::ReqDyLd,
|
||||
DataInCode = 0x29,
|
||||
SourceVersion = 0x2A,
|
||||
DyLibCodeSignDRS = 0x2B
|
||||
};
|
||||
|
||||
struct CommandUUID {
|
||||
u128 uuid;
|
||||
};
|
||||
|
||||
struct Section {
|
||||
char sectionName[16];
|
||||
char segmentName[16];
|
||||
u32 address;
|
||||
type::Size<u32> size;
|
||||
u32 offset;
|
||||
u32 align;
|
||||
u32 reloff;
|
||||
u32 numRelocs;
|
||||
u32 flags;
|
||||
padding[8];
|
||||
|
||||
if (offset > 0)
|
||||
u8 data[size] @ offset [[sealed]];
|
||||
};
|
||||
|
||||
struct CommandSegment {
|
||||
char segmentName[16];
|
||||
u32 vmAddress;
|
||||
type::Size<u32> vmSize;
|
||||
u32 fileOffset;
|
||||
type::Size<u32> fileSize;
|
||||
u32 maxProtection;
|
||||
u32 initProtection;
|
||||
u32 numSections;
|
||||
u32 flags;
|
||||
|
||||
Section sections[numSections];
|
||||
|
||||
if (fileOffset > 0)
|
||||
u8 data[fileSize] @ fileOffset [[sealed]];
|
||||
};
|
||||
|
||||
struct Section64 {
|
||||
char sectionName[16];
|
||||
char segmentName[16];
|
||||
u64 address;
|
||||
type::Size<u64> size;
|
||||
u32 offset;
|
||||
u32 align;
|
||||
u32 reloff;
|
||||
u32 numRelocs;
|
||||
u32 flags;
|
||||
padding[12];
|
||||
|
||||
if (offset > 0)
|
||||
u8 data[size] @ offset [[sealed]];
|
||||
};
|
||||
|
||||
struct CommandSegment64 {
|
||||
char segmentName[16];
|
||||
u64 vmAddress;
|
||||
type::Size<u64> vmSize;
|
||||
u64 fileOffset;
|
||||
type::Size<u64> fileSize;
|
||||
u32 maxProtection;
|
||||
u32 initProtection;
|
||||
u32 numSections;
|
||||
u32 flags;
|
||||
|
||||
Section64 sections[numSections];
|
||||
|
||||
if (fileOffset > 0)
|
||||
u8 data[fileSize] @ fileOffset [[sealed]];
|
||||
};
|
||||
|
||||
struct LoadCommand {
|
||||
Command command;
|
||||
type::Size<u32> commandSize;
|
||||
|
||||
if (command == Command::UUID)
|
||||
CommandUUID data;
|
||||
else if (command == Command::Segment)
|
||||
CommandSegment data;
|
||||
else if (command == Command::Segment64)
|
||||
CommandSegment64 data;
|
||||
else
|
||||
u8 data[commandSize - 8] [[sealed]];
|
||||
};
|
||||
|
||||
struct MachO {
|
||||
Header header;
|
||||
LoadCommand loadCommands[header.numCommands];
|
||||
};
|
||||
|
||||
MachO macho @ 0x00;
|
||||
@@ -1,423 +1,423 @@
|
||||
#pragma MIME application/x-dmp
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/types/win32.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
using RVA = ULONG32;
|
||||
using RVA64 = ULONG64;
|
||||
|
||||
enum MINIDUMP_STREAM_TYPE : ULONG32 {
|
||||
UnusedStream = 0,
|
||||
ReservedStream0 = 1,
|
||||
ReservedStream1 = 2,
|
||||
ThreadListStream = 3,
|
||||
ModuleListStream = 4,
|
||||
MemoryListStream = 5,
|
||||
ExceptionStream = 6,
|
||||
SystemInfoStream = 7,
|
||||
ThreadExListStream = 8,
|
||||
Memory64ListStream = 9,
|
||||
CommentStreamA = 10,
|
||||
CommentStreamW = 11,
|
||||
HandleDataStream = 12,
|
||||
FunctionTableStream = 13,
|
||||
UnloadedModuleListStream = 14,
|
||||
MiscInfoStream = 15,
|
||||
MemoryInfoListStream = 16,
|
||||
ThreadInfoListStream = 17,
|
||||
HandleOperationListStream = 18,
|
||||
TokenStream = 19,
|
||||
JavaScriptDataStream = 20,
|
||||
SystemMemoryInfoStream = 21,
|
||||
ProcessVmCountersStream = 22,
|
||||
IptTraceStream = 23,
|
||||
ThreadNamesStream = 24,
|
||||
ceStreamNull = 0x8000,
|
||||
ceStreamSystemInfo = 0x8001,
|
||||
ceStreamException = 0x8002,
|
||||
ceStreamModuleList = 0x8003,
|
||||
ceStreamProcessList = 0x8004,
|
||||
ceStreamThreadList = 0x8005,
|
||||
ceStreamThreadContextList = 0x8006,
|
||||
ceStreamThreadCallStackList = 0x8007,
|
||||
ceStreamMemoryVirtualList = 0x8008,
|
||||
ceStreamMemoryPhysicalList = 0x8009,
|
||||
ceStreamBucketParameters = 0x800A,
|
||||
ceStreamProcessModuleMap = 0x800B,
|
||||
ceStreamDiagnosisList = 0x800C,
|
||||
LastReservedStream = 0xFFFF
|
||||
};
|
||||
|
||||
struct MINIDUMP_LOCATION_DESCRIPTOR {
|
||||
type::Size32 DataSize;
|
||||
RVA Rva;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_DESCRIPTOR {
|
||||
ULONG64 StartOfMemoryRange;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR Memory;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD {
|
||||
ULONG32 ThreadId;
|
||||
ULONG32 SuspendCount;
|
||||
ULONG32 PriorityClass;
|
||||
ULONG32 Priority;
|
||||
ULONG64 Teb;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR Stack;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_LIST {
|
||||
ULONG32 NumberOfThreads;
|
||||
MINIDUMP_THREAD Threads[NumberOfThreads];
|
||||
};
|
||||
|
||||
struct VS_FIXEDFILEINFO {
|
||||
DWORD dwSignature;
|
||||
DWORD dwStrucVersion;
|
||||
DWORD dwFileVersionMS;
|
||||
DWORD dwFileVersionLS;
|
||||
DWORD dwProductVersionMS;
|
||||
DWORD dwProductVersionLS;
|
||||
DWORD dwFileFlagsMask;
|
||||
DWORD dwFileFlags;
|
||||
DWORD dwFileOS;
|
||||
DWORD dwFileType;
|
||||
DWORD dwFileSubtype;
|
||||
DWORD dwFileDateMS;
|
||||
DWORD dwFileDateLS;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MODULE {
|
||||
ULONG64 BaseOfImage;
|
||||
type::Size32 SizeOfImage;
|
||||
ULONG32 CheckSum;
|
||||
type::time32_t TimeDateStamp;
|
||||
RVA ModuleNameRva;
|
||||
VS_FIXEDFILEINFO VersionInfo;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
|
||||
ULONG64 Reserved0;
|
||||
ULONG64 Reserved1;
|
||||
|
||||
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
|
||||
} [[format("format_module")]];
|
||||
|
||||
fn format_module(ref MINIDUMP_MODULE module) {
|
||||
return module.ModuleName;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MODULE_LIST {
|
||||
ULONG32 NumberOfModules;
|
||||
MINIDUMP_MODULE Modules[NumberOfModules];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_LIST {
|
||||
ULONG32 NumberOfMemoryRanges;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges[NumberOfMemoryRanges];
|
||||
};
|
||||
|
||||
struct MINIDUMP_EXCEPTION {
|
||||
ULONG32 ExceptionCode;
|
||||
ULONG32 ExceptionFlags;
|
||||
ULONG64 ExceptionRecord;
|
||||
ULONG64 ExceptionAddress;
|
||||
ULONG32 NumberParameters;
|
||||
padding[4];
|
||||
ULONG64 ExceptionInformation[15];
|
||||
};
|
||||
|
||||
struct MINIDUMP_EXCEPTION_STREAM {
|
||||
ULONG32 ThreadId;
|
||||
padding[4];
|
||||
MINIDUMP_EXCEPTION ExceptionRecord;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
|
||||
};
|
||||
|
||||
struct CPU_INFORMATION {
|
||||
ULONG32 VendorId[3];
|
||||
ULONG32 VersionInformation;
|
||||
ULONG32 FeatureInformation;
|
||||
ULONG32 AMDExtendedCpuFeatures;
|
||||
};
|
||||
|
||||
struct MINIDUMP_SYSTEM_INFO {
|
||||
USHORT ProcessorArchitecture;
|
||||
USHORT ProcessorLevel;
|
||||
USHORT ProcessorRevision;
|
||||
UCHAR NumberOfProcessors;
|
||||
UCHAR ProductType;
|
||||
ULONG32 MajorVersion;
|
||||
ULONG32 MinorVersion;
|
||||
ULONG32 BuildNumber;
|
||||
ULONG32 PlatformId;
|
||||
RVA CSDVersionRva;
|
||||
USHORT SuiteMask;
|
||||
USHORT Reserved;
|
||||
CPU_INFORMATION Cpu;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_EX {
|
||||
ULONG32 ThreadId;
|
||||
ULONG32 SuspendCount;
|
||||
ULONG32 PriorityClass;
|
||||
ULONG32 Priority;
|
||||
ULONG64 Teb;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR Stack;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR BackingStore;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_EX_LIST {
|
||||
ULONG32 NumberOfThreads;
|
||||
MINIDUMP_THREAD_EX Threads[NumberOfThreads];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_DESCRIPTOR64 {
|
||||
ULONG64 StartOfMemoryRange;
|
||||
type::Size64 DataSize;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY64_LIST {
|
||||
ULONG64 NumberOfMemoryRanges;
|
||||
RVA64 BaseRva;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges[NumberOfMemoryRanges];
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_DESCRIPTOR {
|
||||
ULONG64 Handle;
|
||||
RVA TypeNameRva;
|
||||
RVA ObjectNameRva;
|
||||
ULONG32 Attributes;
|
||||
ULONG32 GrantedAccess;
|
||||
ULONG32 HandleCount;
|
||||
ULONG32 PointerCount;
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_DESCRIPTOR_2 {
|
||||
ULONG64 Handle;
|
||||
RVA TypeNameRva;
|
||||
RVA ObjectNameRva;
|
||||
ULONG32 Attributes;
|
||||
ULONG32 GrantedAccess;
|
||||
ULONG32 HandleCount;
|
||||
ULONG32 PointerCount;
|
||||
RVA ObjectInfoRva;
|
||||
ULONG32 Reserved0;
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_DATA_STREAM {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfDescriptor;
|
||||
ULONG32 NumberOfDescriptors;
|
||||
ULONG32 Reserved;
|
||||
|
||||
if (SizeOfDescriptor == 32)
|
||||
MINIDUMP_HANDLE_DESCRIPTOR HandleDescriptors[NumberOfDescriptors];
|
||||
else if (SizeOfDescriptor == 40)
|
||||
MINIDUMP_HANDLE_DESCRIPTOR_2 HandleDescriptors[NumberOfDescriptors];
|
||||
};
|
||||
|
||||
struct MINIDUMP_FUNCTION_TABLE_DESCRIPTOR {
|
||||
ULONG64 MinimumAddress;
|
||||
ULONG64 MaximumAddress;
|
||||
ULONG64 BaseAddress;
|
||||
ULONG32 EntryCount;
|
||||
type::Size32 SizeOfAlignPad;
|
||||
};
|
||||
|
||||
struct MINIDUMP_FUNCTION_TABLE_STREAM {
|
||||
type::Size32 SizeOfHeader;
|
||||
type::Size32 SizeOfDescriptor;
|
||||
type::Size32 SizeOfNativeDescriptor;
|
||||
type::Size32 SizeOfFunctionEntry;
|
||||
ULONG32 NumberOfDescriptors;
|
||||
ULONG32 SizeOfAlignPad;
|
||||
|
||||
MINIDUMP_FUNCTION_TABLE_DESCRIPTOR FunctionDescriptors[NumberOfDescriptors];
|
||||
};
|
||||
|
||||
struct MINIDUMP_UNLOADED_MODULE {
|
||||
ULONG64 BaseOfImage;
|
||||
type::Size32 SizeOfImage;
|
||||
ULONG32 CheckSum;
|
||||
ULONG32 TimeDateStamp;
|
||||
RVA ModuleNameRva;
|
||||
|
||||
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
|
||||
} [[format("format_unloaded_module")]];
|
||||
|
||||
fn format_unloaded_module(ref MINIDUMP_UNLOADED_MODULE module) {
|
||||
return module.ModuleName;
|
||||
};
|
||||
|
||||
struct MINIDUMP_UNLOADED_MODULE_LIST {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfEntry;
|
||||
ULONG32 NumberOfEntries;
|
||||
|
||||
if (SizeOfHeader > 12)
|
||||
padding[header.SizeOfHeader - 12];
|
||||
|
||||
MINIDUMP_UNLOADED_MODULE Modules[NumberOfEntries];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MISC_INFO {
|
||||
ULONG32 SizeOfInfo;
|
||||
ULONG32 Flags1;
|
||||
ULONG32 ProcessId;
|
||||
ULONG32 ProcessCreateTime;
|
||||
ULONG32 ProcessUserTime;
|
||||
ULONG32 ProcessKernelTime;
|
||||
|
||||
if (SizeOfInfo > 24) {
|
||||
ULONG32 ProcessorMaxMhz;
|
||||
ULONG32 ProcessorCurrentMhz;
|
||||
ULONG32 ProcessorMhzLimit;
|
||||
ULONG32 ProcessorMaxIdleState;
|
||||
ULONG32 ProcessorCurrentIdleState;
|
||||
}
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_INFO {
|
||||
ULONG64 BaseAddress;
|
||||
ULONG64 AllocationBase;
|
||||
ULONG32 AllocationProtect;
|
||||
padding[4];
|
||||
type::Size64 RegionSize;
|
||||
ULONG32 State;
|
||||
ULONG32 Protect;
|
||||
ULONG32 Type;
|
||||
padding[4];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_INFO_LIST {
|
||||
ULONG SizeOfHeader;
|
||||
ULONG SizeOfEntry;
|
||||
ULONG64 NumberOfEntries;
|
||||
|
||||
if (SizeOfHeader > 16)
|
||||
padding[SizeOfHeader - 16];
|
||||
|
||||
MINIDUMP_MEMORY_INFO Info[NumberOfEntries];
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_INFO {
|
||||
ULONG32 ThreadId;
|
||||
ULONG32 DumpFlags;
|
||||
ULONG32 DumpError;
|
||||
ULONG32 ExitStatus;
|
||||
ULONG64 CreateTime;
|
||||
ULONG64 ExitTime;
|
||||
ULONG64 KernelTime;
|
||||
ULONG64 UserTime;
|
||||
ULONG64 StartAddress;
|
||||
ULONG64 Affinity;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_INFO_LIST {
|
||||
ULONG SizeOfHeader;
|
||||
ULONG SizeOfEntry;
|
||||
ULONG NumberOfEntries;
|
||||
|
||||
if (SizeOfHeader > 12)
|
||||
padding[SizeOfHeader - 12];
|
||||
|
||||
MINIDUMP_THREAD_INFO Info[NumberOfEntries];
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_OPERATION_LIST {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfEntry;
|
||||
ULONG32 NumberOfEntries;
|
||||
ULONG32 Reserved;
|
||||
};
|
||||
|
||||
struct MINIDUMP_DIRECTORY {
|
||||
MINIDUMP_STREAM_TYPE StreamType;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR Location;
|
||||
|
||||
if (StreamType == MINIDUMP_STREAM_TYPE::ThreadListStream)
|
||||
MINIDUMP_THREAD_LIST ThreadList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ModuleListStream)
|
||||
MINIDUMP_MODULE_LIST ModuleList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryListStream)
|
||||
MINIDUMP_MEMORY_LIST MemoryList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ExceptionStream)
|
||||
MINIDUMP_EXCEPTION_STREAM ExceptionInfo @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::SystemInfoStream)
|
||||
MINIDUMP_SYSTEM_INFO SystemInfo @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadExListStream)
|
||||
MINIDUMP_THREAD_EX_LIST ThreadExList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::Memory64ListStream)
|
||||
MINIDUMP_MEMORY64_LIST Mem64List @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamA)
|
||||
char Comment[] @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamW)
|
||||
char16 Comment[] @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleDataStream)
|
||||
MINIDUMP_HANDLE_DATA_STREAM HandleData @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::FunctionTableStream)
|
||||
MINIDUMP_FUNCTION_TABLE_STREAM FunctionTable @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::UnloadedModuleListStream)
|
||||
MINIDUMP_UNLOADED_MODULE_LIST UnloadModuleList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::MiscInfoStream)
|
||||
MINIDUMP_MISC_INFO MiscInfo @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryInfoListStream)
|
||||
MINIDUMP_MEMORY_INFO_LIST MemInfoList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadInfoListStream)
|
||||
MINIDUMP_THREAD_INFO_LIST ThreadInfoList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleOperationListStream)
|
||||
MINIDUMP_HANDLE_OPERATION_LIST HandleOperList @ Location.Rva;
|
||||
};
|
||||
|
||||
bitfield MINIDUMP_TYPE {
|
||||
MiniDumpWithDataSegs : 1;
|
||||
MiniDumpWithFullMemory : 1;
|
||||
MiniDumpWithHandleData : 1;
|
||||
MiniDumpFilterMemory : 1;
|
||||
MiniDumpScanMemory : 1;
|
||||
MiniDumpWithUnloadedModules : 1;
|
||||
MiniDumpWithIndirectlyReferencedMemory : 1;
|
||||
MiniDumpFilterModulePaths : 1;
|
||||
MiniDumpWithProcessThreadData : 1;
|
||||
MiniDumpWithPrivateReadWriteMemory : 1;
|
||||
MiniDumpWithoutOptionalData : 1;
|
||||
MiniDumpWithFullMemoryInfo : 1;
|
||||
MiniDumpWithThreadInfo : 1;
|
||||
MiniDumpWithCodeSegs : 1;
|
||||
MiniDumpWithoutAuxiliaryState : 1;
|
||||
MiniDumpWithFullAuxiliaryState : 1;
|
||||
MiniDumpWithPrivateWriteCopyMemory : 1;
|
||||
MiniDumpIgnoreInaccessibleMemory : 1;
|
||||
MiniDumpWithTokenInformation : 1;
|
||||
MiniDumpWithModuleHeaders : 1;
|
||||
MiniDumpFilterTriage : 1;
|
||||
MiniDumpWithAvxXStateContext : 1;
|
||||
MiniDumpWithIptTrace : 1;
|
||||
MiniDumpScanInaccessiblePartialPages : 1;
|
||||
padding : 40;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct MINIDUMP_HEADER {
|
||||
char Signature[4];
|
||||
ULONG32 Version;
|
||||
ULONG32 NumberOfStreams;
|
||||
RVA StreamDirectoryRva;
|
||||
ULONG32 Checksum;
|
||||
type::time32_t TimeDateStamp;
|
||||
MINIDUMP_TYPE Flags;
|
||||
};
|
||||
|
||||
struct MINIDUMP {
|
||||
MINIDUMP_HEADER Header;
|
||||
MINIDUMP_DIRECTORY Streams[Header.NumberOfStreams] [[format_entries("format_stream")]];
|
||||
};
|
||||
|
||||
fn format_stream(ref MINIDUMP_DIRECTORY stream) {
|
||||
return stream.StreamType;
|
||||
};
|
||||
|
||||
MINIDUMP MiniDump @ 0x00;
|
||||
#pragma MIME application/x-dmp
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/types/win32.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
using RVA = ULONG32;
|
||||
using RVA64 = ULONG64;
|
||||
|
||||
enum MINIDUMP_STREAM_TYPE : ULONG32 {
|
||||
UnusedStream = 0,
|
||||
ReservedStream0 = 1,
|
||||
ReservedStream1 = 2,
|
||||
ThreadListStream = 3,
|
||||
ModuleListStream = 4,
|
||||
MemoryListStream = 5,
|
||||
ExceptionStream = 6,
|
||||
SystemInfoStream = 7,
|
||||
ThreadExListStream = 8,
|
||||
Memory64ListStream = 9,
|
||||
CommentStreamA = 10,
|
||||
CommentStreamW = 11,
|
||||
HandleDataStream = 12,
|
||||
FunctionTableStream = 13,
|
||||
UnloadedModuleListStream = 14,
|
||||
MiscInfoStream = 15,
|
||||
MemoryInfoListStream = 16,
|
||||
ThreadInfoListStream = 17,
|
||||
HandleOperationListStream = 18,
|
||||
TokenStream = 19,
|
||||
JavaScriptDataStream = 20,
|
||||
SystemMemoryInfoStream = 21,
|
||||
ProcessVmCountersStream = 22,
|
||||
IptTraceStream = 23,
|
||||
ThreadNamesStream = 24,
|
||||
ceStreamNull = 0x8000,
|
||||
ceStreamSystemInfo = 0x8001,
|
||||
ceStreamException = 0x8002,
|
||||
ceStreamModuleList = 0x8003,
|
||||
ceStreamProcessList = 0x8004,
|
||||
ceStreamThreadList = 0x8005,
|
||||
ceStreamThreadContextList = 0x8006,
|
||||
ceStreamThreadCallStackList = 0x8007,
|
||||
ceStreamMemoryVirtualList = 0x8008,
|
||||
ceStreamMemoryPhysicalList = 0x8009,
|
||||
ceStreamBucketParameters = 0x800A,
|
||||
ceStreamProcessModuleMap = 0x800B,
|
||||
ceStreamDiagnosisList = 0x800C,
|
||||
LastReservedStream = 0xFFFF
|
||||
};
|
||||
|
||||
struct MINIDUMP_LOCATION_DESCRIPTOR {
|
||||
type::Size32 DataSize;
|
||||
RVA Rva;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_DESCRIPTOR {
|
||||
ULONG64 StartOfMemoryRange;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR Memory;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD {
|
||||
ULONG32 ThreadId;
|
||||
ULONG32 SuspendCount;
|
||||
ULONG32 PriorityClass;
|
||||
ULONG32 Priority;
|
||||
ULONG64 Teb;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR Stack;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_LIST {
|
||||
ULONG32 NumberOfThreads;
|
||||
MINIDUMP_THREAD Threads[NumberOfThreads];
|
||||
};
|
||||
|
||||
struct VS_FIXEDFILEINFO {
|
||||
DWORD dwSignature;
|
||||
DWORD dwStrucVersion;
|
||||
DWORD dwFileVersionMS;
|
||||
DWORD dwFileVersionLS;
|
||||
DWORD dwProductVersionMS;
|
||||
DWORD dwProductVersionLS;
|
||||
DWORD dwFileFlagsMask;
|
||||
DWORD dwFileFlags;
|
||||
DWORD dwFileOS;
|
||||
DWORD dwFileType;
|
||||
DWORD dwFileSubtype;
|
||||
DWORD dwFileDateMS;
|
||||
DWORD dwFileDateLS;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MODULE {
|
||||
ULONG64 BaseOfImage;
|
||||
type::Size32 SizeOfImage;
|
||||
ULONG32 CheckSum;
|
||||
type::time32_t TimeDateStamp;
|
||||
RVA ModuleNameRva;
|
||||
VS_FIXEDFILEINFO VersionInfo;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
|
||||
ULONG64 Reserved0;
|
||||
ULONG64 Reserved1;
|
||||
|
||||
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
|
||||
} [[format("format_module")]];
|
||||
|
||||
fn format_module(ref MINIDUMP_MODULE module) {
|
||||
return module.ModuleName;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MODULE_LIST {
|
||||
ULONG32 NumberOfModules;
|
||||
MINIDUMP_MODULE Modules[NumberOfModules];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_LIST {
|
||||
ULONG32 NumberOfMemoryRanges;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges[NumberOfMemoryRanges];
|
||||
};
|
||||
|
||||
struct MINIDUMP_EXCEPTION {
|
||||
ULONG32 ExceptionCode;
|
||||
ULONG32 ExceptionFlags;
|
||||
ULONG64 ExceptionRecord;
|
||||
ULONG64 ExceptionAddress;
|
||||
ULONG32 NumberParameters;
|
||||
padding[4];
|
||||
ULONG64 ExceptionInformation[15];
|
||||
};
|
||||
|
||||
struct MINIDUMP_EXCEPTION_STREAM {
|
||||
ULONG32 ThreadId;
|
||||
padding[4];
|
||||
MINIDUMP_EXCEPTION ExceptionRecord;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
|
||||
};
|
||||
|
||||
struct CPU_INFORMATION {
|
||||
ULONG32 VendorId[3];
|
||||
ULONG32 VersionInformation;
|
||||
ULONG32 FeatureInformation;
|
||||
ULONG32 AMDExtendedCpuFeatures;
|
||||
};
|
||||
|
||||
struct MINIDUMP_SYSTEM_INFO {
|
||||
USHORT ProcessorArchitecture;
|
||||
USHORT ProcessorLevel;
|
||||
USHORT ProcessorRevision;
|
||||
UCHAR NumberOfProcessors;
|
||||
UCHAR ProductType;
|
||||
ULONG32 MajorVersion;
|
||||
ULONG32 MinorVersion;
|
||||
ULONG32 BuildNumber;
|
||||
ULONG32 PlatformId;
|
||||
RVA CSDVersionRva;
|
||||
USHORT SuiteMask;
|
||||
USHORT Reserved;
|
||||
CPU_INFORMATION Cpu;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_EX {
|
||||
ULONG32 ThreadId;
|
||||
ULONG32 SuspendCount;
|
||||
ULONG32 PriorityClass;
|
||||
ULONG32 Priority;
|
||||
ULONG64 Teb;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR Stack;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR BackingStore;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_EX_LIST {
|
||||
ULONG32 NumberOfThreads;
|
||||
MINIDUMP_THREAD_EX Threads[NumberOfThreads];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_DESCRIPTOR64 {
|
||||
ULONG64 StartOfMemoryRange;
|
||||
type::Size64 DataSize;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY64_LIST {
|
||||
ULONG64 NumberOfMemoryRanges;
|
||||
RVA64 BaseRva;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges[NumberOfMemoryRanges];
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_DESCRIPTOR {
|
||||
ULONG64 Handle;
|
||||
RVA TypeNameRva;
|
||||
RVA ObjectNameRva;
|
||||
ULONG32 Attributes;
|
||||
ULONG32 GrantedAccess;
|
||||
ULONG32 HandleCount;
|
||||
ULONG32 PointerCount;
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_DESCRIPTOR_2 {
|
||||
ULONG64 Handle;
|
||||
RVA TypeNameRva;
|
||||
RVA ObjectNameRva;
|
||||
ULONG32 Attributes;
|
||||
ULONG32 GrantedAccess;
|
||||
ULONG32 HandleCount;
|
||||
ULONG32 PointerCount;
|
||||
RVA ObjectInfoRva;
|
||||
ULONG32 Reserved0;
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_DATA_STREAM {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfDescriptor;
|
||||
ULONG32 NumberOfDescriptors;
|
||||
ULONG32 Reserved;
|
||||
|
||||
if (SizeOfDescriptor == 32)
|
||||
MINIDUMP_HANDLE_DESCRIPTOR HandleDescriptors[NumberOfDescriptors];
|
||||
else if (SizeOfDescriptor == 40)
|
||||
MINIDUMP_HANDLE_DESCRIPTOR_2 HandleDescriptors[NumberOfDescriptors];
|
||||
};
|
||||
|
||||
struct MINIDUMP_FUNCTION_TABLE_DESCRIPTOR {
|
||||
ULONG64 MinimumAddress;
|
||||
ULONG64 MaximumAddress;
|
||||
ULONG64 BaseAddress;
|
||||
ULONG32 EntryCount;
|
||||
type::Size32 SizeOfAlignPad;
|
||||
};
|
||||
|
||||
struct MINIDUMP_FUNCTION_TABLE_STREAM {
|
||||
type::Size32 SizeOfHeader;
|
||||
type::Size32 SizeOfDescriptor;
|
||||
type::Size32 SizeOfNativeDescriptor;
|
||||
type::Size32 SizeOfFunctionEntry;
|
||||
ULONG32 NumberOfDescriptors;
|
||||
ULONG32 SizeOfAlignPad;
|
||||
|
||||
MINIDUMP_FUNCTION_TABLE_DESCRIPTOR FunctionDescriptors[NumberOfDescriptors];
|
||||
};
|
||||
|
||||
struct MINIDUMP_UNLOADED_MODULE {
|
||||
ULONG64 BaseOfImage;
|
||||
type::Size32 SizeOfImage;
|
||||
ULONG32 CheckSum;
|
||||
ULONG32 TimeDateStamp;
|
||||
RVA ModuleNameRva;
|
||||
|
||||
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
|
||||
} [[format("format_unloaded_module")]];
|
||||
|
||||
fn format_unloaded_module(ref MINIDUMP_UNLOADED_MODULE module) {
|
||||
return module.ModuleName;
|
||||
};
|
||||
|
||||
struct MINIDUMP_UNLOADED_MODULE_LIST {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfEntry;
|
||||
ULONG32 NumberOfEntries;
|
||||
|
||||
if (SizeOfHeader > 12)
|
||||
padding[header.SizeOfHeader - 12];
|
||||
|
||||
MINIDUMP_UNLOADED_MODULE Modules[NumberOfEntries];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MISC_INFO {
|
||||
ULONG32 SizeOfInfo;
|
||||
ULONG32 Flags1;
|
||||
ULONG32 ProcessId;
|
||||
ULONG32 ProcessCreateTime;
|
||||
ULONG32 ProcessUserTime;
|
||||
ULONG32 ProcessKernelTime;
|
||||
|
||||
if (SizeOfInfo > 24) {
|
||||
ULONG32 ProcessorMaxMhz;
|
||||
ULONG32 ProcessorCurrentMhz;
|
||||
ULONG32 ProcessorMhzLimit;
|
||||
ULONG32 ProcessorMaxIdleState;
|
||||
ULONG32 ProcessorCurrentIdleState;
|
||||
}
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_INFO {
|
||||
ULONG64 BaseAddress;
|
||||
ULONG64 AllocationBase;
|
||||
ULONG32 AllocationProtect;
|
||||
padding[4];
|
||||
type::Size64 RegionSize;
|
||||
ULONG32 State;
|
||||
ULONG32 Protect;
|
||||
ULONG32 Type;
|
||||
padding[4];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_INFO_LIST {
|
||||
ULONG SizeOfHeader;
|
||||
ULONG SizeOfEntry;
|
||||
ULONG64 NumberOfEntries;
|
||||
|
||||
if (SizeOfHeader > 16)
|
||||
padding[SizeOfHeader - 16];
|
||||
|
||||
MINIDUMP_MEMORY_INFO Info[NumberOfEntries];
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_INFO {
|
||||
ULONG32 ThreadId;
|
||||
ULONG32 DumpFlags;
|
||||
ULONG32 DumpError;
|
||||
ULONG32 ExitStatus;
|
||||
ULONG64 CreateTime;
|
||||
ULONG64 ExitTime;
|
||||
ULONG64 KernelTime;
|
||||
ULONG64 UserTime;
|
||||
ULONG64 StartAddress;
|
||||
ULONG64 Affinity;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_INFO_LIST {
|
||||
ULONG SizeOfHeader;
|
||||
ULONG SizeOfEntry;
|
||||
ULONG NumberOfEntries;
|
||||
|
||||
if (SizeOfHeader > 12)
|
||||
padding[SizeOfHeader - 12];
|
||||
|
||||
MINIDUMP_THREAD_INFO Info[NumberOfEntries];
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_OPERATION_LIST {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfEntry;
|
||||
ULONG32 NumberOfEntries;
|
||||
ULONG32 Reserved;
|
||||
};
|
||||
|
||||
struct MINIDUMP_DIRECTORY {
|
||||
MINIDUMP_STREAM_TYPE StreamType;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR Location;
|
||||
|
||||
if (StreamType == MINIDUMP_STREAM_TYPE::ThreadListStream)
|
||||
MINIDUMP_THREAD_LIST ThreadList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ModuleListStream)
|
||||
MINIDUMP_MODULE_LIST ModuleList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryListStream)
|
||||
MINIDUMP_MEMORY_LIST MemoryList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ExceptionStream)
|
||||
MINIDUMP_EXCEPTION_STREAM ExceptionInfo @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::SystemInfoStream)
|
||||
MINIDUMP_SYSTEM_INFO SystemInfo @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadExListStream)
|
||||
MINIDUMP_THREAD_EX_LIST ThreadExList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::Memory64ListStream)
|
||||
MINIDUMP_MEMORY64_LIST Mem64List @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamA)
|
||||
char Comment[] @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamW)
|
||||
char16 Comment[] @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleDataStream)
|
||||
MINIDUMP_HANDLE_DATA_STREAM HandleData @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::FunctionTableStream)
|
||||
MINIDUMP_FUNCTION_TABLE_STREAM FunctionTable @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::UnloadedModuleListStream)
|
||||
MINIDUMP_UNLOADED_MODULE_LIST UnloadModuleList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::MiscInfoStream)
|
||||
MINIDUMP_MISC_INFO MiscInfo @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryInfoListStream)
|
||||
MINIDUMP_MEMORY_INFO_LIST MemInfoList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadInfoListStream)
|
||||
MINIDUMP_THREAD_INFO_LIST ThreadInfoList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleOperationListStream)
|
||||
MINIDUMP_HANDLE_OPERATION_LIST HandleOperList @ Location.Rva;
|
||||
};
|
||||
|
||||
bitfield MINIDUMP_TYPE {
|
||||
MiniDumpWithDataSegs : 1;
|
||||
MiniDumpWithFullMemory : 1;
|
||||
MiniDumpWithHandleData : 1;
|
||||
MiniDumpFilterMemory : 1;
|
||||
MiniDumpScanMemory : 1;
|
||||
MiniDumpWithUnloadedModules : 1;
|
||||
MiniDumpWithIndirectlyReferencedMemory : 1;
|
||||
MiniDumpFilterModulePaths : 1;
|
||||
MiniDumpWithProcessThreadData : 1;
|
||||
MiniDumpWithPrivateReadWriteMemory : 1;
|
||||
MiniDumpWithoutOptionalData : 1;
|
||||
MiniDumpWithFullMemoryInfo : 1;
|
||||
MiniDumpWithThreadInfo : 1;
|
||||
MiniDumpWithCodeSegs : 1;
|
||||
MiniDumpWithoutAuxiliaryState : 1;
|
||||
MiniDumpWithFullAuxiliaryState : 1;
|
||||
MiniDumpWithPrivateWriteCopyMemory : 1;
|
||||
MiniDumpIgnoreInaccessibleMemory : 1;
|
||||
MiniDumpWithTokenInformation : 1;
|
||||
MiniDumpWithModuleHeaders : 1;
|
||||
MiniDumpFilterTriage : 1;
|
||||
MiniDumpWithAvxXStateContext : 1;
|
||||
MiniDumpWithIptTrace : 1;
|
||||
MiniDumpScanInaccessiblePartialPages : 1;
|
||||
padding : 40;
|
||||
};
|
||||
|
||||
struct MINIDUMP_HEADER {
|
||||
char Signature[4];
|
||||
ULONG32 Version;
|
||||
ULONG32 NumberOfStreams;
|
||||
RVA StreamDirectoryRva;
|
||||
ULONG32 Checksum;
|
||||
type::time32_t TimeDateStamp;
|
||||
MINIDUMP_TYPE Flags;
|
||||
};
|
||||
|
||||
struct MINIDUMP {
|
||||
MINIDUMP_HEADER Header;
|
||||
MINIDUMP_DIRECTORY Streams[Header.NumberOfStreams] [[format_entries("format_stream")]];
|
||||
};
|
||||
|
||||
fn format_stream(ref MINIDUMP_DIRECTORY stream) {
|
||||
return stream.StreamType;
|
||||
};
|
||||
|
||||
MINIDUMP MiniDump @ 0x00;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
#pragma bitfield_order right_to_left
|
||||
|
||||
struct DOSHeader {
|
||||
char signature[2];
|
||||
u16 lastPageSize;
|
||||
@@ -186,7 +184,7 @@ bitfield SegmentTableFlags {
|
||||
containsRelocationInfo : 1;
|
||||
padding : 1;
|
||||
discardPriority : 4;
|
||||
} [[right_to_left]];
|
||||
};
|
||||
|
||||
struct SegmentTable {
|
||||
u16 segmentDataPointer;
|
||||
|
||||
@@ -1,161 +1,165 @@
|
||||
bitfield AccessCapability {
|
||||
Read : 4;
|
||||
Write : 4;
|
||||
} [[left_to_right]];
|
||||
|
||||
struct CapabilityContainer {
|
||||
u8 magic;
|
||||
u8 version;
|
||||
u8 memorySize;
|
||||
AccessCapability accessCapability;
|
||||
};
|
||||
|
||||
bitfield NDEFFlags {
|
||||
MB : 1;
|
||||
ME : 1;
|
||||
CF : 1;
|
||||
SR : 1;
|
||||
IL : 1;
|
||||
TNF : 3;
|
||||
} [[left_to_right]];
|
||||
|
||||
enum TNFType : u8 {
|
||||
Empty = 0x00,
|
||||
NFCForumWellKnownType = 0x01,
|
||||
MediaType = 0x02,
|
||||
AbsoluteURI = 0x03,
|
||||
NFCForumExternalType = 0x04,
|
||||
Unknown = 0x05,
|
||||
Unchanged = 0x06,
|
||||
Reserved = 0x07
|
||||
};
|
||||
|
||||
struct NDEF {
|
||||
NDEFFlags flags;
|
||||
u8 typeLength;
|
||||
|
||||
if (flags.SR)
|
||||
u8 payloadLength;
|
||||
else
|
||||
u32 payloadLength;
|
||||
|
||||
if (flags.IL)
|
||||
u8 idLength;
|
||||
|
||||
char type[typeLength];
|
||||
|
||||
if (flags.IL)
|
||||
u8 id[idLength];
|
||||
|
||||
u8 payload[payloadLength];
|
||||
|
||||
if (flags.ME)
|
||||
break;
|
||||
};
|
||||
|
||||
struct LockControl {
|
||||
u8 dynamicLockByteOffset;
|
||||
u8 numBits;
|
||||
u8 pageControlInfo;
|
||||
};
|
||||
|
||||
struct MemoryControl {
|
||||
u8 reservedBytesOffset;
|
||||
u8 numBytes;
|
||||
u8 pageSize;
|
||||
};
|
||||
|
||||
struct Length {
|
||||
u8 byte [[hidden, no_unique_address]];
|
||||
if (byte == 0xFF)
|
||||
u24 length;
|
||||
else
|
||||
u8 length;
|
||||
} [[sealed, transform("transform_length"), format("transform_length")]];
|
||||
|
||||
fn transform_length(Length length) {
|
||||
return length.length;
|
||||
};
|
||||
|
||||
enum Tag : u8 {
|
||||
NULL = 0x00,
|
||||
LockControl = 0x01,
|
||||
MemoryControl = 0x02,
|
||||
NDEFMessage = 0x03,
|
||||
Proprietary = 0xFD,
|
||||
TerminatorTLV = 0xFE
|
||||
};
|
||||
|
||||
struct TLV {
|
||||
Tag tag;
|
||||
if (tag == Tag::TerminatorTLV) {
|
||||
break;
|
||||
} else if (tag == Tag::NULL) {
|
||||
// Empty
|
||||
} else {
|
||||
Length length;
|
||||
|
||||
if (length > 0) {
|
||||
if (tag == Tag::LockControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::MemoryControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::NDEFMessage) {
|
||||
NDEF ndef[while(true)];
|
||||
} else {
|
||||
u8 value[length];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ManufacturerData {
|
||||
u8 serial1[3];
|
||||
u8 checkByte0;
|
||||
u8 serial2[4];
|
||||
u8 checkByte1;
|
||||
u8 internal;
|
||||
u16 lockBytes;
|
||||
};
|
||||
|
||||
struct DynamicLockBytes {
|
||||
u8 bytes[3];
|
||||
padding[1];
|
||||
};
|
||||
|
||||
bitfield MIRROR {
|
||||
MIRROR_CONF : 2;
|
||||
MIRROR_BYTE : 2;
|
||||
padding : 1;
|
||||
STRG_MOD_EN : 1;
|
||||
padding : 2;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield ACCESS {
|
||||
PROT : 1;
|
||||
CFGLCK : 1;
|
||||
padding : 1;
|
||||
NFC_CNT_EN : 1;
|
||||
NFC_CNT_PWD_PROT : 1;
|
||||
AUTHLIM : 3;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
MIRROR MIRROR;
|
||||
u8 MIRROR_PAGE;
|
||||
u8 AUTH0;
|
||||
ACCESS ACCESS;
|
||||
u32 PWD;
|
||||
u16 PACK;
|
||||
};
|
||||
|
||||
struct NTAG {
|
||||
ManufacturerData manufacturerData;
|
||||
CapabilityContainer cc;
|
||||
TLV tlv[while(true)];
|
||||
padding[addressof(tlv) + cc.memorySize * 8 - sizeof(tlv)];
|
||||
DynamicLockBytes dynamicLockBytes;
|
||||
Config config;
|
||||
};
|
||||
|
||||
NTAG ntag @ 0x00;
|
||||
#include <std/core.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
bitfield AccessCapability {
|
||||
Read : 4;
|
||||
Write : 4;
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
struct CapabilityContainer {
|
||||
u8 magic;
|
||||
u8 version;
|
||||
u8 memorySize;
|
||||
be AccessCapability accessCapability;
|
||||
};
|
||||
|
||||
bitfield NDEFFlags {
|
||||
MB : 1;
|
||||
ME : 1;
|
||||
CF : 1;
|
||||
SR : 1;
|
||||
IL : 1;
|
||||
TNF : 3;
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
enum TNFType : u8 {
|
||||
Empty = 0x00,
|
||||
NFCForumWellKnownType = 0x01,
|
||||
MediaType = 0x02,
|
||||
AbsoluteURI = 0x03,
|
||||
NFCForumExternalType = 0x04,
|
||||
Unknown = 0x05,
|
||||
Unchanged = 0x06,
|
||||
Reserved = 0x07
|
||||
};
|
||||
|
||||
struct NDEF {
|
||||
NDEFFlags flags;
|
||||
u8 typeLength;
|
||||
|
||||
if (flags.SR)
|
||||
u8 payloadLength;
|
||||
else
|
||||
u32 payloadLength;
|
||||
|
||||
if (flags.IL)
|
||||
u8 idLength;
|
||||
|
||||
char type[typeLength];
|
||||
|
||||
if (flags.IL)
|
||||
u8 id[idLength];
|
||||
|
||||
u8 payload[payloadLength];
|
||||
|
||||
if (flags.ME)
|
||||
break;
|
||||
};
|
||||
|
||||
struct LockControl {
|
||||
u8 dynamicLockByteOffset;
|
||||
u8 numBits;
|
||||
u8 pageControlInfo;
|
||||
};
|
||||
|
||||
struct MemoryControl {
|
||||
u8 reservedBytesOffset;
|
||||
u8 numBytes;
|
||||
u8 pageSize;
|
||||
};
|
||||
|
||||
struct Length {
|
||||
u8 byte [[hidden, no_unique_address]];
|
||||
if (byte == 0xFF)
|
||||
u24 length;
|
||||
else
|
||||
u8 length;
|
||||
} [[sealed, transform("transform_length"), format("transform_length")]];
|
||||
|
||||
fn transform_length(Length length) {
|
||||
return length.length;
|
||||
};
|
||||
|
||||
enum Tag : u8 {
|
||||
NULL = 0x00,
|
||||
LockControl = 0x01,
|
||||
MemoryControl = 0x02,
|
||||
NDEFMessage = 0x03,
|
||||
Proprietary = 0xFD,
|
||||
TerminatorTLV = 0xFE
|
||||
};
|
||||
|
||||
struct TLV {
|
||||
Tag tag;
|
||||
if (tag == Tag::TerminatorTLV) {
|
||||
break;
|
||||
} else if (tag == Tag::NULL) {
|
||||
// Empty
|
||||
} else {
|
||||
Length length;
|
||||
|
||||
if (length > 0) {
|
||||
if (tag == Tag::LockControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::MemoryControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::NDEFMessage) {
|
||||
NDEF ndef[while(true)];
|
||||
} else {
|
||||
u8 value[length];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ManufacturerData {
|
||||
u8 serial1[3];
|
||||
u8 checkByte0;
|
||||
u8 serial2[4];
|
||||
u8 checkByte1;
|
||||
u8 internal;
|
||||
u16 lockBytes;
|
||||
};
|
||||
|
||||
struct DynamicLockBytes {
|
||||
u8 bytes[3];
|
||||
padding[1];
|
||||
};
|
||||
|
||||
bitfield MIRROR {
|
||||
MIRROR_CONF : 2;
|
||||
MIRROR_BYTE : 2;
|
||||
padding : 1;
|
||||
STRG_MOD_EN : 1;
|
||||
padding : 2;
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
bitfield ACCESS {
|
||||
PROT : 1;
|
||||
CFGLCK : 1;
|
||||
padding : 1;
|
||||
NFC_CNT_EN : 1;
|
||||
NFC_CNT_PWD_PROT : 1;
|
||||
AUTHLIM : 3;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
MIRROR MIRROR;
|
||||
u8 MIRROR_PAGE;
|
||||
u8 AUTH0;
|
||||
ACCESS ACCESS;
|
||||
u32 PWD;
|
||||
u16 PACK;
|
||||
};
|
||||
|
||||
struct NTAG {
|
||||
ManufacturerData manufacturerData;
|
||||
CapabilityContainer cc;
|
||||
TLV tlv[while(true)];
|
||||
padding[addressof(tlv) + cc.memorySize * 8 - sizeof(tlv)];
|
||||
DynamicLockBytes dynamicLockBytes;
|
||||
Config config;
|
||||
};
|
||||
|
||||
NTAG ntag @ 0x00;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma MIME application/x-dosexec
|
||||
#pragma MIME application/x-msdownload
|
||||
#pragma bitfield_order right_to_left
|
||||
#pragma pattern_limit 0x400000
|
||||
|
||||
#include <std/string.pat>
|
||||
@@ -378,7 +377,7 @@ fn architecture() {
|
||||
bitfield OrdinalFlagByte {
|
||||
flag : 1;
|
||||
padding : 7;
|
||||
} [[left_to_right]];
|
||||
};
|
||||
|
||||
struct NameTableEntry {
|
||||
u16 hint;
|
||||
@@ -1278,4 +1277,4 @@ struct StringTable {
|
||||
StringTableString strings[while($ < addressof(this) + size)];
|
||||
} [[inline]];
|
||||
|
||||
StringTable stringTable[checkForDebugInformation] @ addressof(symbolTable) + sizeof(symbolTable);
|
||||
StringTable stringTable[checkForDebugInformation] @ addressof(symbolTable) + sizeof(symbolTable);
|
||||
@@ -1,66 +1,67 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
#include <type/leb128.pat>
|
||||
|
||||
struct ZigZag32 {
|
||||
u32 value;
|
||||
} [[sealed, format("format_zigzag32")]];
|
||||
|
||||
fn format_zigzag32(ZigZag32 zigzag) {
|
||||
return s32((s32(zigzag.value) << 1) ^ (s32(zigzag.value) >> 31));
|
||||
};
|
||||
|
||||
struct ZigZag64 {
|
||||
u64 value;
|
||||
} [[sealed, format("format_zigzag64")]];
|
||||
|
||||
fn format_zigzag64(ZigZag64 zigzag) {
|
||||
return s64((s64(zigzag.value) << 1) ^ (s64(zigzag.value) >> 63));
|
||||
};
|
||||
|
||||
enum WireType : u8 {
|
||||
Varint = 0,
|
||||
_64Bit = 1,
|
||||
LengthDelimited = 2,
|
||||
StartGroup = 3,
|
||||
EndGroup = 4,
|
||||
_32Bit = 5
|
||||
};
|
||||
|
||||
bitfield Key {
|
||||
field_number : 5;
|
||||
wire_type : 3;
|
||||
} [[left_to_right]];
|
||||
|
||||
union _64Bit {
|
||||
u64 fixed64;
|
||||
ZigZag64 sfixed64;
|
||||
double dbl;
|
||||
};
|
||||
|
||||
union _32Bit {
|
||||
u32 fixed32;
|
||||
ZigZag32 sfixed32;
|
||||
float flt;
|
||||
};
|
||||
|
||||
struct LengthDelimited {
|
||||
type::LEB128 length;
|
||||
char data[length];
|
||||
};
|
||||
|
||||
|
||||
struct Entry {
|
||||
Key key;
|
||||
|
||||
if (key.wire_type == WireType::Varint)
|
||||
type::LEB128 value;
|
||||
else if (key.wire_type == WireType::_64Bit)
|
||||
_64Bit value;
|
||||
else if (key.wire_type == WireType::LengthDelimited)
|
||||
LengthDelimited value;
|
||||
else if (key.wire_type == WireType::_32Bit)
|
||||
_32Bit value;
|
||||
};
|
||||
|
||||
Entry entries[while(!std::mem::eof())] @ 0x00;
|
||||
#include <std/core.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
#include <type/leb128.pat>
|
||||
|
||||
struct ZigZag32 {
|
||||
u32 value;
|
||||
} [[sealed, format("format_zigzag32")]];
|
||||
|
||||
fn format_zigzag32(ZigZag32 zigzag) {
|
||||
return s32((s32(zigzag.value) << 1) ^ (s32(zigzag.value) >> 31));
|
||||
};
|
||||
|
||||
struct ZigZag64 {
|
||||
u64 value;
|
||||
} [[sealed, format("format_zigzag64")]];
|
||||
|
||||
fn format_zigzag64(ZigZag64 zigzag) {
|
||||
return s64((s64(zigzag.value) << 1) ^ (s64(zigzag.value) >> 63));
|
||||
};
|
||||
|
||||
enum WireType : u8 {
|
||||
Varint = 0,
|
||||
_64Bit = 1,
|
||||
LengthDelimited = 2,
|
||||
StartGroup = 3,
|
||||
EndGroup = 4,
|
||||
_32Bit = 5
|
||||
};
|
||||
|
||||
bitfield Key {
|
||||
field_number : 5;
|
||||
wire_type : 3;
|
||||
} [[bitfield_order(std::core::BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
union _64Bit {
|
||||
u64 fixed64;
|
||||
ZigZag64 sfixed64;
|
||||
double dbl;
|
||||
};
|
||||
|
||||
union _32Bit {
|
||||
u32 fixed32;
|
||||
ZigZag32 sfixed32;
|
||||
float flt;
|
||||
};
|
||||
|
||||
struct LengthDelimited {
|
||||
type::LEB128 length;
|
||||
char data[length];
|
||||
};
|
||||
|
||||
|
||||
struct Entry {
|
||||
Key key;
|
||||
|
||||
if (key.wire_type == WireType::Varint)
|
||||
type::LEB128 value;
|
||||
else if (key.wire_type == WireType::_64Bit)
|
||||
_64Bit value;
|
||||
else if (key.wire_type == WireType::LengthDelimited)
|
||||
LengthDelimited value;
|
||||
else if (key.wire_type == WireType::_32Bit)
|
||||
_32Bit value;
|
||||
};
|
||||
|
||||
Entry entries[while(!std::mem::eof())] @ 0x00;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma MIME image/qoi
|
||||
#pragma endian big
|
||||
#pragma bitfield_order left_to_right
|
||||
|
||||
#include <std/mem.pat>
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@ namespace v5 {
|
||||
folder : 1;
|
||||
encrypted : 1;
|
||||
padding : 5;
|
||||
} [[left_to_right]];
|
||||
};
|
||||
|
||||
bitfield Flags2 {
|
||||
padding : 7;
|
||||
resource_fork : 1;
|
||||
padding : 8;
|
||||
} [[left_to_right]];
|
||||
};
|
||||
|
||||
using MacOSHFSPlusDate = u32 [[format("v5::format_macos_date")]];
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
enum GeneratorID : u16 {
|
||||
Khronos = 0,
|
||||
LunarG = 1,
|
||||
@@ -642,4 +644,4 @@ struct Instruction {
|
||||
Header header @ 0x00;
|
||||
|
||||
// SPIR-V does not have any footer, increase number of instructions manually if you encounter a bigger shader
|
||||
Instruction instructions[1024] @ 0x14;
|
||||
Instruction instructions[while (!std::mem::eof())] @ 0x14;
|
||||
@@ -1,269 +1,272 @@
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/string.pat>
|
||||
|
||||
enum DescriptorType : u8 {
|
||||
DeviceDescriptor = 0x01,
|
||||
ConfigDescriptor = 0x02,
|
||||
StringDescriptor = 0x03,
|
||||
InterfaceDescriptor = 0x04,
|
||||
EndpointDescriptor = 0x05,
|
||||
DeviceQualifierDescriptor = 0x06,
|
||||
OtherSpeedConfigurationDescriptor = 0x07,
|
||||
InterfacePowerDescriptor = 0x08,
|
||||
OTGDescriptor = 0x09,
|
||||
DebugDescriptor = 0x0A,
|
||||
InterfaceAssociationDescriptor = 0x0B,
|
||||
|
||||
HIDDescriptor = 0x21,
|
||||
ReportDescriptor = 0x22,
|
||||
PhysicalDescriptor = 0x23
|
||||
};
|
||||
|
||||
enum InterfaceClass : u8 {
|
||||
UseClassInformationInInterfaceDescriptors = 0x00,
|
||||
Audio = 0x01,
|
||||
CommunicationAndCDCControl = 0x02,
|
||||
HID = 0x03,
|
||||
Physical = 0x05,
|
||||
Image = 0x06,
|
||||
Printer = 0x07,
|
||||
MassStorage = 0x08,
|
||||
Hub = 0x09,
|
||||
CDCData = 0x0A,
|
||||
SmartCard = 0x0B,
|
||||
ContentSecurity = 0x0C,
|
||||
Video = 0x0E,
|
||||
PersonalHealthcare = 0x0F,
|
||||
AudioVideoDevice = 0x10,
|
||||
BillboardDevice = 0x11,
|
||||
USBTypeCBridge = 0x12,
|
||||
I3CDevice = 0x3C,
|
||||
DiagnosticDevice = 0xDC,
|
||||
WirelessController = 0xE0,
|
||||
Miscellaneous = 0xEF,
|
||||
ApplicationSpecific = 0xFE,
|
||||
VendorSpecific = 0xFF
|
||||
};
|
||||
|
||||
enum CountryCode : u8 {
|
||||
NotSupported = 0,
|
||||
Arabic = 1,
|
||||
Belgian = 2,
|
||||
CanadianBilingual = 3,
|
||||
CanadianFrench = 4,
|
||||
CzechRepublic = 5,
|
||||
Danish = 6,
|
||||
Finnish = 7,
|
||||
French = 8,
|
||||
German = 9,
|
||||
Greek = 10,
|
||||
Hebrew = 11,
|
||||
Hungary = 12,
|
||||
International = 13,
|
||||
Italian = 14,
|
||||
JapanKatakana = 15,
|
||||
Korean = 16,
|
||||
LatinAmerican = 17,
|
||||
Dutch = 18,
|
||||
Norwegian = 19,
|
||||
PersianFarsi = 20,
|
||||
Polish = 21,
|
||||
Portuguese = 22,
|
||||
Russian = 23,
|
||||
Slovakian = 24,
|
||||
Spanish = 25,
|
||||
Swedish = 26,
|
||||
SwissFrench = 27,
|
||||
SwissGerman = 28,
|
||||
Switzerland = 29,
|
||||
Taiwan = 30,
|
||||
TurkishQ = 31,
|
||||
EnglishUK = 32,
|
||||
EnglishUS = 33,
|
||||
Yugoslavian = 34,
|
||||
TurkishF = 35,
|
||||
Reserved = 36 ... 255
|
||||
};
|
||||
|
||||
enum HubInterfaceSubClass : u8 {
|
||||
Hub = 0x00
|
||||
};
|
||||
|
||||
enum AudioVideoDeviceSubClass : u8 {
|
||||
AVControlInterface = 0x01,
|
||||
AVDataVideoStreamingInterface = 0x02,
|
||||
AVDataAudioStreamingInterface = 0x03
|
||||
};
|
||||
|
||||
enum HubInterfaceProtocol : u8 {
|
||||
FullSpeedHub = 0x00,
|
||||
HiSpeedHubWithSingleTT = 0x01,
|
||||
HiSpeedHubWithMultipleTTs = 0x02
|
||||
};
|
||||
|
||||
struct Ampere {
|
||||
u8 amps;
|
||||
} [[sealed, format("format_ampere")]];
|
||||
|
||||
fn format_ampere(Ampere ampere) {
|
||||
return std::format("{} mA", ampere.amps * 2);
|
||||
};
|
||||
|
||||
bitfield ConfigAttributes {
|
||||
padding : 1;
|
||||
SelfPowered : 1;
|
||||
RemoteWakeup : 1;
|
||||
padding : 5;
|
||||
} [[left_to_right]];
|
||||
|
||||
struct BCD<auto Size> {
|
||||
u8 bytes[Size];
|
||||
} [[sealed, format("format_bcd")]];
|
||||
|
||||
fn format_bcd(ref auto bcd) {
|
||||
str result;
|
||||
for (s8 i = sizeof(bcd.bytes) - 1, i >= 0, i -= 1)
|
||||
result += std::format("{:X}.", bcd.bytes[i]);
|
||||
|
||||
return std::string::substr(result, 0, std::string::length(result) - 1);
|
||||
};
|
||||
|
||||
struct DeviceDescriptor {
|
||||
BCD<2> bcdUSB;
|
||||
InterfaceClass bDeviceClass;
|
||||
if (bDeviceClass == InterfaceClass::Hub) {
|
||||
HubInterfaceSubClass bDeviceSubClass;
|
||||
if (bDeviceSubClass == HubInterfaceSubClass::Hub)
|
||||
HubInterfaceProtocol bDeviceSubClass;
|
||||
else
|
||||
u8 bDeviceSubClass;
|
||||
} else if (bDeviceClass == InterfaceClass::AudioVideoDevice) {
|
||||
AudioVideoDeviceSubClass bDeviceSubClass;
|
||||
u8 bDeviceSubClass;
|
||||
} else {
|
||||
u8 bDeviceSubClass;
|
||||
}
|
||||
};
|
||||
|
||||
struct ConfigDescriptor {
|
||||
u16 wTotalLength;
|
||||
u8 bNumInterfaces;
|
||||
u8 bConfigurationValue;
|
||||
u8 iConfiguration;
|
||||
ConfigAttributes bmAttributes;
|
||||
Ampere bMaxPower;
|
||||
};
|
||||
|
||||
struct StringDescriptor {
|
||||
char bString[parent.bLength - 2];
|
||||
};
|
||||
|
||||
struct InterfaceDescriptor {
|
||||
u8 bInterfaceNumber;
|
||||
u8 bAlternateSetting;
|
||||
u8 bNumEndpoints;
|
||||
|
||||
InterfaceClass bInterfaceClass;
|
||||
if (bInterfaceClass == InterfaceClass::Hub) {
|
||||
HubInterfaceSubClass bInterfaceSubClass;
|
||||
if (bInterfaceSubClass == HubInterfaceSubClass::Hub)
|
||||
HubInterfaceProtocol bInterfaceProtocol;
|
||||
else
|
||||
u8 bInterfaceProtocol;
|
||||
} else if (bInterfaceClass == InterfaceClass::AudioVideoDevice) {
|
||||
AudioVideoDeviceSubClass bInterfaceSubClass;
|
||||
u8 bInterfaceProtocol;
|
||||
} else {
|
||||
u8 bInterfaceSubClass;
|
||||
u8 bInterfaceProtocol;
|
||||
}
|
||||
|
||||
u8 iInterface;
|
||||
};
|
||||
|
||||
enum EndpointDirection : u8 {
|
||||
OUT = 0,
|
||||
IN = 1
|
||||
};
|
||||
|
||||
fn format_direction(u8 value) {
|
||||
EndpointDirection direction;
|
||||
direction = value;
|
||||
return direction;
|
||||
};
|
||||
|
||||
bitfield EndpointAddress {
|
||||
Direction : 1 [[format("format_direction")]];
|
||||
padding : 3;
|
||||
EndpointNumber : 4;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield EndpointAttributes {
|
||||
TransferType : 2;
|
||||
SynchronizationType : 2;
|
||||
UsageType : 2;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct EndpointDescriptor {
|
||||
EndpointAddress bEndPointAddress;
|
||||
EndpointAttributes bmAttributes;
|
||||
u16 wMaxPacketSize;
|
||||
u8 bInterval;
|
||||
};
|
||||
|
||||
struct OtherSpeedConfigurationDescriptor {
|
||||
ConfigDescriptor content [[inline]];
|
||||
};
|
||||
|
||||
struct DeviceQualifierDescriptor {
|
||||
DeviceDescriptor deviceDescriptor [[inline]];
|
||||
u8 bMaxPacketSize0;
|
||||
u8 bNumConfigurations;
|
||||
padding[1];
|
||||
};
|
||||
|
||||
bitfield OTGAttributes {
|
||||
SRPSupport : 1;
|
||||
HNPSupport : 1;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct OTGDescriptor {
|
||||
OTGAttributes bmAttributes;
|
||||
};
|
||||
|
||||
struct HIDDescriptor {
|
||||
BCD<2> bcdVersion;
|
||||
CountryCode bCountryCode;
|
||||
u8 bNumDescriptors;
|
||||
DescriptorType bDescriptorType;
|
||||
u16 wDescriptorLength;
|
||||
};
|
||||
|
||||
struct USBDescriptor {
|
||||
u8 bLength;
|
||||
DescriptorType bDescriptorType;
|
||||
|
||||
if (bDescriptorType == DescriptorType::DeviceDescriptor)
|
||||
DeviceDescriptor deviceDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::ConfigDescriptor)
|
||||
ConfigDescriptor configDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::StringDescriptor)
|
||||
StringDescriptor stringDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::InterfaceDescriptor)
|
||||
InterfaceDescriptor interfaceDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::EndpointDescriptor)
|
||||
EndpointDescriptor endpointDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::OtherSpeedConfigurationDescriptor)
|
||||
OtherSpeedConfigurationDescriptor otherSpeedConfigurationDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::DeviceQualifierDescriptor)
|
||||
DeviceQualifierDescriptor deviceQualifierDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::OTGDescriptor)
|
||||
OTGDescriptor otgDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::HIDDescriptor)
|
||||
HIDDescriptor hidDescriptor [[inline]];
|
||||
|
||||
padding[bLength - ($ - addressof(this))];
|
||||
};
|
||||
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/string.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
enum DescriptorType : u8 {
|
||||
DeviceDescriptor = 0x01,
|
||||
ConfigDescriptor = 0x02,
|
||||
StringDescriptor = 0x03,
|
||||
InterfaceDescriptor = 0x04,
|
||||
EndpointDescriptor = 0x05,
|
||||
DeviceQualifierDescriptor = 0x06,
|
||||
OtherSpeedConfigurationDescriptor = 0x07,
|
||||
InterfacePowerDescriptor = 0x08,
|
||||
OTGDescriptor = 0x09,
|
||||
DebugDescriptor = 0x0A,
|
||||
InterfaceAssociationDescriptor = 0x0B,
|
||||
|
||||
HIDDescriptor = 0x21,
|
||||
ReportDescriptor = 0x22,
|
||||
PhysicalDescriptor = 0x23
|
||||
};
|
||||
|
||||
enum InterfaceClass : u8 {
|
||||
UseClassInformationInInterfaceDescriptors = 0x00,
|
||||
Audio = 0x01,
|
||||
CommunicationAndCDCControl = 0x02,
|
||||
HID = 0x03,
|
||||
Physical = 0x05,
|
||||
Image = 0x06,
|
||||
Printer = 0x07,
|
||||
MassStorage = 0x08,
|
||||
Hub = 0x09,
|
||||
CDCData = 0x0A,
|
||||
SmartCard = 0x0B,
|
||||
ContentSecurity = 0x0C,
|
||||
Video = 0x0E,
|
||||
PersonalHealthcare = 0x0F,
|
||||
AudioVideoDevice = 0x10,
|
||||
BillboardDevice = 0x11,
|
||||
USBTypeCBridge = 0x12,
|
||||
I3CDevice = 0x3C,
|
||||
DiagnosticDevice = 0xDC,
|
||||
WirelessController = 0xE0,
|
||||
Miscellaneous = 0xEF,
|
||||
ApplicationSpecific = 0xFE,
|
||||
VendorSpecific = 0xFF
|
||||
};
|
||||
|
||||
enum CountryCode : u8 {
|
||||
NotSupported = 0,
|
||||
Arabic = 1,
|
||||
Belgian = 2,
|
||||
CanadianBilingual = 3,
|
||||
CanadianFrench = 4,
|
||||
CzechRepublic = 5,
|
||||
Danish = 6,
|
||||
Finnish = 7,
|
||||
French = 8,
|
||||
German = 9,
|
||||
Greek = 10,
|
||||
Hebrew = 11,
|
||||
Hungary = 12,
|
||||
International = 13,
|
||||
Italian = 14,
|
||||
JapanKatakana = 15,
|
||||
Korean = 16,
|
||||
LatinAmerican = 17,
|
||||
Dutch = 18,
|
||||
Norwegian = 19,
|
||||
PersianFarsi = 20,
|
||||
Polish = 21,
|
||||
Portuguese = 22,
|
||||
Russian = 23,
|
||||
Slovakian = 24,
|
||||
Spanish = 25,
|
||||
Swedish = 26,
|
||||
SwissFrench = 27,
|
||||
SwissGerman = 28,
|
||||
Switzerland = 29,
|
||||
Taiwan = 30,
|
||||
TurkishQ = 31,
|
||||
EnglishUK = 32,
|
||||
EnglishUS = 33,
|
||||
Yugoslavian = 34,
|
||||
TurkishF = 35,
|
||||
Reserved = 36 ... 255
|
||||
};
|
||||
|
||||
enum HubInterfaceSubClass : u8 {
|
||||
Hub = 0x00
|
||||
};
|
||||
|
||||
enum AudioVideoDeviceSubClass : u8 {
|
||||
AVControlInterface = 0x01,
|
||||
AVDataVideoStreamingInterface = 0x02,
|
||||
AVDataAudioStreamingInterface = 0x03
|
||||
};
|
||||
|
||||
enum HubInterfaceProtocol : u8 {
|
||||
FullSpeedHub = 0x00,
|
||||
HiSpeedHubWithSingleTT = 0x01,
|
||||
HiSpeedHubWithMultipleTTs = 0x02
|
||||
};
|
||||
|
||||
struct Ampere {
|
||||
u8 amps;
|
||||
} [[sealed, format("format_ampere")]];
|
||||
|
||||
fn format_ampere(Ampere ampere) {
|
||||
return std::format("{} mA", ampere.amps * 2);
|
||||
};
|
||||
|
||||
bitfield ConfigAttributes {
|
||||
padding : 1;
|
||||
SelfPowered : 1;
|
||||
RemoteWakeup : 1;
|
||||
padding : 5;
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
struct BCD<auto Size> {
|
||||
u8 bytes[Size];
|
||||
} [[sealed, format("format_bcd")]];
|
||||
|
||||
fn format_bcd(ref auto bcd) {
|
||||
str result;
|
||||
for (s8 i = sizeof(bcd.bytes) - 1, i >= 0, i -= 1)
|
||||
result += std::format("{:X}.", bcd.bytes[i]);
|
||||
|
||||
return std::string::substr(result, 0, std::string::length(result) - 1);
|
||||
};
|
||||
|
||||
struct DeviceDescriptor {
|
||||
BCD<2> bcdUSB;
|
||||
InterfaceClass bDeviceClass;
|
||||
if (bDeviceClass == InterfaceClass::Hub) {
|
||||
HubInterfaceSubClass bDeviceSubClass;
|
||||
if (bDeviceSubClass == HubInterfaceSubClass::Hub)
|
||||
HubInterfaceProtocol bDeviceSubClass;
|
||||
else
|
||||
u8 bDeviceSubClass;
|
||||
} else if (bDeviceClass == InterfaceClass::AudioVideoDevice) {
|
||||
AudioVideoDeviceSubClass bDeviceSubClass;
|
||||
u8 bDeviceSubClass;
|
||||
} else {
|
||||
u8 bDeviceSubClass;
|
||||
}
|
||||
};
|
||||
|
||||
struct ConfigDescriptor {
|
||||
u16 wTotalLength;
|
||||
u8 bNumInterfaces;
|
||||
u8 bConfigurationValue;
|
||||
u8 iConfiguration;
|
||||
ConfigAttributes bmAttributes;
|
||||
Ampere bMaxPower;
|
||||
};
|
||||
|
||||
struct StringDescriptor {
|
||||
char bString[parent.bLength - 2];
|
||||
};
|
||||
|
||||
struct InterfaceDescriptor {
|
||||
u8 bInterfaceNumber;
|
||||
u8 bAlternateSetting;
|
||||
u8 bNumEndpoints;
|
||||
|
||||
InterfaceClass bInterfaceClass;
|
||||
if (bInterfaceClass == InterfaceClass::Hub) {
|
||||
HubInterfaceSubClass bInterfaceSubClass;
|
||||
if (bInterfaceSubClass == HubInterfaceSubClass::Hub)
|
||||
HubInterfaceProtocol bInterfaceProtocol;
|
||||
else
|
||||
u8 bInterfaceProtocol;
|
||||
} else if (bInterfaceClass == InterfaceClass::AudioVideoDevice) {
|
||||
AudioVideoDeviceSubClass bInterfaceSubClass;
|
||||
u8 bInterfaceProtocol;
|
||||
} else {
|
||||
u8 bInterfaceSubClass;
|
||||
u8 bInterfaceProtocol;
|
||||
}
|
||||
|
||||
u8 iInterface;
|
||||
};
|
||||
|
||||
enum EndpointDirection : u8 {
|
||||
OUT = 0,
|
||||
IN = 1
|
||||
};
|
||||
|
||||
fn format_direction(u8 value) {
|
||||
EndpointDirection direction;
|
||||
direction = value;
|
||||
return direction;
|
||||
};
|
||||
|
||||
bitfield EndpointAddress {
|
||||
EndpointNumber : 4;
|
||||
padding : 3;
|
||||
Direction : 1 [[format("format_direction")]];
|
||||
};
|
||||
|
||||
bitfield EndpointAttributes {
|
||||
TransferType : 2;
|
||||
SynchronizationType : 2;
|
||||
UsageType : 2;
|
||||
};
|
||||
|
||||
struct EndpointDescriptor {
|
||||
EndpointAddress bEndPointAddress;
|
||||
EndpointAttributes bmAttributes;
|
||||
u16 wMaxPacketSize;
|
||||
u8 bInterval;
|
||||
};
|
||||
|
||||
struct OtherSpeedConfigurationDescriptor {
|
||||
ConfigDescriptor content [[inline]];
|
||||
};
|
||||
|
||||
struct DeviceQualifierDescriptor {
|
||||
DeviceDescriptor deviceDescriptor [[inline]];
|
||||
u8 bMaxPacketSize0;
|
||||
u8 bNumConfigurations;
|
||||
padding[1];
|
||||
};
|
||||
|
||||
bitfield OTGAttributes {
|
||||
SRPSupport : 1;
|
||||
HNPSupport : 1;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct OTGDescriptor {
|
||||
OTGAttributes bmAttributes;
|
||||
};
|
||||
|
||||
struct HIDDescriptor {
|
||||
BCD<2> bcdVersion;
|
||||
CountryCode bCountryCode;
|
||||
u8 bNumDescriptors;
|
||||
DescriptorType bDescriptorType;
|
||||
u16 wDescriptorLength;
|
||||
};
|
||||
|
||||
struct USBDescriptor {
|
||||
u8 bLength;
|
||||
DescriptorType bDescriptorType;
|
||||
|
||||
if (bDescriptorType == DescriptorType::DeviceDescriptor)
|
||||
DeviceDescriptor deviceDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::ConfigDescriptor)
|
||||
ConfigDescriptor configDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::StringDescriptor)
|
||||
StringDescriptor stringDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::InterfaceDescriptor)
|
||||
InterfaceDescriptor interfaceDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::EndpointDescriptor)
|
||||
EndpointDescriptor endpointDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::OtherSpeedConfigurationDescriptor)
|
||||
OtherSpeedConfigurationDescriptor otherSpeedConfigurationDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::DeviceQualifierDescriptor)
|
||||
DeviceQualifierDescriptor deviceQualifierDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::OTGDescriptor)
|
||||
OTGDescriptor otgDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::HIDDescriptor)
|
||||
HIDDescriptor hidDescriptor [[inline]];
|
||||
|
||||
padding[bLength - ($ - addressof(this))];
|
||||
};
|
||||
|
||||
USBDescriptor descriptors[while(!std::mem::eof())] @ 0x00;
|
||||
@@ -22,7 +22,7 @@ bitfield AllowedMedia {
|
||||
padding : 20;
|
||||
NonSecureHardDisk : 1;
|
||||
NonSecureMode : 1;
|
||||
} [[right_to_left]];
|
||||
};
|
||||
|
||||
bitfield GameRegion {
|
||||
NorthAmerica : 1;
|
||||
@@ -30,7 +30,7 @@ bitfield GameRegion {
|
||||
RestOfTheWorld : 1;
|
||||
padding : 28;
|
||||
Manufacturing : 1;
|
||||
} [[right_to_left]];
|
||||
};
|
||||
|
||||
struct Certificate {
|
||||
type::Size<u32> certificateSize;
|
||||
@@ -52,7 +52,7 @@ bitfield InitializationFlags {
|
||||
Limit64Megabytes : 1;
|
||||
DontSetuptHarddisk : 1;
|
||||
padding : 28;
|
||||
} [[right_to_left]];
|
||||
};
|
||||
|
||||
union EntryPoint {
|
||||
u32 betaAddress [[format("format_beta_entrypoint")]];
|
||||
@@ -333,7 +333,7 @@ bitfield LibraryFlags {
|
||||
QFEVersion : 13;
|
||||
Approved : 2;
|
||||
DebugBuild : 1;
|
||||
} [[right_to_left]];
|
||||
};
|
||||
|
||||
struct LibraryVersion {
|
||||
char libraryName[8];
|
||||
@@ -349,7 +349,7 @@ bitfield SectionFlags {
|
||||
HeadPageReadOnly : 1;
|
||||
TailPageReadOnly : 1;
|
||||
padding : 26;
|
||||
} [[right_to_left]];
|
||||
};
|
||||
|
||||
struct SectionHeader {
|
||||
SectionFlags sectionFlags;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md
|
||||
|
||||
#pragma MIME application/zstd
|
||||
|
||||
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
#define ZSTD_MAGIC_NUMBER 0xFD2FB528
|
||||
|
||||
bitfield frame_header_descriptor_t {
|
||||
@@ -15,12 +18,12 @@ bitfield frame_header_descriptor_t {
|
||||
reserved_bit : 1;
|
||||
content_checksum_flag : 1;
|
||||
dictionary_id_flag : 2;
|
||||
} [[left_to_right]];
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
bitfield window_descriptor_t {
|
||||
exponent : 5;
|
||||
mantissa : 3;
|
||||
} [[left_to_right]];
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
fn window_size(window_descriptor_t window_descriptor) {
|
||||
u64 window_log = 10 + window_descriptor.exponent;
|
||||
@@ -67,7 +70,7 @@ bitfield block_header_t {
|
||||
last_block : 1;
|
||||
block_type : 2;
|
||||
block_size : 21;
|
||||
} [[right_to_left]];
|
||||
};
|
||||
|
||||
enum block_type : u8 {
|
||||
raw_block = 0,
|
||||
|
||||
Reference in New Issue
Block a user