Added a SymbolTableSection class and split functionality from ELFFile to create it
authoreliben <devnull@localhost>
Thu, 8 Sep 2011 13:57:21 +0000 (16:57 +0300)
committereliben <devnull@localhost>
Thu, 8 Sep 2011 13:57:21 +0000 (16:57 +0300)
elftools/common/exceptions.py
elftools/elf/constants.py
elftools/elf/elffile.py
elftools/elf/sections.py
elftools/elf/structs.py
z.py

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