def _parse_header(self, data):
        """
        Parse the ELF header in ``data`` and populate the properties.

        Args:
            data(bytes): The ELF header.
        """

        (magic, word_size, byte_order, version, osabi, abi_version, _), data = \
            unpack('4sBBBBB7s', data[:16]), data[16:]

        assert magic == self._ELF_MAGIC, 'Missing ELF magic'
        assert word_size in (1, 2), 'Invalid word size'
        assert byte_order in (1, 2), 'Invalid byte order'

        assert version == 1, 'Invalid version'

        self.osabi = self.OSABI(osabi)
        self.abi_version = abi_version

        endian = Target.Endian(byte_order - 1)
        (type_, machine, version), data = unpack('HHI', data[:8], endian=endian), data[8:]

        try:
            self.type = self.Type(type_)
        except ValueError:
            self.type = self.Type.unknown

        try:
            self.machine = ELF.Machine(machine)
        except ValueError:
            self.machine = ELF.Machine.unknown

        assert version == 1, 'Invalid version'

        if self.machine is ELF.Machine.i386:
            arch = Target.Arch.x86
            assert word_size == 1, 'Unexpected ELF64 for machine type x86'
            assert endian is Target.Endian.little, 'Unexpected big-endian for machine type x86'
        elif self.machine is ELF.Machine.x86_64:
            arch = Target.Arch.x86
            assert word_size == 2, 'Unexpected ELF32 for machine type x64_64'
            assert endian is Target.Endian.little, 'Unexpected big-endian for machine type x86'
        elif self.machine is ELF.Machine.arm:
            arch = Target.Arch.arm
            assert word_size == 1, 'Unexpected ELF64 for machine type arm'
        elif self.machine is ELF.Machine.aarch64:
            arch = Target.Arch.arm
            assert word_size == 2, 'Unexpected ELF32 for machine type aarch64'
        else:
            arch = Target.Arch.unknown

        self.arch = arch
        self.bits = 32 * word_size
        self.endian = endian

        if self.bits == 32:
            fmt = 'IIIIHHHHHH'
        else:
            fmt = 'QQQIHHHHHH'

        fmt_size = pack_size(fmt)
        (self.entry, self.phoff, self.shoff, self.flags, self.hsize, self.phentsize,
            self.phnum, self.shentsize, self.shnum, self.shstrndx) = \
            unpack(fmt, data[:fmt_size], target=self)
Parse the ELF header in ``data`` and populate the properties.

        Args:
            data(bytes): The ELF header.