blob: 518c857aa92c28bdd5fdc7aab457426a5fc8efaf [file] [log] [blame]
# elftools: elf/
# ELF sections
# Eli Bendersky (
# This code is in the public domain
from ..construct import CString
from ..common.utils import struct_parse, elf_assert, parse_cstring_from_stream
class Section(object):
""" Base class for ELF sections. Also used for all sections types that have
no special functionality.
Allows dictionary-like access to the section header. For example:
> sec = Section(...)
> sec['sh_type'] # section type
def __init__(self, header, name, stream):
self.header = header = name = stream
def data(self):
""" The section data from the file.
def is_null(self):
""" Is this a null section?
return False
def __getitem__(self, name):
""" Implement dict-like access to header entries
return self.header[name]
def __eq__(self, other):
return self.header == other.header
class NullSection(Section):
""" ELF NULL section
def __init__(self, header, name, stream):
super(NullSection, self).__init__(header, name, stream)
def is_null(self):
return True
class StringTableSection(Section):
""" ELF string table section.
def __init__(self, header, name, stream):
super(StringTableSection, self).__init__(header, name, stream)
def get_string(self, offset):
""" Get the string stored at the given offset in this string table.
table_offset = self['sh_offset']
s = parse_cstring_from_stream(, table_offset + offset)
return s
class SymbolTableSection(Section):
""" ELF symbol table section. Has an associated StringTableSection that's
passed in the constructor.
def __init__(self, header, name, stream, elffile, stringtable):
super(SymbolTableSection, self).__init__(header, name, stream)
self.elffile = elffile
self.elfstructs = self.elffile.structs
self.stringtable = stringtable
elf_assert(self['sh_entsize'] > 0,
'Expected entry size of section %s to be > 0' % name)
elf_assert(self['sh_size'] % self['sh_entsize'] == 0,
'Expected section size to be a multiple of entry size in section %s' % name)
def num_symbols(self):
""" Number of symbols in the table
return self['sh_size'] // self['sh_entsize']
def get_symbol(self, n):
""" Get the symbol at index #n from the table (Symbol object)
# Grab the symbol's entry from the stream
entry_offset = self['sh_offset'] + n * self['sh_entsize']
entry = struct_parse(
# Find the symbol name in the associated string table
name = self.stringtable.get_string(entry['st_name'])
return Symbol(entry, name)
def iter_symbols(self):
""" Yield all the symbols in the table
for i in range(self.num_symbols()):
yield self.get_symbol(i)
class Symbol(object):
""" Symbol object - representing a single symbol entry from a symbol table
Similarly to Section objects, allows dictionary-like access to the
symbol entry.
def __init__(self, entry, name):
self.entry = entry = name
def __getitem__(self, name):
""" Implement dict-like access to entries
return self.entry[name]