c-scripting/symbol_set.ld_meta/mr4th/exefmt/elf/mr4th_elf.c

481 lines
16 KiB
C

////////////////////////////////
// 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);
}