major version 1.0 (actual)
parent
32ce56df78
commit
cba79b611e
|
|
@ -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
|
||||
|
|
|
|||
5861
mr4th/mr4th_base.c
5861
mr4th/mr4th_base.c
File diff suppressed because it is too large
Load Diff
1891
mr4th/mr4th_base.h
1891
mr4th/mr4th_base.h
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue