s += _DESCR_SH_FLAGS[flag] if (x & flag) else ''
return s
+def describe_symbol_type(x):
+ return _DESCR_ST_INFO_TYPE.get(x, _unknown())
+
+def describe_symbol_bind(x):
+ return _DESCR_ST_INFO_BIND.get(x, _unknown())
+
+def describe_symbol_visibility(x):
+ return _DESCR_ST_VISIBILITY.get(x, _unknown())
+
+def describe_symbol_shndx(x):
+ return _DESCR_ST_SHNDX.get(x, '%3s' % x)
+
#-------------------------------------------------------------------------------
def _unknown():
SH_FLAGS.SHF_EXCLUDE: 'E',
}
+_DESCR_ST_INFO_TYPE = dict(
+ STT_NOTYPE='NOTYPE',
+ STT_OBJECT='OBJECT',
+ STT_FUNC='FUNC',
+ STT_SECTION='SECTION',
+ STT_FILE='FILE',
+ STT_COMMON='COMMON',
+ STT_TLS='TLS',
+ STT_NUM='NUM',
+ STT_RELC='RELC',
+ STT_SRELC='SRELC',
+)
+
+_DESCR_ST_INFO_BIND = dict(
+ STB_LOCAL='LOCAL',
+ STB_GLOBAL='GLOBAL',
+ STB_WEAK='WEAK',
+)
+
+_DESCR_ST_VISIBILITY = dict(
+ STV_DEFAULT='DEFAULT',
+ STV_INTERNAL='INTERNAL',
+ STV_HIDDEN='HIDDEN',
+ STD_PROTECTED='PROTECTED',
+)
+
+_DESCR_ST_SHNDX = dict(
+ SHN_UNDEF='UND',
+ SHN_ABS='ABS',
+ SHN_COMMON='COM',
+)
+
+
# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
+from ..construct import Pass
+
# e_ident[EI_CLASS] in the ELF header
ENUM_EI_CLASS = dict(
STT_COMMON=5,
STT_TLS=6,
STT_NUM=7,
+ STT_RELC=8,
+ STT_SRELC=9,
STT_LOOS=10,
STT_HIOS=12,
STT_LOPROC=13,
STT_HIPROC=15,
)
+
+# visibility from st_other
+ENUM_ST_VISIBILITY = dict(
+ STV_DEFAULT=0,
+ STV_INTERNAL=1,
+ STV_HIDDEN=2,
+ STV_PROTECTED=3,
+)
+
+# st_shndx
+ENUM_ST_SHNDX = dict(
+ SHN_UNDEF=0,
+ SHN_ABS=0xfff1,
+ SHN_COMMON=0xfff2,
+ _default_=Pass,
+)
+
)
def _create_sym(self):
- # Note that st_info is hierarchical. To access the type, use
+ # 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))
+ # st_other is hierarchical. To access the visibility,
+ # use container['st_other']['visibility']
+ st_other_struct = BitStruct('st_other',
+ Padding(5),
+ Enum(BitField('visibility', 3), **ENUM_ST_VISIBILITY))
if self.elfclass == 32:
self.Elf_Sym = Struct('Elf_Sym',
self.Elf_word('st_name'),
self.Elf_addr('st_value'),
self.Elf_word('st_size'),
st_info_struct,
- self.Elf_byte('st_other'),
- self.Elf_half('st_shndx'),
+ st_other_struct,
+ Enum(self.Elf_half('st_shndx'), **ENUM_ST_SHNDX),
)
else:
self.Elf_Sym = Struct('Elf_Sym',
self.Elf_word('st_name'),
st_info_struct,
- self.Elf_byte('st_other'),
- self.Elf_half('st_shndx'),
+ st_other_struct,
+ Enum(self.Elf_half('st_shndx'), **ENUM_ST_SHNDX),
self.Elf_addr('st_value'),
self.Elf_xword('st_size'),
)
+#!/usr/bin/env python
#-------------------------------------------------------------------------------
# readelf.py
#
from elftools.common.exceptions import ELFError
from elftools.elf.elffile import ELFFile
from elftools.elf.segments import InterpSegment
+from elftools.elf.sections import SymbolTableSection
from elftools.elf.descriptions import (
describe_ei_class, describe_ei_data, describe_ei_version,
describe_ei_osabi, describe_e_type, describe_e_machine,
describe_e_version_numeric, describe_p_type, describe_p_flags,
describe_sh_type, describe_sh_flags,
+ describe_symbol_type, describe_symbol_bind, describe_symbol_visibility,
+ describe_symbol_shndx,
)
self._emitline(' I (info), L (link order), G (group), x (unknown)')
self._emitline(' O (extra OS processing required) o (OS specific), p (processor specific)')
+ def display_symbol_tables(self):
+ """ Display the symbol tables contained in the file
+ """
+ for section in self.elffile.iter_sections():
+ if not isinstance(section, SymbolTableSection):
+ continue
+
+ if section['sh_entsize'] == 0:
+ self._emitline("\nSymbol table '%s' has a sh_entsize of zero!" % (
+ section.name))
+ continue
+
+ self._emitline("\nSymbol table '%s' contains %s entries:" % (
+ section.name, section.num_symbols()))
+
+ if self.elffile.elfclass == 32:
+ self._emitline(' Num: Value Size Type Bind Vis Ndx Name')
+ else: # 64
+ self._emitline(' Num: Value Size Type Bind Vis Ndx Name')
+
+ for nsym, symbol in enumerate(section.iter_symbols()):
+ self._emitline('%6d: %s %5d %-7s %-6s %-7s %4s %s' % (
+ nsym,
+ self._format_hex(symbol['st_value'], fullhex=True, lead0x=False),
+ symbol['st_size'],
+ describe_symbol_type(symbol['st_info']['type']),
+ describe_symbol_bind(symbol['st_info']['bind']),
+ describe_symbol_visibility(symbol['st_other']['visibility']),
+ describe_symbol_shndx(symbol['st_shndx']),
+ symbol.name))
+
def _format_hex(self, addr, fieldsize=None, fullhex=False, lead0x=True):
""" Format an address into a hexadecimal string.
with open(args[0], 'rb') as file:
try:
readelf = ReadElf(file, sys.stdout)
- readelf.display_file_header()
- print '----'
+ #readelf.display_file_header()
#readelf.display_program_headers()
- readelf.display_section_headers()
+ #readelf.display_section_headers()
+ readelf.display_symbol_tables()
except ELFError as ex:
sys.stderr.write('ELF read error: %s\n' % ex)
sys.exit(1)