major version 1.0 (actual)

main
Allen Webster 2026-06-29 17:28:46 -07:00
parent 32ce56df78
commit cba79b611e
9 changed files with 2 additions and 9773 deletions

View File

@ -2,9 +2,9 @@
code=$PWD
opts=-Wno-switch
inc="-I$code/ld_meta/mr4th"
inc="-I$code/symbol_set.ld_meta/mr4th"
mkdir -p build
cd build
clang -o symbol_set.ld_meta "$code/ld_meta/symbol_set.ld_meta.c" $opts $inc
clang -o symbol_set.ld_meta "$code/symbol_set.ld_meta/symbol_set.ld_meta.c" $opts $inc

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,294 +0,0 @@
////////////////////////////////
// Functions: Command Line Parsing
MR4TH_SYMBOL MR4TH_READ_ONLY
CMDLN_Params cmdln__params_nil = {0};
#define cmdln_params_nil (CMDLN_Params*)(&cmdln__params_nil)
MR4TH_SYMBOL CMDLN*
cmdln_from_args(Arena *arena, String8List *args){
CMDLN *cmdln = push_array(arena, CMDLN, 1);
cmdln->raw = str8_list_copy(arena, args);
String8Node *node = cmdln->raw.first;
// first string is 'program'
if (node != 0){
cmdln->program = node->string;
node = node->next;
}
// consume string nodes
B32 forced_input = 0;
for (;node != 0;){
String8 string = str8_skip_chop_whitespace(node->string);
node = node->next;
// check if argument is a flag
B32 is_flag = 0;
if (!forced_input){
is_flag = (string.size != 0 && string.str[0] == '-');
}
// parse flag
if (is_flag){
// long flag
B32 is_long_flag = (string.size > 1 && string.str[1] == '-');
if (is_long_flag){
// end 'normal' mode
B32 double_dash = (string.size == 2);
if (double_dash){
forced_input = 1;
}
// parse long flag
if (!double_dash){
String8 flag_whole = str8_skip(string, 2);
// parameter delimter
U64 delim = flag_whole.size;
for (U8 *ptr = flag_whole.str, *opl = flag_whole.str + flag_whole.size;
ptr < opl; ptr += 1){
if (*ptr == '=' || *ptr == ':'){
delim = (U64)(ptr - flag_whole.str);
break;
}
}
// split flag at delimiter
String8 flag_name = str8_prefix(flag_whole, delim);
String8 flag_param = str8_skip(flag_whole, delim + 1);
// if have a param delimiter at end
// then use the next argument as the flag_param
if (delim == flag_whole.size - 1){
if (node != 0){
flag_param = node->string;
node = node->next;
}
}
// parse parameters
CMDLN_Params *params = cmdln_params_from_string(arena, flag_param);
// store flag node
{
CMDLN_Node *cmdlnnode = push_array(arena, CMDLN_Node, 1);
SLLQueuePush(cmdln->first, cmdln->last, cmdlnnode);
cmdlnnode->string = flag_name;
cmdlnnode->params = params;
cmdln->flag_count += 1;
}
}
}
// short flags
if (!is_long_flag){
String8 short_flags = str8_skip(string, 1);
U8 *flag = short_flags.str;
U8 *flagopl = short_flags.str + short_flags.size;
for (; flag < flagopl; flag += 1){
U8 *flagptr = flag;
// check for parameters
String8 flag_param = {0};
if (flag + 1 < flagopl &&
(flag[1] == '=' || flag[1] == ':')){
flag_param = str8_range(flag + 2, flagopl);
if (flag_param.size == 0){
if (node != 0){
flag_param = node->string;
node = node->next;
}
}
// kill the flag loop after finding parameters
flag = flagopl;
}
// parse parameters
CMDLN_Params *params = cmdln_params_from_string(arena, flag_param);
// store flag node
{
CMDLN_Node *cmdlnnode = push_array(arena, CMDLN_Node, 1);
SLLQueuePush(cmdln->first, cmdln->last, cmdlnnode);
cmdlnnode->string = str8(flagptr, 1);
cmdlnnode->params = params;
cmdln->flag_count += 1;
}
}
}
}
// parse input
if (!is_flag){
String8 input_string = string;
// store input node
{
CMDLN_Node *cmdlnnode = push_array(arena, CMDLN_Node, 1);
SLLQueuePush(cmdln->first, cmdln->last, cmdlnnode);
cmdlnnode->string = input_string;
cmdln->input_count += 1;
}
}
}
// pointer arrays
cmdln->inputs = push_array(arena, CMDLN_Node*, cmdln->input_count);
cmdln->flags = push_array(arena, CMDLN_Node*, cmdln->flag_count);
{
CMDLN_Node **inputptr = cmdln->inputs;
CMDLN_Node **flagptr = cmdln->flags;
for (CMDLN_Node *node = cmdln->first;
node != 0;
node = node->next){
if (node->params == 0){
*inputptr = node;
inputptr += 1;
}
else{
*flagptr = node;
flagptr += 1;
}
}
}
return(cmdln);
}
MR4TH_SYMBOL CMDLN_Params*
cmdln_params_from_string(Arena *arena, String8 flag_param){
CMDLN_Params *params = cmdln_params_nil;
if (flag_param.size > 0){
params = push_array(arena, CMDLN_Params, 1);
params->raw = flag_param;
params->list = str8_split(arena, flag_param, (U8*)",", 1);
}
return(params);
}
MR4TH_SYMBOL U64
cmdln_input_count(CMDLN *cmdln){
return(cmdln->input_count);
}
MR4TH_SYMBOL String8
cmdln_input_from_idx(CMDLN *cmdln, U64 idx){
String8 result = {0};
if (idx < cmdln->input_count){
result = cmdln->inputs[idx]->string;
}
return(result);
}
MR4TH_SYMBOL U64
cmdln_flag_count(CMDLN *cmdln){
return(cmdln->flag_count);
}
MR4TH_SYMBOL CMDLN_Flag*
cmdln_flag_from_idx(CMDLN *cmdln, U64 idx){
CMDLN_Flag *result = 0;
if (idx < cmdln->flag_count){
result = cmdln->flags[idx];
}
return(result);
}
MR4TH_SYMBOL CMDLN_Params*
cmdln_get_params(CMDLN *cmdln, String8 flagstr, char abbrev){
CMDLN_Params *result = 0;
for (CMDLN_Node *node = cmdln->first;
node != 0;
node = node->next){
if (node->params != 0){
if (str8_match(flagstr, node->string, 0) ||
(node->string.size == 1 && node->string.str[0] == (U8)abbrev)){
result = node->params;
break;
}
}
}
return(result);
}
MR4TH_SYMBOL B32
cmdln_has_flag(CMDLN *cmdln, String8 flagstr, char abbrev){
CMDLN_Params *params = cmdln_get_params(cmdln, flagstr, abbrev);
B32 result = (params != 0);
return(result);
}
MR4TH_SYMBOL String8
cmdln_get_str8(CMDLN *cmdln, String8 flagstr, char abbrev){
CMDLN_Params *params = cmdln_get_params(cmdln, flagstr, abbrev);
String8 result = {0};
if (params != 0){
result = params->raw;
}
return(result);
}
MR4TH_SYMBOL S64
cmdln_get_s64(CMDLN *cmdln, String8 flagstr, char abbrev){
String8 str = cmdln_get_str8(cmdln, flagstr, abbrev);
S64 result = cmdln_s64_from_str8(str);
return(result);
}
MR4TH_SYMBOL F64
cmdln_get_f64(CMDLN *cmdln, String8 flagstr, char abbrev){
String8 str = cmdln_get_str8(cmdln, flagstr, abbrev);
F64 result = cmdln_f64_from_str8(str);
return(result);
}
MR4TH_SYMBOL S64
cmdln_s64_from_str8(String8 valstr){
S64 result = s64_from_str8_c_syntax(valstr);
return(result);
}
MR4TH_SYMBOL F64
cmdln_f64_from_str8(String8 valstr){
F64 result = f64_from_str8(valstr);
return(result);
}
MR4TH_SYMBOL void
cmdln_dump(Arena *arena, String8List *out, CMDLN *cmdln, U32 indent){
// raw
str8_list_pushf(arena, out, "%Nraw:\n", indent);
for (String8Node *node = cmdln->raw.first;
node != 0;
node = node->next){
str8_list_pushf(arena, out, "%N%S\n", indent + 1, node->string);
}
// program
str8_list_pushf(arena, out, "%Nprogram: %S\n", indent, cmdln->program);
// input nodes
str8_list_pushf(arena, out, "%Nnodes:\n", indent);
for (CMDLN_Node *cmdlnnode = cmdln->first;
cmdlnnode != 0;
cmdlnnode = cmdlnnode->next){
if (cmdlnnode->params == 0){
str8_list_pushf(arena, out, "%N[input] %S\n", indent + 1, cmdlnnode->string);
}
else{
str8_list_pushf(arena, out, "%N[flag ] %S\n", indent + 1, cmdlnnode->string);
for (String8Node *node = cmdlnnode->params->list.first;
node != 0;
node = node->next){
str8_list_pushf(arena, out, "%N[param] %S\n", indent + 2, node->string);
}
}
}
}

