# Path: VM/ELF/ELF_structs.py
# class ELF32_Ehdr(ELF_parser):
#     e_ident    : ELF32_Ident
#     e_type     : 'H' = enums.e_type
#     e_machine  : 'H' = enums.e_machine
#     e_version  : 'I'
#     e_entry    : 'I'
#     e_phoff    : 'I'
#     e_shoff    : 'I'
#     e_flags    : 'I'
#     e_ehsize   : 'H'
#     e_phentsize: 'H'
#     e_phnum    : 'H'
#     e_shentsize: 'H'
#     e_shnum    : 'H'
#     e_shstrndx : 'H'
# 
# class ELF32_Shdr(ELF_parser):
#     sh_name     : 'I'
#     sh_type     : 'I' = enums.sh_type
#     sh_flags    : 'I' = enums.sh_flags
#     sh_addr     : 'I'
#     sh_offset   : 'I'
#     sh_size     : 'I'
#     sh_link     : 'I'
#     sh_info     : 'I'
#     sh_addralign: 'I'
#     sh_entsize  : 'I'
# 
# class ELF32_Phdr(ELF_parser):
#     p_type  : 'I' = enums.p_type
#     p_offset: 'I'
#     p_vaddr : 'I'
#     p_paddr : 'I'
#     p_filesz: 'I'
#     p_memsz : 'I'
#     p_flags : 'I' = enums.p_flags
#     p_align : 'I'
# 
# class ELF32_Sym(ELF_parser):
#     st_name: 'I'
#     st_value: 'I'
#     st_size: 'I'
#     st_info: 'B' = lambda x: str(enums.st_bind(x>>4)) + '|' + str(enums.st_type(x & 0xF))
#     st_other: 'B'
#     st_shndex: 'H'
# 
# Path: VM/ELF/ELF_enums.py
# EI_CLASS = Enum('EI_CLASS', 'ELFCLASSNONE ELFCLASS32 ELFCLASS64', start=0)
# 
# EI_DATA = Enum('EI_DATA', 'ELFDATANONE ELFDATA2LSB ELFDATA2MSB', start=0)
# 
# class e_machine(Enum):
#     NONE = 0x00
#     SPARC = 0x02
#     x86 = 0x03
#     MIPS = 0x08
#     PowerPC = 0x14
#     S390 = 0x16
#     ARM = 0x28
#     SuperH = 0x2A
#     IA_64 = 0x32
#     x86_64 = 0x3E
#     AArch64 = 0xB7
#     RISC_V = 0xF3
# 
# class e_type(Enum):
#     ET_NONE = 0x00
#     ET_REL = 1
#     ET_EXEC = 2
#     ET_DYN = 3
#     ET_CORE = 4
#     ET_LOOS = 0xfe00
#     ET_HIOS = 0xfeff
#     ET_LOPROC = 0xff00
#     ET_HIPROC = 0xffff
# 
# class p_type(Enum):
#     PT_NULL	= 0
#     PT_LOAD	= 0x00000001  # Loadable segment
#     PT_DYNAMIC = 0x00000002	 # Dynamic linking information
#     PT_INTERP = 0x00000003  # Interpreter information
#     PT_NOTE = 0x00000004  # Auxiliary information
#     PT_SHLIB = 0x00000005  # reserved
#     PT_PHDR = 0x00000006  # segment containing program header table itself
#     PT_TLS = 0x00000007  # Thread-local storage segment
#     PT_NUM = 0x00000008  # Number of defined types
# 
#     PT_LOOS = 0x60000000
#     PT_HIOS = 0x6FFFFFFF
#     PT_LOPROC = 0x70000000
#     
#     PT_GNU_EH_FRAME = 0x60000000 + 0x474e550
#     PT_GNU_STACK = 0x6474e551  # Indicates stack executability
#     PT_GNU_RELRO = 0x6474e552  # Read-only after relocation
#     
#     PT_HIPROC = 0x7FFFFFFF
#     
#     def _missing_(self):
#         return self


from .ELF_structs import ELF32_Ehdr, ELF32_Shdr, ELF32_Phdr, ELF32_Sym
from .ELF_enums import EI_CLASS, EI_DATA, e_machine, e_type, p_type


__all__ = 'ELF32',


class ELF32:
    def __init__(self, fname: str):
        self.fname = fname
        self.file = open(self.fname, 'rb')
        self.hdr = ELF32_Ehdr(self.file)
        
        ident = self.hdr.e_ident
        
        assert (ident.EI_MAG0, ident.EI_MAG1, ident.EI_MAG2, ident.EI_MAG3) == (127, 69, 76, 70), f'Invalid header in file {self.fname!r}'
        
        assert ident.EI_CLASS == EI_CLASS.ELFCLASS32, f'64-bit architecture is not supported (file {self.fname!r})'

