mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-04-01 21:17:43 -05:00
git: Fixed line endings of all files
This commit is contained in:
@@ -1,57 +1,57 @@
|
||||
#pragma endian little
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
#define VTOR 0x00000000
|
||||
#define EXTERNAL_INTERRUPT_COUNT 64
|
||||
|
||||
using Address = u32;
|
||||
|
||||
struct Exceptions {
|
||||
Address reset [[name("Reset Handler")]];
|
||||
Address nmi [[name("Non-maskable Interrupt Handler")]];
|
||||
Address hard_fault [[name("HardFault Handler")]];
|
||||
Address mem_manage [[name("Memory Protection Error Handler")]];
|
||||
Address bus_fault [[name("Bus Fault Handler")]];
|
||||
Address usage_fault [[name("UsageFault (Instruction Execution fault) Handler")]];
|
||||
Address reserved_1[4] [[hidden]];
|
||||
Address sv_call [[name("Synchronous Supervisor Call (SVC Instruction) Handler")]];
|
||||
Address debug_monitor [[name("Synchronous Debug Event Handler")]];
|
||||
Address reserved_2[1] [[hidden]];
|
||||
Address pend_sv [[name("Asynchronous Supervisor Call Handler")]];
|
||||
Address sys_tick [[name("System Timer Tick Handler")]];
|
||||
};
|
||||
|
||||
struct ExternalInterrupts {
|
||||
Address external_interrupt[EXTERNAL_INTERRUPT_COUNT] [[inline]];
|
||||
};
|
||||
|
||||
struct VectorTable {
|
||||
Address initial_sp [[name("Initial Stack Pointer Value")]];
|
||||
Exceptions exceptions [[inline, name("Exceptions")]];
|
||||
ExternalInterrupts external_interrupts [[name("External Interrupts")]];
|
||||
};
|
||||
|
||||
VectorTable vector_table @ VTOR;
|
||||
|
||||
fn main() {
|
||||
u32 table_size = sizeof(vector_table);
|
||||
|
||||
u32 default_handler_address = 0x00;
|
||||
|
||||
for (u32 i = 4, i < table_size, i = i + 4) {
|
||||
u32 occurrences = 0;
|
||||
for (u32 j = 4, j < table_size, j = j + 4) {
|
||||
if (std::mem::read_unsigned(i, 4) == std::mem::read_unsigned(j, 4)) {
|
||||
occurrences = occurrences + 1;
|
||||
|
||||
if (occurrences > 1)
|
||||
default_handler_address = std::mem::read_unsigned(i, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (default_handler_address != 0x00)
|
||||
std::print("Default Handler implementation at 0x{:08X}", default_handler_address);
|
||||
#pragma endian little
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
#define VTOR 0x00000000
|
||||
#define EXTERNAL_INTERRUPT_COUNT 64
|
||||
|
||||
using Address = u32;
|
||||
|
||||
struct Exceptions {
|
||||
Address reset [[name("Reset Handler")]];
|
||||
Address nmi [[name("Non-maskable Interrupt Handler")]];
|
||||
Address hard_fault [[name("HardFault Handler")]];
|
||||
Address mem_manage [[name("Memory Protection Error Handler")]];
|
||||
Address bus_fault [[name("Bus Fault Handler")]];
|
||||
Address usage_fault [[name("UsageFault (Instruction Execution fault) Handler")]];
|
||||
Address reserved_1[4] [[hidden]];
|
||||
Address sv_call [[name("Synchronous Supervisor Call (SVC Instruction) Handler")]];
|
||||
Address debug_monitor [[name("Synchronous Debug Event Handler")]];
|
||||
Address reserved_2[1] [[hidden]];
|
||||
Address pend_sv [[name("Asynchronous Supervisor Call Handler")]];
|
||||
Address sys_tick [[name("System Timer Tick Handler")]];
|
||||
};
|
||||
|
||||
struct ExternalInterrupts {
|
||||
Address external_interrupt[EXTERNAL_INTERRUPT_COUNT] [[inline]];
|
||||
};
|
||||
|
||||
struct VectorTable {
|
||||
Address initial_sp [[name("Initial Stack Pointer Value")]];
|
||||
Exceptions exceptions [[inline, name("Exceptions")]];
|
||||
ExternalInterrupts external_interrupts [[name("External Interrupts")]];
|
||||
};
|
||||
|
||||
VectorTable vector_table @ VTOR;
|
||||
|
||||
fn main() {
|
||||
u32 table_size = sizeof(vector_table);
|
||||
|
||||
u32 default_handler_address = 0x00;
|
||||
|
||||
for (u32 i = 4, i < table_size, i = i + 4) {
|
||||
u32 occurrences = 0;
|
||||
for (u32 j = 4, j < table_size, j = j + 4) {
|
||||
if (std::mem::read_unsigned(i, 4) == std::mem::read_unsigned(j, 4)) {
|
||||
occurrences = occurrences + 1;
|
||||
|
||||
if (occurrences > 1)
|
||||
default_handler_address = std::mem::read_unsigned(i, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (default_handler_address != 0x00)
|
||||
std::print("Default Handler implementation at 0x{:08X}", default_handler_address);
|
||||
};
|
||||
@@ -1,47 +1,47 @@
|
||||
#pragma endian little
|
||||
|
||||
#include <std/sys.pat>
|
||||
|
||||
#pragma MIME image/vnd.microsoft.icon
|
||||
#pragma MIME image/x-icon
|
||||
#pragma MIME image/icon
|
||||
#pragma MIME image/ico
|
||||
#pragma MIME text/ico
|
||||
#pragma MIME application/ico
|
||||
|
||||
enum ImageType : u16 {
|
||||
Icon = 1,
|
||||
Cursor = 2
|
||||
};
|
||||
|
||||
struct ICONDIR {
|
||||
u16 reserved [[hidden]];
|
||||
ImageType type;
|
||||
u16 num_images;
|
||||
};
|
||||
|
||||
struct ImageData {
|
||||
u8 data[parent.image_data_size] [[inline]];
|
||||
};
|
||||
|
||||
struct ICONDIRENTRY {
|
||||
u8 width, height;
|
||||
u8 num_colors;
|
||||
u8 reserved [[hidden]];
|
||||
|
||||
if (header.type == ImageType::Icon) {
|
||||
u16 color_planes;
|
||||
u16 bits_per_pixel;
|
||||
} else if (header.type == ImageType::Cursor) {
|
||||
u16 horizontal_hotspot_coordinate;
|
||||
u16 vertical_hotspot_coordinate;
|
||||
}
|
||||
|
||||
u32 image_data_size;
|
||||
ImageData *image_data : u32;
|
||||
};
|
||||
|
||||
ICONDIR header @ 0x00;
|
||||
ICONDIRENTRY images[header.num_images] @ $;
|
||||
|
||||
#pragma endian little
|
||||
|
||||
#include <std/sys.pat>
|
||||
|
||||
#pragma MIME image/vnd.microsoft.icon
|
||||
#pragma MIME image/x-icon
|
||||
#pragma MIME image/icon
|
||||
#pragma MIME image/ico
|
||||
#pragma MIME text/ico
|
||||
#pragma MIME application/ico
|
||||
|
||||
enum ImageType : u16 {
|
||||
Icon = 1,
|
||||
Cursor = 2
|
||||
};
|
||||
|
||||
struct ICONDIR {
|
||||
u16 reserved [[hidden]];
|
||||
ImageType type;
|
||||
u16 num_images;
|
||||
};
|
||||
|
||||
struct ImageData {
|
||||
u8 data[parent.image_data_size] [[inline]];
|
||||
};
|
||||
|
||||
struct ICONDIRENTRY {
|
||||
u8 width, height;
|
||||
u8 num_colors;
|
||||
u8 reserved [[hidden]];
|
||||
|
||||
if (header.type == ImageType::Icon) {
|
||||
u16 color_planes;
|
||||
u16 bits_per_pixel;
|
||||
} else if (header.type == ImageType::Cursor) {
|
||||
u16 horizontal_hotspot_coordinate;
|
||||
u16 vertical_hotspot_coordinate;
|
||||
}
|
||||
|
||||
u32 image_data_size;
|
||||
ImageData *image_data : u32;
|
||||
};
|
||||
|
||||
ICONDIR header @ 0x00;
|
||||
ICONDIRENTRY images[header.num_images] @ $;
|
||||
|
||||
std::assert(header.reserved == 0x00, "Invalid ICO header");
|
||||
@@ -1,270 +1,270 @@
|
||||
#pragma endian big
|
||||
#pragma bitfield_order left_to_right
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
struct MAC {
|
||||
u8 octets[6];
|
||||
} [[format("mac_formatter")]];
|
||||
|
||||
fn mac_formatter(MAC mac) {
|
||||
return std::format("{0:02X}:{1:02X}:{2:02X}:{3:02X}:{4:02X}:{5:02X}",
|
||||
mac.octets[0],
|
||||
mac.octets[1],
|
||||
mac.octets[2],
|
||||
mac.octets[3],
|
||||
mac.octets[4],
|
||||
mac.octets[5]);
|
||||
};
|
||||
|
||||
enum EtherType : u16 {
|
||||
IPv4 = 0x0800,
|
||||
ARP = 0x0806,
|
||||
WakeOnLAN = 0x0842,
|
||||
AVTP = 0x22F0,
|
||||
IETF_TRILL = 0x22F3,
|
||||
SRP = 0x22EA,
|
||||
DEC_MOP_RC = 0x6002,
|
||||
DECnet = 0x6003,
|
||||
DEC_LAT = 0x6004,
|
||||
RARP = 0x8035,
|
||||
AppleTalk = 0x809B,
|
||||
AppleTalk_AARP = 0x80F3,
|
||||
VLANTaggedFrame = 0x8100,
|
||||
SLPP = 0x8102,
|
||||
VLACP = 0x8103,
|
||||
IPX = 0x8137,
|
||||
QNX_Qnet = 0x8204,
|
||||
IPv6 = 0x860D,
|
||||
EthernetFlowControl = 0x8808,
|
||||
EthernetSlowProtocols = 0x8809,
|
||||
CobraNet = 0x8819,
|
||||
MPLS_Unicast = 0x8847,
|
||||
MPLS_Multicast = 0x8848,
|
||||
PPPoE_Discovery = 0x8863,
|
||||
PPPoE_Session = 0x8864,
|
||||
HomePlug = 0x887B,
|
||||
EAPOverLAN = 0x888E,
|
||||
PROFINET = 0x8892,
|
||||
HyperSCSI = 0x889A,
|
||||
ATAOverEthernet = 0x88A2,
|
||||
EtherCAT = 0x88A4,
|
||||
ServiceVLANTagIdentifier = 0x88A8,
|
||||
EthernetPowerlink = 0x88AB,
|
||||
GOOSE = 0x88B8,
|
||||
GSE = 0x88B9,
|
||||
SV = 0x88BA,
|
||||
MikroTik_RoMON = 0x88BF,
|
||||
LLDP = 0x88CC,
|
||||
SERCOS_III = 0x88CD,
|
||||
HomePlugGreenPHY = 0x88E1,
|
||||
MRP = 0x88E3,
|
||||
IEEE802_1AE = 0x88E5,
|
||||
PBB = 0x88E7,
|
||||
PTP = 0x88F7,
|
||||
NC_SI = 0x88F8,
|
||||
PRP = 0x88FB,
|
||||
CFM = 0x8902,
|
||||
FCoE = 0x8906,
|
||||
FCoEIP = 0x8914,
|
||||
RoCE = 0x8915,
|
||||
TTE = 0x891D,
|
||||
IEEE_1905_1 = 0x893A,
|
||||
HSR = 0x892F,
|
||||
ECTP = 0x9000,
|
||||
RedundancyTag = 0xF1C1
|
||||
};
|
||||
|
||||
namespace ip {
|
||||
|
||||
enum Protocol : u8 {
|
||||
ICMP = 1,
|
||||
IGMP = 2,
|
||||
TCP = 6,
|
||||
UDP = 17,
|
||||
ENCAP = 41,
|
||||
OSPF = 89,
|
||||
SCTP = 132
|
||||
};
|
||||
|
||||
namespace udp {
|
||||
|
||||
struct Packet {
|
||||
u16 source_port;
|
||||
u16 destination_port;
|
||||
u16 length;
|
||||
std::assert(length >= 8, "UDP Packet has invalid length");
|
||||
u16 checksum;
|
||||
u8 data[length - 8];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace tcp {
|
||||
|
||||
bitfield Flags {
|
||||
data_offset : 4;
|
||||
padding : 3;
|
||||
ns : 1;
|
||||
cwr : 1;
|
||||
ece : 1;
|
||||
urg : 1;
|
||||
ack : 1;
|
||||
psh : 1;
|
||||
rst : 1;
|
||||
syn : 1;
|
||||
fin : 1;
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
u16 source_port;
|
||||
u16 destination_port;
|
||||
u32 sequence_number;
|
||||
u32 ack_number;
|
||||
Flags flags [[inline]];
|
||||
u16 window_size;
|
||||
u16 checksum;
|
||||
u16 urgent_pointer;
|
||||
|
||||
if (flags.data_offset > 5)
|
||||
u8 options[(flags.data_offset - 5) * sizeof(u32)];
|
||||
|
||||
u8 data[parent.parent.header.total_length - 40];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
struct Payload {
|
||||
if (parent.protocol == ip::Protocol::UDP)
|
||||
udp::Packet packet [[inline]];
|
||||
else if (parent.protocol == ip::Protocol::TCP)
|
||||
tcp::Packet packet [[inline]];
|
||||
else
|
||||
std::error(std::format("Unknown protocol: {}", parent.protocol));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace ipv4 {
|
||||
|
||||
struct Address {
|
||||
u8 octets[4];
|
||||
} [[format("ipv4::address_formatter")]];
|
||||
|
||||
fn address_formatter(Address addr) {
|
||||
return std::format("{0}.{1}.{2}.{3}",
|
||||
addr.octets[0],
|
||||
addr.octets[1],
|
||||
addr.octets[2],
|
||||
addr.octets[3]);
|
||||
};
|
||||
|
||||
bitfield Header {
|
||||
version : 4;
|
||||
ihl : 4;
|
||||
tos : 8;
|
||||
total_length : 16;
|
||||
};
|
||||
|
||||
bitfield Flags {
|
||||
reserved : 1;
|
||||
df : 1;
|
||||
mf : 1;
|
||||
fragment_offset : 13;
|
||||
};
|
||||
|
||||
|
||||
struct Packet {
|
||||
Header header [[inline]];
|
||||
u16 identification;
|
||||
Flags flags [[inline]];
|
||||
u8 time_to_live;
|
||||
ip::Protocol protocol;
|
||||
u16 header_checksum;
|
||||
|
||||
Address source_ip_address;
|
||||
Address destination_ip_address;
|
||||
|
||||
if (header.ihl > 5)
|
||||
u8 options[(header.ihl - 5) * sizeof(u32)];
|
||||
|
||||
ip::Payload payload;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace ipv6 {
|
||||
|
||||
struct Address {
|
||||
u16 segments[8];
|
||||
} [[format("ipv6::address_formatter")]];
|
||||
|
||||
fn address_formatter(Address addr) {
|
||||
return std::format("{0:04X}:{1:04X}:{2:04X}:{3:04X}:{4:04X}:{5:04X}:{6:04X}:{7:04X}",
|
||||
addr.segments[0],
|
||||
addr.segments[1],
|
||||
addr.segments[2],
|
||||
addr.segments[3],
|
||||
addr.segments[4],
|
||||
addr.segments[5],
|
||||
addr.segments[6],
|
||||
addr.segments[7]);
|
||||
};
|
||||
|
||||
bitfield Header {
|
||||
version : 4;
|
||||
ds : 6;
|
||||
ecn : 2;
|
||||
flow_label : 20;
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
Header header [[inline]];
|
||||
u16 payload_length;
|
||||
ip::Protocol next_header;
|
||||
u8 hop_limit;
|
||||
|
||||
Address source_address;
|
||||
Address destination_address;
|
||||
|
||||
ip::Payload payload;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct Payload {
|
||||
if (parent.type == EtherType::IPv4)
|
||||
ipv4::Packet packet [[inline]];
|
||||
else
|
||||
std::error(std::format("Unknown payload type: 0x{:04X}", parent.type));
|
||||
};
|
||||
|
||||
bitfield TCI {
|
||||
pcp : 3;
|
||||
dei : 1;
|
||||
vid : 12;
|
||||
};
|
||||
|
||||
struct EthernetIIFrame {
|
||||
MAC destination_address;
|
||||
MAC source_address;
|
||||
|
||||
u16 possible_tpid [[no_unique_address, hidden]];
|
||||
if (possible_tpid == EtherType::VLANTaggedFrame) {
|
||||
u16 tpid;
|
||||
TCI tci [[inline]];
|
||||
}
|
||||
|
||||
EtherType type;
|
||||
|
||||
Payload payload;
|
||||
std::assert(sizeof(payload) >= 40 && sizeof(payload) <= 1500, std::format("Payload size out of range: {}", sizeof(payload)));
|
||||
|
||||
u32 frame_check_sequence;
|
||||
};
|
||||
|
||||
EthernetIIFrame frame @ 0x00;
|
||||
#pragma endian big
|
||||
#pragma bitfield_order left_to_right
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
struct MAC {
|
||||
u8 octets[6];
|
||||
} [[format("mac_formatter")]];
|
||||
|
||||
fn mac_formatter(MAC mac) {
|
||||
return std::format("{0:02X}:{1:02X}:{2:02X}:{3:02X}:{4:02X}:{5:02X}",
|
||||
mac.octets[0],
|
||||
mac.octets[1],
|
||||
mac.octets[2],
|
||||
mac.octets[3],
|
||||
mac.octets[4],
|
||||
mac.octets[5]);
|
||||
};
|
||||
|
||||
enum EtherType : u16 {
|
||||
IPv4 = 0x0800,
|
||||
ARP = 0x0806,
|
||||
WakeOnLAN = 0x0842,
|
||||
AVTP = 0x22F0,
|
||||
IETF_TRILL = 0x22F3,
|
||||
SRP = 0x22EA,
|
||||
DEC_MOP_RC = 0x6002,
|
||||
DECnet = 0x6003,
|
||||
DEC_LAT = 0x6004,
|
||||
RARP = 0x8035,
|
||||
AppleTalk = 0x809B,
|
||||
AppleTalk_AARP = 0x80F3,
|
||||
VLANTaggedFrame = 0x8100,
|
||||
SLPP = 0x8102,
|
||||
VLACP = 0x8103,
|
||||
IPX = 0x8137,
|
||||
QNX_Qnet = 0x8204,
|
||||
IPv6 = 0x860D,
|
||||
EthernetFlowControl = 0x8808,
|
||||
EthernetSlowProtocols = 0x8809,
|
||||
CobraNet = 0x8819,
|
||||
MPLS_Unicast = 0x8847,
|
||||
MPLS_Multicast = 0x8848,
|
||||
PPPoE_Discovery = 0x8863,
|
||||
PPPoE_Session = 0x8864,
|
||||
HomePlug = 0x887B,
|
||||
EAPOverLAN = 0x888E,
|
||||
PROFINET = 0x8892,
|
||||
HyperSCSI = 0x889A,
|
||||
ATAOverEthernet = 0x88A2,
|
||||
EtherCAT = 0x88A4,
|
||||
ServiceVLANTagIdentifier = 0x88A8,
|
||||
EthernetPowerlink = 0x88AB,
|
||||
GOOSE = 0x88B8,
|
||||
GSE = 0x88B9,
|
||||
SV = 0x88BA,
|
||||
MikroTik_RoMON = 0x88BF,
|
||||
LLDP = 0x88CC,
|
||||
SERCOS_III = 0x88CD,
|
||||
HomePlugGreenPHY = 0x88E1,
|
||||
MRP = 0x88E3,
|
||||
IEEE802_1AE = 0x88E5,
|
||||
PBB = 0x88E7,
|
||||
PTP = 0x88F7,
|
||||
NC_SI = 0x88F8,
|
||||
PRP = 0x88FB,
|
||||
CFM = 0x8902,
|
||||
FCoE = 0x8906,
|
||||
FCoEIP = 0x8914,
|
||||
RoCE = 0x8915,
|
||||
TTE = 0x891D,
|
||||
IEEE_1905_1 = 0x893A,
|
||||
HSR = 0x892F,
|
||||
ECTP = 0x9000,
|
||||
RedundancyTag = 0xF1C1
|
||||
};
|
||||
|
||||
namespace ip {
|
||||
|
||||
enum Protocol : u8 {
|
||||
ICMP = 1,
|
||||
IGMP = 2,
|
||||
TCP = 6,
|
||||
UDP = 17,
|
||||
ENCAP = 41,
|
||||
OSPF = 89,
|
||||
SCTP = 132
|
||||
};
|
||||
|
||||
namespace udp {
|
||||
|
||||
struct Packet {
|
||||
u16 source_port;
|
||||
u16 destination_port;
|
||||
u16 length;
|
||||
std::assert(length >= 8, "UDP Packet has invalid length");
|
||||
u16 checksum;
|
||||
u8 data[length - 8];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace tcp {
|
||||
|
||||
bitfield Flags {
|
||||
data_offset : 4;
|
||||
padding : 3;
|
||||
ns : 1;
|
||||
cwr : 1;
|
||||
ece : 1;
|
||||
urg : 1;
|
||||
ack : 1;
|
||||
psh : 1;
|
||||
rst : 1;
|
||||
syn : 1;
|
||||
fin : 1;
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
u16 source_port;
|
||||
u16 destination_port;
|
||||
u32 sequence_number;
|
||||
u32 ack_number;
|
||||
Flags flags [[inline]];
|
||||
u16 window_size;
|
||||
u16 checksum;
|
||||
u16 urgent_pointer;
|
||||
|
||||
if (flags.data_offset > 5)
|
||||
u8 options[(flags.data_offset - 5) * sizeof(u32)];
|
||||
|
||||
u8 data[parent.parent.header.total_length - 40];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
struct Payload {
|
||||
if (parent.protocol == ip::Protocol::UDP)
|
||||
udp::Packet packet [[inline]];
|
||||
else if (parent.protocol == ip::Protocol::TCP)
|
||||
tcp::Packet packet [[inline]];
|
||||
else
|
||||
std::error(std::format("Unknown protocol: {}", parent.protocol));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace ipv4 {
|
||||
|
||||
struct Address {
|
||||
u8 octets[4];
|
||||
} [[format("ipv4::address_formatter")]];
|
||||
|
||||
fn address_formatter(Address addr) {
|
||||
return std::format("{0}.{1}.{2}.{3}",
|
||||
addr.octets[0],
|
||||
addr.octets[1],
|
||||
addr.octets[2],
|
||||
addr.octets[3]);
|
||||
};
|
||||
|
||||
bitfield Header {
|
||||
version : 4;
|
||||
ihl : 4;
|
||||
tos : 8;
|
||||
total_length : 16;
|
||||
};
|
||||
|
||||
bitfield Flags {
|
||||
reserved : 1;
|
||||
df : 1;
|
||||
mf : 1;
|
||||
fragment_offset : 13;
|
||||
};
|
||||
|
||||
|
||||
struct Packet {
|
||||
Header header [[inline]];
|
||||
u16 identification;
|
||||
Flags flags [[inline]];
|
||||
u8 time_to_live;
|
||||
ip::Protocol protocol;
|
||||
u16 header_checksum;
|
||||
|
||||
Address source_ip_address;
|
||||
Address destination_ip_address;
|
||||
|
||||
if (header.ihl > 5)
|
||||
u8 options[(header.ihl - 5) * sizeof(u32)];
|
||||
|
||||
ip::Payload payload;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace ipv6 {
|
||||
|
||||
struct Address {
|
||||
u16 segments[8];
|
||||
} [[format("ipv6::address_formatter")]];
|
||||
|
||||
fn address_formatter(Address addr) {
|
||||
return std::format("{0:04X}:{1:04X}:{2:04X}:{3:04X}:{4:04X}:{5:04X}:{6:04X}:{7:04X}",
|
||||
addr.segments[0],
|
||||
addr.segments[1],
|
||||
addr.segments[2],
|
||||
addr.segments[3],
|
||||
addr.segments[4],
|
||||
addr.segments[5],
|
||||
addr.segments[6],
|
||||
addr.segments[7]);
|
||||
};
|
||||
|
||||
bitfield Header {
|
||||
version : 4;
|
||||
ds : 6;
|
||||
ecn : 2;
|
||||
flow_label : 20;
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
Header header [[inline]];
|
||||
u16 payload_length;
|
||||
ip::Protocol next_header;
|
||||
u8 hop_limit;
|
||||
|
||||
Address source_address;
|
||||
Address destination_address;
|
||||
|
||||
ip::Payload payload;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct Payload {
|
||||
if (parent.type == EtherType::IPv4)
|
||||
ipv4::Packet packet [[inline]];
|
||||
else
|
||||
std::error(std::format("Unknown payload type: 0x{:04X}", parent.type));
|
||||
};
|
||||
|
||||
bitfield TCI {
|
||||
pcp : 3;
|
||||
dei : 1;
|
||||
vid : 12;
|
||||
};
|
||||
|
||||
struct EthernetIIFrame {
|
||||
MAC destination_address;
|
||||
MAC source_address;
|
||||
|
||||
u16 possible_tpid [[no_unique_address, hidden]];
|
||||
if (possible_tpid == EtherType::VLANTaggedFrame) {
|
||||
u16 tpid;
|
||||
TCI tci [[inline]];
|
||||
}
|
||||
|
||||
EtherType type;
|
||||
|
||||
Payload payload;
|
||||
std::assert(sizeof(payload) >= 40 && sizeof(payload) <= 1500, std::format("Payload size out of range: {}", sizeof(payload)));
|
||||
|
||||
u32 frame_check_sequence;
|
||||
};
|
||||
|
||||
EthernetIIFrame frame @ 0x00;
|
||||
|
||||
@@ -1,342 +1,342 @@
|
||||
#pragma endian big
|
||||
#pragma MIME application/x-java-applet
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
// The Java documentations use the number of bytes instead of the number of bits for its type names
|
||||
using u1 = u8;
|
||||
using u2 = u16;
|
||||
using u4 = u32;
|
||||
|
||||
using f4 = float;
|
||||
using f8 = double;
|
||||
|
||||
enum cp_tag : u8 {
|
||||
CONSTANT_Utf8 = 1,
|
||||
CONSTANT_Integer = 3,
|
||||
CONSTANT_Float = 4,
|
||||
CONSTANT_Long = 5,
|
||||
CONSTANT_Double = 6,
|
||||
CONSTANT_Class = 7,
|
||||
CONSTANT_String = 8,
|
||||
CONSTANT_Fieldref = 9,
|
||||
CONSTANT_Methodref = 10,
|
||||
CONSTANT_InterfaceMethodref = 11,
|
||||
CONSTANT_NameAndType = 12,
|
||||
CONSTANT_MethodHandle = 15,
|
||||
CONSTANT_MethodType = 16,
|
||||
CONSTANT_InvokeDynamic = 18
|
||||
};
|
||||
|
||||
enum major_version : u2 {
|
||||
JDK_1_1 = 45,
|
||||
JDK_1_2 = 46,
|
||||
JDK_1_3 = 47,
|
||||
JDK_1_4 = 48,
|
||||
|
||||
Java_SE_5_0 = 49,
|
||||
Java_SE_6_0 = 50,
|
||||
Java_SE_7 = 51,
|
||||
Java_SE_8 = 52,
|
||||
Java_SE_9 = 53,
|
||||
Java_SE_10 = 54,
|
||||
Java_SE_11 = 55,
|
||||
Java_SE_12 = 56,
|
||||
Java_SE_13 = 57,
|
||||
Java_SE_14 = 58,
|
||||
Java_SE_15 = 59,
|
||||
Java_SE_16 = 60,
|
||||
Java_SE_17 = 61,
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Utf8
|
||||
struct CONSTANT_Utf8_info {
|
||||
u2 length;
|
||||
char bytes[length]; // u1 in documentation. Changed to char to improve readability
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Integer
|
||||
struct CONSTANT_Integer_info {
|
||||
u4 bytes;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Float
|
||||
struct CONSTANT_Float_info {
|
||||
f4 bytes; // u4 in documentation. Changed to f4 to improve readablilty
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Long
|
||||
struct CONSTANT_Long_info {
|
||||
u4 high_bytes;
|
||||
u4 low_bytes;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Double
|
||||
struct CONSTANT_Double_info {
|
||||
u4 high_bytes;
|
||||
u4 low_bytes;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Class
|
||||
struct CONSTANT_Class_info {
|
||||
u2 name_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_String
|
||||
struct CONSTANT_String_info {
|
||||
u2 string_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Fieldref
|
||||
struct CONSTANT_Fieldref_info {
|
||||
u2 class_index;
|
||||
u2 name_and_type_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Methodref
|
||||
struct CONSTANT_Methodref_info {
|
||||
u2 class_index;
|
||||
u2 name_and_type_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_InterfaceMethodref
|
||||
struct CONSTANT_InterfaceMethodref_info {
|
||||
u2 class_index;
|
||||
u2 name_and_type_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_NameAndType
|
||||
struct CONSTANT_NameAndType_info {
|
||||
u2 name_index;
|
||||
u2 descriptor_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_MethodHandle
|
||||
struct CONSTANT_MethodHandle_info {
|
||||
u1 reference_kind;
|
||||
u2 reference_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_MethodType
|
||||
struct CONSTANT_MethodType_info {
|
||||
u2 descriptor_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_InvokeDynamic
|
||||
struct CONSTANT_InvokeDynamic_info {
|
||||
u2 bootstrap_method_attr_index;
|
||||
u2 name_and_type_index;
|
||||
};
|
||||
|
||||
struct cp_info {
|
||||
cp_tag tag;
|
||||
|
||||
if (tag == cp_tag::CONSTANT_Utf8)
|
||||
CONSTANT_Utf8_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Integer)
|
||||
CONSTANT_Integer_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Float)
|
||||
CONSTANT_Float_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Long)
|
||||
CONSTANT_Long_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Double)
|
||||
CONSTANT_Double_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Class)
|
||||
CONSTANT_Class_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_String)
|
||||
CONSTANT_String_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Fieldref)
|
||||
CONSTANT_Fieldref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Methodref)
|
||||
CONSTANT_Methodref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_InterfaceMethodref)
|
||||
CONSTANT_InterfaceMethodref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_NameAndType)
|
||||
CONSTANT_NameAndType_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_MethodHandle)
|
||||
CONSTANT_MethodHandle_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_MethodType)
|
||||
CONSTANT_MethodType_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_InvokeDynamic)
|
||||
CONSTANT_InvokeDynamic_info info [[inline]];
|
||||
};
|
||||
|
||||
bitfield access_flags_method {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
ACC_PRIVATE : 1; // 0x0002
|
||||
ACC_PROTECTED : 1; // 0x0004
|
||||
ACC_STATIC : 1; // 0x0008
|
||||
ACC_FINAL : 1; // 0x0010
|
||||
ACC_SYNCHRONIZED: 1; // 0x0020
|
||||
ACC_BRIDGE : 1; // 0x0040
|
||||
ACC_VARARGS : 1; // 0x0080
|
||||
ACC_NATIVE : 1; // 0x0100
|
||||
padding : 1; // 0x0200
|
||||
ACC_ABSTRACT : 1; // 0x0400
|
||||
ACC_STRICT : 1; // 0x0800
|
||||
ACC_SYNTHETIC : 1; // 0x1000
|
||||
padding : 1; // 0x2000
|
||||
padding : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
|
||||
bitfield access_flags_field {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
ACC_PRIVATE : 1; // 0x0002
|
||||
ACC_PROTECTED : 1; // 0x0004
|
||||
ACC_STATIC : 1; // 0x0008
|
||||
ACC_FINAL : 1; // 0x0010
|
||||
padding : 1; // 0x0020
|
||||
ACC_VOLATILE : 1; // 0x0040
|
||||
ACC_TRANSIENT : 1; // 0x0080
|
||||
padding : 1; // 0x0100
|
||||
padding : 1; // 0x0200
|
||||
padding : 1; // 0x0400
|
||||
padding : 1; // 0x0800
|
||||
ACC_SYNTHETIC : 1; // 0x1000
|
||||
padding : 1; // 0x2000
|
||||
ACC_ENUM : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
|
||||
bitfield access_flags_class {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
padding : 1; // 0x0002
|
||||
padding : 1; // 0x0004
|
||||
padding : 1; // 0x0008
|
||||
ACC_FINAL : 1; // 0x0010
|
||||
ACC_SUPER : 1; // 0x0020
|
||||
padding : 1; // 0x0040
|
||||
padding : 1; // 0x0080
|
||||
padding : 1; // 0x0100
|
||||
ACC_INTERFACE : 1; // 0x0200
|
||||
ACC_ABSTRACT : 1; // 0x0400
|
||||
padding : 1; // 0x0800
|
||||
ACC_SYNTHETIC : 1; // 0x1000
|
||||
ACC_ANNOTATION : 1; // 0x2000
|
||||
ACC_ENUM : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
|
||||
struct attribute_info {
|
||||
u2 attribute_name_info;
|
||||
|
||||
u4 attribute_length;
|
||||
|
||||
u1 info[attribute_length];
|
||||
};
|
||||
|
||||
struct field_info {
|
||||
access_flags_field access_flags;
|
||||
u2 name_index;
|
||||
u2 descriptor_index;
|
||||
|
||||
u2 attribute_count;
|
||||
attribute_info attributes[attribute_count];
|
||||
};
|
||||
|
||||
struct method_info {
|
||||
access_flags_method access_flags;
|
||||
u2 name_index;
|
||||
u2 descriptor_index;
|
||||
u2 attributes_count;
|
||||
attribute_info attributes[attributes_count];
|
||||
};
|
||||
|
||||
struct ClassFile {
|
||||
u4 magic;
|
||||
|
||||
u2 minor_version;
|
||||
major_version major_version;
|
||||
|
||||
u2 constant_pool_count;
|
||||
cp_info constant_pool[constant_pool_count - 1];
|
||||
|
||||
access_flags_class access_flags;
|
||||
u2 this_class;
|
||||
u2 super_class;
|
||||
|
||||
u2 interfaces_count;
|
||||
u2 interfaces[interfaces_count];
|
||||
|
||||
u2 fields_count;
|
||||
field_info fields[fields_count];
|
||||
|
||||
u2 methods_count;
|
||||
method_info methods[methods_count];
|
||||
|
||||
u2 attribute_count;
|
||||
attribute_info attributes[attribute_count];
|
||||
};
|
||||
|
||||
ClassFile class_file @ 0x00;
|
||||
|
||||
fn main() {
|
||||
|
||||
std::assert(class_file.magic == 0xCAFEBABE, "File is not a valid Java Class file! Invalid header magic");
|
||||
|
||||
|
||||
std::print("Fields:");
|
||||
for (le u16 i = 0, i < class_file.fields_count, i = i + 1) {
|
||||
str method_string = " ";
|
||||
|
||||
if (class_file.fields[i].access_flags.ACC_PUBLIC)
|
||||
method_string = method_string + "public ";
|
||||
if (class_file.fields[i].access_flags.ACC_PRIVATE)
|
||||
method_string = method_string + "private ";
|
||||
if (class_file.fields[i].access_flags.ACC_PROTECTED)
|
||||
method_string = method_string + "protected ";
|
||||
if (class_file.fields[i].access_flags.ACC_STATIC)
|
||||
method_string = method_string + "static ";
|
||||
if (class_file.fields[i].access_flags.ACC_FINAL)
|
||||
method_string = method_string + "final ";
|
||||
if (class_file.fields[i].access_flags.ACC_VOLATILE)
|
||||
method_string = method_string + "volatile ";
|
||||
if (class_file.fields[i].access_flags.ACC_NATIVE)
|
||||
method_string = method_string + "native ";
|
||||
if (class_file.fields[i].access_flags.ACC_TRANSIENT)
|
||||
method_string = method_string + "transient ";
|
||||
if (class_file.fields[i].access_flags.ACC_ENUM)
|
||||
method_string = method_string + "enum ";
|
||||
|
||||
method_string = method_string + class_file.constant_pool[class_file.fields[i].name_index - 1].info.bytes;
|
||||
method_string = method_string + " [ " + class_file.constant_pool[class_file.fields[i].descriptor_index - 1].info.bytes + " ]";
|
||||
|
||||
std::print("{}", method_string);
|
||||
}
|
||||
|
||||
std::print("Methods:");
|
||||
for (le u16 i = 0, i < class_file.methods_count, i = i + 1) {
|
||||
str method_string = " ";
|
||||
|
||||
if (class_file.methods[i].access_flags.ACC_PUBLIC)
|
||||
method_string = method_string + "public ";
|
||||
if (class_file.methods[i].access_flags.ACC_PRIVATE)
|
||||
method_string = method_string + "private ";
|
||||
if (class_file.methods[i].access_flags.ACC_PROTECTED)
|
||||
method_string = method_string + "protected ";
|
||||
if (class_file.methods[i].access_flags.ACC_STATIC)
|
||||
method_string = method_string + "static ";
|
||||
if (class_file.methods[i].access_flags.ACC_FINAL)
|
||||
method_string = method_string + "final ";
|
||||
if (class_file.methods[i].access_flags.ACC_SYNCHRONIZED)
|
||||
method_string = method_string + "synchronized ";
|
||||
if (class_file.methods[i].access_flags.ACC_NATIVE)
|
||||
method_string = method_string + "native ";
|
||||
if (class_file.methods[i].access_flags.ACC_ABSTRACT)
|
||||
method_string = method_string + "abstract ";
|
||||
if (class_file.methods[i].access_flags.ACC_STRICT)
|
||||
method_string = method_string + "strictfp ";
|
||||
|
||||
method_string = method_string + class_file.constant_pool[class_file.methods[i].name_index - 1].info.bytes;
|
||||
method_string = method_string + " [ " + class_file.constant_pool[class_file.methods[i].descriptor_index - 1].info.bytes + " ]";
|
||||
|
||||
std::print("{}", method_string);
|
||||
}
|
||||
|
||||
std::print("Class Attributes:");
|
||||
for (le u16 i = 0, i < class_file.attribute_count, i = i + 1) {
|
||||
std::print(" {}", class_file.constant_pool[class_file.attributes[i].attribute_name_info - 1].info.bytes);
|
||||
}
|
||||
#pragma endian big
|
||||
#pragma MIME application/x-java-applet
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
// The Java documentations use the number of bytes instead of the number of bits for its type names
|
||||
using u1 = u8;
|
||||
using u2 = u16;
|
||||
using u4 = u32;
|
||||
|
||||
using f4 = float;
|
||||
using f8 = double;
|
||||
|
||||
enum cp_tag : u8 {
|
||||
CONSTANT_Utf8 = 1,
|
||||
CONSTANT_Integer = 3,
|
||||
CONSTANT_Float = 4,
|
||||
CONSTANT_Long = 5,
|
||||
CONSTANT_Double = 6,
|
||||
CONSTANT_Class = 7,
|
||||
CONSTANT_String = 8,
|
||||
CONSTANT_Fieldref = 9,
|
||||
CONSTANT_Methodref = 10,
|
||||
CONSTANT_InterfaceMethodref = 11,
|
||||
CONSTANT_NameAndType = 12,
|
||||
CONSTANT_MethodHandle = 15,
|
||||
CONSTANT_MethodType = 16,
|
||||
CONSTANT_InvokeDynamic = 18
|
||||
};
|
||||
|
||||
enum major_version : u2 {
|
||||
JDK_1_1 = 45,
|
||||
JDK_1_2 = 46,
|
||||
JDK_1_3 = 47,
|
||||
JDK_1_4 = 48,
|
||||
|
||||
Java_SE_5_0 = 49,
|
||||
Java_SE_6_0 = 50,
|
||||
Java_SE_7 = 51,
|
||||
Java_SE_8 = 52,
|
||||
Java_SE_9 = 53,
|
||||
Java_SE_10 = 54,
|
||||
Java_SE_11 = 55,
|
||||
Java_SE_12 = 56,
|
||||
Java_SE_13 = 57,
|
||||
Java_SE_14 = 58,
|
||||
Java_SE_15 = 59,
|
||||
Java_SE_16 = 60,
|
||||
Java_SE_17 = 61,
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Utf8
|
||||
struct CONSTANT_Utf8_info {
|
||||
u2 length;
|
||||
char bytes[length]; // u1 in documentation. Changed to char to improve readability
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Integer
|
||||
struct CONSTANT_Integer_info {
|
||||
u4 bytes;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Float
|
||||
struct CONSTANT_Float_info {
|
||||
f4 bytes; // u4 in documentation. Changed to f4 to improve readablilty
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Long
|
||||
struct CONSTANT_Long_info {
|
||||
u4 high_bytes;
|
||||
u4 low_bytes;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Double
|
||||
struct CONSTANT_Double_info {
|
||||
u4 high_bytes;
|
||||
u4 low_bytes;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Class
|
||||
struct CONSTANT_Class_info {
|
||||
u2 name_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_String
|
||||
struct CONSTANT_String_info {
|
||||
u2 string_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Fieldref
|
||||
struct CONSTANT_Fieldref_info {
|
||||
u2 class_index;
|
||||
u2 name_and_type_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_Methodref
|
||||
struct CONSTANT_Methodref_info {
|
||||
u2 class_index;
|
||||
u2 name_and_type_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_InterfaceMethodref
|
||||
struct CONSTANT_InterfaceMethodref_info {
|
||||
u2 class_index;
|
||||
u2 name_and_type_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_NameAndType
|
||||
struct CONSTANT_NameAndType_info {
|
||||
u2 name_index;
|
||||
u2 descriptor_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_MethodHandle
|
||||
struct CONSTANT_MethodHandle_info {
|
||||
u1 reference_kind;
|
||||
u2 reference_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_MethodType
|
||||
struct CONSTANT_MethodType_info {
|
||||
u2 descriptor_index;
|
||||
};
|
||||
|
||||
// Tag == CONSTANT_InvokeDynamic
|
||||
struct CONSTANT_InvokeDynamic_info {
|
||||
u2 bootstrap_method_attr_index;
|
||||
u2 name_and_type_index;
|
||||
};
|
||||
|
||||
struct cp_info {
|
||||
cp_tag tag;
|
||||
|
||||
if (tag == cp_tag::CONSTANT_Utf8)
|
||||
CONSTANT_Utf8_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Integer)
|
||||
CONSTANT_Integer_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Float)
|
||||
CONSTANT_Float_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Long)
|
||||
CONSTANT_Long_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Double)
|
||||
CONSTANT_Double_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Class)
|
||||
CONSTANT_Class_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_String)
|
||||
CONSTANT_String_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Fieldref)
|
||||
CONSTANT_Fieldref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Methodref)
|
||||
CONSTANT_Methodref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_InterfaceMethodref)
|
||||
CONSTANT_InterfaceMethodref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_NameAndType)
|
||||
CONSTANT_NameAndType_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_MethodHandle)
|
||||
CONSTANT_MethodHandle_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_MethodType)
|
||||
CONSTANT_MethodType_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_InvokeDynamic)
|
||||
CONSTANT_InvokeDynamic_info info [[inline]];
|
||||
};
|
||||
|
||||
bitfield access_flags_method {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
ACC_PRIVATE : 1; // 0x0002
|
||||
ACC_PROTECTED : 1; // 0x0004
|
||||
ACC_STATIC : 1; // 0x0008
|
||||
ACC_FINAL : 1; // 0x0010
|
||||
ACC_SYNCHRONIZED: 1; // 0x0020
|
||||
ACC_BRIDGE : 1; // 0x0040
|
||||
ACC_VARARGS : 1; // 0x0080
|
||||
ACC_NATIVE : 1; // 0x0100
|
||||
padding : 1; // 0x0200
|
||||
ACC_ABSTRACT : 1; // 0x0400
|
||||
ACC_STRICT : 1; // 0x0800
|
||||
ACC_SYNTHETIC : 1; // 0x1000
|
||||
padding : 1; // 0x2000
|
||||
padding : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
|
||||
bitfield access_flags_field {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
ACC_PRIVATE : 1; // 0x0002
|
||||
ACC_PROTECTED : 1; // 0x0004
|
||||
ACC_STATIC : 1; // 0x0008
|
||||
ACC_FINAL : 1; // 0x0010
|
||||
padding : 1; // 0x0020
|
||||
ACC_VOLATILE : 1; // 0x0040
|
||||
ACC_TRANSIENT : 1; // 0x0080
|
||||
padding : 1; // 0x0100
|
||||
padding : 1; // 0x0200
|
||||
padding : 1; // 0x0400
|
||||
padding : 1; // 0x0800
|
||||
ACC_SYNTHETIC : 1; // 0x1000
|
||||
padding : 1; // 0x2000
|
||||
ACC_ENUM : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
|
||||
bitfield access_flags_class {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
padding : 1; // 0x0002
|
||||
padding : 1; // 0x0004
|
||||
padding : 1; // 0x0008
|
||||
ACC_FINAL : 1; // 0x0010
|
||||
ACC_SUPER : 1; // 0x0020
|
||||
padding : 1; // 0x0040
|
||||
padding : 1; // 0x0080
|
||||
padding : 1; // 0x0100
|
||||
ACC_INTERFACE : 1; // 0x0200
|
||||
ACC_ABSTRACT : 1; // 0x0400
|
||||
padding : 1; // 0x0800
|
||||
ACC_SYNTHETIC : 1; // 0x1000
|
||||
ACC_ANNOTATION : 1; // 0x2000
|
||||
ACC_ENUM : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
|
||||
struct attribute_info {
|
||||
u2 attribute_name_info;
|
||||
|
||||
u4 attribute_length;
|
||||
|
||||
u1 info[attribute_length];
|
||||
};
|
||||
|
||||
struct field_info {
|
||||
access_flags_field access_flags;
|
||||
u2 name_index;
|
||||
u2 descriptor_index;
|
||||
|
||||
u2 attribute_count;
|
||||
attribute_info attributes[attribute_count];
|
||||
};
|
||||
|
||||
struct method_info {
|
||||
access_flags_method access_flags;
|
||||
u2 name_index;
|
||||
u2 descriptor_index;
|
||||
u2 attributes_count;
|
||||
attribute_info attributes[attributes_count];
|
||||
};
|
||||
|
||||
struct ClassFile {
|
||||
u4 magic;
|
||||
|
||||
u2 minor_version;
|
||||
major_version major_version;
|
||||
|
||||
u2 constant_pool_count;
|
||||
cp_info constant_pool[constant_pool_count - 1];
|
||||
|
||||
access_flags_class access_flags;
|
||||
u2 this_class;
|
||||
u2 super_class;
|
||||
|
||||
u2 interfaces_count;
|
||||
u2 interfaces[interfaces_count];
|
||||
|
||||
u2 fields_count;
|
||||
field_info fields[fields_count];
|
||||
|
||||
u2 methods_count;
|
||||
method_info methods[methods_count];
|
||||
|
||||
u2 attribute_count;
|
||||
attribute_info attributes[attribute_count];
|
||||
};
|
||||
|
||||
ClassFile class_file @ 0x00;
|
||||
|
||||
fn main() {
|
||||
|
||||
std::assert(class_file.magic == 0xCAFEBABE, "File is not a valid Java Class file! Invalid header magic");
|
||||
|
||||
|
||||
std::print("Fields:");
|
||||
for (le u16 i = 0, i < class_file.fields_count, i = i + 1) {
|
||||
str method_string = " ";
|
||||
|
||||
if (class_file.fields[i].access_flags.ACC_PUBLIC)
|
||||
method_string = method_string + "public ";
|
||||
if (class_file.fields[i].access_flags.ACC_PRIVATE)
|
||||
method_string = method_string + "private ";
|
||||
if (class_file.fields[i].access_flags.ACC_PROTECTED)
|
||||
method_string = method_string + "protected ";
|
||||
if (class_file.fields[i].access_flags.ACC_STATIC)
|
||||
method_string = method_string + "static ";
|
||||
if (class_file.fields[i].access_flags.ACC_FINAL)
|
||||
method_string = method_string + "final ";
|
||||
if (class_file.fields[i].access_flags.ACC_VOLATILE)
|
||||
method_string = method_string + "volatile ";
|
||||
if (class_file.fields[i].access_flags.ACC_NATIVE)
|
||||
method_string = method_string + "native ";
|
||||
if (class_file.fields[i].access_flags.ACC_TRANSIENT)
|
||||
method_string = method_string + "transient ";
|
||||
if (class_file.fields[i].access_flags.ACC_ENUM)
|
||||
method_string = method_string + "enum ";
|
||||
|
||||
method_string = method_string + class_file.constant_pool[class_file.fields[i].name_index - 1].info.bytes;
|
||||
method_string = method_string + " [ " + class_file.constant_pool[class_file.fields[i].descriptor_index - 1].info.bytes + " ]";
|
||||
|
||||
std::print("{}", method_string);
|
||||
}
|
||||
|
||||
std::print("Methods:");
|
||||
for (le u16 i = 0, i < class_file.methods_count, i = i + 1) {
|
||||
str method_string = " ";
|
||||
|
||||
if (class_file.methods[i].access_flags.ACC_PUBLIC)
|
||||
method_string = method_string + "public ";
|
||||
if (class_file.methods[i].access_flags.ACC_PRIVATE)
|
||||
method_string = method_string + "private ";
|
||||
if (class_file.methods[i].access_flags.ACC_PROTECTED)
|
||||
method_string = method_string + "protected ";
|
||||
if (class_file.methods[i].access_flags.ACC_STATIC)
|
||||
method_string = method_string + "static ";
|
||||
if (class_file.methods[i].access_flags.ACC_FINAL)
|
||||
method_string = method_string + "final ";
|
||||
if (class_file.methods[i].access_flags.ACC_SYNCHRONIZED)
|
||||
method_string = method_string + "synchronized ";
|
||||
if (class_file.methods[i].access_flags.ACC_NATIVE)
|
||||
method_string = method_string + "native ";
|
||||
if (class_file.methods[i].access_flags.ACC_ABSTRACT)
|
||||
method_string = method_string + "abstract ";
|
||||
if (class_file.methods[i].access_flags.ACC_STRICT)
|
||||
method_string = method_string + "strictfp ";
|
||||
|
||||
method_string = method_string + class_file.constant_pool[class_file.methods[i].name_index - 1].info.bytes;
|
||||
method_string = method_string + " [ " + class_file.constant_pool[class_file.methods[i].descriptor_index - 1].info.bytes + " ]";
|
||||
|
||||
std::print("{}", method_string);
|
||||
}
|
||||
|
||||
std::print("Class Attributes:");
|
||||
for (le u16 i = 0, i < class_file.attribute_count, i = i + 1) {
|
||||
std::print(" {}", class_file.constant_pool[class_file.attributes[i].attribute_name_info - 1].info.bytes);
|
||||
}
|
||||
};
|
||||
@@ -1,205 +1,205 @@
|
||||
enum Model : u16 {
|
||||
NX = 1
|
||||
};
|
||||
|
||||
struct WlanCountryCode {
|
||||
char code[3];
|
||||
} [[static]];
|
||||
|
||||
struct Cert {
|
||||
u8 DeviceKey[0x30];
|
||||
padding[0x10];
|
||||
u8 DeviceCertificate[0x180];
|
||||
padding[0x10];
|
||||
} [[static]];
|
||||
|
||||
enum RegionCode : u32 {
|
||||
JPN = 0,
|
||||
USA = 1,
|
||||
EUR = 2,
|
||||
AUS = 3,
|
||||
CHN = 4,
|
||||
KOR = 5,
|
||||
HKG = 6
|
||||
};
|
||||
|
||||
enum ProductModel : u32 {
|
||||
Invalid = 0,
|
||||
NX = 1,
|
||||
Copper = 2,
|
||||
Iowa = 3,
|
||||
Hoag = 4,
|
||||
Calcio = 5,
|
||||
Aula = 6
|
||||
};
|
||||
|
||||
struct PRODINFO {
|
||||
char MagicNumber[4];
|
||||
u32 Version;
|
||||
u32 BodySize;
|
||||
Model Model;
|
||||
u16 UpdateCount;
|
||||
|
||||
padding[0x10];
|
||||
|
||||
u8 BodyHash[0x20];
|
||||
char ConfigurationId1[0x1E];
|
||||
|
||||
padding[0x02];
|
||||
padding[0x20];
|
||||
|
||||
u32 WlanCountryCodesNum;
|
||||
u32 WlanCountryCodesLastIndex;
|
||||
WlanCountryCode WlanCountryCodes[WlanCountryCodesNum];
|
||||
padding[0x180 - sizeof(WlanCountryCodes)];
|
||||
padding[0x08];
|
||||
u8 WlanMacAddress[6];
|
||||
padding[0x10 - 6];
|
||||
u8 BdAddress[6];
|
||||
|
||||
padding[0x10 - 6];
|
||||
|
||||
u8 AccelerometerOffset[6];
|
||||
padding[2];
|
||||
u8 AccelerometerScale[6];
|
||||
padding[2];
|
||||
u8 GyroscopeOffset[6];
|
||||
padding[2];
|
||||
u8 GyroscopeScale[6];
|
||||
padding[2];
|
||||
|
||||
char SerialNumber[0x18];
|
||||
|
||||
padding[8];
|
||||
|
||||
Cert EccP256Certificate;
|
||||
Cert EccB233Certificate;
|
||||
|
||||
Cert Ecc256ETicket;
|
||||
Cert Ecc233ETicket;
|
||||
|
||||
u8 SslKey[0x110];
|
||||
padding[0x10];
|
||||
u32 SslCertificateSize;
|
||||
padding[0x0C];
|
||||
u8 SslCertificate[0x800];
|
||||
u8 SslCertificateHash[0x20];
|
||||
|
||||
u8 RandomNumber[0x1000];
|
||||
u8 RandomNumberHash[0x20];
|
||||
|
||||
u8 GameCardKey[0x110];
|
||||
u8 GameCardCertificate[0x400];
|
||||
padding[0x10];
|
||||
u8 GameCardCertificateHash[0x20];
|
||||
|
||||
u8 Rsa2048ETicketKey[0x220];
|
||||
padding[0x10];
|
||||
u8 Rsa2048ETicketCertificate[0x240];
|
||||
|
||||
padding[0x10];
|
||||
|
||||
char BatteryLot[0x18];
|
||||
|
||||
padding[0x08];
|
||||
|
||||
u8 SpeakerCalibrationValue[0x800];
|
||||
|
||||
padding[0x10];
|
||||
|
||||
RegionCode RegionCode;
|
||||
|
||||
padding[0x0C];
|
||||
|
||||
u8 AmiiboKey[0x50];
|
||||
padding[0x10];
|
||||
u8 AmiiboEcqvCertificate[0x14];
|
||||
padding[0x0C];
|
||||
u8 AmiiboEcdsaCertificate[0x70];
|
||||
padding[0x10];
|
||||
u8 AmiiboEcqvBlsKey[0x40];
|
||||
padding[0x10];
|
||||
u8 AmiiboEcqvBlsCertificate[0x20];
|
||||
padding[0x10];
|
||||
u8 AmiiboEcqvBlsRootCertificate[0x90];
|
||||
|
||||
padding[0x10];
|
||||
|
||||
ProductModel ProductModel;
|
||||
|
||||
padding[0x0C];
|
||||
|
||||
u8 ColorVariation[6];
|
||||
|
||||
padding[0x0A];
|
||||
|
||||
u8 LcdBacklightBrightnessMapping[0x0C];
|
||||
|
||||
padding[0x04];
|
||||
|
||||
u8 ExtendedEccB233DeviceKey[0x50];
|
||||
padding[0x10];
|
||||
u8 ExtendedEccP256ETicketKey[0x50];
|
||||
padding[0x10];
|
||||
u8 ExtendedEccB233ETicketKey[0x50];
|
||||
padding[0x10];
|
||||
u8 ExtendedRsa2048ETicketKey[0x240];
|
||||
padding[0x10];
|
||||
u8 ExtendedSslKey[0x130];
|
||||
padding[0x10];
|
||||
u8 ExtendedGameCardKey[0x130];
|
||||
padding[0x10];
|
||||
u32 LcdVendorId;
|
||||
|
||||
padding[0x0C];
|
||||
|
||||
u8 ExtendedRsa2048DeviceKey[0x240];
|
||||
padding[0x10];
|
||||
u8 Rsa2048DeviceCertificate[0x240];
|
||||
|
||||
padding[0x10];
|
||||
|
||||
u8 UsbTypeCPowerSourceCircuitVersion;
|
||||
|
||||
padding[0x0F];
|
||||
|
||||
u32 HousingSubColor;
|
||||
padding[0x0C];
|
||||
u32 HousingBezelColor;
|
||||
padding[0x0C];
|
||||
u32 HousingMainColor1;
|
||||
padding[0x0C];
|
||||
u32 HousingMainColor2;
|
||||
padding[0x0C];
|
||||
u32 HousingMainColor3;
|
||||
|
||||
padding[0x0C];
|
||||
|
||||
u8 AnalogStickModuleTypeL;
|
||||
padding[0x0F];
|
||||
u8 AnalogStickModelParameterL[0x12];
|
||||
padding[0x0E];
|
||||
u8 AnalogStickFactoryCalibrationL[0x09];
|
||||
padding[0x07];
|
||||
u8 AnalogStickModuleTypeR;
|
||||
padding[0x0F];
|
||||
u8 AnalogStickModelParameterR[0x12];
|
||||
padding[0x0E];
|
||||
u8 AnalogStickFactoryCalibrationR[0x09];
|
||||
|
||||
padding[0x07];
|
||||
|
||||
u8 ConsoleSixAxisSensorModuleType;
|
||||
padding[0x0F];
|
||||
u8 ConsoleSixAxisSensorHorizontalOffset[6];
|
||||
padding[0x0A];
|
||||
u8 BatteryVersion;
|
||||
padding[0x0F];
|
||||
u8 TouchIcVendorId;
|
||||
padding[0x0F];
|
||||
u32 ColorModel;
|
||||
padding[0x0C];
|
||||
u8 ConsoleSixAxisSensorMountType;
|
||||
};
|
||||
|
||||
enum Model : u16 {
|
||||
NX = 1
|
||||
};
|
||||
|
||||
struct WlanCountryCode {
|
||||
char code[3];
|
||||
} [[static]];
|
||||
|
||||
struct Cert {
|
||||
u8 DeviceKey[0x30];
|
||||
padding[0x10];
|
||||
u8 DeviceCertificate[0x180];
|
||||
padding[0x10];
|
||||
} [[static]];
|
||||
|
||||
enum RegionCode : u32 {
|
||||
JPN = 0,
|
||||
USA = 1,
|
||||
EUR = 2,
|
||||
AUS = 3,
|
||||
CHN = 4,
|
||||
KOR = 5,
|
||||
HKG = 6
|
||||
};
|
||||
|
||||
enum ProductModel : u32 {
|
||||
Invalid = 0,
|
||||
NX = 1,
|
||||
Copper = 2,
|
||||
Iowa = 3,
|
||||
Hoag = 4,
|
||||
Calcio = 5,
|
||||
Aula = 6
|
||||
};
|
||||
|
||||
struct PRODINFO {
|
||||
char MagicNumber[4];
|
||||
u32 Version;
|
||||
u32 BodySize;
|
||||
Model Model;
|
||||
u16 UpdateCount;
|
||||
|
||||
padding[0x10];
|
||||
|
||||
u8 BodyHash[0x20];
|
||||
char ConfigurationId1[0x1E];
|
||||
|
||||
padding[0x02];
|
||||
padding[0x20];
|
||||
|
||||
u32 WlanCountryCodesNum;
|
||||
u32 WlanCountryCodesLastIndex;
|
||||
WlanCountryCode WlanCountryCodes[WlanCountryCodesNum];
|
||||
padding[0x180 - sizeof(WlanCountryCodes)];
|
||||
padding[0x08];
|
||||
u8 WlanMacAddress[6];
|
||||
padding[0x10 - 6];
|
||||
u8 BdAddress[6];
|
||||
|
||||
padding[0x10 - 6];
|
||||
|
||||
u8 AccelerometerOffset[6];
|
||||
padding[2];
|
||||
u8 AccelerometerScale[6];
|
||||
padding[2];
|
||||
u8 GyroscopeOffset[6];
|
||||
padding[2];
|
||||
u8 GyroscopeScale[6];
|
||||
padding[2];
|
||||
|
||||
char SerialNumber[0x18];
|
||||
|
||||
padding[8];
|
||||
|
||||
Cert EccP256Certificate;
|
||||
Cert EccB233Certificate;
|
||||
|
||||
Cert Ecc256ETicket;
|
||||
Cert Ecc233ETicket;
|
||||
|
||||
u8 SslKey[0x110];
|
||||
padding[0x10];
|
||||
u32 SslCertificateSize;
|
||||
padding[0x0C];
|
||||
u8 SslCertificate[0x800];
|
||||
u8 SslCertificateHash[0x20];
|
||||
|
||||
u8 RandomNumber[0x1000];
|
||||
u8 RandomNumberHash[0x20];
|
||||
|
||||
u8 GameCardKey[0x110];
|
||||
u8 GameCardCertificate[0x400];
|
||||
padding[0x10];
|
||||
u8 GameCardCertificateHash[0x20];
|
||||
|
||||
u8 Rsa2048ETicketKey[0x220];
|
||||
padding[0x10];
|
||||
u8 Rsa2048ETicketCertificate[0x240];
|
||||
|
||||
padding[0x10];
|
||||
|
||||
char BatteryLot[0x18];
|
||||
|
||||
padding[0x08];
|
||||
|
||||
u8 SpeakerCalibrationValue[0x800];
|
||||
|
||||
padding[0x10];
|
||||
|
||||
RegionCode RegionCode;
|
||||
|
||||
padding[0x0C];
|
||||
|
||||
u8 AmiiboKey[0x50];
|
||||
padding[0x10];
|
||||
u8 AmiiboEcqvCertificate[0x14];
|
||||
padding[0x0C];
|
||||
u8 AmiiboEcdsaCertificate[0x70];
|
||||
padding[0x10];
|
||||
u8 AmiiboEcqvBlsKey[0x40];
|
||||
padding[0x10];
|
||||
u8 AmiiboEcqvBlsCertificate[0x20];
|
||||
padding[0x10];
|
||||
u8 AmiiboEcqvBlsRootCertificate[0x90];
|
||||
|
||||
padding[0x10];
|
||||
|
||||
ProductModel ProductModel;
|
||||
|
||||
padding[0x0C];
|
||||
|
||||
u8 ColorVariation[6];
|
||||
|
||||
padding[0x0A];
|
||||
|
||||
u8 LcdBacklightBrightnessMapping[0x0C];
|
||||
|
||||
padding[0x04];
|
||||
|
||||
u8 ExtendedEccB233DeviceKey[0x50];
|
||||
padding[0x10];
|
||||
u8 ExtendedEccP256ETicketKey[0x50];
|
||||
padding[0x10];
|
||||
u8 ExtendedEccB233ETicketKey[0x50];
|
||||
padding[0x10];
|
||||
u8 ExtendedRsa2048ETicketKey[0x240];
|
||||
padding[0x10];
|
||||
u8 ExtendedSslKey[0x130];
|
||||
padding[0x10];
|
||||
u8 ExtendedGameCardKey[0x130];
|
||||
padding[0x10];
|
||||
u32 LcdVendorId;
|
||||
|
||||
padding[0x0C];
|
||||
|
||||
u8 ExtendedRsa2048DeviceKey[0x240];
|
||||
padding[0x10];
|
||||
u8 Rsa2048DeviceCertificate[0x240];
|
||||
|
||||
padding[0x10];
|
||||
|
||||
u8 UsbTypeCPowerSourceCircuitVersion;
|
||||
|
||||
padding[0x0F];
|
||||
|
||||
u32 HousingSubColor;
|
||||
padding[0x0C];
|
||||
u32 HousingBezelColor;
|
||||
padding[0x0C];
|
||||
u32 HousingMainColor1;
|
||||
padding[0x0C];
|
||||
u32 HousingMainColor2;
|
||||
padding[0x0C];
|
||||
u32 HousingMainColor3;
|
||||
|
||||
padding[0x0C];
|
||||
|
||||
u8 AnalogStickModuleTypeL;
|
||||
padding[0x0F];
|
||||
u8 AnalogStickModelParameterL[0x12];
|
||||
padding[0x0E];
|
||||
u8 AnalogStickFactoryCalibrationL[0x09];
|
||||
padding[0x07];
|
||||
u8 AnalogStickModuleTypeR;
|
||||
padding[0x0F];
|
||||
u8 AnalogStickModelParameterR[0x12];
|
||||
padding[0x0E];
|
||||
u8 AnalogStickFactoryCalibrationR[0x09];
|
||||
|
||||
padding[0x07];
|
||||
|
||||
u8 ConsoleSixAxisSensorModuleType;
|
||||
padding[0x0F];
|
||||
u8 ConsoleSixAxisSensorHorizontalOffset[6];
|
||||
padding[0x0A];
|
||||
u8 BatteryVersion;
|
||||
padding[0x0F];
|
||||
u8 TouchIcVendorId;
|
||||
padding[0x0F];
|
||||
u32 ColorModel;
|
||||
padding[0x0C];
|
||||
u8 ConsoleSixAxisSensorMountType;
|
||||
};
|
||||
|
||||
PRODINFO PRODINFO @ 0x00;
|
||||
@@ -1,98 +1,98 @@
|
||||
#include <std/sys.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
#pragma MIME application/microformats+json
|
||||
#pragma MIME application/microformats2+json
|
||||
#pragma MIME application/mf2+json
|
||||
#pragma MIME application/uf2+json
|
||||
|
||||
#pragma pattern_limit 100000
|
||||
|
||||
bitfield UF2_Flags {
|
||||
NotMainFlash : 1;
|
||||
padding : 11;
|
||||
FileContainer : 1;
|
||||
FamilyIDPresent : 1;
|
||||
MD5ChecksumPresent : 1;
|
||||
ExtensionTagsPresent : 1;
|
||||
padding : 16;
|
||||
};
|
||||
|
||||
struct UF2_Hash {
|
||||
u32 startAddress;
|
||||
u32 size;
|
||||
u8 md5Checksum[16];
|
||||
} [[static]];
|
||||
|
||||
struct UF2_TagType {
|
||||
u8 bytes[3];
|
||||
} [[format("formatTagType")]];
|
||||
|
||||
enum UF2_TagTypeEnum : u32 {
|
||||
FirmwareFileVersion = 0x9FC7BC,
|
||||
DeviceDescription = 0x650D9D,
|
||||
TargetPageSize = 0x0BE9F7,
|
||||
SHA1Checksum = 0xB46DB0,
|
||||
DeviceTypeIdentifier = 0xC8A729
|
||||
};
|
||||
|
||||
fn formatTagType(UF2_TagType type) {
|
||||
u32 value = (type.bytes[0] << 16) | (type.bytes[1] << 8) | (type.bytes[2]);
|
||||
|
||||
if (value == UF2_TagTypeEnum::FirmwareFileVersion)
|
||||
return "Firmware File Version";
|
||||
else if (value == UF2_TagTypeEnum::DeviceDescription)
|
||||
return "Device Description";
|
||||
else if (value == UF2_TagTypeEnum::TargetPageSize)
|
||||
return "Target Page Size";
|
||||
else if (value == UF2_TagTypeEnum::SHA1Checksum)
|
||||
return "SHA1 Checksum";
|
||||
else if (value == UF2_TagTypeEnum::DeviceTypeIdentifier)
|
||||
return "Device Type Identifier";
|
||||
else
|
||||
return "Custom Type";
|
||||
};
|
||||
|
||||
struct UF2_ExtensionTag {
|
||||
u8 size;
|
||||
UF2_TagType type;
|
||||
u8 data[size - 4];
|
||||
|
||||
if (size == 0 && type.bytes[0] == 0x00 && type.bytes[1] == 0x00 && type.bytes[2] == 0x00)
|
||||
break;
|
||||
};
|
||||
|
||||
struct UF2_Block {
|
||||
char magicStart0[4];
|
||||
u32 magicStart1;
|
||||
UF2_Flags flags;
|
||||
u32 targetAddr;
|
||||
u32 payloadSize;
|
||||
u32 blockNo;
|
||||
u32 numBlocks;
|
||||
|
||||
if (flags.FamilyIDPresent)
|
||||
u32 familyId;
|
||||
else
|
||||
u32 fileSize;
|
||||
|
||||
if (flags.MD5ChecksumPresent) {
|
||||
u8 data[452];
|
||||
UF2_Hash hash;
|
||||
}
|
||||
else {
|
||||
u8 data[476];
|
||||
}
|
||||
|
||||
if (flags.ExtensionTagsPresent) {
|
||||
UF2_ExtensionTag extensionTags[0xFF];
|
||||
}
|
||||
|
||||
u32 magicEnd;
|
||||
|
||||
std::assert(magicStart0 == "UF2\n", "Invalid magicStart0 value!");
|
||||
std::assert(magicStart1 == 0x9E5D5157, "Invalid magicStart1 value!");
|
||||
std::assert(magicEnd == 0x0AB16F30, "Invalid magicEnd value!");
|
||||
};
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
#pragma MIME application/microformats+json
|
||||
#pragma MIME application/microformats2+json
|
||||
#pragma MIME application/mf2+json
|
||||
#pragma MIME application/uf2+json
|
||||
|
||||
#pragma pattern_limit 100000
|
||||
|
||||
bitfield UF2_Flags {
|
||||
NotMainFlash : 1;
|
||||
padding : 11;
|
||||
FileContainer : 1;
|
||||
FamilyIDPresent : 1;
|
||||
MD5ChecksumPresent : 1;
|
||||
ExtensionTagsPresent : 1;
|
||||
padding : 16;
|
||||
};
|
||||
|
||||
struct UF2_Hash {
|
||||
u32 startAddress;
|
||||
u32 size;
|
||||
u8 md5Checksum[16];
|
||||
} [[static]];
|
||||
|
||||
struct UF2_TagType {
|
||||
u8 bytes[3];
|
||||
} [[format("formatTagType")]];
|
||||
|
||||
enum UF2_TagTypeEnum : u32 {
|
||||
FirmwareFileVersion = 0x9FC7BC,
|
||||
DeviceDescription = 0x650D9D,
|
||||
TargetPageSize = 0x0BE9F7,
|
||||
SHA1Checksum = 0xB46DB0,
|
||||
DeviceTypeIdentifier = 0xC8A729
|
||||
};
|
||||
|
||||
fn formatTagType(UF2_TagType type) {
|
||||
u32 value = (type.bytes[0] << 16) | (type.bytes[1] << 8) | (type.bytes[2]);
|
||||
|
||||
if (value == UF2_TagTypeEnum::FirmwareFileVersion)
|
||||
return "Firmware File Version";
|
||||
else if (value == UF2_TagTypeEnum::DeviceDescription)
|
||||
return "Device Description";
|
||||
else if (value == UF2_TagTypeEnum::TargetPageSize)
|
||||
return "Target Page Size";
|
||||
else if (value == UF2_TagTypeEnum::SHA1Checksum)
|
||||
return "SHA1 Checksum";
|
||||
else if (value == UF2_TagTypeEnum::DeviceTypeIdentifier)
|
||||
return "Device Type Identifier";
|
||||
else
|
||||
return "Custom Type";
|
||||
};
|
||||
|
||||
struct UF2_ExtensionTag {
|
||||
u8 size;
|
||||
UF2_TagType type;
|
||||
u8 data[size - 4];
|
||||
|
||||
if (size == 0 && type.bytes[0] == 0x00 && type.bytes[1] == 0x00 && type.bytes[2] == 0x00)
|
||||
break;
|
||||
};
|
||||
|
||||
struct UF2_Block {
|
||||
char magicStart0[4];
|
||||
u32 magicStart1;
|
||||
UF2_Flags flags;
|
||||
u32 targetAddr;
|
||||
u32 payloadSize;
|
||||
u32 blockNo;
|
||||
u32 numBlocks;
|
||||
|
||||
if (flags.FamilyIDPresent)
|
||||
u32 familyId;
|
||||
else
|
||||
u32 fileSize;
|
||||
|
||||
if (flags.MD5ChecksumPresent) {
|
||||
u8 data[452];
|
||||
UF2_Hash hash;
|
||||
}
|
||||
else {
|
||||
u8 data[476];
|
||||
}
|
||||
|
||||
if (flags.ExtensionTagsPresent) {
|
||||
UF2_ExtensionTag extensionTags[0xFF];
|
||||
}
|
||||
|
||||
u32 magicEnd;
|
||||
|
||||
std::assert(magicStart0 == "UF2\n", "Invalid magicStart0 value!");
|
||||
std::assert(magicStart1 == 0x9E5D5157, "Invalid magicStart1 value!");
|
||||
std::assert(magicEnd == 0x0AB16F30, "Invalid magicEnd value!");
|
||||
};
|
||||
|
||||
UF2_Block block[while(!std::mem::eof())] @ 0;
|
||||
@@ -1,36 +1,36 @@
|
||||
#pragma eval_depth 0x10000
|
||||
|
||||
#include <std/mem.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
enum Type : u8 {
|
||||
Set = 0x00,
|
||||
String = 0x01,
|
||||
Integer = 0x02,
|
||||
EndSet = 0x08
|
||||
};
|
||||
|
||||
struct Entry {
|
||||
Type type;
|
||||
|
||||
char name[];
|
||||
|
||||
if (type == Type::Set) {
|
||||
Entry entries[while (std::mem::read_unsigned($, 1) != Type::EndSet)];
|
||||
Type endSet [[hidden]];
|
||||
std::assert(endSet == Type::EndSet, "Invalid end of set byte!");
|
||||
}
|
||||
else if (type == Type::Integer)
|
||||
u32 value;
|
||||
else if (type == Type::String) {
|
||||
char value[];
|
||||
}
|
||||
};
|
||||
|
||||
struct Set {
|
||||
Entry entry [[inline]];
|
||||
Type endSet [[hidden]];
|
||||
std::assert(endSet == Type::EndSet, "Invalid end of set byte!");
|
||||
};
|
||||
|
||||
#pragma eval_depth 0x10000
|
||||
|
||||
#include <std/mem.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
enum Type : u8 {
|
||||
Set = 0x00,
|
||||
String = 0x01,
|
||||
Integer = 0x02,
|
||||
EndSet = 0x08
|
||||
};
|
||||
|
||||
struct Entry {
|
||||
Type type;
|
||||
|
||||
char name[];
|
||||
|
||||
if (type == Type::Set) {
|
||||
Entry entries[while (std::mem::read_unsigned($, 1) != Type::EndSet)];
|
||||
Type endSet [[hidden]];
|
||||
std::assert(endSet == Type::EndSet, "Invalid end of set byte!");
|
||||
}
|
||||
else if (type == Type::Integer)
|
||||
u32 value;
|
||||
else if (type == Type::String) {
|
||||
char value[];
|
||||
}
|
||||
};
|
||||
|
||||
struct Set {
|
||||
Entry entry [[inline]];
|
||||
Type endSet [[hidden]];
|
||||
std::assert(endSet == Type::EndSet, "Invalid end of set byte!");
|
||||
};
|
||||
|
||||
Set set[while (std::mem::read_unsigned($ - 1, 1) != Type::EndSet)] @ 0x00;
|
||||
Reference in New Issue
Block a user