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