View File

@ -1,64 +0,0 @@
#ifndef MR4TH_CMDLN_H
#define MR4TH_CMDLN_H
////////////////////////////////
// Types: Command Line Parsing
typedef struct CMDLN_Params{
String8 raw;
String8List list;
} CMDLN_Params;
typedef struct CMDLN_Node{
struct CMDLN_Node *next;
String8 string;
CMDLN_Params *params;
// (params == 0 ) -> 'input' (not a flag)
// (params != 0 ) -> flag
// (params == nil) -> flag has no parameters
} CMDLN_Node;
typedef CMDLN_Node CMDLN_Flag;
typedef struct CMDLN{
String8List raw;
String8 program;
CMDLN_Node *first;
CMDLN_Node *last;
U64 input_count;
U64 flag_count;
CMDLN_Node **inputs;
CMDLN_Node **flags;
} CMDLN;
////////////////////////////////
// Functions: Command Line Parsing
MR4TH_SYMBOL CMDLN* cmdln_from_args(Arena *arena, String8List *args);
MR4TH_SYMBOL CMDLN_Params* cmdln_params_from_string(Arena *arena, String8 flag_param);
MR4TH_SYMBOL U64 cmdln_input_count(CMDLN *cmdln);
MR4TH_SYMBOL String8 cmdln_input_from_idx(CMDLN *cmdln, U64 idx);
MR4TH_SYMBOL U64 cmdln_flag_count(CMDLN *cmdln);
MR4TH_SYMBOL CMDLN_Flag* cmdln_flag_from_idx(CMDLN *cmdln, U64 idx);
MR4TH_SYMBOL CMDLN_Params* cmdln_get_params(CMDLN *cmdln, String8 flagstr, char abbrev);
MR4TH_SYMBOL B32 cmdln_has_flag(CMDLN *cmdln, String8 flagstr, char abbrev);
MR4TH_SYMBOL String8 cmdln_get_str8(CMDLN *cmdln, String8 flagstr, char abbrev);
MR4TH_SYMBOL S64 cmdln_get_s64(CMDLN *cmdln, String8 flagstr, char abbrev);
MR4TH_SYMBOL F64 cmdln_get_f64(CMDLN *cmdln, String8 flagstr, char abbrev);
MR4TH_SYMBOL S64 cmdln_s64_from_str8(String8 valstr);
MR4TH_SYMBOL F64 cmdln_f64_from_str8(String8 valstr);
MR4TH_SYMBOL void cmdln_dump(Arena *arena, String8List *out, CMDLN *cmdln, U32 indent);
/* TODO:
** [ ] fuzz
** [ ] built in parser diagnostics
** [ ] built in misuse feedback
** [ ] help structurer
*/
#endif //MR4TH_CMDLN_H

View File