# Path: VM/ELF/ELF_structs.py
# class ELF32_Ehdr(ELF_parser):
#     e_ident    : ELF32_Ident
#     e_type     : 'H' = enums.e_type
#     e_machine  : 'H' = enums.e_machine
#     e_version  : 'I'
#     e_entry    : 'I'
#     e_phoff    : 'I'
#     e_shoff    : 'I'
#     e_flags    : 'I'
#     e_ehsize   : 'H'
#     e_phentsize: 'H'
#     e_phnum    : 'H'
#     e_shentsize: 'H'
#     e_shnum    : 'H'
#     e_shstrndx : 'H'
# 
# class ELF32_Shdr(ELF_parser):
#     sh_name     : 'I'
#     sh_type     : 'I' = enums.sh_type
#     sh_flags    : 'I' = enums.sh_flags
#     sh_addr     : 'I'
#     sh_offset   : 'I'
#     sh_size     : 'I'
#     sh_link     : 'I'
#     sh_info     : 'I'
#     sh_addralign: 'I'
#     sh_entsize  : 'I'
# 
# class ELF32_Phdr(ELF_parser):
#     p_type  : 'I' = enums.p_type
#     p_offset: 'I'
#     p_vaddr : 'I'
#     p_paddr : 'I'
#     p_filesz: 'I'
#     p_memsz : 'I'
#     p_flags : 'I' = enums.p_flags
#     p_align : 'I'
# 
# class ELF32_Sym(ELF_parser):
#     st_name: 'I'
#     st_value: 'I'
#     st_size: 'I'
#     st_info: 'B' = lambda x: str(enums.st_bind(x>>4)) + '|' + str(enums.st_type(x & 0xF))
#     st_other: 'B'
#     st_shndex: 'H'
# 
# Path: VM/ELF/ELF_enums.py
# EI_CLASS = Enum('EI_CLASS', 'ELFCLASSNONE ELFCLASS32 ELFCLASS64', start=0)
# 
# EI_DATA = Enum('EI_DATA', 'ELFDATANONE ELFDATA2LSB ELFDATA2MSB', start=0)
# 
# class e_machine(Enum):
#     NONE = 0x00
#     SPARC = 0x02
#     x86 = 0x03
#     MIPS = 0x08
#     PowerPC = 0x14
#     S390 = 0x16
#     ARM = 0x28
#     SuperH = 0x2A
#     IA_64 = 0x32
#     x86_64 = 0x3E
#     AArch64 = 0xB7
#     RISC_V = 0xF3
# 
# class e_type(Enum):
#     ET_NONE = 0x00
#     ET_REL = 1
#     ET_EXEC = 2
#     ET_DYN = 3
#     ET_CORE = 4
#     ET_LOOS = 0xfe00
#     ET_HIOS = 0xfeff
#     ET_LOPROC = 0xff00
#     ET_HIPROC = 0xffff
# 
# class p_type(Enum):
#     PT_NULL	= 0
#     PT_LOAD	= 0x00000001  # Loadable segment
#     PT_DYNAMIC = 0x00000002	 # Dynamic linking information
#     PT_INTERP = 0x00000003  # Interpreter information
#     PT_NOTE = 0x00000004  # Auxiliary information
#     PT_SHLIB = 0x00000005  # reserved
#     PT_PHDR = 0x00000006  # segment containing program header table itself
#     PT_TLS = 0x00000007  # Thread-local storage segment
#     PT_NUM = 0x00000008  # Number of defined types
# 
#     PT_LOOS = 0x60000000
#     PT_HIOS = 0x6FFFFFFF
#     PT_LOPROC = 0x70000000
#     
#     PT_GNU_EH_FRAME = 0x60000000 + 0x474e550
#     PT_GNU_STACK = 0x6474e551  # Indicates stack executability
#     PT_GNU_RELRO = 0x6474e552  # Read-only after relocation
#     
#     PT_HIPROC = 0x7FFFFFFF
#     
#     def _missing_(self):
#         return self


# Path: VM/ELF/ELF_impl.py
from .ELF_structs import ELF32_Ehdr, ELF32_Shdr, ELF32_Phdr, ELF32_Sym
from .ELF_enums import EI_CLASS, EI_DATA, e_machine, e_type, p_type



__all__ = 'ELF32',


class ELF32:
    def __init__(self, fname: str):
        self.fname = fname
        self.file = open(self.fname, 'rb')
        self.hdr = ELF32_Ehdr(self.file)
        
        ident = self.hdr.e_ident
        
        assert (ident.EI_MAG0, ident.EI_MAG1, ident.EI_MAG2, ident.EI_MAG3) == (127, 69, 76, 70), f'Invalid header in file {self.fname!r}'
        
        assert ident.EI_CLASS == EI_CLASS.ELFCLASS32, f'64-bit architecture is not supported (file {self.fname!r})'

        assert ident.EI_DATA == EI_DATA.ELFDATA2LSB, f'Big endian is not supported (file {self.fname!r})'