diff --git a/src/elf/elf.h b/src/elf/elf.h index ddc6950e..a46413c3 100644 --- a/src/elf/elf.h +++ b/src/elf/elf.h @@ -784,15 +784,6 @@ typedef struct U16 vs_vers; } ELF_ExternalVersym; -typedef struct -{ - U32 name_size; - U32 desc_size; - U32 type; - // name + desc - // U8 data[1]; -} ELF_Note; - //////////////////////////////// // Extensions diff --git a/src/elf/elf_parse.c b/src/elf/elf_parse.c index 5949ebad..77efa627 100644 --- a/src/elf/elf_parse.c +++ b/src/elf/elf_parse.c @@ -164,3 +164,48 @@ elf_gnu_debug_link_from_bin(String8 raw_data, ELF_Bin *bin) } return result; } + +internal ELF_NoteList +elf_parse_note(Arena *arena, String8 raw_note, ELF_Class elf_class, ELF_MachineKind e_machine) +{ + ELF_NoteList result = {0}; + + for (U64 cursor = 0; cursor < raw_note.size; ) { + U32 owner_size; + U64 owner_size_size = str8_deserial_read_struct(raw_note, cursor, &owner_size); + if (owner_size_size == 0) { goto exit; } + cursor += owner_size_size; + + U32 desc_size; + U64 desc_size_size = str8_deserial_read_struct(raw_note, cursor, &desc_size); + if (desc_size_size == 0) { goto exit; } + cursor += desc_size_size; + + ELF_NoteType type; + U64 type_size = str8_deserial_read_struct(raw_note, cursor, &type); + if (type_size == 0) { goto exit; } + cursor += type_size; + + if (cursor + owner_size > raw_note.size) { goto exit; } + String8 owner = str8_cstring_capped(raw_note.str + cursor, raw_note.str + cursor + owner_size); + cursor += owner_size; + + if (cursor + desc_size > raw_note.size) { goto exit; } + String8 desc = str8_substr(raw_note, r1u64(cursor, cursor + desc_size)); + cursor += desc_size; + cursor = AlignPow2(cursor, 4); + + ELF_NoteNode *n = push_array(arena, ELF_NoteNode, 1); + n->v.owner = owner; + n->v.desc = desc; + n->v.type = type; + + SLLQueuePush(result.first, result.last, n); + result.count += 1; + } + +exit:; + return result; +} + + diff --git a/src/elf/elf_parse.h b/src/elf/elf_parse.h index 70a467e8..f15708c8 100644 --- a/src/elf/elf_parse.h +++ b/src/elf/elf_parse.h @@ -10,22 +10,22 @@ typedef struct ELF_Shdr64Array ELF_Shdr64Array; struct ELF_Shdr64Array { + U64 count; ELF_Shdr64 *v; - U64 count; }; typedef struct ELF_Phdr64Array ELF_Phdr64Array; struct ELF_Phdr64Array { + U64 count; ELF_Phdr64 *v; - U64 count; }; typedef struct ELF_Bin ELF_Bin; struct ELF_Bin { - ELF_Hdr64 hdr; - Rng1U64 sh_name_range; + ELF_Hdr64 hdr; + Rng1U64 sh_name_range; ELF_Shdr64Array shdrs; ELF_Phdr64Array phdrs; }; @@ -34,7 +34,30 @@ typedef struct ELF_GnuDebugLink ELF_GnuDebugLink; struct ELF_GnuDebugLink { String8 path; - U32 checksum; + U32 checksum; +}; + +typedef struct ELF_Note ELF_Note; +struct ELF_Note +{ + String8 owner; + ELF_NoteType type; + String8 desc; +}; + +typedef struct ELF_NoteNode ELF_NoteNode; +struct ELF_NoteNode +{ + ELF_Note v; + ELF_NoteNode *next; +}; + +typedef struct ELF_NoteList ELF_NoteList; +struct ELF_NoteList +{ + U64 count; + ELF_NoteNode *first; + ELF_NoteNode *last; }; //////////////////////////////// @@ -49,4 +72,6 @@ internal String8 elf_name_from_shdr64(String8 raw_data, ELF_Bin *bin, ELF_Shdr64 internal U64 elf_base_addr_from_bin(ELF_Bin *bin); internal ELF_GnuDebugLink elf_gnu_debug_link_from_bin(String8 raw_data, ELF_Bin *bin); +internal ELF_NoteList elf_parse_note(Arena *arena, String8 raw_note, ELF_Class elf_class, ELF_MachineKind e_machine); + #endif // ELF_PARSE_H