--- /dev/null
+#-------------------------------------------------------------------------------
+# elftools: elf/descriptions.py
+#
+# Textual descriptions of the various enums and flags of ELF
+#
+# Eli Bendersky (eliben@gmail.com)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+from .enums import ENUM_E_VERSION
+
+
+def describe_ei_class(x):
+ return _DESCR_EI_CLASS.get(x, _unknown())
+
+def describe_ei_data(x):
+ return _DESCR_EI_DATA.get(x, _unknown())
+
+def describe_ei_version(x):
+ s = '%d' % ENUM_E_VERSION[x]
+ if x == 'EV_CURRENT':
+ s += ' (current)'
+ return s
+
+def describe_ei_osabi(x):
+ return _DESCR_EI_OSABI.get(x, _unknown())
+
+def describe_e_type(x):
+ return _DESCR_E_TYPE.get(x, _unknown())
+
+
+#-------------------------------------------------------------------------------
+def _unknown():
+ return '<unknown>'
+
+
+_DESCR_EI_CLASS = dict(
+ ELFCLASSNONE='none',
+ ELFCLASS32='ELF32',
+ ELFCLASS64='ELF64',
+)
+
+_DESCR_EI_DATA = dict(
+ ELFDATANONE='none',
+ ELFDATA2LSB="2's complement, little endian",
+ ELFDATA2MSB="2's complement, big endian",
+)
+
+_DESCR_EI_OSABI = dict(
+ ELFOSABI_SYSV='UNIX - System V',
+ ELFOSABI_HPUX='UNIX - HP-UX',
+ ELFOSABI_NETBSD='UNIX - NetBSD',
+ ELFOSABI_LINUX='UNIX - Linux',
+ ELFOSABI_HURD='UNIX - GNU/Hurd',
+ ELFOSABI_SOLARIS='UNIX - Solaris',
+ ELFOSABI_AIX='UNIX - AIX',
+ ELFOSABI_IRIX='UNIX - IRIX',
+ ELFOSABI_FREEBSD='UNIX - FreeBSD',
+ ELFOSABI_TRU64='UNIX - TRU64',
+ ELFOSABI_MODESTO='Novell - Modesto',
+ ELFOSABI_OPENBSD='UNIX - OpenBSD',
+ ELFOSABI_OPENVMS='VMS - OpenVMS',
+ ELFOSABI_NSK='HP - Non-Stop Kernel',
+ ELFOSABI_AROS='AROS',
+ ELFOSABI_ARM='ARM',
+ ELFOSABI_STANDALONE='Standalone App',
+)
+
+_DESCR_E_TYPE = dict(
+ ET_NONE='NONE (None)',
+ ET_REL='REL (Relocatable file)',
+ ET_EXEC='EXEC (Executable file)',
+ ET_DYN='DYN (Shared object file)',
+ ET_CORE='CORE (Core file)',
+ PROC_SPECIFIC='Processor Specific',
+)
+
header:
the complete ELF file header
+
+ e_ident_raw:
+ the raw e_ident field of the header
"""
def __init__(self, stream):
self.stream = stream
little_endian=self.little_endian,
elfclass=self.elfclass)
self.header = self._parse_elf_header()
+
+ self.stream.seek(0)
+ self.e_ident_raw = self.stream.read(16)
self._file_stringtable_section = self._get_file_stringtable()
EV_CURRENT=1
)
+# e_ident[EI_OSABI] in the ELF header
+ENUM_EI_OSABI = dict(
+ ELFOSABI_SYSV=0,
+ ELFOSABI_HPUX=1,
+ ELFOSABI_NETBSD=2,
+ ELFOSABI_LINUX=3,
+ ELFOSABI_HURD=4,
+ ELFOSABI_SOLARIS=6,
+ ELFOSABI_AIX=7,
+ ELFOSABI_IRIX=8,
+ ELFOSABI_FREEBSD=9,
+ ELFOSABI_TRU64=10,
+ ELFOSABI_MODESTO=11,
+ ELFOSABI_OPENBSD=12,
+ ELFOSABI_OPENVMS=13,
+ ELFOSABI_NSK=14,
+ ELFOSABI_AROS=15,
+ ELFOSABI_ARM=97,
+ ELFOSABI_STANDALONE=255,
+)
+
# e_type in the ELF header
ENUM_E_TYPE = dict(
ET_NONE=0,
class Symbol(object):
""" Symbol object - representing a single symbol entry from a symbol table
section.
+
+ Similarly to Section objects, allows dictionary-like access to the
+ symbol entry.
"""
def __init__(self, entry, name):
self.entry = entry
Enum(self.Elf_byte('EI_CLASS'), **ENUM_EI_CLASS),
Enum(self.Elf_byte('EI_DATA'), **ENUM_EI_DATA),
Enum(self.Elf_byte('EI_VERSION'), **ENUM_E_VERSION),
- Padding(9)
+ Enum(self.Elf_byte('EI_OSABI'), **ENUM_EI_OSABI),
+ self.Elf_byte('EI_ABIVERSION'),
+ Padding(7)
),
Enum(self.Elf_half('e_type'), **ENUM_E_TYPE),
Enum(self.Elf_half('e_machine'), **ENUM_E_MACHINE),
)
def _create_sym(self):
+ # Note that st_info is hierarchical. To access the type, use
+ # container['st_info']['type']
st_info_struct = BitStruct('st_info',
Enum(BitField('bind', 4), **ENUM_ST_INFO_BIND),
Enum(BitField('type', 4), **ENUM_ST_INFO_TYPE))
--- /dev/null
+#-------------------------------------------------------------------------------
+# readelf.py
+#
+# A clone of 'readelf' in Python, based on the pyelftools library
+#
+# Eli Bendersky (eliben@gmail.com)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+import sys
+from optparse import OptionParser
+
+# If elftools is not installed, maybe we're running from the root or scripts
+# dir of the source distribution
+#
+try:
+ import elftools
+except ImportError:
+ sys.path.extend(['.', '..'])
+
+from elftools.common.exceptions import ELFError
+from elftools.elf.elffile import ELFFile
+from elftools.elf.descriptions import (
+ describe_ei_class, describe_ei_data, describe_ei_version,
+ describe_ei_osabi, describe_e_type,
+ )
+
+
+class ReadElf(object):
+ """ display_* methods are used to emit output into the output stream
+ """
+ def __init__(self, file, output):
+ """ file:
+ stream object with the ELF file to read
+
+ output:
+ output stream to write to
+ """
+ self.elffile = ELFFile(file)
+ self.output = output
+
+ def display_file_header(self):
+ """ Display the ELF file header
+ """
+ self._emitline('ELF Header:')
+ self._emit(' Magic: ')
+ self._emitline(' '.join('%2.2x' % ord(b)
+ for b in self.elffile.e_ident_raw))
+ header = self.elffile.header
+ e_ident = header['e_ident']
+ self._emitline(' Class: %s' %
+ describe_ei_class(e_ident['EI_CLASS']))
+ self._emitline(' Data: %s' %
+ describe_ei_data(e_ident['EI_DATA']))
+ self._emitline(' Version: %s' %
+ describe_ei_version(e_ident['EI_VERSION']))
+ self._emitline(' OS/ABI: %s' %
+ describe_ei_osabi(e_ident['EI_OSABI']))
+ self._emitline(' ABI Version: %d' %
+ e_ident['EI_ABIVERSION'])
+ self._emitline(' Type: %s' %
+ describe_e_type(header['e_type']))
+
+ def _emit(self, s):
+ """ Emit an object to output
+ """
+ self.output.write(str(s))
+
+ def _emitline(self, s):
+ """ Emit an object to output, followed by a newline
+ """
+ self.output.write(str(s) + '\n')
+
+
+def main():
+ optparser = OptionParser()
+ options, args = optparser.parse_args()
+
+ with open(args[0], 'rb') as file:
+ try:
+ readelf = ReadElf(file, sys.stdout)
+ readelf.display_file_header()
+ except ELFError as ex:
+ sys.stderr.write('ELF read error: %s\n' % ex)
+ sys.exit(1)
+
+
+#-------------------------------------------------------------------------------
+if __name__ == '__main__':
+ main()
+