mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
includes: Added pattern language standard library (#19)
* libstd: Initial standard library work bit operations, fixed point, numeric limits and math functions * libstd: Added ctype, rustint, stdint and string library, expand bit, fxpt and math library * patterns: Drastically improve ELF pattern * patterns: Added atmosphere AFE2 * patterns: tabs -> spaces * patterns: Added archive file pattern
This commit is contained in:
@@ -16,12 +16,14 @@ Hex patterns, include patterns and magic files for the use with the ImHex Hex Ed
|
||||
| ZIP | `application/zip` | `patterns/zip.hexpat` | End of Central Directory Header, Central Directory File Headers |
|
||||
| PCAP | `application/vnd.tcpdump.pcap` | `patterns/pcap.hexpat` | pcap header and packets |
|
||||
| SPIRV | | `patterns/spirv.hexpat` | SPIR-V header and instructions |
|
||||
| AFE2 | | `patterns/afe2.hexpat` | Nintendo Switch Atmosphère CFW Fatal Error log |
|
||||
| AR | `application/x-archive` | `patterns/ar.hexpat` | Static library archive files |
|
||||
|
||||
### Pattern Libraries
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| cstdint | `includes/cstdint.hexpat` | C standard style fixed width integer types |
|
||||
| libstd | `includes/libstd/*` | Pattern Language Standard Libaray |
|
||||
|
||||
### Magic files
|
||||
|
||||
|
||||
35
includes/libstd/bit.pat
Normal file
35
includes/libstd/bit.pat
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace std::bit {
|
||||
|
||||
fn popcount(u128 x) {
|
||||
x = (x & (std::limits::u128_max() / 3)) + ((x >> 1) & (std::limits::u128_max() / 3));
|
||||
x = (x & (std::limits::u128_max() / 5)) + ((x >> 2) & (std::limits::u128_max() / 5));
|
||||
x = (x & (std::limits::u128_max() / 17)) + ((x >> 4) & (std::limits::u128_max() / 17));
|
||||
|
||||
return x % 0xFF;
|
||||
};
|
||||
|
||||
fn has_single_bit(u128 x) {
|
||||
return x != 0 && (x & (x - 1)) == 0;
|
||||
};
|
||||
|
||||
fn bit_ceil(u128 x) {
|
||||
if (x == 0) return 0;
|
||||
|
||||
u8 i;
|
||||
while ((1 << i) < x)
|
||||
i = i + 1;
|
||||
|
||||
return 1 << i;
|
||||
};
|
||||
|
||||
fn bit_floor(u128 x) {
|
||||
if (x == 0) return 0;
|
||||
|
||||
u8 i;
|
||||
while ((x >> i) > 0)
|
||||
i = i + 1;
|
||||
|
||||
return 1 << (i - 1);
|
||||
};
|
||||
|
||||
}
|
||||
51
includes/libstd/ctype.pat
Normal file
51
includes/libstd/ctype.pat
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace std::ctype {
|
||||
|
||||
fn isdigit(char c) {
|
||||
return c >= '0' && c <= '9';
|
||||
};
|
||||
|
||||
fn isxdigit(char c) {
|
||||
return std::ctype::isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
|
||||
};
|
||||
|
||||
fn isupper(char c) {
|
||||
return c >= 'A' && c <= 'Z';
|
||||
};
|
||||
|
||||
fn islower(char c) {
|
||||
return c >= 'a' && c <= 'z';
|
||||
};
|
||||
|
||||
fn isalpha(char c) {
|
||||
return std::ctype::isupper(c) || std::ctype::islower(c);
|
||||
};
|
||||
|
||||
fn isalnum(char c) {
|
||||
return std::ctype::isalpha(c) || std::ctype::isdigit(c);
|
||||
};
|
||||
|
||||
fn isspace(char c) {
|
||||
return (c >= 0x09 && c <= 0x0D) || c == 0x20;
|
||||
};
|
||||
|
||||
fn isblank(char c) {
|
||||
return c == 0x09 || c == ' ';
|
||||
};
|
||||
|
||||
fn isprint(char c) {
|
||||
return c >= '0' && c <= '~';
|
||||
};
|
||||
|
||||
fn iscntrl(char c) {
|
||||
return !std::ctype::isprint(c);
|
||||
};
|
||||
|
||||
fn isgraph(char c) {
|
||||
return std::ctype::isprint(c) && !std::ctype::isspace(c);
|
||||
};
|
||||
|
||||
fn isgraph(char c) {
|
||||
return std::ctype::isgraph(c) && !std::ctype::isalnum(c);
|
||||
};
|
||||
|
||||
}
|
||||
29
includes/libstd/fxpt.pat
Normal file
29
includes/libstd/fxpt.pat
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace std::fxpt {
|
||||
|
||||
using fixed = s128;
|
||||
|
||||
fn to_float(fixed fxt, u32 precision) {
|
||||
return double(fxt) / double((1 << precision));
|
||||
};
|
||||
|
||||
fn to_fixed(double flt, u32 precision) {
|
||||
return fixed((flt * (1 << precision)));
|
||||
};
|
||||
|
||||
fn add(fixed a, fixed b, u32 precision) {
|
||||
return a + b;
|
||||
};
|
||||
|
||||
fn subtract(fixed a, fixed b, u32 precision) {
|
||||
return a - b;
|
||||
};
|
||||
|
||||
fn multiply(fixed a, fixed b, u32 precision) {
|
||||
return (a * b) / (1 << precision);
|
||||
};
|
||||
|
||||
fn divide(fixed a, fixed b, u32 precision) {
|
||||
return (a << precision) / b;
|
||||
};
|
||||
|
||||
}
|
||||
83
includes/libstd/limits.pat
Normal file
83
includes/libstd/limits.pat
Normal file
@@ -0,0 +1,83 @@
|
||||
namespace std::limits {
|
||||
|
||||
fn u8_min() {
|
||||
return u8(0);
|
||||
};
|
||||
|
||||
fn u8_max() {
|
||||
return u8(-1);
|
||||
};
|
||||
|
||||
fn s8_min() {
|
||||
return -s8((std::limits::u8_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
fn s8_max() {
|
||||
return s8((u8_max() / 2));
|
||||
};
|
||||
|
||||
fn u16_min() {
|
||||
return u16(0);
|
||||
};
|
||||
|
||||
fn u16_max() {
|
||||
return u16(-1);
|
||||
};
|
||||
|
||||
fn s16_min() {
|
||||
return -s16((std::limits::u16_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
fn s16_max() {
|
||||
return s16((u16_max() / 2));
|
||||
};
|
||||
|
||||
fn u32_min() {
|
||||
return u32(0);
|
||||
};
|
||||
|
||||
fn u32_max() {
|
||||
return u32(-1);
|
||||
};
|
||||
|
||||
fn s32_min() {
|
||||
return -s32((std::limits::u32_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
fn s32_max() {
|
||||
return s32((u32_max() / 2));
|
||||
};
|
||||
|
||||
fn u64_min() {
|
||||
return u64(0);
|
||||
};
|
||||
|
||||
fn u64_max() {
|
||||
return u64(-1);
|
||||
};
|
||||
|
||||
fn s64_min() {
|
||||
return -s64((std::limits::u64_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
fn s64_max() {
|
||||
return s64((u64_max() / 2));
|
||||
};
|
||||
|
||||
fn u128_min() {
|
||||
return u128(0);
|
||||
};
|
||||
|
||||
fn u128_max() {
|
||||
return u128(-1);
|
||||
};
|
||||
|
||||
fn s128_min() {
|
||||
return -s128((std::limits::u128_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
fn s128_max() {
|
||||
return s128((u128_max() / 2));
|
||||
};
|
||||
|
||||
}
|
||||
20
includes/libstd/math.pat
Normal file
20
includes/libstd/math.pat
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace std::math {
|
||||
|
||||
fn min(auto a, auto b) {
|
||||
return a < b ? a : b;
|
||||
};
|
||||
|
||||
fn max(auto a, auto b) {
|
||||
return a > b ? a : b;
|
||||
};
|
||||
|
||||
fn clamp(auto x, auto min, auto max) {
|
||||
return (x < min) ? min : ((x > max) ? max : x);
|
||||
};
|
||||
|
||||
fn abs(auto x) {
|
||||
if (x < 0) return -x;
|
||||
else return x;
|
||||
};
|
||||
|
||||
}
|
||||
14
includes/libstd/rustint.pat
Normal file
14
includes/libstd/rustint.pat
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace std {
|
||||
|
||||
using i8 = s8;
|
||||
using i16 = s16;
|
||||
using i32 = s32;
|
||||
using i64 = s64;
|
||||
using i128 = s128;
|
||||
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
|
||||
using usize = u64;
|
||||
using isize = s64;
|
||||
}
|
||||
21
includes/libstd/stdint.pat
Normal file
21
includes/libstd/stdint.pat
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace std {
|
||||
|
||||
using uint8_t = u8;
|
||||
using uint16_t = u16;
|
||||
using uint32_t = u32;
|
||||
using uint64_t = u64;
|
||||
using uint128_t = u128;
|
||||
|
||||
using int8_t = s8;
|
||||
using int16_t = s16;
|
||||
using int32_t = s32;
|
||||
using int64_t = s64;
|
||||
using int128_t = s128;
|
||||
|
||||
using float32_t = float;
|
||||
using float64_t = double;
|
||||
|
||||
using size_t = u64;
|
||||
using ssize_t = s64;
|
||||
|
||||
}
|
||||
30
includes/libstd/string.pat
Normal file
30
includes/libstd/string.pat
Normal file
@@ -0,0 +1,30 @@
|
||||
namespace std::string {
|
||||
|
||||
fn to_string(auto x) {
|
||||
return std::format("{}", x);
|
||||
};
|
||||
|
||||
fn starts_with(str string, str part) {
|
||||
return std::string::substr(string, 0, std::string::length(part)) == part;
|
||||
};
|
||||
|
||||
fn ends_with(str string, str part) {
|
||||
return std::string::substr(string, std::string::length(string) - std::string::length(part), std::string::length(part)) == part;
|
||||
};
|
||||
|
||||
fn contains(str a, str b) {
|
||||
s32 a_len, b_len;
|
||||
a_len = std::string::length(a);
|
||||
b_len = std::string::length(b);
|
||||
|
||||
s32 i;
|
||||
while (i < a_len - b_len) {
|
||||
if (std::string::substr(a, i, b_len) == b)
|
||||
return true;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
}
|
||||
55
patterns/afe2.hexpat
Normal file
55
patterns/afe2.hexpat
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma endian little
|
||||
|
||||
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC "AFE2"
|
||||
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 "AFE1"
|
||||
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0 "AFE0"
|
||||
|
||||
#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20
|
||||
#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100
|
||||
#define AMS_FATAL_ERROR_TLS_SIZE 0x100
|
||||
|
||||
struct gprs_named {
|
||||
u64 gprs[29];
|
||||
u64 fp;
|
||||
u64 lr;
|
||||
u64 sp;
|
||||
};
|
||||
|
||||
union gprs {
|
||||
u64 gprs[32];
|
||||
gprs_named named;
|
||||
};
|
||||
|
||||
struct atmosphere_fatal_error_ctx {
|
||||
char magic[4];
|
||||
u32 error_desc;
|
||||
u64 program_id;
|
||||
gprs gprs;
|
||||
u64 pc;
|
||||
u64 module_base;
|
||||
u32 pstate;
|
||||
u32 afsr0;
|
||||
u32 afsr1;
|
||||
u32 esr;
|
||||
u64 far;
|
||||
u64 report_identifier; /* Normally just system tick */
|
||||
u64 stack_trace_size;
|
||||
u64 stack_dump_size;
|
||||
u64 stack_trace[AMS_FATAL_ERROR_MAX_STACKTRACE];
|
||||
u8 stack_dump[AMS_FATAL_ERROR_MAX_STACKDUMP];
|
||||
u8 tls[AMS_FATAL_ERROR_TLS_SIZE];
|
||||
};
|
||||
|
||||
atmosphere_fatal_error_ctx ctx @ 0x00;
|
||||
|
||||
std::assert(ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC ||
|
||||
ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 ||
|
||||
ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0,
|
||||
"File is not a valid Atmosphere fatal error binary!");
|
||||
|
||||
std::assert_warn(ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC,
|
||||
"Atmosphere fatal error binary is for an older version!");
|
||||
|
||||
|
||||
std::print("Error Description: 0x{:04X}", ctx.error_desc);
|
||||
std::print("Program ID: {:016X}", ctx.program_id);
|
||||
21
patterns/ar.hexpat
Normal file
21
patterns/ar.hexpat
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma MIME application/x-archive
|
||||
|
||||
struct ARFile {
|
||||
char file_name[16];
|
||||
char modification_timestamp[12];
|
||||
char owner_id[6];
|
||||
char group_id[6];
|
||||
char file_mode[8];
|
||||
char file_size[10];
|
||||
u16 end_marker;
|
||||
|
||||
if (end_marker == 0x0A60) {
|
||||
u8 data[std::string::parse_int(this.file_size, 10)];
|
||||
padding[sizeof(data) & 1];
|
||||
}
|
||||
} [[static]];
|
||||
|
||||
char signature[8] @ 0x00;
|
||||
std::assert(signature == "!<arch>\n", "File is not a valid archive!");
|
||||
|
||||
ARFile files[while($ < std::mem::size())] @ $;
|
||||
@@ -1,52 +1,261 @@
|
||||
#pragma MIME application/x-executable
|
||||
#pragma MIME application/x-sharedlib
|
||||
|
||||
#define EI_NIDENT 16
|
||||
namespace elf {
|
||||
|
||||
using Elf32_Addr = u32;
|
||||
using Elf32_Half = u16;
|
||||
using Elf32_Off = u32;
|
||||
using Elf32_Sword = s32;
|
||||
using Elf32_Word = u32;
|
||||
enum Class : u8 {
|
||||
_32Bit = 1,
|
||||
_64Bit = 2
|
||||
};
|
||||
|
||||
enum Endian : u8 {
|
||||
Little = 1,
|
||||
Big = 2
|
||||
};
|
||||
|
||||
enum OSABI : u8 {
|
||||
SystemV = 0x00,
|
||||
HP_UX = 0x01,
|
||||
NetBSD = 0x02,
|
||||
Linux = 0x03,
|
||||
GNU_Hurd = 0x04,
|
||||
Solaris = 0x06,
|
||||
AIX = 0x07,
|
||||
IRIX = 0x08,
|
||||
FreeBSD = 0x09,
|
||||
Tru64 = 0x0A,
|
||||
NovellModesto = 0x0B,
|
||||
OpenBSD = 0x0C,
|
||||
OpenVMS = 0x0D,
|
||||
NonStop_Kernel = 0x0E,
|
||||
AROS = 0x0F,
|
||||
FenixOS = 0x10,
|
||||
CloudABI = 0x11,
|
||||
Stratus_Technologies_OpenVOS = 0x12
|
||||
};
|
||||
|
||||
enum Type : u16 {
|
||||
NONE = 0x00,
|
||||
REL = 0x01,
|
||||
EXEC = 0x02,
|
||||
DYN = 0x03,
|
||||
CORE = 0x04,
|
||||
LOOS = 0xFE00,
|
||||
HIOS = 0xFEFF,
|
||||
LOPROC = 0xFF00,
|
||||
HIPROC = 0xFFFF
|
||||
};
|
||||
|
||||
enum Machine : u16 {
|
||||
Undefined = 0x00,
|
||||
ATNT_WE_32100 = 0x01,
|
||||
SPARC = 0x02,
|
||||
x86 = 0x03,
|
||||
Motorola_68000 = 0x04,
|
||||
Motorola_88000 = 0x05,
|
||||
IntelMCU = 0x06,
|
||||
Intel_80860 = 0x07,
|
||||
MIPS = 0x08,
|
||||
IBM_System370 = 0x09,
|
||||
MIPS_RS300_LE = 0x0A,
|
||||
/* 0x0B - 0x0D: Reserved */
|
||||
HP_PA_RISC = 0x0E,
|
||||
/* 0x0F: Reserved */
|
||||
Intel_80960 = 0x13,
|
||||
PowerPC = 0x14,
|
||||
PowerPC_64 = 0x15,
|
||||
S390 = 0x16,
|
||||
IBM_SPU_SPC = 0x17,
|
||||
/* 0x18 - 0x23: Reserved */
|
||||
NEC_V800 = 0x24,
|
||||
Fujitsu_FR20 = 0x25,
|
||||
TRW_RH_32 = 0x26,
|
||||
Motorola_RCE = 0x27,
|
||||
ARM32 = 0x28,
|
||||
Digital_Alpha = 0x29,
|
||||
SuperH = 0x2A,
|
||||
SPARCv9 = 0x2B,
|
||||
Siemens_TriCore = 0x2C,
|
||||
Argonaut_RISC_Core = 0x2D,
|
||||
Hitachi_H8_300 = 0x2E,
|
||||
Hitachi_H8_300H = 0x2F,
|
||||
Hitachi_H8S = 0x30,
|
||||
Hitachi_H8_500 = 0x31,
|
||||
IA_64 = 0x32,
|
||||
Standford_MIPS_X = 0x33,
|
||||
Motorola_ColdFire = 0x34,
|
||||
Motorola_M68HC12 = 0x35,
|
||||
Fujitsu_MMA = 0x36,
|
||||
Siemens_PCP = 0x37,
|
||||
Sony_nCPU = 0x38,
|
||||
Denso_NDR1 = 0x39,
|
||||
Motorola_StarCore = 0x3A,
|
||||
Toyota_ME16 = 0x3B,
|
||||
STMicroelectronics_ST100 = 0x3C,
|
||||
Advanced_Logic_Corp_TinyJ = 0x3D,
|
||||
AMD_x86_64 = 0x3E,
|
||||
TMS320C6000 = 0x8C,
|
||||
MCST_Elbrus_e2k = 0xAF,
|
||||
ARM64 = 0xB7,
|
||||
RISC_V = 0xF3,
|
||||
Berkeley_Packet_Filter = 0xF7,
|
||||
WDC_65C816 = 0x101
|
||||
};
|
||||
|
||||
struct Identity {
|
||||
char magic[4];
|
||||
Class class;
|
||||
Endian endian;
|
||||
u8 version;
|
||||
OSABI os_abi;
|
||||
|
||||
if (os_abi == elf::OSABI::Linux)
|
||||
u8 dynamic_linker_version;
|
||||
else
|
||||
u8 abi_version;
|
||||
};
|
||||
|
||||
using Elf64_Addr = u64;
|
||||
using Elf64_Half = u16;
|
||||
using Elf64_Off = u64;
|
||||
using Elf64_Sword = s32;
|
||||
using Elf64_Word = u32;
|
||||
struct Header {
|
||||
Identity identity;
|
||||
padding[7];
|
||||
Type type;
|
||||
Machine machine;
|
||||
u32 version;
|
||||
|
||||
if (identity.class == elf::Class::_32Bit) {
|
||||
u32 entry_point;
|
||||
u32 program_header_offset;
|
||||
u32 section_header_offset;
|
||||
} else {
|
||||
u64 entry_point;
|
||||
u64 program_header_offset;
|
||||
u64 section_header_offset;
|
||||
}
|
||||
|
||||
u32 flags;
|
||||
|
||||
u16 elf_header_size;
|
||||
u16 program_header_entry_size;
|
||||
u16 program_header_entry_count;
|
||||
u16 section_header_entry_size;
|
||||
u16 section_header_entry_count;
|
||||
u16 section_name_entry_id;
|
||||
};
|
||||
|
||||
struct Elf32_Ehdr {
|
||||
u8 e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
};
|
||||
}
|
||||
|
||||
struct Elf64_Ehdr {
|
||||
u8 e_ident[EI_NIDENT];
|
||||
Elf64_Half e_type;
|
||||
Elf64_Half e_machine;
|
||||
Elf64_Word e_version;
|
||||
Elf64_Addr e_entry;
|
||||
Elf64_Off e_phoff;
|
||||
Elf64_Off e_shoff;
|
||||
Elf64_Word e_flags;
|
||||
Elf64_Half e_ehsize;
|
||||
Elf64_Half e_phentsize;
|
||||
Elf64_Half e_phnum;
|
||||
Elf64_Half e_shentsize;
|
||||
Elf64_Half e_shnum;
|
||||
Elf64_Half e_shstrndx;
|
||||
};
|
||||
namespace program {
|
||||
|
||||
Elf64_Ehdr header @ 0x00;
|
||||
enum Type : u32 {
|
||||
NULL = 0x00,
|
||||
LOAD = 0x01,
|
||||
DYNAMIC = 0x02,
|
||||
INTERP = 0x03,
|
||||
NOTE = 0x04,
|
||||
SHLIB = 0x05,
|
||||
PHDR = 0x06,
|
||||
TLS = 0x07,
|
||||
LOOS = 0x60000000,
|
||||
HIOS = 0x6FFFFFFF,
|
||||
LOPROC = 0x70000000,
|
||||
HIPROC = 0x7FFFFFFF
|
||||
};
|
||||
|
||||
struct Header {
|
||||
Type type;
|
||||
|
||||
if (parent.header.identity.class == elf::Class::_32Bit) {
|
||||
u32 offset;
|
||||
u32 virtual_address;
|
||||
u32 physical_address;
|
||||
u32 file_size;
|
||||
u32 memory_size;
|
||||
u32 flags;
|
||||
u32 alignment;
|
||||
} else {
|
||||
u32 flags;
|
||||
u64 offset;
|
||||
u64 virtual_address;
|
||||
u64 physical_address;
|
||||
u64 file_size;
|
||||
u64 memory_size;
|
||||
u64 alignment;
|
||||
}
|
||||
} [[static]];
|
||||
|
||||
}
|
||||
|
||||
namespace section {
|
||||
|
||||
struct String {
|
||||
char characters[];
|
||||
};
|
||||
|
||||
enum Type : u32 {
|
||||
NULL = 0x00,
|
||||
PROGBITS = 0x01,
|
||||
SYMTAB = 0x02,
|
||||
STRTAB = 0x03,
|
||||
RELA = 0x04,
|
||||
HASH = 0x05,
|
||||
DYNAMIC = 0x06,
|
||||
NOTE = 0x07,
|
||||
NOBITS = 0x08,
|
||||
REL = 0x09,
|
||||
SHLIB = 0x0A,
|
||||
DYNSYM = 0x0B,
|
||||
INIT_ARRAY = 0x0E,
|
||||
FINI_ARRAY = 0x0F,
|
||||
PREINIT_ARRAY = 0x10,
|
||||
GROUP = 0x11,
|
||||
SYMTAB_SHNDX = 0x12,
|
||||
NUM = 0x13,
|
||||
LOOS = 0x60000000
|
||||
};
|
||||
|
||||
bitfield Flags {
|
||||
WRITE : 1;
|
||||
ALLOC : 1;
|
||||
EXECINSTR : 1;
|
||||
pad1 : 1;
|
||||
MERGE : 1;
|
||||
STRINGS : 1;
|
||||
INFO_LINK : 1;
|
||||
LINK_ORDER : 1;
|
||||
OS_NONCONFORMING : 1;
|
||||
GROUP : 1;
|
||||
TLS : 1;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
u32 name_offset;
|
||||
section::Type type;
|
||||
Flags flags;
|
||||
padding[2];
|
||||
|
||||
if (parent.header.identity.class == elf::Class::_32Bit) {
|
||||
u32 address;
|
||||
u32 offset;
|
||||
u32 size;
|
||||
u32 link;
|
||||
u32 info;
|
||||
u32 address_alignment;
|
||||
u32 entry_size;
|
||||
} else {
|
||||
padding[4];
|
||||
u64 address;
|
||||
u64 offset;
|
||||
u64 size;
|
||||
u32 link;
|
||||
u32 info;
|
||||
u64 address_alignment;
|
||||
u64 entry_size;
|
||||
}
|
||||
} [[static]];
|
||||
|
||||
}
|
||||
|
||||
|
||||
elf::Header header @ 0x00;
|
||||
program::Header program_headers[header.program_header_entry_count] @ header.program_header_offset;
|
||||
section::Header section_headers[header.section_header_entry_count] @ header.section_header_offset;
|
||||
Reference in New Issue
Block a user