from construct import Computed, Hex, Int32ul, LazyArray, Struct, Tell, this

from hilda.snippets.macho.macho_load_commands import LOAD_COMMAND_TYPE, load_command_t


def __calculate_aslr(ctx):
    loaded_address = ctx.load_address
    for load_command in ctx.load_commands:
        if load_command.cmd == LOAD_COMMAND_TYPE.LC_SEGMENT_64 and load_command.data.segname == '__TEXT':
            return loaded_address - load_command.data.vmaddr


mach_header_t = Struct(
    'load_address' / Tell,
    'magic' / Hex(Int32ul),
    'cputype' / Hex(Int32ul),
    'cpusubtype' / Hex(Int32ul),
    'filetype' / Hex(Int32ul),
    'ncmds' / Hex(Int32ul),
    'sizeofcmds' / Hex(Int32ul),
    'flags' / Hex(Int32ul),
    'reserved' / Hex(Int32ul),
    'load_commands' / LazyArray(this.ncmds, load_command_t),
    'aslr' / Computed(__calculate_aslr)
)
