#ifndef MR4TH_ELF_PARSE_H
#define MR4TH_ELF_PARSE_H

////////////////////////////////
// Elf Parse Types

#define ELFP_SYMBOL_TABLE_symtab 0
#define ELFP_SYMBOL_TABLE_dynsym 1
#define ELFP_SYMBOL_TABLE_COUNT  2

typedef struct ELF_Parse{
    ELF_Class    elf_class;
    ELF_Encoding encoding;
    U32 section_count;
    U32 segment_count;
    void *header;
    U64   size;
    void *sections;
    void *segments;
    U8   *section_strtable_first;
    U8   *section_strtable_opl;
    void *symbols[ELFP_SYMBOL_TABLE_COUNT];
    U32   symbol_count[ELFP_SYMBOL_TABLE_COUNT];
    U8   *symbol_strtable_first[ELFP_SYMBOL_TABLE_COUNT];
    U8   *symbol_strtable_opl[ELFP_SYMBOL_TABLE_COUNT];
} ELF_Parse;

////////////////////////////////
// Elf Parse Functions

MR4TH_SYMBOL ELF_Parse* elfp_begin(Arena *arena, String8 data);

MR4TH_SYMBOL void    elfp_header_read(ELF_Parse *elf, ELF_Header64 *out);

MR4TH_SYMBOL U32     elfp_section_count(ELF_Parse *elf);
MR4TH_SYMBOL void    elfp_section_read(ELF_Parse *elf, U32 idx, ELF_Section64 *out);
MR4TH_SYMBOL String8 elfp_section_name(ELF_Parse *elf, U32 idx);

MR4TH_SYMBOL U32     elfp_segment_count(ELF_Parse *elf);
MR4TH_SYMBOL void    elfp_segment_read(ELF_Parse *elf, U32 idx, ELF_Segment64 *out);

MR4TH_SYMBOL U32     elfp_symbol_count(ELF_Parse *elf, U32 table);
MR4TH_SYMBOL void    elfp_symbol_read(ELF_Parse *elf, U32 table, U32 idx, ELF_Symbol64 *out);
MR4TH_SYMBOL String8 elfp_symbol_name(ELF_Parse *elf, U32 table, U32 idx);

MR4TH_SYMBOL U32     elfp_relocs_count(ELF_Parse *elf, U32 secidx);
MR4TH_SYMBOL void    elfp_relocs_read(ELF_Parse *elf, U32 secidx, U32 relocidx, ELF_RelocationAdd64 *out);

#endif //MR4TH_ELF_PARSE_H