@ -1,480 +0,0 @@
////////////////////////////////
// Functions: ELF
// normalizing
MR4TH_SYMBOL_STATIC U16
elf_u16_decode(void *ptr, B32 flip){
U16 result = 0;
if (flip){
U8 *buf = (U8*)ptr;
result = buf[1] | (buf[0] << 8);
}
else{
result = *(U16*)ptr;
}
return(result);
}
MR4TH_SYMBOL_STATIC U32
elf_u32_decode(void *ptr, B32 flip){
U32 result = 0;
if (flip){
U8 *buf = (U8*)ptr;
result = buf[3] | (buf[2] << 8) | (buf[1] << 16) | (buf[0] << 24);
}
else{
result = *(U32*)ptr;
}
return(result);
}
MR4TH_SYMBOL_STATIC U64
elf_u64_decode(void *ptr, B32 flip){
U64 result = 0;
if (flip){
U8 *buf = (U8*)ptr;
result = ((((U64)buf[7]) << 0) | (((U64)buf[6]) << 8) |
(((U64)buf[5]) << 16) | (((U64)buf[4]) << 24) |
(((U64)buf[3]) << 32) | (((U64)buf[2]) << 40) |
(((U64)buf[1]) << 48) | (((U64)buf[0]) << 56));
}
else{
result = *(U64*)ptr;
}
return(result);
}
MR4TH_SYMBOL_STATIC void
elf_header64_from_header32(ELF_Header64 *dst, ELF_Header32 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
MemoryCopyArray(dst->ident, src->ident);
dst->type = elf_u16_decode(&src->type, flip_order);
dst->machine = elf_u16_decode(&src->machine, flip_order);
dst->version = elf_u32_decode(&src->version, flip_order);
dst->entry = (U64)elf_u32_decode(&src->entry, flip_order);
dst->segment_table_foff = (U64)elf_u32_decode(&src->segment_table_foff, flip_order);
dst->section_table_foff = (U64)elf_u32_decode(&src->section_table_foff, flip_order);
dst->flags = elf_u32_decode(&src->flags, flip_order);
dst->header_size = elf_u16_decode(&src->header_size, flip_order);
dst->segment_size = elf_u16_decode(&src->segment_size, flip_order);
dst->segment_count = elf_u16_decode(&src->segment_count, flip_order);
dst->section_size = elf_u16_decode(&src->section_size, flip_order);
dst->section_count = elf_u16_decode(&src->section_count, flip_order);
dst->string_section_index = elf_u16_decode(&src->string_section_index, flip_order);
}
MR4TH_SYMBOL_STATIC void
elf_header64_from_header64(ELF_Header64 *dst, ELF_Header64 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
if (!flip_order){
MemoryCopyStruct(dst, src);
}
else{
MemoryCopyArray(dst->ident, src->ident);
dst->type = elf_u16_decode(&src->type, 1);
dst->machine = elf_u16_decode(&src->machine, 1);
dst->version = elf_u32_decode(&src->version, 1);
dst->entry = elf_u32_decode(&src->entry, 1);
dst->segment_table_foff = elf_u32_decode(&src->segment_table_foff, 1);
dst->section_table_foff = elf_u32_decode(&src->section_table_foff, 1);
dst->flags = elf_u32_decode(&src->flags, 1);
dst->header_size = elf_u16_decode(&src->header_size, 1);
dst->segment_size = elf_u16_decode(&src->segment_size, 1);
dst->segment_count = elf_u16_decode(&src->segment_count, 1);
dst->section_size = elf_u16_decode(&src->section_size, 1);
dst->section_count = elf_u16_decode(&src->section_count, 1);
dst->string_section_index = elf_u16_decode(&src->string_section_index, 1);
}
}
MR4TH_SYMBOL_STATIC void
elf_section64_from_section32(ELF_Section64 *dst, ELF_Section32 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
dst->name = elf_u32_decode(&src->name, flip_order);
dst->type = elf_u32_decode(&src->type, flip_order);
dst->flags = elf_u32_decode(&src->flags, flip_order);
dst->addr = elf_u32_decode(&src->addr, flip_order);
dst->offset = elf_u32_decode(&src->offset, flip_order);
dst->size = elf_u32_decode(&src->size, flip_order);
dst->link = elf_u32_decode(&src->link, flip_order);
dst->info = elf_u32_decode(&src->info, flip_order);
dst->addralign = elf_u32_decode(&src->addralign, flip_order);
dst->entsize = elf_u32_decode(&src->entsize, flip_order);
}
MR4TH_SYMBOL_STATIC void
elf_section64_from_section64(ELF_Section64 *dst, ELF_Section64 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
if (!flip_order){
MemoryCopyStruct(dst, src);
}
else{
dst->name = elf_u32_decode(&src->name, 1);
dst->type = elf_u32_decode(&src->type, 1);
dst->flags = elf_u64_decode(&src->flags, 1);
dst->addr = elf_u64_decode(&src->addr, 1);
dst->offset = elf_u64_decode(&src->offset, 1);
dst->size = elf_u64_decode(&src->size, 1);
dst->link = elf_u32_decode(&src->link, 1);
dst->info = elf_u32_decode(&src->info, 1);
dst->addralign = elf_u64_decode(&src->addralign, 1);
dst->entsize = elf_u64_decode(&src->entsize, 1);
}
}
MR4TH_SYMBOL_STATIC void
elf_segment64_from_segment32(ELF_Segment64 *dst, ELF_Segment32 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
dst->type = elf_u32_decode(&src->type, flip_order);
dst->offset = elf_u32_decode(&src->offset, flip_order);
dst->vaddr = elf_u32_decode(&src->vaddr, flip_order);
dst->paddr = elf_u32_decode(&src->paddr, flip_order);
dst->file_size = elf_u32_decode(&src->file_size, flip_order);
dst->memory_size = elf_u32_decode(&src->memory_size, flip_order);
dst->flags = elf_u32_decode(&src->flags, flip_order);
dst->align = elf_u32_decode(&src->align, flip_order);
}
MR4TH_SYMBOL_STATIC void
elf_segment64_from_segment64(ELF_Segment64 *dst, ELF_Segment64 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
if (!flip_order){
MemoryCopyStruct(dst, src);
}
else{
dst->type = elf_u32_decode(&src->type, 1);
dst->flags = elf_u32_decode(&src->flags, 1);
dst->offset = elf_u64_decode(&src->offset, 1);
dst->vaddr = elf_u64_decode(&src->vaddr, 1);
dst->paddr = elf_u64_decode(&src->paddr, 1);
dst->file_size = elf_u64_decode(&src->file_size, 1);
dst->memory_size = elf_u64_decode(&src->memory_size, 1);
dst->align = elf_u64_decode(&src->align, 1);
}
}
MR4TH_SYMBOL_STATIC void
elf_symbol64_from_symbol32(ELF_Symbol64 *dst, ELF_Symbol32 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
dst->name = elf_u32_decode(&src->name, flip_order);
dst->value = elf_u32_decode(&src->value, flip_order);
dst->size = elf_u32_decode(&src->size, flip_order);
dst->info = src->info;
dst->other = src->other;
dst->section_index = elf_u16_decode(&src->section_index, flip_order);
}
MR4TH_SYMBOL_STATIC void
elf_symbol64_from_symbol64(ELF_Symbol64 *dst, ELF_Symbol64 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
if (!flip_order){
MemoryCopyStruct(dst, src);
}
else{
dst->name = elf_u32_decode(&src->name, 1);
dst->info = src->info;
dst->other = src->other;
dst->section_index = elf_u16_decode(&src->section_index, 1);
dst->value = elf_u64_decode(&src->value, 1);
dst->size = elf_u64_decode(&src->size, 1);
}
}
MR4TH_SYMBOL_STATIC void
elf_reloca64_from_reloc32(ELF_RelocationAdd64 *dst, ELF_Relocation32 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
dst->offset = elf_u32_decode(&src->offset, flip_order);
dst->info = elf_u32_decode(&src->info, flip_order);
dst->addend = 0;
}
MR4TH_SYMBOL_STATIC void
elf_reloca64_from_reloc64(ELF_RelocationAdd64 *dst, ELF_Relocation64 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
dst->offset = elf_u64_decode(&src->offset, flip_order);
dst->info = elf_u64_decode(&src->info, flip_order);
dst->addend = 0;
}
MR4TH_SYMBOL_STATIC void
elf_reloca64_from_reloca32(ELF_RelocationAdd64 *dst, ELF_RelocationAdd32 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
dst->offset = elf_u32_decode(&src->offset, flip_order);
dst->info = elf_u32_decode(&src->info, flip_order);
dst->addend = (S32)elf_u32_decode(&src->addend, flip_order);
}
MR4TH_SYMBOL_STATIC void
elf_reloca64_from_reloca64(ELF_RelocationAdd64 *dst, ELF_RelocationAdd64 *src, ELF_Encoding src_encoding){
B32 src_big_endian = (src_encoding == ELF_Encoding_2MSB);
B32 flip_order = (src_big_endian != ARCH_BIG_ENDIAN);
dst->offset = elf_u64_decode(&src->offset, flip_order);
dst->info = elf_u64_decode(&src->info, flip_order);
dst->addend = (S64)elf_u64_decode(&src->addend, flip_order);
}
// strings
MR4TH_SYMBOL_STATIC String8
elf_str8_from_identification_idx(ELF_IdentificationIdx idx){
String8 result = str8_lit("ERROR");
switch (idx){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_IdentificationIdx_XList(X)
#undef X
}
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_class(ELF_Class elf_class){
String8 result = str8_lit("ERROR");
switch (elf_class){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_Class_XList(X)
#undef X
}
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_encoding(ELF_Encoding elf_encoding){
String8 result = str8_lit("ERROR");
switch (elf_encoding){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_Encoding_XList(X)
#undef X
}
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_osabi(ELF_OsAbiExtension elf_osabi){
String8 result = str8_lit("ERROR");
switch (elf_osabi){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_OsAbiExtension_XList(X)
#undef X
}
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_file_type(ELF_FileType file_type){
String8 result = str8_lit("ERROR");
switch (file_type){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_FileType_XList(X)
#undef X
}
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_machine_type(ELF_FileType machine_type){
String8 result = str8_lit("ERROR");
switch (machine_type){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_MachineType_XList(X)
#undef X
}
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_section_type(ELF_SectionType section_type){
String8 result = str8_lit("ERROR");
if (ELF_SectionType_LOOS <= section_type &&
section_type <= ELF_SectionType_HIOS){
result = str8_lit("OS-CUSTOM-TYPE");
}
else if (ELF_SectionType_LOPROC <= section_type &&
section_type <= ELF_SectionType_HIPROC){
result = str8_lit("PROC-CUSTOM-TYPE");
}
else if (ELF_SectionType_LOUSER <= section_type &&
section_type <= ELF_SectionType_HIUSER){
result = str8_lit("USER-CUSTOM-TYPE");
}
else{
switch (section_type){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_SectionType_XList(X)
#undef X
}
}
return(result);
}
MR4TH_SYMBOL_STATIC void
elf_str8list_from_section_flags(Arena *arena, String8List *out, U32 flags){
U32 f = 1;
for (U32 i = 0; i < 20; i += 1){
if ((flags & f) != 0){
switch (f){
#define X(N,C) case C: str8_list_push(arena, out, str8_lit(#N)); break;
ELF_SectionFlags_XList(X)
#undef X
}
}
f <<= 1;
}
if ((flags & ELF_SectionFlag_MASKOS) != 0){
str8_list_pushf(arena, out, "OS-CUSTOM(%02x)", (flags >> 20)&0xFF);
}
if ((flags & ELF_SectionFlag_MASKPROC) != 0){
str8_list_pushf(arena, out, "PROC-CUSTOM(%01x)", (flags >> 28)&0xF);
}
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_section_flags(Arena *arena, U32 flags){
ArenaTemp scratch = arena_get_scratch(&arena, 1);
String8List list = {0};
elf_str8list_from_section_flags(scratch.arena, &list, flags);
String8 result = str8_join_flags(arena, &list);
arena_release_scratch(&scratch);
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_segment_type(ELF_SegmentType segment_type){
String8 result = str8_lit("ERROR");
if (ELF_SegmentType_LOOS <= segment_type &&
segment_type <= ELF_SegmentType_HIOS){
result = str8_lit("OS-CUSTOM-TYPE");
}
else if (ELF_SegmentType_LOPROC <= segment_type &&
segment_type <= ELF_SegmentType_HIPROC){
result = str8_lit("PROC-CUSTOM-TYPE");
}
else{
switch (segment_type){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_SegmentType_XList(X)
#undef X
}
}
return(result);
}
MR4TH_SYMBOL_STATIC void
elf_str8list_from_segment_flags(Arena *arena, String8List *out, ELF_SegmentFlags flags){
U32 f = 1;
for (U32 i = 0; i < 20; i += 1){
if ((flags & f) != 0){
switch (f){
#define X(N,C) case C: str8_list_push(arena, out, str8_lit(#N)); break;
ELF_SegmentFlags_XList(X)
#undef X
}
}
f <<= 1;
}
if ((flags & ELF_SegmentFlag_MASKOS) != 0){
str8_list_pushf(arena, out, "OS-CUSTOM(%02x)", (flags >> 20)&0xFF);
}
if ((flags & ELF_SegmentFlag_MASKPROC) != 0){
str8_list_pushf(arena, out, "PROC-CUSTOM(%01x)", (flags >> 28)&0xF);
}
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_segment_flags(Arena *arena, ELF_SegmentFlags flags){
ArenaTemp scratch = arena_get_scratch(&arena, 1);
String8List list = {0};
elf_str8list_from_segment_flags(scratch.arena, &list, flags);
String8 result = str8_join_flags(arena, &list);
arena_release_scratch(&scratch);
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_symbol_binding(ELF_SymbolBinding bind){
String8 result = str8_lit("ERROR");
if (ELF_SymbolBinding_LOOS <= bind &&
bind <= ELF_SymbolBinding_HIOS){
result = str8_lit("OS-CUSTOM-TYPE");
}
else if (ELF_SymbolBinding_LOPROC <= bind &&
bind <= ELF_SymbolBinding_HIPROC){
result = str8_lit("PROC-CUSTOM-TYPE");
}
else{
switch (bind){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_SymbolBinding_XList(X)
#undef X
}
}
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_symbol_type(ELF_SymbolType type){
String8 result = str8_lit("ERROR");
if (ELF_SymbolType_LOOS <= type &&
type <= ELF_SymbolType_HIOS){
result = str8_lit("OS-CUSTOM-TYPE");
}
else if (ELF_SymbolType_LOPROC <= type &&
type <= ELF_SymbolType_HIPROC){
result = str8_lit("PROC-CUSTOM-TYPE");
}
else{
switch (type){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_SymbolType_XList(X)
#undef X
}
}
return(result);
}
MR4TH_SYMBOL_STATIC String8
elf_str8_from_symbol_vis(ELF_SymbolVis vis){
String8 result = str8_lit("ERROR");
switch (vis){
#define X(N,C) case C: result = str8_lit(#N); break;
ELF_SymbolVis_XList(X)
#undef X
}
return(result);
}

View File

@ -1,710 +0,0 @@
#ifndef MR4TH_ELF_H
#define MR4TH_ELF_H
/*
** ELF total layout summary:
**
** TODO
*/
////////////////////////////////
// Types: ELF
// identification
#define ELF_NUM_IDENT 16
#define ELF_IdentificationIdx_XList(X)\
X(MAG0, 0)\
X(MAG1, 1)\
X(MAG2, 2)\
X(MAG3, 3)\
X(CLASS, 4)\
X(DATA, 5)\
X(VERSION, 6)\
X(OSABI, 7)\
X(ABIVERSION, 8)\
X(PAD0, 9)\
X(PAD1, 10)\
X(PAD2, 11)\
X(PAD3, 12)\
X(PAD4, 13)\
X(PAD5, 14)\
X(PAD6, 15)
typedef enum ELF_IdentificationIdx{
#define X(N,C) ELF_IdentificationIdx_##N = C,
ELF_IdentificationIdx_XList(X)
#undef X
} ELF_IdentificationIdx;
#define ELF_Magic_Byte0 0x7F
#define ELF_Magic_Byte1 'E'
#define ELF_Magic_Byte2 'L'
#define ELF_Magic_Byte3 'F'
// elf class
#define ELF_Class_XList(X)\
X(NONE, 0)\
X(32, 1)\
X(64, 2)
typedef enum ELF_Class{
#define X(N,C) ELF_Class_##N = C,
ELF_Class_XList(X)
#undef X
} ELF_Class;
// elf encoding
#define ELF_Encoding_XList(X)\
X(NONE, 0)\
X(2LSB, 1)\
X(2MSB, 2)
typedef enum ELF_Encoding{
#define X(N,C) ELF_Encoding_##N = C,
ELF_Encoding_XList(X)
#undef X
} ELF_Encoding;
// elf os/abi extension
#define ELF_OsAbiExtension_XList(X)\
X(NONE, 0)\
X(HPUX, 1)\
X(NETBSD, 2)\
X(GNU, 3)\
X(SOLARIS, 6)\
X(AIX, 7)\
X(IRIX, 8)\
X(FREEBSD, 9)\
X(TRU64, 10)\
X(MODESTO, 11)\
X(OPENBSD, 12)\
X(OPENVMS, 13)\
X(NSK, 14)\
X(AROS, 15)\
X(FENIXOS, 16)\
X(CLOUDABI, 17)\
X(OPENVOS, 18)
typedef enum ELF_OsAbiExtension{
#define X(N,C) ELF_OsAbiExtension_##N = C,
ELF_OsAbiExtension_XList(X)
#undef X
} ELF_OsAbiExtension;
// file type
#define ELF_FileType_XList(X)\
X(NONE, 0)\
X(REL, 1)\
X(EXEC, 2)\
X(DYN, 3)\
X(CORE, 4)\
X(LOOS, 0xfe00)\
X(HIOS, 0xfeff)\
X(LOPROC, 0xff00)\
X(HIPROC, 0xffff)
typedef U16 ELF_FileType;
enum{
#define X(N,C) ELF_FileType_##N = C,
ELF_FileType_XList(X)
#undef X
};
// machine type
#define ELF_MachineType_XList(X)\
X(NONE, 0)\
X(M32, 1)\
X(SPARC, 2)\
X(386, 3)\
X(68K, 4)\
X(88K, 5)\
X(IAMCU, 6)\
X(860, 7)\
X(MIPS, 8)\
X(S370, 9)\
X(MIPS_RS3_LE, 10)\
X(PARISC, 15)\
X(VPP500, 17)\
X(SPARC32PLUS, 18)\
X(960, 19)\
X(PPC, 20)\
X(PPC64, 21)\
X(S390, 22)\
X(SPU, 23)\
X(V800, 36)\
X(FR20, 37)\
X(RH32, 38)\
X(RCE, 39)\
X(ARM, 40)\
X(ALPHA, 41)\
X(SH, 42)\
X(SPARCV9, 43)\
X(TRICORE, 44)\
X(ARC, 45)\
X(H8_300, 300)\
X(H8S, 48)\
X(H8_500, 49)\
X(IA_64, 50)\
X(MIPS_X, 51)\
X(COLDFIRE, 52)\
X(68HC12, 53)\
X(MMA, 54)\
X(PCP, 55)\
X(NCPU, 56)\
X(NDR1, 57)\
X(STARCORE, 58)\
X(ME16, 59)\
X(ST100, 60)\
X(TINYJ, 61)\
X(X86_64, 62)\
X(PDSP, 63)\
X(PDP10, 64)\
X(PDP11, 65)\
X(FX66, 66)\
X(ST9PLUS, 67)\
X(ST7, 68)\
X(68HC16, 69)\
X(68HC11, 70)\
X(68HC08, 71)\
X(68HC05, 72)\
X(SVX, 73)\
X(ST19, 74)\
X(VAX, 75)\
X(CRIS, 76)\
X(JAVELIN, 77)\
X(FIREPATH, 78)\
X(ZSP, 79)\
X(MMIX, 80)\
X(HUANY, 81)\
X(PRISM, 82)\
X(AVR, 83)\
X(FR30, 84)\
X(D10V, 85)\
X(D30V, 86)\
X(V850, 87)\
X(M32R, 88)\
X(MN10300, 89)\
X(MN10200, 90)\
X(PJ, 91)\
X(OPENRISC, 92)\
X(ARC_COMPACT, 93)\
X(XTENSA, 94)\
X(VIDEOCORE, 95)\
X(TMM_GPP, 96)\
X(NS32K, 97)\
X(TPC, 98)\
X(SNP1K, 99)\
X(ST200, 100)\
X(IP2K, 101)\
X(MAX, 102)\
X(CR, 103)\
X(F2MC16, 104)\
X(MSP430, 105)\
X(BLACKFIN, 106)\
X(SE_C33, 107)\
X(SEP, 108)\
X(ARCA, 109)\
X(UNICORE, 110)\
X(EXCESS, 111)\
X(DXP, 112)\
X(ALTERA_NIOS2, 113)\
X(CRX, 114)\
X(XGATE, 115)\
X(C166, 116)\
X(M16C, 117)\
X(DSPIC30F, 118)\
X(CE, 119)\
X(M32C, 120)\
X(TSK3000, 131)\
X(RS08, 132)\
X(SHARC, 133)\
X(ECOG2, 134)\
X(SCORE7, 135)\
X(DSP24, 136)\
X(VIDEOCORE3, 137)\
X(LATTICEMICO32, 138)\
X(SE_C17, 139)\
X(TI_C6000, 140)\
X(TI_C2000, 141)\
X(TI_C5500, 142)\
X(TI_ARP32, 143)\
X(TI_PRU, 144)\
X(MMDSP_PLUS, 160)\
X(CYPRESS_M8C, 161)\
X(R32C, 162)\
X(TRIMEDIA, 163)\
X(QDSP6, 164)\
X(8051, 165)\
X(STXP7X, 166)\
X(NDS32, 167)\
X(ECOG1, 168)\
X(MAXQ30, 169)\
X(XIMO16, 170)\
X(MANIK, 171)\
X(CRAYNV2, 172)\
X(RX, 173)\
X(METAG, 174)\
X(MCST_ELBRUS, 175)\
X(ECOG16, 176)\
X(CR16, 177)\
X(ETPU, 178)\
X(SLE9X, 179)\
X(L10M, 180)\
X(K10M, 181)\
X(AARCH64, 183)\
X(AVR32, 185)\
X(STM8, 186)\
X(TILE64, 187)\
X(TILEPRO, 188)\
X(MICROBLAZE, 189)\
X(CUDA, 190)\
X(TILEGX, 191)\
X(CLOUDSHIELD, 192)\
X(COREA_1ST, 193)\
X(COREA_2ND, 194)\
X(ARC_COMPACT2, 195)\
X(OPEN8, 196)\
X(RL78, 197)\
X(VIDEOCORE5, 198)\
X(78KOR, 199)\
X(56800EX, 200)\
X(BA1, 201)\
X(BA2, 202)\
X(XCORE, 203)\
X(MCHP_PIC, 204)\
X(INTEL205, 205)\
X(INTEL206, 206)\
X(INTEL207, 207)\
X(INTEL208, 208)\
X(INTEL209, 209)\
X(KM32, 210)\
X(KMX32, 211)\
X(KMX16, 212)\
X(KMX8, 213)\
X(KVARC, 214)\
X(CDP, 215)\
X(COGE, 216)\
X(COOL, 217)\
X(NORC, 218)\
X(CSR_KALIMBA, 219)\
X(Z80, 220)\
X(VISIUM, 221)\
X(FT32, 222)\
X(MOXIE, 223)\
X(AMDGPU, 224)\
X(RISCV, 243)
typedef U16 ELF_MachineType;
enum{
#define X(N,C) ELF_MachineType_##N = C,
ELF_MachineType_XList(X)
#undef X
};
// elf header
typedef struct ELF_Header32{
U8 ident[ELF_NUM_IDENT];
ELF_FileType type;
ELF_MachineType machine;
U32 version;
U32 entry;
U32 segment_table_foff;
U32 section_table_foff;
U32 flags;
U16 header_size;
U16 segment_size;
U16 segment_count;
U16 section_size;
U16 section_count;
U16 string_section_index;
} ELF_Header32;
typedef struct ELF_Header64{
U8 ident[ELF_NUM_IDENT];
ELF_FileType type;
ELF_MachineType machine;
U32 version;
U64 entry;
U64 segment_table_foff;
U64 section_table_foff;
U32 flags;
U16 header_size;
U16 segment_size;
U16 segment_count;
U16 section_size;
U16 section_count;
U16 string_section_index;
} ELF_Header64;
// elf section type
#define ELF_SectionType_XList(X)\
X(NULL, 0)\
X(PROGBITS, 1)\
X(SYMTAB, 2)\
X(STRTAB, 3)\
X(RELA, 4)\
X(HASH, 5)\
X(DYNAMIC, 6)\
X(NOTE, 7)\
X(NOBITS, 8)\
X(REL, 9)\
X(SHLIB, 10)\
X(DYNSYM, 11)\
X(INIT_ARRAY, 14)\
X(FINI_ARRAY, 15)\
X(PREINIT_ARRAY, 16)\
X(GROUP, 17)\
X(SYMTAB_SHNDX, 18)\
X(LOOS, 0x60000000)\
X(HIOS, 0x6fffffff)\
X(LOPROC, 0x70000000)\
X(HIPROC, 0x7fffffff)\
X(LOUSER, 0x80000000)\
X(HIUSER, 0xffffffff)
typedef U32 ELF_SectionType;
enum{
#define X(N,C) ELF_SectionType_##N = C,
ELF_SectionType_XList(X)
#undef X
};
// elf section flags
#define ELF_SectionFlags_XList(X)\
X(WRITE, 0x1)\
X(ALLOC, 0x2)\
X(EXECINSTR, 0x4)\
X(MERGE, 0x10)\
X(STRINGS, 0x20)\
X(INFO_LINK, 0x40)\
X(LINK_ORDER, 0x80)\
X(OS_NONCONFORMING, 0x100)\
X(GROUP, 0x200)\
X(TLS, 0x400)\
X(COMPRESSED, 0x800)\
X(MASKOS, 0x0ff00000)\
X(MASKPROC, 0xf0000000)
enum{
#define X(N,C) ELF_SectionFlag_##N = C,
ELF_SectionFlags_XList(X)
#undef X
};
// elf section indexes
#define ELF_SectionIndex_XList(X)\
X(UNDEF, 0)\
X(LORESERVE, 0xff00)\
X(LOPROC, 0xff00)\
X(HIPROC, 0xff1f)\
X(LOOS, 0xff20)\
X(HIOS, 0xff3f)\
X(ABS, 0xfff1)\
X(COMMON, 0xfff2)\
X(XINDEX, 0xffff)\
X(HIRESERVE, 0xffff)
typedef enum ELF_SectionIndex{
#define X(N,C) ELF_SectionIndex_##N = C,
ELF_SectionIndex_XList(X)
#undef X
} ELF_SectionIndex;
// elf section
typedef struct ELF_Section32{
U32 name;
ELF_SectionType type;
U32 flags;
U32 addr;
U32 offset;
U32 size;
U32 link;
U32 info;
U32 addralign;
U32 entsize;
} ELF_Section32;
typedef struct ELF_Section64{
U32 name;
ELF_SectionType type;
U64 flags;
U64 addr;
U64 offset;
U64 size;
U32 link;
U32 info;
U64 addralign;
U64 entsize;
} ELF_Section64;
// elf compression type
#define ELF_CompressionType_XList(X)\
X(ZLIB, 1)\
X(LOOS, 0x60000000)\
X(HIOS, 0x6fffffff)\
X(LOPROC, 0x70000000)\
X(HIPROC, 0x7fffffff)
typedef enum ELF_CompressionType{
#define X(N,C) ELF_CompressionType_##N = C,
ELF_CompressionType_XList(X)
#undef X
} ELF_CompressionType;
// elf compression header
typedef struct ELF_CompressionHeader32{
ELF_CompressionType type;
U32 size;
U32 addralign;
} ELF_CompressionHeader32;
typedef struct ELF_CompressionHeader64{
ELF_CompressionType type;
U32 reserved;
U64 size;
U64 addralign;
} ELF_CompressionHeader64;
// elf section group flags
#define ELF_SectionGroupFlags_XList(X)\
X(COMDAT, 0x1)\
X(MASKOS, 0x0ff00000)\
X(MASKPROC, 0xf0000000)
typedef U32 ELF_SectionGroupFlags;
enum{
#define X(N,C) ELF_SectionGroupFlag_##N = C,
ELF_SectionGroupFlags_XList(X)
#undef X
};
// elf symbol
typedef struct ELF_Symbol32{
U32 name;
U32 value;
U32 size;
U8 info;
U8 other;
U16 section_index;
} ELF_Symbol32;
typedef struct ELF_Symbol64{
U32 name;
U8 info;
U8 other;
U16 section_index;
U64 value;
U64 size;
} ELF_Symbol64;
#define ELF_Symbol_BindFromInfo(inf) ((inf)>>4)
#define ELF_Symbol_TypeFromInfo(inf) ((inf)&0xF)
#define ELF_Symbol_InfoFromBindType(bin,typ) (((bin)<<4)|((type)&0xF))
#define ELF_Symbol_VisFromOther(oth) ((oth)&0x3)
#define ELF_Symbol_OtherFromVis(vis) (((vis)&0x3))
// elf symbol binding
#define ELF_SymbolBinding_XList(X)\
X(LOCAL, 0)\
X(GLOBAL, 1)\
X(WEAK, 2)\
X(LOOS, 10)\
X(HIOS, 12)\
X(LOPROC, 13)\
X(HIPROC, 15)
typedef enum ELF_SymbolBinding{
#define X(N,C) ELF_SymbolBinding_##N = C,
ELF_SymbolBinding_XList(X)
#undef X
} ELF_SymbolBinding;
// elf symbol types
#define ELF_SymbolType_XList(X)\
X(NOTYPE, 0)\
X(OBJECT, 1)\
X(FUNC, 2)\
X(SECTION, 3)\
X(FILE, 4)\
X(COMMON, 5)\
X(TLS, 6)\
X(LOOS, 10)\
X(HIOS, 12)\
X(LOPROC, 13)\
X(HIPROC, 15)
typedef enum ELF_SymbolType{
#define X(N,C) ELF_SymbolType_##N = C,
ELF_SymbolType_XList(X)
#undef X
} ELF_SymbolType;
// elf symbol visibility
#define ELF_SymbolVis_XList(X)\
X(DEFAULT, 0)\
X(INTERNAL, 1)\
X(HIDDEN, 2)\
X(PROTECTED, 3)
typedef enum ELF_SymbolVis{
#define X(N,C) ELF_SymbolVis_##N = C,
ELF_SymbolVis_XList(X)
#undef X
} ELF_SymbolVis;
// elf relocations
typedef struct ELF_Relocation32{
U32 offset;
U32 info;
} ELF_Relocation32;
typedef struct ELF_RelocationAdd32{
U32 offset;
U32 info;
S32 addend;
} ELF_RelocationAdd32;
typedef struct ELF_Relocation64{
U64 offset;
U64 info;
} ELF_Relocation64;
typedef struct ELF_RelocationAdd64{
U64 offset;
U64 info;
S64 addend;
} ELF_RelocationAdd64;
// elf segment type
#define ELF_SegmentType_XList(X)\
X(NULL, 0)\
X(LOAD, 1)\
X(DYNAMIC, 2)\
X(INTERP, 3)\
X(NOTE, 4)\
X(SHLIB, 5)\
X(PHDR, 6)\
X(TLS, 7)\
X(LOOS, 0x60000000)\
X(HIOS, 0x6fffffff)\
X(LOPROC, 0x70000000)\
X(HIPROC, 0x7fffffff)
typedef U32 ELF_SegmentType;
enum{
#define X(N,C) ELF_SegmentType_##N = C,
ELF_SegmentType_XList(X)
#undef X
};
// elf segment flags
#define ELF_SegmentFlags_XList(X)\
X(X, 0x1)\
X(W, 0x2)\
X(R, 0x4)\
X(MASKOS, 0x0ff00000)\
X(MASKPROC, 0xf0000000)\
typedef U32 ELF_SegmentFlags;
enum{
#define X(N,C) ELF_SegmentFlag_##N = C,
ELF_SegmentFlags_XList(X)
#undef X
};
// elf segment
typedef struct ELF_Segment32{
ELF_SegmentType type;
U32 offset;
U32 vaddr;
U32 paddr;
U32 file_size;
U32 memory_size;
ELF_SegmentFlags flags;
U32 align;
} ELF_Segment32;
typedef struct ELF_Segment64{
ELF_SegmentType type;
ELF_SegmentFlags flags;
U64 offset;
U64 vaddr;
U64 paddr;
U64 file_size;
U64 memory_size;
U64 align;
} ELF_Segment64;
////////////////////////////////
// Functions: ELF
// normalizing
MR4TH_SYMBOL_STATIC U16 elf_u16_decode(void *ptr, B32 flip);
MR4TH_SYMBOL_STATIC U32 elf_u32_decode(void *ptr, B32 flip);
MR4TH_SYMBOL_STATIC U64 elf_u64_decode(void *ptr, B32 flip);
MR4TH_SYMBOL_STATIC void elf_header64_from_header32(ELF_Header64 *dst, ELF_Header32 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_header64_from_header64(ELF_Header64 *dst, ELF_Header64 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_section64_from_section32(ELF_Section64 *dst, ELF_Section32 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_section64_from_section64(ELF_Section64 *dst, ELF_Section64 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_segment64_from_segment32(ELF_Segment64 *dst, ELF_Segment32 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_segment64_from_segment64(ELF_Segment64 *dst, ELF_Segment64 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_symbol64_from_symbol32(ELF_Symbol64 *dst, ELF_Symbol32 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_symbol64_from_symbol64(ELF_Symbol64 *dst, ELF_Symbol64 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_reloca64_from_reloc32(ELF_RelocationAdd64 *dst, ELF_Relocation32 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_reloca64_from_reloc64(ELF_RelocationAdd64 *dst, ELF_Relocation64 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_reloca64_from_reloca32(ELF_RelocationAdd64 *dst, ELF_RelocationAdd32 *src, ELF_Encoding src_encoding);
MR4TH_SYMBOL_STATIC void elf_reloca64_from_reloca64(ELF_RelocationAdd64 *dst, ELF_RelocationAdd64 *src, ELF_Encoding src_encoding);
// strings
MR4TH_SYMBOL_STATIC String8 elf_str8_from_identification_idx(ELF_IdentificationIdx idx);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_class(ELF_Class elf_class);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_encoding(ELF_Encoding elf_encoding);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_osabi(ELF_OsAbiExtension elf_osabi);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_file_type(ELF_FileType file_type);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_machine_type(ELF_FileType machine_type);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_section_type(ELF_SectionType section_type);
MR4TH_SYMBOL_STATIC void elf_str8list_from_section_flags(Arena *arena, String8List *out, U32 flags);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_section_flags(Arena *arena, U32 flags);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_segment_type(ELF_SegmentType segment_type);
MR4TH_SYMBOL_STATIC void elf_str8list_from_segment_flags(Arena *arena, String8List *out, ELF_SegmentFlags flags);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_segment_flags(Arena *arena, ELF_SegmentFlags flags);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_symbol_binding(ELF_SymbolBinding bind);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_symbol_type(ELF_SymbolType type);
MR4TH_SYMBOL_STATIC String8 elf_str8_from_symbol_vis(ELF_SymbolVis vis);
#endif //MR4TH_ELF_H

View File

@ -1,422 +0,0 @@
////////////////////////////////
// Elf Parse Functions
MR4TH_SYMBOL ELF_Parse*
elfp_begin(Arena *arena, String8 data){
// magic check
B32 elf_magic = 0;
ELF_Class elf_class = ELF_Class_NONE;
ELF_Encoding elf_encoding = ELF_Encoding_NONE;
U32 elf_version = 0;
ELF_OsAbiExtension elf_ext = ELF_OsAbiExtension_NONE;
B32 good_headers = 0;
if (data.size >= ELF_NUM_IDENT){
elf_class = data.str[ELF_IdentificationIdx_CLASS];
elf_encoding = data.str[ELF_IdentificationIdx_DATA];
elf_version = data.str[ELF_IdentificationIdx_VERSION];
elf_ext = data.str[ELF_IdentificationIdx_OSABI];
if (data.str[0] == ELF_Magic_Byte0 &&
data.str[1] == ELF_Magic_Byte1 &&
data.str[2] == ELF_Magic_Byte2 &&
data.str[3] == ELF_Magic_Byte3 &&
elf_version == 1 &&
(elf_class == ELF_Class_32 || elf_class == ELF_Class_64) &&
(elf_encoding == ELF_Encoding_2LSB ||
elf_encoding == ELF_Encoding_2MSB)){
good_headers = 1;
}
}
// header
void *header = 0;
U64 section_table_foff = 0;
U16 section_count = 0;
U16 section_size = 0;
U64 segment_table_foff = 0;
U16 segment_count = 0;
U16 segment_size = 0;
U16 string_section_index = 0;
if (good_headers){
switch (elf_class){
default:break;
case ELF_Class_32: {
if (sizeof(ELF_Header32) <= data.size){
header = data.str;
ELF_Header32 *h = (ELF_Header32*)header;
section_table_foff = h->section_table_foff;
section_count = h->section_count;
section_size = h->section_size;
segment_table_foff = h->segment_table_foff;
segment_count = h->segment_count;
segment_size = h->segment_size;
string_section_index = h->string_section_index;
}
}break;
case ELF_Class_64: {
if (sizeof(ELF_Header64) <= data.size){
header = data.str;
ELF_Header64 *h = (ELF_Header64*)header;
section_table_foff = h->section_table_foff;
section_count = h->section_count;
section_size = h->section_size;
segment_table_foff = h->segment_table_foff;
segment_count = h->segment_count;
segment_size = h->segment_size;
string_section_index = h->string_section_index;
}
}break;
}
}
// sections
void *sections = 0;
if (section_count > 0 && section_table_foff + section_count*section_size <= data.size){
sections = data.str + section_table_foff;
}
// segments
void *segments = 0;
if (segment_count > 0 && segment_table_foff + segment_count*segment_size <= data.size){
segments = data.str + segment_table_foff;
}
// string table
U8 *section_strtable_first = 0;
U8 *section_strtable_opl = 0;
{
U32 index = 0;
if (string_section_index != ELF_SectionIndex_UNDEF &&
string_section_index != ELF_SectionIndex_XINDEX){
index = string_section_index;
}
else if (string_section_index == ELF_SectionIndex_XINDEX){
switch (elf_class){
default:break;
case ELF_Class_32: index = ((ELF_Section32*)sections)->link; break;
case ELF_Class_64: index = ((ELF_Section64*)sections)->link; break;
}
}
if (index > 0){
U64 offset = 0;
U64 size = 0;
switch (elf_class){
default:break;
case ELF_Class_32:
{
offset = ((ELF_Section32*)sections)[index].offset;
size = ((ELF_Section32*)sections)[index].size;
}break;
case ELF_Class_64:
{
offset = ((ELF_Section64*)sections)[index].offset;
size = ((ELF_Section64*)sections)[index].size;
}break;
}
if (offset < data.size && offset + size < data.size){
section_strtable_first = data.str + offset;
section_strtable_opl = data.str + offset + size;
}
}
}
// find symtab & dynsym sections
void *symbols[ELFP_SYMBOL_TABLE_COUNT] = {0};
U32 symbol_count[ELFP_SYMBOL_TABLE_COUNT] = {0};
U8 *symbol_strtable_first[ELFP_SYMBOL_TABLE_COUNT] = {0};
U8 *symbol_strtable_opl[ELFP_SYMBOL_TABLE_COUNT] = {0};
if (sections != 0){
for (U32 i = 0; i < section_count; i += 1){
ELF_SectionType type = 0;
U64 foff = 0;
U64 opl = 0;
switch (elf_class){
default:break;
case ELF_Class_32: {
ELF_Section32 *sec32 = (ELF_Section32*)sections + i;
type = sec32->type;
foff = sec32->offset;
opl = foff + sec32->size;
}break;
case ELF_Class_64: {
ELF_Section64 *sec64 = (ELF_Section64*)sections + i;
type = sec64->type;
foff = sec64->offset;
opl = foff + sec64->size;
}break;
}
U32 idx = ELFP_SYMBOL_TABLE_COUNT;
switch (type){
case ELF_SectionType_SYMTAB: idx = ELFP_SYMBOL_TABLE_symtab; break;
case ELF_SectionType_DYNSYM: idx = ELFP_SYMBOL_TABLE_dynsym; break;
}
if (idx < ELFP_SYMBOL_TABLE_COUNT &&
foff < data.size && opl < data.size){
U32 link = 0;
//U32 info = 0;
U32 count = 0;
switch (elf_class){
default:break;
case ELF_Class_32: {
ELF_Section32 *sec32 = (ELF_Section32*)sections + i;
link = sec32->link;
//info = sec32->info;
count = sec32->size/sizeof(ELF_Symbol32);
}break;
case ELF_Class_64: {
ELF_Section64 *sec64 = (ELF_Section64*)sections + i;
link = sec64->link;
//info = sec64->info;
count = sec64->size/sizeof(ELF_Symbol64);
}break;
}
symbols[idx] = data.str + foff;
symbol_count[idx] = count;
if (link < section_count){
U64 strtable_off = 0;
U64 strtable_size = 0;
switch (elf_class){
default:break;
case ELF_Class_32: {
ELF_Section32 *sec32 = (ELF_Section32*)sections + link;
strtable_off = sec32->offset;
strtable_size = sec32->size;
}break;
case ELF_Class_64: {
ELF_Section64 *sec64 = (ELF_Section64*)sections + link;
strtable_off = sec64->offset;
strtable_size = sec64->size;
}break;
}
if (strtable_off < data.size &&
strtable_off + strtable_size < data.size){
symbol_strtable_first[idx] = data.str + strtable_off;
symbol_strtable_opl[idx] = data.str + strtable_off + strtable_size;
}
}
}
}
}
// fill result
ELF_Parse *elf = 0;
if (header != 0){
elf = push_array(arena, ELF_Parse, 1);
elf->elf_class = elf_class;
elf->encoding = elf_encoding;
elf->section_count = section_count;
elf->segment_count = segment_count;
elf->header = header;
elf->size = data.size;
elf->sections = sections;
elf->segments = segments;
elf->section_strtable_first = section_strtable_first;
elf->section_strtable_opl = section_strtable_opl;
MemoryCopyArray(elf->symbols, symbols);
MemoryCopyArray(elf->symbol_count, symbol_count);
MemoryCopyArray(elf->symbol_strtable_first, symbol_strtable_first);
MemoryCopyArray(elf->symbol_strtable_opl, symbol_strtable_opl);
}
return(elf);
}
MR4TH_SYMBOL void
elfp_header_read(ELF_Parse *elf, ELF_Header64 *out){
if (elf->header != 0){
switch (elf->elf_class){
default:break;
case ELF_Class_32: {
elf_header64_from_header32(out, (ELF_Header32*)elf->header, elf->encoding);
}break;
case ELF_Class_64: {
elf_header64_from_header64(out, (ELF_Header64*)elf->header, elf->encoding);
}break;
}
}
}
MR4TH_SYMBOL U32
elfp_section_count(ELF_Parse *elf){
U32 result = elf->section_count;
return(result);
}
MR4TH_SYMBOL void
elfp_section_read(ELF_Parse *elf, U32 idx, ELF_Section64 *out){
if (elf->sections != 0 && idx < elf->section_count){
switch (elf->elf_class){
default:break;
case ELF_Class_32: {
elf_section64_from_section32(out, (ELF_Section32*)elf->sections + idx, elf->encoding);
}break;
case ELF_Class_64: {
elf_section64_from_section64(out, (ELF_Section64*)elf->sections + idx, elf->encoding);
}break;
}
}
}
MR4TH_SYMBOL String8
elfp_section_name(ELF_Parse *elf, U32 idx){
String8 result = {0};
if (elf->sections != 0 && idx < elf->section_count){
U32 name = 0;
switch (elf->elf_class){
default:break;
case ELF_Class_32: name = ((ELF_Section32*)elf->sections)[idx].name; break;
case ELF_Class_64: name = ((ELF_Section64*)elf->sections)[idx].name; break;
}
result = str8_cstring_capped(elf->section_strtable_first + name,
elf->section_strtable_opl);
}
return(result);
}
MR4TH_SYMBOL U32
elfp_segment_count(ELF_Parse *elf){
U32 result = elf->segment_count;
return(result);
}
MR4TH_SYMBOL void
elfp_segment_read(ELF_Parse *elf, U32 idx, ELF_Segment64 *out){
if (elf->segments != 0 && idx < elf->segment_count){
switch (elf->elf_class){
default:break;
case ELF_Class_32: {
elf_segment64_from_segment32(out, (ELF_Segment32*)elf->segments + idx, elf->encoding);
}break;
case ELF_Class_64: {
elf_segment64_from_segment64(out, (ELF_Segment64*)elf->segments + idx, elf->encoding);
}break;
}
}
}
MR4TH_SYMBOL U32
elfp_symbol_count(ELF_Parse *elf, U32 table){
U32 result = 0;
if (table < ELFP_SYMBOL_TABLE_COUNT){
result = elf->symbol_count[table];
}
return(result);
}
MR4TH_SYMBOL void
elfp_symbol_read(ELF_Parse *elf, U32 table, U32 idx, ELF_Symbol64 *out){
if (table < ELFP_SYMBOL_TABLE_COUNT){
void *symbols = elf->symbols[table];
switch (elf->elf_class){
default:break;
case ELF_Class_32: {
elf_symbol64_from_symbol32(out, (ELF_Symbol32*)symbols + idx, elf->encoding);
}break;
case ELF_Class_64: {
elf_symbol64_from_symbol64(out, (ELF_Symbol64*)symbols + idx, elf->encoding);
}break;
}
}
}
MR4TH_SYMBOL String8
elfp_symbol_name(ELF_Parse *elf, U32 table, U32 idx){
String8 result = {0};
if (table < ELFP_SYMBOL_TABLE_COUNT){
void *s = elf->symbols[table];
U8 *string_table_first = elf->symbol_strtable_first[table];
U8 *string_table_opl = elf->symbol_strtable_opl[table];
U32 name = 0;
switch (elf->elf_class){
default:break;
case ELF_Class_32: name = ((ELF_Symbol32*)s)[idx].name; break;
case ELF_Class_64: name = ((ELF_Symbol64*)s)[idx].name; break;
}
if (string_table_first != 0){
result = str8_cstring_capped(string_table_first + name,
string_table_opl);
}
}
return(result);
}
MR4TH_SYMBOL U32
elfp_relocs_count(ELF_Parse *elf, U32 secidx){
U32 result = 0;
if (elf->sections != 0 && secidx < elf->section_count){
switch (elf->elf_class){
default:break;
case ELF_Class_32: {
ELF_Section32 *sec32 = ((ELF_Section32*)elf->sections) + secidx;
switch (sec32->type){
case ELF_SectionType_REL:
result = sec32->size/sizeof(ELF_Relocation32); break;
case ELF_SectionType_RELA:
result = sec32->size/sizeof(ELF_RelocationAdd32); break;
}
}break;
case ELF_Class_64: {
ELF_Section64 *sec64 = ((ELF_Section64*)elf->sections) + secidx;
switch (sec64->type){
case ELF_SectionType_REL:
result = sec64->size/sizeof(ELF_Relocation64); break;
case ELF_SectionType_RELA:
result = sec64->size/sizeof(ELF_RelocationAdd64); break;
}
}break;
}
}
return(result);
}
MR4TH_SYMBOL void
elfp_relocs_read(ELF_Parse *elf, U32 secidx, U32 relocidx, ELF_RelocationAdd64 *out){
if (elf->sections != 0 && secidx < elf->section_count){
switch (elf->elf_class){
default:break;
case ELF_Class_32: {
ELF_Section32 *sec32 = ((ELF_Section32*)elf->sections) + secidx;
U64 opl = ClampTop(sec32->offset + sec32->size, elf->size);
U64 size = opl - sec32->offset;
switch (sec32->type){
case ELF_SectionType_REL: {
ELF_Relocation32 *relocs = (ELF_Relocation32*)((U8*)elf->header + sec32->offset);
U32 count = sec32->size/sizeof(*relocs);
if (relocidx < count){
elf_reloca64_from_reloc32(out, relocs + relocidx, elf->encoding);
}
}break;
case ELF_SectionType_RELA: {
ELF_RelocationAdd32 *relocs = (ELF_RelocationAdd32*)((U8*)elf->header + sec32->offset);
U32 count = sec32->size/sizeof(*relocs);
if (relocidx < count){
elf_reloca64_from_reloca32(out, relocs + relocidx, elf->encoding);
}
}break;
}
}break;
case ELF_Class_64: {
ELF_Section64 *sec64 = ((ELF_Section64*)elf->sections) + secidx;
U64 opl = ClampTop(sec64->offset + sec64->size, elf->size);
U64 size = opl - sec64->offset;
switch (sec64->type){
case ELF_SectionType_REL: {
ELF_Relocation64 *relocs = (ELF_Relocation64*)((U8*)elf->header + sec64->offset);
U32 count = sec64->size/sizeof(*relocs);
if (relocidx < count){
elf_reloca64_from_reloc64(out, relocs + relocidx, elf->encoding);
}
}break;
case ELF_SectionType_RELA: {
ELF_RelocationAdd64 *relocs = (ELF_RelocationAdd64*)((U8*)elf->header + sec64->offset);
U32 count = sec64->size/sizeof(*relocs);
if (relocidx < count){
elf_reloca64_from_reloca64(out, relocs + relocidx, elf->encoding);
}
}break;
}
}break;
}
}
}

View File

@ -1,49 +0,0 @@
#ifndef MR4TH_ELF_PARSE_H
#define MR4TH_ELF_PARSE_H
////////////////////////////////
// Elf Parse Types
#define ELFP_SYMBOL_TABLE_symtab 0
#define ELFP_SYMBOL_TABLE_dynsym 1
#define ELFP_SYMBOL_TABLE_COUNT 2
typedef struct ELF_Parse{
ELF_Class elf_class;
ELF_Encoding encoding;
U32 section_count;
U32 segment_count;
void *header;
U64 size;
void *sections;
void *segments;
U8 *section_strtable_first;
U8 *section_strtable_opl;
void *symbols[ELFP_SYMBOL_TABLE_COUNT];
U32 symbol_count[ELFP_SYMBOL_TABLE_COUNT];
U8 *symbol_strtable_first[ELFP_SYMBOL_TABLE_COUNT];
U8 *symbol_strtable_opl[ELFP_SYMBOL_TABLE_COUNT];
} ELF_Parse;
////////////////////////////////
// Elf Parse Functions
MR4TH_SYMBOL ELF_Parse* elfp_begin(Arena *arena, String8 data);
MR4TH_SYMBOL void elfp_header_read(ELF_Parse *elf, ELF_Header64 *out);
MR4TH_SYMBOL U32 elfp_section_count(ELF_Parse *elf);
MR4TH_SYMBOL void elfp_section_read(ELF_Parse *elf, U32 idx, ELF_Section64 *out);
MR4TH_SYMBOL String8 elfp_section_name(ELF_Parse *elf, U32 idx);
MR4TH_SYMBOL U32 elfp_segment_count(ELF_Parse *elf);
MR4TH_SYMBOL void elfp_segment_read(ELF_Parse *elf, U32 idx, ELF_Segment64 *out);
MR4TH_SYMBOL U32 elfp_symbol_count(ELF_Parse *elf, U32 table);
MR4TH_SYMBOL void elfp_symbol_read(ELF_Parse *elf, U32 table, U32 idx, ELF_Symbol64 *out);
MR4TH_SYMBOL String8 elfp_symbol_name(ELF_Parse *elf, U32 table, U32 idx);
MR4TH_SYMBOL U32 elfp_relocs_count(ELF_Parse *elf, U32 secidx);
MR4TH_SYMBOL void elfp_relocs_read(ELF_Parse *elf, U32 secidx, U32 relocidx, ELF_RelocationAdd64 *out);
#endif //MR4TH_ELF_PARSE_H