Added a SymbolTableSection class and split functionality from ELFFile to create it
diff --git a/elftools/common/exceptions.py b/elftools/common/exceptions.py
index 05fa602..a4df582 100644
--- a/elftools/common/exceptions.py
+++ b/elftools/common/exceptions.py
@@ -6,7 +6,6 @@
# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
-
class ELFError(Exception):
pass
diff --git a/elftools/elf/constants.py b/elftools/elf/constants.py
index 5af8372..cd21e09 100644
--- a/elftools/elf/constants.py
+++ b/elftools/elf/constants.py
@@ -6,7 +6,6 @@
# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
-
class SHN_INDICES(object):
""" Special section indices
"""
diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py
index 7d134b9..045e1c4 100644
--- a/elftools/elf/elffile.py
+++ b/elftools/elf/elffile.py
@@ -10,7 +10,7 @@
from ..common.utils import struct_parse
from ..construct import ConstructError
from .structs import ELFStructs
-from .sections import Section, StringTableSection
+from .sections import Section, StringTableSection, SymbolTableSection
from .segments import Segment
@@ -42,11 +42,11 @@
return self['e_shnum']
def get_section(self, n):
- """ Get the section at index #n from the file (Section object)
+ """ Get the section at index #n from the file (Section object or a
+ subclass)
"""
section_header = self._get_section_header(n)
- name = self._get_section_name(section_header)
- return Section(section_header, name, self.stream)
+ return self._make_section(section_header)
def iter_sections(self):
""" Yield all the sections in the file
@@ -130,6 +130,28 @@
name_offset = section_header['sh_name']
return self._file_stringtable_section.get_string(name_offset)
+ def _make_section(self, section_header):
+ """ Create a section object of the appropriate type
+ """
+ name = self._get_section_name(section_header)
+ sectype = section_header['sh_type']
+
+ if sectype == 'SHT_STRTAB':
+ return StringTableSection(section_header, name, self.stream)
+ elif sectype in ('SHT_SYMTAB', 'SHT_DYNSYM'):
+ return self._make_symbol_table_section(section_header, name)
+ else:
+ return Section(section_header, name, self.stream)
+
+ def _make_symbol_table_section(self, section_header, name):
+ """ Create a SymbolTableSection
+ """
+ linked_strtab_index = section_header['sh_link']
+ strtab_section = self.get_section(linked_strtab_index)
+ return SymbolTableSection(
+ section_header, name, self.stream,
+ stringtable=strtab_section)
+
def _get_segment_header(self, n):
""" Find the header of segment #n, parse it and return the struct
"""
diff --git a/elftools/elf/sections.py b/elftools/elf/sections.py
index 502b69f..931095f 100644
--- a/elftools/elf/sections.py
+++ b/elftools/elf/sections.py
@@ -7,9 +7,17 @@
# This code is in the public domain
#-------------------------------------------------------------------------------
from ..construct import CString
+from ..common.utils import struct_parse
-class Section(object):
+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
self.name = name
@@ -27,7 +35,9 @@
return self.header[name]
-class StringTableSection(Section):
+class StringTableSection(Section):
+ """ ELF string table section.
+ """
def __init__(self, header, name, stream):
super(StringTableSection, self).__init__(header, name, stream)
@@ -35,9 +45,18 @@
""" Get the string stored at the given offset in this string table.
"""
table_offset = self['sh_offset']
- self.stream.seek(table_offset + offset)
- return CString('').parse_stream(self.stream)
+ return struct_parse(
+ CString(''),
+ self.stream,
+ stream_pos=table_offset + offset)
+class SymbolTableSection(Section):
+ """ ELF symbol table section. Has an associated StringTableSection that's
+ passed in the constructor.
+ """
+ def __init__(self, header, name, stream, stringtable):
+ super(SymbolTableSection, self).__init__(header, name, stream)
+ self.stringtable = stringtable
-
+
diff --git a/elftools/elf/structs.py b/elftools/elf/structs.py
index 0b9f58f..465a9c8 100644
--- a/elftools/elf/structs.py
+++ b/elftools/elf/structs.py
@@ -7,7 +7,6 @@
# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
-
from ..construct import (
UBInt8, UBInt16, UBInt32, UBInt64,
ULInt8, ULInt16, ULInt32, ULInt64,
diff --git a/z.py b/z.py
index adcfd6c..2a5485c 100644
--- a/z.py
+++ b/z.py
@@ -1,6 +1,7 @@
import sys
from elftools.elf.structs import ELFStructs
from elftools.elf.elffile import ELFFile
+from elftools.elf.sections import *
# read a little-endian, 64-bit file
es = ELFStructs(True, 64)
@@ -13,11 +14,14 @@
print '===> %s segments!' % efile.num_segments()
for sec in efile.iter_sections():
- print sec.name
+ print type(sec), sec.name
+ if isinstance(sec, SymbolTableSection):
+ print ' linked string table:', sec.stringtable.name
for seg in efile.iter_segments():
print seg['p_type'], seg['p_offset']
+
#~ print 'num', efile.num_sections()
#~ sec = efile.get_section(39)
#~ print sec.header