481 lines
16 KiB
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);
|
|
}
|