blob: 3d2307402e6dcd503cec24be56602aefadededec [file] [log] [blame]
# Copyright 2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from portage.util.endian.decode import (decode_uint16_le,
decode_uint32_le, decode_uint16_be, decode_uint32_be)
from portage.util.elf.constants import (E_ENTRY, E_MACHINE, E_TYPE,
EI_CLASS, ELFCLASS32, ELFCLASS64, ELFDATA2LSB, ELFDATA2MSB)
class ELFHeader(object):
__slots__ = ('e_flags', 'e_machine', 'e_type', 'ei_class',
'ei_data')
@classmethod
def read(cls, f):
"""
@param f: an open ELF file
@type f: file
@rtype: ELFHeader
@return: A new ELFHeader instance containing data from f
"""
f.seek(EI_CLASS)
ei_class = ord(f.read(1))
ei_data = ord(f.read(1))
if ei_class == ELFCLASS32:
width = 32
elif ei_class == ELFCLASS64:
width = 64
else:
width = None
if ei_data == ELFDATA2LSB:
uint16 = decode_uint16_le
uint32 = decode_uint32_le
elif ei_data == ELFDATA2MSB:
uint16 = decode_uint16_be
uint32 = decode_uint32_be
else:
uint16 = None
uint32 = None
if width is None or uint16 is None:
e_flags = None
e_machine = None
e_type = None
else:
f.seek(E_TYPE)
e_type = uint16(f.read(2))
f.seek(E_MACHINE)
e_machine = uint16(f.read(2))
# E_ENTRY + 3 * sizeof(uintN)
e_flags_offset = E_ENTRY + 3 * width // 8
f.seek(e_flags_offset)
e_flags = uint32(f.read(4))
obj = cls()
obj.e_flags = e_flags
obj.e_machine = e_machine
obj.e_type = e_type
obj.ei_class = ei_class
obj.ei_data = ei_data
return obj