mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07:00
deleted obsolete DWARF parser files
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,102 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ DWARF Stringize Functions
|
||||
|
||||
static char dwarf_spaces[] = " ";
|
||||
|
||||
static void
|
||||
dwarf_stringize_info(Arena *arena, String8List *out, DWARF_InfoUnit *unit, U32 indent){
|
||||
String8 unit_type_string = dwarf_string_from_unit_type((DWARF_UnitType)unit->unit_type);
|
||||
|
||||
str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off);
|
||||
str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off);
|
||||
str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off);
|
||||
str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces,
|
||||
unit->offset_size);
|
||||
str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version);
|
||||
str8_list_pushf(arena, out, "%.*sunit_type=%.*s\n", indent, dwarf_spaces,
|
||||
str8_varg(unit_type_string));
|
||||
str8_list_pushf(arena, out, "%.*saddress_size=%u\n", indent, dwarf_spaces,
|
||||
unit->address_size);
|
||||
str8_list_pushf(arena, out, "%.*sabbrev_off=0x%llx\n", indent, dwarf_spaces,
|
||||
unit->abbrev_off);
|
||||
|
||||
switch (unit->unit_type){
|
||||
case DWARF_UnitType_skeleton: case DWARF_UnitType_split_compile:
|
||||
{
|
||||
str8_list_pushf(arena, out, "%.*sdwo_id=%llu\n", indent, dwarf_spaces, unit->dwo_id);
|
||||
}break;
|
||||
|
||||
case DWARF_UnitType_type: case DWARF_UnitType_split_type:
|
||||
{
|
||||
str8_list_pushf(arena, out, "%.*stype_signature=%llu\n", indent, dwarf_spaces,
|
||||
unit->type_signature);
|
||||
str8_list_pushf(arena, out, "%.*stype_offset=%llu\n", indent, dwarf_spaces,
|
||||
unit->type_offset);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dwarf_stringize_pubnames(Arena *arena, String8List *out, DWARF_PubNamesUnit *unit,
|
||||
U32 indent){
|
||||
str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off);
|
||||
str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off);
|
||||
str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off);
|
||||
str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, unit->offset_size);
|
||||
str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version);
|
||||
str8_list_pushf(arena, out, "%.*sinfo_off=0x%llx\n", indent, dwarf_spaces, unit->info_off);
|
||||
str8_list_pushf(arena, out, "%.*sinfo_length=0x%llx\n", indent, dwarf_spaces,
|
||||
unit->info_length);
|
||||
}
|
||||
|
||||
static void
|
||||
dwarf_stringize_names(Arena *arena, String8List *out, DWARF_NamesUnit *unit, U32 indent){
|
||||
str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off);
|
||||
str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off);
|
||||
str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off);
|
||||
str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version);
|
||||
str8_list_pushf(arena, out, "%.*scomp_unit_count=%u\n", indent, dwarf_spaces,
|
||||
unit->comp_unit_count);
|
||||
str8_list_pushf(arena, out, "%.*slocal_type_unit_count=%u\n", indent, dwarf_spaces,
|
||||
unit->local_type_unit_count);
|
||||
str8_list_pushf(arena, out, "%.*sforeign_type_unit_count=%u\n", indent, dwarf_spaces,
|
||||
unit->foreign_type_unit_count);
|
||||
str8_list_pushf(arena, out, "%.*sbucket_count=%u\n", indent, dwarf_spaces,
|
||||
unit->bucket_count);
|
||||
str8_list_pushf(arena, out, "%.*sname_count=%u\n", indent, dwarf_spaces, unit->name_count);
|
||||
str8_list_pushf(arena, out, "%.*sabbrev_table_size=%u\n", indent, dwarf_spaces,
|
||||
unit->abbrev_table_size);
|
||||
str8_list_pushf(arena, out, "%.*saugmentation_string=%.*s\n", indent, dwarf_spaces,
|
||||
str8_varg(unit->augmentation_string));
|
||||
}
|
||||
|
||||
static void
|
||||
dwarf_stringize_aranges(Arena *arena, String8List *out, DWARF_ArangesUnit *unit, U32 indent){
|
||||
str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off);
|
||||
str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off);
|
||||
str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off);
|
||||
str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version);
|
||||
str8_list_pushf(arena, out, "%.*saddress_size=%u\n", indent, dwarf_spaces,
|
||||
unit->address_size);
|
||||
str8_list_pushf(arena, out, "%.*ssegment_selector_size=%u\n", indent, dwarf_spaces,
|
||||
unit->segment_selector_size);
|
||||
str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, unit->offset_size);
|
||||
str8_list_pushf(arena, out, "%.*sinfo_off=0x%llx\n", indent, dwarf_spaces, unit->info_off);
|
||||
}
|
||||
|
||||
static void
|
||||
dwarf_stringize_addr(Arena *arena, String8List *out, DWARF_AddrUnit *unit, U32 indent){
|
||||
str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off);
|
||||
str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off);
|
||||
str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off);
|
||||
str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces,
|
||||
unit->offset_size);
|
||||
str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->dwarf_version);
|
||||
str8_list_pushf(arena, out, "%.*saddress_size=%u\n", indent, dwarf_spaces,
|
||||
unit->address_size);
|
||||
str8_list_pushf(arena, out, "%.*ssegment_selector_size=%u\n", indent, dwarf_spaces,
|
||||
unit->segment_selector_size);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef RDI_DWARF_STRINGIZE_H
|
||||
#define RDI_DWARF_STRINGIZE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ DWARF Stringize Functions
|
||||
|
||||
static void
|
||||
dwarf_stringize_info(Arena *arena, String8List *out, DWARF_InfoUnit *unit, U32 indent);
|
||||
|
||||
static void
|
||||
dwarf_stringize_pubnames(Arena *arena, String8List *out, DWARF_PubNamesUnit *unit,
|
||||
U32 indent);
|
||||
|
||||
static void
|
||||
dwarf_stringize_names(Arena *arena, String8List *out, DWARF_NamesUnit *unit, U32 indent);
|
||||
|
||||
static void
|
||||
dwarf_stringize_aranges(Arena *arena, String8List *out, DWARF_ArangesUnit *unit, U32 indent);
|
||||
|
||||
static void
|
||||
dwarf_stringize_addr(Arena *arena, String8List *out, DWARF_AddrUnit *unit, U32 indent);
|
||||
|
||||
|
||||
|
||||
#endif //RDI_DWARF_STRINGIZE_H
|
||||
@@ -1,557 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ ELF Parser Functions
|
||||
|
||||
static ELF_Parsed*
|
||||
elf_parsed_from_data(Arena *arena, String8 elf_data){
|
||||
//- test magic number
|
||||
B32 has_good_magic_number = 0;
|
||||
if (elf_data.size >= sizeof(ELF_NIDENT) &&
|
||||
MemoryMatch(elf_data.str, elf_magic, sizeof(elf_magic))){
|
||||
has_good_magic_number = 1;
|
||||
}
|
||||
|
||||
//- determine elf class
|
||||
U8 elf_class = ELF_Class_NONE;
|
||||
if (has_good_magic_number){
|
||||
elf_class = elf_data.str[ELF_Identification_CLASS];
|
||||
}
|
||||
|
||||
//- extract header information
|
||||
B32 decoded_header = 0;
|
||||
|
||||
U8 e_data_encoding = ELF_DataEncoding_NONE;
|
||||
U16 e_machine = ELF_Machine_NONE;
|
||||
|
||||
U64 e_entry = 0;
|
||||
|
||||
U64 e_shoff = 0;
|
||||
U16 e_shentsize = 0;
|
||||
U16 e_shnum = 0;
|
||||
|
||||
U64 e_phoff = 0;
|
||||
U16 e_phentsize = 0;
|
||||
U16 e_phnum = 0;
|
||||
|
||||
U16 e_shstrndx = 0;
|
||||
|
||||
switch (elf_class){
|
||||
case ELF_Class_NONE: /* not good */ break;
|
||||
|
||||
case ELF_Class_32:
|
||||
{
|
||||
if (elf_data.size >= sizeof(ELF_Ehdr32)){
|
||||
ELF_Ehdr32 *hdr = (ELF_Ehdr32*)elf_data.str;
|
||||
|
||||
decoded_header = 1;
|
||||
e_data_encoding = hdr->e_ident[ELF_Identification_DATA];
|
||||
e_machine = hdr->e_machine;
|
||||
e_entry = hdr->e_entry;
|
||||
e_phoff = hdr->e_phoff;
|
||||
e_shoff = hdr->e_shoff;
|
||||
e_phentsize = hdr->e_phentsize;
|
||||
e_phnum = hdr->e_phnum;
|
||||
e_shentsize = hdr->e_shentsize;
|
||||
e_shnum = hdr->e_shnum;
|
||||
e_shstrndx = hdr->e_shstrndx;
|
||||
}
|
||||
}break;
|
||||
|
||||
case ELF_Class_64:
|
||||
{
|
||||
if (elf_data.size >= sizeof(ELF_Ehdr64)){
|
||||
ELF_Ehdr64 *hdr = (ELF_Ehdr64*)elf_data.str;
|
||||
|
||||
decoded_header = 1;
|
||||
e_data_encoding = hdr->e_ident[ELF_Identification_DATA];
|
||||
e_machine = hdr->e_machine;
|
||||
e_entry = hdr->e_entry;
|
||||
e_phoff = hdr->e_phoff;
|
||||
e_shoff = hdr->e_shoff;
|
||||
e_phentsize = hdr->e_phentsize;
|
||||
e_phnum = hdr->e_phnum;
|
||||
e_shentsize = hdr->e_shentsize;
|
||||
e_shnum = hdr->e_shnum;
|
||||
e_shstrndx = hdr->e_shstrndx;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
|
||||
//- validate & translate header values
|
||||
B32 header_is_good = 0;
|
||||
Arch arch = Arch_Null;
|
||||
if (decoded_header){
|
||||
header_is_good = 1;
|
||||
|
||||
// only supporting little-endian versions right now
|
||||
if (header_is_good){
|
||||
if (e_data_encoding != ELF_DataEncoding_2LSB){
|
||||
header_is_good = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure this is a supported machine type
|
||||
if (header_is_good){
|
||||
switch (e_machine){
|
||||
default: header_is_good = 0;
|
||||
case ELF_Machine_386: arch = Arch_x86; break;
|
||||
case ELF_Machine_X86_64: arch = Arch_x64; break;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure section & segment sizes are correct
|
||||
if (header_is_good){
|
||||
switch (elf_class){
|
||||
case ELF_Class_32:
|
||||
{
|
||||
if (e_shentsize != sizeof(ELF_Shdr32) ||
|
||||
e_phentsize != sizeof(ELF_Phdr32)){
|
||||
header_is_good = 0;
|
||||
}
|
||||
}break;
|
||||
case ELF_Class_64:
|
||||
{
|
||||
if (e_shentsize != sizeof(ELF_Shdr64) ||
|
||||
e_phentsize != sizeof(ELF_Phdr64)){
|
||||
header_is_good = 0;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- extract extra information from the special first section
|
||||
U64 section_count_raw = e_shnum;
|
||||
U32 section_header_string_table_index = e_shstrndx;
|
||||
if (header_is_good){
|
||||
if (e_shoff <= elf_data.size && e_shentsize <= elf_data.size &&
|
||||
e_shoff + e_shentsize <= elf_data.size){
|
||||
U64 size = 0;
|
||||
U32 link = 0;
|
||||
switch (elf_class){
|
||||
case ELF_Class_32:
|
||||
{
|
||||
ELF_Shdr32 *shdr = (ELF_Shdr32*)(elf_data.str + e_shoff);
|
||||
size = shdr->sh_size;
|
||||
link = shdr->sh_link;
|
||||
}break;
|
||||
case ELF_Class_64:
|
||||
{
|
||||
ELF_Shdr64 *shdr = (ELF_Shdr64*)(elf_data.str + e_shoff);
|
||||
size = shdr->sh_size;
|
||||
link = shdr->sh_link;
|
||||
}break;
|
||||
}
|
||||
|
||||
// extended section count
|
||||
if (size != 0){
|
||||
section_count_raw = size;
|
||||
}
|
||||
|
||||
// extended section header string table index
|
||||
if (link != 0){
|
||||
section_header_string_table_index = link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- clamp section & program arrays to size
|
||||
U64 section_foff = 0;
|
||||
U64 section_size = 0;
|
||||
U64 section_count = 0;
|
||||
|
||||
U64 segment_foff = 0;
|
||||
U64 segment_size = 0;
|
||||
U64 segment_count = 0;
|
||||
|
||||
if (header_is_good){
|
||||
if (e_shentsize > 0){
|
||||
U64 section_opl_raw = e_shoff + e_shentsize*section_count_raw;
|
||||
U64 section_opl = ClampTop(section_opl_raw, elf_data.size);
|
||||
if (section_opl > e_shoff){
|
||||
section_foff = e_shoff;
|
||||
section_size = e_shentsize;
|
||||
section_count = (section_opl - e_shoff)/e_shentsize;
|
||||
}
|
||||
}
|
||||
|
||||
if (e_phentsize > 0){
|
||||
U64 segment_opl_raw = e_phoff + e_phentsize*e_phnum;
|
||||
U64 segment_opl = ClampTop(segment_opl_raw, elf_data.size);
|
||||
if (segment_opl > e_phoff){
|
||||
segment_foff = e_phoff;
|
||||
segment_size = e_phentsize;
|
||||
segment_count = (segment_opl - e_phoff)/e_phentsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- determine the vbase for this file
|
||||
U64 vbase = 0;
|
||||
if (header_is_good){
|
||||
// find the first LOAD segment
|
||||
U64 load_segment_off = 0;
|
||||
{
|
||||
U64 segment_cursor = segment_foff;
|
||||
U64 segment_opl = segment_foff + segment_size*segment_count;
|
||||
for (;segment_cursor < segment_opl; segment_cursor += segment_size){
|
||||
U32 p_type = *(U32*)(elf_data.str + segment_cursor);
|
||||
if (p_type == ELF_SegmentType_LOAD){
|
||||
load_segment_off = segment_cursor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use the segment's p_vaddr to determine vbase
|
||||
if (load_segment_off != 0){
|
||||
switch (elf_class){
|
||||
case ELF_Class_32:
|
||||
{
|
||||
ELF_Phdr32 *phdr = (ELF_Phdr32*)(elf_data.str + load_segment_off);
|
||||
vbase = phdr->p_vaddr;
|
||||
}break;
|
||||
case ELF_Class_64:
|
||||
{
|
||||
ELF_Phdr64 *phdr = (ELF_Phdr64*)(elf_data.str + load_segment_off);
|
||||
vbase = phdr->p_vaddr;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- locate the section header string table
|
||||
U64 section_name_table_foff = 0;
|
||||
U64 section_name_table_opl = 0;
|
||||
if (header_is_good){
|
||||
if (section_header_string_table_index < section_count){
|
||||
U64 sec_foff = section_foff + section_header_string_table_index*section_size;
|
||||
switch (elf_class){
|
||||
case ELF_Class_32:
|
||||
{
|
||||
ELF_Shdr32 *shdr = (ELF_Shdr32*)(elf_data.str + sec_foff);
|
||||
section_name_table_foff = shdr->sh_offset;
|
||||
section_name_table_opl = shdr->sh_offset + shdr->sh_size;
|
||||
}break;
|
||||
case ELF_Class_64:
|
||||
{
|
||||
ELF_Shdr64 *shdr = (ELF_Shdr64*)(elf_data.str + sec_foff);
|
||||
section_name_table_foff = shdr->sh_offset;
|
||||
section_name_table_opl = shdr->sh_offset + shdr->sh_size;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- format sections data
|
||||
ELF_Shdr64 *sections = 0;
|
||||
if (header_is_good && section_count > 0){
|
||||
switch (elf_class){
|
||||
case ELF_Class_32:
|
||||
{
|
||||
sections = push_array(arena, ELF_Shdr64, section_count);
|
||||
{
|
||||
ELF_Shdr32 *shdr32 = (ELF_Shdr32*)(elf_data.str + section_foff);
|
||||
ELF_Shdr64 *shdr64 = sections;
|
||||
for (U64 i = 0; i < section_count; i += 1, shdr32 += 1, shdr64 += 1){
|
||||
shdr64->sh_name = shdr32->sh_name;
|
||||
shdr64->sh_type = shdr32->sh_type;
|
||||
shdr64->sh_flags = shdr32->sh_flags;
|
||||
shdr64->sh_addr = shdr32->sh_addr;
|
||||
shdr64->sh_offset = shdr32->sh_offset;
|
||||
shdr64->sh_size = shdr32->sh_size;
|
||||
shdr64->sh_link = shdr32->sh_link;
|
||||
shdr64->sh_info = shdr32->sh_info;
|
||||
shdr64->sh_addralign = shdr32->sh_addralign;
|
||||
shdr64->sh_entsize = shdr32->sh_entsize;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
case ELF_Class_64:
|
||||
{
|
||||
sections = (ELF_Shdr64*)(elf_data.str + section_foff);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
//- extract section names
|
||||
String8 *section_names = 0;
|
||||
if (sections != 0 && section_count > 0){
|
||||
U8 *string_table_opl = elf_data.str + section_name_table_opl;
|
||||
|
||||
section_names = push_array(arena, String8, section_count);
|
||||
String8 *sec_name = section_names;
|
||||
ELF_Shdr64 *sec = sections;
|
||||
for (U64 i = 0;
|
||||
i < section_count;
|
||||
i += 1, sec += 1, sec_name += 1){
|
||||
U64 name_foff = section_name_table_foff + sec->sh_name;
|
||||
if (section_name_table_foff <= name_foff && name_foff < section_name_table_opl){
|
||||
U8 *base = elf_data.str + name_foff;
|
||||
U8 *opl = base;
|
||||
for (;opl < string_table_opl && *opl != 0; opl += 1);
|
||||
sec_name->str = base;
|
||||
sec_name->size = (U64)(opl - base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- format segments data
|
||||
ELF_Phdr64 *segments = 0;
|
||||
if (header_is_good && segment_count > 0){
|
||||
switch (elf_class){
|
||||
case ELF_Class_32:
|
||||
{
|
||||
segments = push_array(arena, ELF_Phdr64, segment_count);
|
||||
{
|
||||
ELF_Phdr32 *phdr32 = (ELF_Phdr32*)(elf_data.str + segment_foff);
|
||||
ELF_Phdr64 *phdr64 = segments;
|
||||
for (U64 i = 0; i < segment_count; i += 1, phdr32 += 1, phdr64 += 1){
|
||||
phdr64->p_type = phdr32->p_type;
|
||||
phdr64->p_flags = phdr32->p_flags;
|
||||
phdr64->p_offset = phdr32->p_offset;
|
||||
phdr64->p_vaddr = phdr32->p_vaddr;
|
||||
phdr64->p_paddr = phdr32->p_paddr;
|
||||
phdr64->p_filesz = phdr32->p_filesz;
|
||||
phdr64->p_memsz = phdr32->p_memsz;
|
||||
phdr64->p_align = phdr32->p_align;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
case ELF_Class_64:
|
||||
{
|
||||
segments = (ELF_Phdr64*)(elf_data.str + segment_foff);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
//- find special sections
|
||||
U64 strtab_idx = 0;
|
||||
U64 symtab_idx = 0;
|
||||
U64 dynsym_idx = 0;
|
||||
if (section_names != 0){
|
||||
for (U64 i = 0; i < section_count; i += 1){
|
||||
String8 name = section_names[i];
|
||||
if (str8_match(name, str8_lit(".strtab"), 0)){
|
||||
strtab_idx = i;
|
||||
}
|
||||
else if (str8_match(name, str8_lit(".symtab"), 0)){
|
||||
symtab_idx = i;
|
||||
}
|
||||
else if (str8_match(name, str8_lit(".dynsym"), 0)){
|
||||
dynsym_idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- fill result
|
||||
ELF_Parsed *result = 0;
|
||||
if (header_is_good){
|
||||
result = push_array(arena, ELF_Parsed, 1);
|
||||
result->data = elf_data;
|
||||
result->elf_class = elf_class;
|
||||
result->arch = arch;
|
||||
result->sections = sections;
|
||||
result->section_names = section_names;
|
||||
result->section_foff = section_foff;
|
||||
result->section_count = section_count;
|
||||
result->segments = segments;
|
||||
result->segment_foff = segment_foff;
|
||||
result->segment_count = segment_count;
|
||||
result->vbase = vbase;
|
||||
result->entry_vaddr = e_entry;
|
||||
result->section_name_table_foff = section_name_table_foff;
|
||||
result->section_name_table_opl = section_name_table_opl;
|
||||
result->strtab_idx = strtab_idx;
|
||||
result->symtab_idx = symtab_idx;
|
||||
result->dynsym_idx = dynsym_idx;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static ELF_SectionArray
|
||||
elf_section_array_from_elf(ELF_Parsed *elf){
|
||||
ELF_SectionArray result = {0};
|
||||
if (elf != 0){
|
||||
result.sections = elf->sections;
|
||||
result.count = elf->section_count;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static String8Array
|
||||
elf_section_name_array_from_elf(ELF_Parsed *elf){
|
||||
String8Array result = {0};
|
||||
if (elf != 0){
|
||||
result.v = elf->section_names;
|
||||
result.count = elf->section_count;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static ELF_SegmentArray
|
||||
elf_segment_array_from_elf(ELF_Parsed *elf){
|
||||
ELF_SegmentArray result = {0};
|
||||
if (elf != 0){
|
||||
result.segments = elf->segments;
|
||||
result.count = elf->segment_count;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static String8
|
||||
elf_section_name_from_name_offset(ELF_Parsed *elf, U64 offset){
|
||||
String8 result = {0};
|
||||
if (elf != 0){
|
||||
if (offset > 0){
|
||||
U64 foff = elf->section_name_table_foff + offset;
|
||||
if (elf->section_name_table_foff <= foff && foff < elf->section_name_table_opl){
|
||||
U8 *base = elf->data.str + foff;
|
||||
U8 *section_opl = elf->data.str + elf->section_name_table_opl;
|
||||
U8 *opl = base;
|
||||
for (;opl < section_opl && *opl != 0; opl += 1);
|
||||
result.str = base;
|
||||
result.size = opl - base;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static String8
|
||||
elf_section_name_from_idx(ELF_Parsed *elf, U32 idx){
|
||||
String8 result = {0};
|
||||
if (elf != 0){
|
||||
if (idx < elf->section_count){
|
||||
result = elf->section_names[idx];
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static U32
|
||||
elf_section_idx_from_name(ELF_Parsed *elf, String8 name){
|
||||
U32 result = 0;
|
||||
if (elf != 0){
|
||||
String8 *sec_name = elf->section_names;
|
||||
U64 count = elf->section_count;
|
||||
for (U64 i = 0; i < count; i += 1, sec_name += 1){
|
||||
if (str8_match(*sec_name, name, 0)){
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static String8
|
||||
elf_section_data_from_idx(ELF_Parsed *elf, U32 idx){
|
||||
String8 result = {0};
|
||||
if (elf != 0){
|
||||
if (idx < elf->section_count){
|
||||
ELF_Shdr64 *shdr = elf->sections + idx;
|
||||
U64 off_raw = shdr->sh_offset;
|
||||
U64 size = shdr->sh_size;
|
||||
if (shdr->sh_flags & ELF_SectionType_NOBITS){
|
||||
size = 0;
|
||||
}
|
||||
U64 opl_raw = off_raw + size;
|
||||
U64 opl = ClampTop(opl_raw, elf->data.size);
|
||||
U64 off = ClampTop(off_raw, opl);
|
||||
result.str = elf->data.str + off;
|
||||
result.size = opl - off;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static ELF_SymArray
|
||||
elf_sym_array_from_data(Arena *arena, ELF_Class elf_class, String8 data){
|
||||
// converge to sym64 layout
|
||||
ELF_Sym64 *symbols = 0;
|
||||
U64 count = 0;
|
||||
switch (elf_class){
|
||||
default:{}break;
|
||||
|
||||
case ELF_Class_32:
|
||||
{
|
||||
count = data.size/sizeof(ELF_Sym32);
|
||||
symbols = push_array(arena, ELF_Sym64, count);
|
||||
{
|
||||
ELF_Sym32 *sym32 = (ELF_Sym32*)(data.str);
|
||||
ELF_Sym64 *sym64 = symbols;
|
||||
for (U64 i = 0; i < count; i += 1, sym32 += 1, sym64 += 1){
|
||||
sym64->st_name = sym32->st_name;
|
||||
sym64->st_value = sym32->st_value;
|
||||
sym64->st_size = sym32->st_size;
|
||||
sym64->st_info = sym32->st_info;
|
||||
sym64->st_other = sym32->st_other;
|
||||
sym64->st_shndx = sym32->st_shndx;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
case ELF_Class_64:
|
||||
{
|
||||
count = data.size/sizeof(ELF_Sym64);
|
||||
symbols = (ELF_Sym64*)(data.str);
|
||||
}break;
|
||||
}
|
||||
|
||||
// fill result
|
||||
ELF_SymArray result = {0};
|
||||
result.symbols = symbols;
|
||||
result.count = count;
|
||||
return(result);
|
||||
}
|
||||
|
||||
// string functions
|
||||
|
||||
static String8
|
||||
elf_string_from_section_type(ELF_SectionType section_type){
|
||||
String8 result = str8_lit("INVALID_SECTION_TYPE");
|
||||
switch (section_type){
|
||||
#define X(N,C) case C: result = str8_lit(#N); break;
|
||||
ELF_SectionTypeXList(X)
|
||||
#undef X
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static String8
|
||||
elf_string_from_symbol_binding(ELF_SymbolBinding binding){
|
||||
String8 result = str8_lit("INVALID_SYMBOL_BINDING");
|
||||
switch (binding){
|
||||
#define X(N,C) case C: result = str8_lit(#N); break;
|
||||
ELF_SymbolBindingXList(X)
|
||||
#undef X
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static String8
|
||||
elf_string_from_symbol_type(ELF_SymbolType type){
|
||||
String8 result = str8_lit("INVALID_SYMBOL_TYPE");
|
||||
switch (type){
|
||||
#define X(N,C) case C: result = str8_lit(#N); break;
|
||||
ELF_SymbolTypeXList(X)
|
||||
#undef X
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static String8
|
||||
elf_string_from_symbol_visibility(ELF_SymbolVisibility visibility){
|
||||
String8 result = str8_lit("INVALID_SYMBOL_VISIBILITY");
|
||||
switch (visibility){
|
||||
#define X(N,C) case C: result = str8_lit(#N); break;
|
||||
ELF_SymbolVisibilityXList(X)
|
||||
#undef X
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
@@ -1,517 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef RDI_ELF_H
|
||||
#define RDI_ELF_H
|
||||
|
||||
// https://refspecs.linuxfoundation.org/elf/elf.pdf
|
||||
|
||||
////////////////////////////////
|
||||
//~ Elf Format Types
|
||||
|
||||
// elf header
|
||||
|
||||
#define ELF_NIDENT 16
|
||||
|
||||
typedef struct ELF_Ehdr32{
|
||||
U8 e_ident[ELF_NIDENT];
|
||||
U16 e_type;
|
||||
U16 e_machine;
|
||||
U32 e_version;
|
||||
U32 e_entry;
|
||||
U32 e_phoff;
|
||||
U32 e_shoff;
|
||||
U32 e_flags;
|
||||
U16 e_ehsize;
|
||||
U16 e_phentsize;
|
||||
U16 e_phnum;
|
||||
U16 e_shentsize;
|
||||
U16 e_shnum;
|
||||
U16 e_shstrndx;
|
||||
} ELF_Ehdr32;
|
||||
|
||||
typedef struct ELF_Ehdr64{
|
||||
U8 e_ident[ELF_NIDENT];
|
||||
U16 e_type;
|
||||
U16 e_machine;
|
||||
U32 e_version;
|
||||
U64 e_entry;
|
||||
U64 e_phoff;
|
||||
U64 e_shoff;
|
||||
U32 e_flags;
|
||||
U16 e_ehsize;
|
||||
U16 e_phentsize;
|
||||
U16 e_phnum;
|
||||
U16 e_shentsize;
|
||||
U16 e_shnum;
|
||||
U16 e_shstrndx;
|
||||
} ELF_Ehdr64;
|
||||
|
||||
typedef enum ELF_Type{
|
||||
ELF_Type_NONE = 0,
|
||||
ELF_Type_REL = 1,
|
||||
ELF_Type_EXEC = 2,
|
||||
ELF_Type_DYN = 3,
|
||||
ELF_Type_CORE = 4,
|
||||
ELF_Type_LOOS = 0xfe00,
|
||||
ELF_Type_HIOS = 0xfeff,
|
||||
ELF_Type_LOPROC = 0xff00,
|
||||
ELF_Type_HIPROC = 0xffff,
|
||||
} ELF_Type;
|
||||
|
||||
typedef enum ELF_Machine{
|
||||
ELF_Machine_NONE = 0,
|
||||
ELF_Machine_M32 = 1,
|
||||
ELF_Machine_SPARC = 2,
|
||||
ELF_Machine_386 = 3,
|
||||
ELF_Machine_68K = 4,
|
||||
ELF_Machine_88K = 5,
|
||||
ELF_Machine_860 = 7,
|
||||
ELF_Machine_MIPS = 8,
|
||||
ELF_Machine_S370 = 9,
|
||||
ELF_Machine_MIPS_RS3_LE = 10,
|
||||
ELF_Machine_PARISC = 15,
|
||||
ELF_Machine_VPP500 = 17,
|
||||
ELF_Machine_SPARC32PLUS = 18,
|
||||
ELF_Machine_960 = 19,
|
||||
ELF_Machine_PPC = 20,
|
||||
ELF_Machine_PPC64 = 21,
|
||||
ELF_Machine_S390 = 22,
|
||||
ELF_Machine_V800 = 36,
|
||||
ELF_Machine_FR20 = 37,
|
||||
ELF_Machine_RH32 = 38,
|
||||
ELF_Machine_RCE = 39,
|
||||
ELF_Machine_ARM = 40,
|
||||
ELF_Machine_ALPHA = 41,
|
||||
ELF_Machine_SH = 42,
|
||||
ELF_Machine_SPARCV9 = 43,
|
||||
ELF_Machine_TRICORE = 44,
|
||||
ELF_Machine_ARC = 45,
|
||||
ELF_Machine_H8_300 = 46,
|
||||
ELF_Machine_H8_300H = 47,
|
||||
ELF_Machine_H8S = 48,
|
||||
ELF_Machine_H8_500 = 49,
|
||||
ELF_Machine_IA_64 = 50,
|
||||
ELF_Machine_MIPS_X = 51,
|
||||
ELF_Machine_COLDFIRE = 52,
|
||||
ELF_Machine_68HC12 = 53,
|
||||
ELF_Machine_MMA = 54,
|
||||
ELF_Machine_PCP = 55,
|
||||
ELF_Machine_NCPU = 56,
|
||||
ELF_Machine_NDR1 = 57,
|
||||
ELF_Machine_STARCORE = 58,
|
||||
ELF_Machine_ME16 = 59,
|
||||
ELF_Machine_ST100 = 60,
|
||||
ELF_Machine_TINYJ = 61,
|
||||
ELF_Machine_X86_64 = 62,
|
||||
ELF_Machine_PDSP = 63,
|
||||
ELF_Machine_PDP10 = 64,
|
||||
ELF_Machine_PDP11 = 65,
|
||||
ELF_Machine_FX66 = 66,
|
||||
ELF_Machine_ST9PLUS = 67,
|
||||
ELF_Machine_ST7 = 68,
|
||||
ELF_Machine_68HC16 = 69,
|
||||
ELF_Machine_68HC11 = 70,
|
||||
ELF_Machine_68HC08 = 71,
|
||||
ELF_Machine_68HC05 = 72,
|
||||
ELF_Machine_SVX = 73,
|
||||
ELF_Machine_ST19 = 74,
|
||||
ELF_Machine_VAX = 75,
|
||||
ELF_Machine_CRIS = 76,
|
||||
ELF_Machine_JAVELIN = 77,
|
||||
ELF_Machine_FIREPATH = 78,
|
||||
ELF_Machine_ZSP = 79,
|
||||
ELF_Machine_MMIX = 80,
|
||||
ELF_Machine_HUANY = 81,
|
||||
ELF_Machine_PRISM = 82,
|
||||
ELF_Machine_AVR = 83,
|
||||
ELF_Machine_FR30 = 84,
|
||||
ELF_Machine_D10V = 85,
|
||||
ELF_Machine_D30V = 86,
|
||||
ELF_Machine_V850 = 87,
|
||||
ELF_Machine_M32R = 88,
|
||||
ELF_Machine_MN10300 = 89,
|
||||
ELF_Machine_MN10200 = 90,
|
||||
ELF_Machine_PJ = 91,
|
||||
ELF_Machine_OPENRISC = 92,
|
||||
ELF_Machine_ARC_A5 = 93,
|
||||
ELF_Machine_XTENSA = 94,
|
||||
ELF_Machine_VIDEOCORE = 95,
|
||||
ELF_Machine_TMM_GPP = 96,
|
||||
ELF_Machine_NS32K = 97,
|
||||
ELF_Machine_TPC = 98,
|
||||
ELF_Machine_SNP1K = 99,
|
||||
ELF_Machine_ST200 = 100,
|
||||
} ELF_Machine;
|
||||
|
||||
typedef enum ELF_Version{
|
||||
ELF_Version_NONE = 0,
|
||||
ELF_Version_CURRENT = 1,
|
||||
} ELF_Version;
|
||||
|
||||
typedef enum ELF_Identification{
|
||||
ELF_Identification_MAG0 = 0,
|
||||
ELF_Identification_MAG1 = 1,
|
||||
ELF_Identification_MAG2 = 2,
|
||||
ELF_Identification_MAG3 = 3,
|
||||
ELF_Identification_CLASS = 4,
|
||||
ELF_Identification_DATA = 5,
|
||||
ELF_Identification_VERSION = 6,
|
||||
ELF_Identification_OSABI = 7,
|
||||
ELF_Identification_ABIVERSION = 8,
|
||||
ELF_Identification_PAD = 9,
|
||||
} ELF_Identification;
|
||||
|
||||
read_only global U8 elf_magic[] = {0x7F, 'E', 'L', 'F'};
|
||||
|
||||
typedef enum ELF_Class{
|
||||
ELF_Class_NONE = 0,
|
||||
ELF_Class_32 = 1,
|
||||
ELF_Class_64 = 2,
|
||||
} ELF_Class;
|
||||
|
||||
typedef enum ELF_DataEncoding{
|
||||
ELF_DataEncoding_NONE = 0,
|
||||
ELF_DataEncoding_2LSB = 1,
|
||||
ELF_DataEncoding_2MSB = 2,
|
||||
} ELF_DataEncoding;
|
||||
|
||||
typedef enum ELF_OsAbi{
|
||||
ELF_OsAbi_NONE = 0,
|
||||
ELF_OsAbi_HPUX = 1,
|
||||
ELF_OsAbi_NETBSD = 2,
|
||||
ELF_OsAbi_LINUX = 3,
|
||||
ELF_OsAbi_SOLARIS = 6,
|
||||
ELF_OsAbi_AIX = 7,
|
||||
ELF_OsAbi_IRIX = 8,
|
||||
ELF_OsAbi_FREEBSD = 9,
|
||||
ELF_OsAbi_TRU64 = 10,
|
||||
ELF_OsAbi_MODESTO = 11,
|
||||
ELF_OsAbi_OPENBSD = 12,
|
||||
ELF_OsAbi_OPENVMS = 13,
|
||||
ELF_OsAbi_NSK = 14,
|
||||
} ELF_OsAbi;
|
||||
|
||||
// sections
|
||||
|
||||
typedef enum ELF_ReservedSectionIndex{
|
||||
ELF_ReservedSectionIndex_UNDEF = 0,
|
||||
ELF_ReservedSectionIndex_LORESERVE = 0xFF00,
|
||||
ELF_ReservedSectionIndex_LOPROC = 0xFF00,
|
||||
ELF_ReservedSectionIndex_HIPROC = 0xFF1F,
|
||||
ELF_ReservedSectionIndex_LOOS = 0xFF20,
|
||||
ELF_ReservedSectionIndex_HIOS = 0xFF3F,
|
||||
ELF_ReservedSectionIndex_ABS = 0xFFF1,
|
||||
ELF_ReservedSectionIndex_COMMON = 0xFFF2,
|
||||
ELF_ReservedSectionIndex_XINDEX = 0xFFFF,
|
||||
ELF_ReservedSectionIndex_HIRESERVE = 0xFFFF,
|
||||
} ELF_ReservedSectionIndex;
|
||||
|
||||
typedef struct ELF_Shdr32{
|
||||
U32 sh_name;
|
||||
U32 sh_type;
|
||||
U32 sh_flags;
|
||||
U32 sh_addr;
|
||||
U32 sh_offset;
|
||||
U32 sh_size;
|
||||
U32 sh_link;
|
||||
U32 sh_info;
|
||||
U32 sh_addralign;
|
||||
U32 sh_entsize;
|
||||
} ELF_Shdr32;
|
||||
|
||||
typedef struct ELF_Shdr64{
|
||||
U32 sh_name;
|
||||
U32 sh_type;
|
||||
U64 sh_flags;
|
||||
U64 sh_addr;
|
||||
U64 sh_offset;
|
||||
U64 sh_size;
|
||||
U32 sh_link;
|
||||
U32 sh_info;
|
||||
U64 sh_addralign;
|
||||
U64 sh_entsize;
|
||||
} ELF_Shdr64;
|
||||
|
||||
// X(name, code)
|
||||
#define ELF_SectionTypeXList(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, 0x8FFFFFFF)
|
||||
|
||||
typedef enum ELF_SectionType{
|
||||
#define X(N,C) ELF_SectionType_##N = C,
|
||||
ELF_SectionTypeXList(X)
|
||||
#undef X
|
||||
} ELF_SectionType;
|
||||
|
||||
typedef enum ELF_SectionAttributeFlags{
|
||||
ELF_SectionAttributeFlag_WRITE = 0x001,
|
||||
ELF_SectionAttributeFlag_ALLOC = 0x002,
|
||||
ELF_SectionAttributeFlag_EXECINSTR = 0x004,
|
||||
ELF_SectionAttributeFlag_MERGE = 0x010,
|
||||
ELF_SectionAttributeFlag_STRINGS = 0x020,
|
||||
ELF_SectionAttributeFlag_INFO_LINK = 0x040,
|
||||
ELF_SectionAttributeFlag_LINK_ORDER = 0x080,
|
||||
ELF_SectionAttributeFlag_OS_NONCONFORMING = 0x100,
|
||||
ELF_SectionAttributeFlag_GROUP = 0x200,
|
||||
ELF_SectionAttributeFlag_TLS = 0x400,
|
||||
ELF_SectionAttributeFlag_MASKOS = 0x0FF00000,
|
||||
ELF_SectionAttributeFlag_MASKPROC = 0xF0000000,
|
||||
} ELF_SectionAttributeFlags;
|
||||
|
||||
typedef enum ELF_SectionGroupFlags{
|
||||
ELF_SectionGroupFlag_COMDAT = 0x1,
|
||||
ELF_SectionGroupFlag_MASKOS = 0x0FF00000,
|
||||
ELF_SectionGroupFlag_MASKPROC = 0xF0000000,
|
||||
} ELF_SectionGroupFlags;
|
||||
|
||||
typedef enum ELF_ReservedSymbolTableIndex{
|
||||
ELF_ReservedSymbolTableIndex_UNDEF = 0,
|
||||
} ELF_ReservedSymbolTableIndex;
|
||||
|
||||
// symbol table
|
||||
|
||||
typedef struct ELF_Sym32{
|
||||
U32 st_name;
|
||||
U32 st_value;
|
||||
U32 st_size;
|
||||
U8 st_info;
|
||||
U8 st_other;
|
||||
U16 st_shndx;
|
||||
} ELF_Sym32;
|
||||
|
||||
typedef struct ELF_Sym64{
|
||||
U32 st_name;
|
||||
U8 st_info;
|
||||
U8 st_other;
|
||||
U16 st_shndx;
|
||||
U64 st_value;
|
||||
U64 st_size;
|
||||
} ELF_Sym64;
|
||||
|
||||
#define ELF_SymBindingFromInfo(x) (ELF_SymbolBinding)((x)>>4)
|
||||
#define ELF_SymTypeFromInfo(x) (ELF_SymbolType)((x)&0xF)
|
||||
#define ELF_SymInfoFromBindingType(b,t) ((((b)<<4)&0xF)|((t)&0xF))
|
||||
|
||||
#define ELF_SymVisibilityFromOther(x) ((x)&0x3)
|
||||
#define ELF_SymOtherFromVisibility(x) ((x)&0x3)
|
||||
|
||||
#define ELF_SymbolBindingXList(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_SymbolBindingXList(X)
|
||||
#undef X
|
||||
} ELF_SymbolBinding;
|
||||
|
||||
#define ELF_SymbolTypeXList(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_SymbolTypeXList(X)
|
||||
#undef X
|
||||
} ELF_SymbolType;
|
||||
|
||||
#define ELF_SymbolVisibilityXList(X)\
|
||||
X(DEFAULT, 0)\
|
||||
X(INTERNAL, 1)\
|
||||
X(HIDDEN, 2)\
|
||||
X(PROTECTED, 3)
|
||||
|
||||
typedef enum ELF_SymbolVisibility{
|
||||
#define X(N,C) ELF_SymbolVisibility_##N = C,
|
||||
ELF_SymbolVisibilityXList(X)
|
||||
#undef X
|
||||
} ELF_SymbolVisibility;
|
||||
|
||||
// relocation
|
||||
|
||||
typedef struct ELF_Rel32{
|
||||
U32 r_offset;
|
||||
U32 r_info;
|
||||
} ELF_Rel32;
|
||||
|
||||
typedef struct ELF_Rela32{
|
||||
U32 r_offset;
|
||||
U32 r_info;
|
||||
S32 r_addend;
|
||||
} ELF_Rela32;
|
||||
|
||||
typedef struct ELF_Rel64{
|
||||
U64 r_offset;
|
||||
U64 r_info;
|
||||
} ELF_Rel64;
|
||||
|
||||
typedef struct ELF_Rela64{
|
||||
U64 r_offset;
|
||||
U64 r_info;
|
||||
S64 r_addend;
|
||||
} ELF_Rela64;
|
||||
|
||||
#define ELF_RelSymIndexFromInfo32(x) ((x)>>8)
|
||||
#define ELF_RelTypeFromInfo32(x) ((x)&0xF)
|
||||
#define ELF_RelInfoFromSymIndexType32(n,t) (((n)<<8)|((t)&0xF))
|
||||
|
||||
#define ELF_RelSymIndexFromInfo64(x) ((x)>>32)
|
||||
#define ELF_RelTypeFromInfo64(x) ((x)&0xFFFFFFFFL)
|
||||
#define ELF_RelInfoFromSymIndexType64(n,t) (((n)<<8)|((t)&0xFFFFFFFFL))
|
||||
|
||||
|
||||
|
||||
// program header
|
||||
|
||||
typedef struct ELF_Phdr32{
|
||||
U32 p_type;
|
||||
U32 p_offset;
|
||||
U32 p_vaddr;
|
||||
U32 p_paddr;
|
||||
U32 p_filesz;
|
||||
U32 p_memsz;
|
||||
U32 p_flags;
|
||||
U32 p_align;
|
||||
} ELF_Phdr32;
|
||||
|
||||
typedef struct ELF_Phdr64{
|
||||
U32 p_type;
|
||||
U32 p_flags;
|
||||
U64 p_offset;
|
||||
U64 p_vaddr;
|
||||
U64 p_paddr;
|
||||
U64 p_filesz;
|
||||
U64 p_memsz;
|
||||
U64 p_align;
|
||||
} ELF_Phdr64;
|
||||
|
||||
typedef enum ELF_SegmentType{
|
||||
ELF_SegmentType_NULL = 0,
|
||||
ELF_SegmentType_LOAD = 1,
|
||||
ELF_SegmentType_DYNAMIC = 2,
|
||||
ELF_SegmentType_INTERP = 3,
|
||||
ELF_SegmentType_NOTE = 4,
|
||||
ELF_SegmentType_SHLIB = 5,
|
||||
ELF_SegmentType_PHDR = 6,
|
||||
ELF_SegmentType_TLS = 7,
|
||||
ELF_SegmentType_LOOS = 0x60000000,
|
||||
ELF_SegmentType_HIOS = 0x6fffffff,
|
||||
ELF_SegmentType_LOPROC = 0x70000000,
|
||||
ELF_SegmentType_HIPROC = 0x7fffffff,
|
||||
} ELF_SegmentType;
|
||||
|
||||
typedef enum ELF_SegmentFlags{
|
||||
ELF_SegmentFlag_X = 0x1,
|
||||
ELF_SegmentFlag_W = 0x2,
|
||||
ELF_SegmentFlag_R = 0x4,
|
||||
ELF_SegmentFlag_MASKOS = 0x0FF00000,
|
||||
ELF_SegmentFlag_MASKPROC = 0xF0000000,
|
||||
} ELF_SegmentFlags;
|
||||
|
||||
////////////////////////////////
|
||||
//~ ELF Parser Types
|
||||
|
||||
// elf top level
|
||||
|
||||
typedef struct ELF_SectionArray{
|
||||
ELF_Shdr64 *sections;
|
||||
U64 count;
|
||||
} ELF_SectionArray;
|
||||
|
||||
typedef struct ELF_SegmentArray{
|
||||
ELF_Phdr64 *segments;
|
||||
U64 count;
|
||||
} ELF_SegmentArray;
|
||||
|
||||
typedef struct ELF_Parsed{
|
||||
String8 data;
|
||||
ELF_Class elf_class;
|
||||
Arch arch;
|
||||
|
||||
ELF_Shdr64 *sections;
|
||||
String8 *section_names;
|
||||
U64 section_foff;
|
||||
U64 section_count;
|
||||
|
||||
ELF_Phdr64 *segments;
|
||||
U64 segment_foff;
|
||||
U64 segment_count;
|
||||
|
||||
U64 vbase;
|
||||
U64 entry_vaddr;
|
||||
U64 section_name_table_foff;
|
||||
U64 section_name_table_opl;
|
||||
|
||||
U64 strtab_idx;
|
||||
U64 symtab_idx;
|
||||
U64 dynsym_idx;
|
||||
} ELF_Parsed;
|
||||
|
||||
// elf symtab
|
||||
|
||||
typedef struct ELF_SymArray{
|
||||
ELF_Sym64 *symbols;
|
||||
U64 count;
|
||||
} ELF_SymArray;
|
||||
|
||||
////////////////////////////////
|
||||
//~ ELF Parser Functions
|
||||
|
||||
static ELF_Parsed* elf_parsed_from_data(Arena *arena, String8 elf_data);
|
||||
|
||||
static ELF_SectionArray elf_section_array_from_elf(ELF_Parsed *elf);
|
||||
static String8Array elf_section_name_array_from_elf(ELF_Parsed *elf);
|
||||
static ELF_SegmentArray elf_segment_array_from_elf(ELF_Parsed *elf);
|
||||
|
||||
static String8 elf_section_name_from_name_offset(ELF_Parsed *elf, U64 offset);
|
||||
static String8 elf_section_name_from_idx(ELF_Parsed *elf, U32 idx);
|
||||
static U32 elf_section_idx_from_name(ELF_Parsed *elf, String8 name);
|
||||
|
||||
static String8 elf_section_data_from_idx(ELF_Parsed *elf, U32 idx);
|
||||
|
||||
static ELF_SymArray elf_sym_array_from_data(Arena *arena, ELF_Class elf_class, String8 data);
|
||||
|
||||
// string functions
|
||||
|
||||
static String8 elf_string_from_section_type(ELF_SectionType section_type);
|
||||
static String8 elf_string_from_symbol_binding(ELF_SymbolBinding binding);
|
||||
static String8 elf_string_from_symbol_type(ELF_SymbolType type);
|
||||
static String8 elf_string_from_symbol_visibility(ELF_SymbolVisibility visibility);
|
||||
|
||||
#endif //RDI_ELF_H
|
||||
Reference in New Issue
Block a user