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