added Symbol decoding from a symbol table section
diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py
index dc1b246..b0e2b67 100644
--- a/elftools/elf/elffile.py
+++ b/elftools/elf/elffile.py
@@ -150,6 +150,7 @@
         strtab_section = self.get_section(linked_strtab_index)
         return SymbolTableSection(
             section_header, name, self.stream,
+            elfstructs=self.structs,
             stringtable=strtab_section)
 
     def _get_segment_header(self, n):
diff --git a/elftools/elf/enums.py b/elftools/elf/enums.py
index 31647ac..1cd5a9b 100644
--- a/elftools/elf/enums.py
+++ b/elftools/elf/enums.py
@@ -105,3 +105,30 @@
     PT_GNU_RELRO=0x6474e552,
 )
 
+# st_info bindings in the symbol header
+ENUM_ST_INFO_BIND = dict(
+    STB_LOCAL=0,
+    STB_GLOBAL=1,
+    STB_WEAK=2,
+    STB_NUM=3,
+    STB_LOOS=10,
+    STB_HIOS=12,
+    STB_LOPROC=13,
+    STB_HIPROC=15,
+)
+
+# st_info type in the symbol header
+ENUM_ST_INFO_TYPE = dict(
+    STT_NOTYPE=0,
+    STT_OBJECT=1,
+    STT_FUNC=2,
+    STT_SECTION=3,
+    STT_FILE=4,
+    STT_COMMON=5,
+    STT_TLS=6,
+    STT_NUM=7,
+    STT_LOOS=10,
+    STT_HIOS=12,
+    STT_LOPROC=13,
+    STT_HIPROC=15,
+)
diff --git a/elftools/elf/sections.py b/elftools/elf/sections.py
index 04410f3..fd11875 100644
--- a/elftools/elf/sections.py
+++ b/elftools/elf/sections.py
@@ -55,6 +55,50 @@
     """ ELF symbol table section. Has an associated StringTableSection that's
         passed in the constructor.
     """
-    def __init__(self, header, name, stream, stringtable):
+    def __init__(self, header, name, stream, elfstructs, stringtable):
         super(SymbolTableSection, self).__init__(header, name, stream)
+        self.elfstructs = elfstructs
         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(
+            self.elfstructs.Elf_Sym,
+            self.stream,
+            stream_pos=entry_offset)
+        # 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
+        section.
+    """
+    def __init__(self, entry, name):
+        self.entry = entry
+        self.name = name
+
+    def __getitem__(self, name):
+        """ Implement dict-like access to entries
+        """
+        return self.entry[name]
+
diff --git a/elftools/elf/structs.py b/elftools/elf/structs.py
index c628c93..21ea2b7 100644
--- a/elftools/elf/structs.py
+++ b/elftools/elf/structs.py
@@ -11,7 +11,7 @@
     UBInt8, UBInt16, UBInt32, UBInt64,
     ULInt8, ULInt16, ULInt32, ULInt64,
     SBInt32, SLInt32, SBInt64, SLInt64,
-    Struct, Array, Enum, Padding,
+    Struct, Array, Enum, Padding, BitStruct, BitField,
     )
 
 from .enums import *
@@ -130,19 +130,22 @@
         )
     
     def _create_sym(self):
+        st_info_struct = BitStruct('st_info',
+            Enum(BitField('bind', 4), **ENUM_ST_INFO_BIND),
+            Enum(BitField('type', 4), **ENUM_ST_INFO_TYPE))
         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'),
-                self.Elf_byte('st_info'),
+                st_info_struct,
                 self.Elf_byte('st_other'),
                 self.Elf_half('st_shndx'),
             )
         else:
             self.Elf_Sym = Struct('Elf_Sym',
                 self.Elf_word('st_name'),
-                self.Elf_byte('st_info'),
+                st_info_struct,
                 self.Elf_byte('st_other'),
                 self.Elf_half('st_shndx'),
                 self.Elf_addr('st_value'),
diff --git a/z.py b/z.py
index fc295e7..dd2ab54 100644
--- a/z.py
+++ b/z.py
@@ -22,6 +22,12 @@
 for seg in efile.iter_segments():
     print seg['p_type'], seg['p_offset']
 
+for sec in efile.iter_sections():
+    if isinstance(sec, SymbolTableSection):
+        print 'symbol table "%s ~~~"' % sec.name
+        for sym in sec.iter_symbols():
+            print '%-26s %s %s' % (sym.name, sym['st_info']['type'], sym['st_info']['bind'])
+
 
 #~ print 'num', efile.num_sections()
 #~ sec = efile.get_section(39)