split gnu|sunw versions code in a separate file
authorYann Rouillard <yann@pleiades.fr.eu.org>
Wed, 29 May 2013 21:34:51 +0000 (23:34 +0200)
committerYann Rouillard <yann@pleiades.fr.eu.org>
Wed, 29 May 2013 21:34:51 +0000 (23:34 +0200)
elftools/elf/elffile.py
elftools/elf/gnuversions.py [new file with mode: 0644]
elftools/elf/sections.py

index 0a7969dac599f878a53b07b33a310d422272873a..979ed2d0a245d7ae606dd76a72b47526901637ce 100644 (file)
@@ -13,11 +13,12 @@ from ..construct import ConstructError
 from .structs import ELFStructs
 from .sections import (
         Section, StringTableSection, SymbolTableSection,
-        SUNWSyminfoTableSection, GNUVerNeedTableSection, 
-        GNUVerDefTableSection, GNUVerSymTableSection,
-        NullSection)
+        SUNWSyminfoTableSection, NullSection)
 from .dynamic import DynamicSection, DynamicSegment
 from .relocation import RelocationSection, RelocationHandler
+from .gnuversions import (
+        GNUVerNeedTableSection, GNUVerDefTableSection,
+        GNUVerSymTableSection)
 from .segments import Segment, InterpSegment
 from .enums import ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64
 from ..dwarf.dwarfinfo import DWARFInfo, DebugSectionDescriptor, DwarfConfig
diff --git a/elftools/elf/gnuversions.py b/elftools/elf/gnuversions.py
new file mode 100644 (file)
index 0000000..79110d7
--- /dev/null
@@ -0,0 +1,251 @@
+#------------------------------------------------------------------------------
+# elftools: elf/gnuversions.py
+#
+# ELF sections
+#
+# Yann Rouillard (yann@pleiades.fr.eu.org)
+# This code is in the public domain
+#------------------------------------------------------------------------------
+from ..construct import CString
+from ..common.utils import struct_parse, elf_assert
+from .sections import Section, Symbol
+
+
+class Version(object):
+    """ Version object - representing a version definition or dependency
+        entry from a "Version Needed" or a "Version Dependency" table section.
+
+        This kind of entry contains a pointer to an array of auxiliary entries
+        that store the information about version names or dependencies.
+        These entries are not stored in this object and should be accessed
+        through the appropriate method of a section object which will return
+        an iterator of VersionAuxiliary objects.
+
+        Similarly to Section objects, allows dictionary-like access to
+        verdef/verneed entry
+    """
+    def __init__(self, entry, name=None):
+        self.entry = entry
+        self.name = name
+
+    def __getitem__(self, name):
+        """ Implement dict-like access to entry
+        """
+        return self.entry[name]
+
+
+class VersionAuxiliary(object):
+    """ Version Auxiliary object - representing an auxiliary entry of a version
+        definition or dependency entry
+
+        Similarly to Section objects, allows dictionary-like access to the
+        verdaux/vernaux entry
+    """
+    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]
+
+
+class GNUVerNeedTableSection(Section):
+    """ ELF SUNW or GNU Version Needed table section.
+        Has an associated StringTableSection that's passed in the constructor.
+    """
+    def __init__(self, header, name, stream, elffile, stringtable):
+        super(GNUVerNeedTableSection, self).__init__(header, name, stream)
+        self.elffile = elffile
+        self.elfstructs = self.elffile.structs
+        self.stringtable = stringtable
+        self._has_indexes = None
+
+    def num_versions(self):
+        """ Number of version dependency in the table
+        """
+        return self['sh_info']
+
+    def has_indexes(self):
+        """ Return True if at least one version definition entry has an index
+            that is stored in the vna_other field.
+            This information is used for symbol versioning
+        """
+        if self._has_indexes is None:
+            self._has_indexes = False
+            for _, vernaux_iter in self.iter_versions():
+                for vernaux in vernaux_iter:
+                    if vernaux['vna_other']:
+                        self._has_indexes = True
+                        break
+
+        return self._has_indexes
+
+    def get_version(self, index):
+        """ Get the version information located at index #n in the table
+            Return boths the verneed structure and the vernaux structure
+            that contains the name of the version
+        """
+        for verneed, vernaux_iter in self.iter_versions():
+            for vernaux in vernaux_iter:
+                if vernaux['vna_other'] == index:
+                    return verneed, vernaux
+
+        return None
+
+    def _iter_version_auxiliaries(self, entry_offset, count):
+        """ Yield all auxiliary entries of a version dependency
+        """
+        for _ in range(count):
+            entry = struct_parse(
+                        self.elfstructs.Elf_Vernaux,
+                        self.stream,
+                        stream_pos=entry_offset)
+
+            name = self.stringtable.get_string(entry['vna_name'])
+            version_aux = VersionAuxiliary(entry, name)
+            yield version_aux
+
+            if not entry['vna_next']:
+                break
+
+            entry_offset += entry['vna_next']
+
+    def iter_versions(self):
+        """ Yield all the version dependencies entries in the table
+            Each time it returns the main version dependency structure
+            and an iterator to walk through its auxiliaries entries
+        """
+        entry_offset = self['sh_offset']
+        for _ in range(self.num_versions()):
+            entry = struct_parse(
+                self.elfstructs.Elf_Verneed,
+                self.stream,
+                stream_pos=entry_offset)
+
+            name = self.stringtable.get_string(entry['vn_file'])
+            elf_assert(entry['vn_cnt'] > 0,
+                'Expected number of version names to be > 0 for'
+                'version definition %s' % name)
+
+            verneed = Version(entry, name)
+            aux_entries_offset = entry_offset + entry['vn_aux']
+            vernaux_iter = self._iter_version_auxiliaries(aux_entries_offset,
+                                                          entry['vn_cnt'])
+            yield verneed, vernaux_iter
+
+            if not entry['vn_next']:
+                break
+
+            entry_offset += entry['vn_next']
+
+
+class GNUVerDefTableSection(Section):
+    """ ELF SUNW or GNU Version Definition table section.
+        Has an associated StringTableSection that's passed in the constructor.
+    """
+    def __init__(self, header, name, stream, elffile, stringtable):
+        super(GNUVerDefTableSection, self).__init__(header, name, stream)
+        self.elffile = elffile
+        self.elfstructs = self.elffile.structs
+        self.stringtable = stringtable
+
+    def num_versions(self):
+        """ Number of version definitions in the table
+        """
+        return self['sh_info']
+
+    def get_version(self, index):
+        """ Get the version information located at index #n in the table
+            Return boths the verdef structure and an iterator to retrieve
+            both the version names and dependencies in the form of
+            verdaux entries
+        """
+        for verdef, verdaux_iter in self.iter_versions():
+            if verdef['vd_ndx'] == index:
+                return verdef, verdaux_iter
+
+        return None
+
+    def _iter_version_auxiliaries(self, entry_offset, count):
+        """ Yield all auxiliary entries of a version definition
+        """
+        for _ in range(count):
+            entry = struct_parse(
+                        self.elfstructs.Elf_Verdaux,
+                        self.stream,
+                        stream_pos=entry_offset)
+
+            name = self.stringtable.get_string(entry['vda_name'])
+            vernaux = VersionAuxiliary(entry, name)
+            yield vernaux
+
+            if not entry['vda_next']:
+                break
+
+            entry_offset += entry['vda_next']
+
+    def iter_versions(self):
+        """ Yield all the version definition entries in the table
+            Each time it returns the main version definition structure
+            and an iterator to walk through its auxiliaries entries
+        """
+        entry_offset = self['sh_offset']
+        for _ in range(self.num_versions()):
+            entry = struct_parse(
+                self.elfstructs.Elf_Verdef,
+                self.stream,
+                stream_pos=entry_offset)
+
+            elf_assert(entry['vd_cnt'] > 0,
+                'Expected number of version names to be > 0'
+                'for version definition at index %i' % entry['vd_ndx'])
+
+            verdef = Version(entry)
+            aux_entries_offset = entry_offset + entry['vd_aux']
+            verdaux_iter = self._iter_version_auxiliaries(aux_entries_offset,
+                                                          entry['vd_cnt'])
+            yield verdef, verdaux_iter
+
+            if not entry['vd_next']:
+                break
+
+            entry_offset += entry['vd_next']
+
+
+class GNUVerSymTableSection(Section):
+    """ ELF SUNW or GNU Versym table section.
+        Has an associated SymbolTableSection that's passed in the constructor.
+    """
+    def __init__(self, header, name, stream, elffile, symboltable):
+        super(GNUVerSymTableSection, self).__init__(header, name, stream)
+        self.elffile = elffile
+        self.elfstructs = self.elffile.structs
+        self.symboltable = symboltable
+
+    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)
+            It begins at 1 and not 0 since the first entry is used to
+            store the current version of the syminfo table
+        """
+        # Grab the symbol's entry from the stream
+        entry_offset = self['sh_offset'] + n * self['sh_entsize']
+        entry = struct_parse(
+            self.elfstructs.Elf_Versym,
+            self.stream,
+            stream_pos=entry_offset)
+        # Find the symbol name in the associated symbol table
+        name = self.symboltable.get_symbol(n).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)
index 1b947e214816daa78995fd32f23c8bc490ce5377..ce6245057ee798380755e0e60c426bc144897d15 100644 (file)
@@ -158,245 +158,3 @@ class SUNWSyminfoTableSection(Section):
         """
         for i in range(1, self.num_symbols() + 1):
             yield self.get_symbol(i)
-
-
-class Version(object):
-    """ Version object - representing a version definition or dependency
-        entry from a "Version Needed" or a "Version Dependency" table section.
-
-        This kind of entry contains a pointer to an array of auxiliary entries
-        that store the information about version names or dependencies. 
-        These entries are not stored in this object and should be accessed
-        through the appropriate method of a section object which will return
-        an iterator of VersionAuxiliary objects.
-
-        Similarly to Section objects, allows dictionary-like access to
-        verdef/verneed entry
-    """
-    def __init__(self, entry, name=None):
-        self.entry = entry
-        self.name = name
-
-    def __getitem__(self, name):
-        """ Implement dict-like access to entry
-        """
-        return self.entry[name]
-
-
-class VersionAuxiliary(object):
-    """ Version Auxiliary object - representing an auxiliary entry of a version
-        definition or dependency entry
-
-        Similarly to Section objects, allows dictionary-like access to the
-        verdaux/vernaux entry
-    """
-    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]
-
-class GNUVerNeedTableSection(Section):
-    """ ELF SUNW or GNU Version Needed table section.
-        Has an associated StringTableSection that's passed in the constructor.
-    """
-    def __init__(self, header, name, stream, elffile, stringtable):
-        super(GNUVerNeedTableSection, self).__init__(header, name, stream)
-        self.elffile = elffile
-        self.elfstructs = self.elffile.structs
-        self.stringtable = stringtable
-        self._has_indexes = None
-
-    def num_versions(self):
-        """ Number of version dependency in the table
-        """
-        return self['sh_info']
-
-    def has_indexes(self):
-        """ Return True if at least one version definition entry has an index
-            that is stored in the vna_other field.
-            This information is used for symbol versioning
-        """
-        if self._has_indexes is None:
-            self._has_indexes = False
-            for _, vernaux_iter in self.iter_versions():
-                for vernaux in vernaux_iter:
-                    if vernaux['vna_other']:
-                        self._has_indexes = True
-                        break
-
-        return self._has_indexes
-        
-    def get_version(self, index):
-        """ Get the version information located at index #n in the table
-            Return boths the verneed structure and the vernaux structure
-            that contains the name of the version
-        """
-        for verneed, vernaux_iter in self.iter_versions():
-            for vernaux in vernaux_iter:
-                if vernaux['vna_other'] == index:
-                    return verneed, vernaux
-
-        return None
-
-
-    def _iter_version_auxiliaries(self, entry_offset, count):
-        """ Yield all auxiliary entries of a version dependency
-        """
-        for _ in range(count): 
-            entry = struct_parse(
-                        self.elfstructs.Elf_Vernaux,
-                        self.stream,
-                        stream_pos=entry_offset)
-
-            name = self.stringtable.get_string(entry['vna_name'])
-            version_aux = VersionAuxiliary(entry, name)
-            yield version_aux
-
-            if not entry['vna_next']:
-                break
-
-            entry_offset += entry['vna_next']
-        
-
-    def iter_versions(self):
-        """ Yield all the version dependencies entries in the table 
-            Each time it returns the main version dependency structure
-            and an iterator to walk through its auxiliaries entries
-        """
-        entry_offset = self['sh_offset']
-        for _ in range(self.num_versions()):
-            entry = struct_parse(
-                self.elfstructs.Elf_Verneed,
-                self.stream,
-                stream_pos=entry_offset)
-
-            name = self.stringtable.get_string(entry['vn_file'])
-            elf_assert(entry['vn_cnt'] > 0,
-                'Expected number of version names to be > 0 for version definition %s' % name)
-
-            verneed = Version(entry, name)
-            aux_entries_offset = entry_offset + entry['vn_aux']
-            vernaux_iter = self._iter_version_auxiliaries(aux_entries_offset,
-                                                          entry['vn_cnt'])
-            yield verneed, vernaux_iter
-
-            if not entry['vn_next']:
-                break
-
-            entry_offset += entry['vn_next'] 
-
-
-class GNUVerDefTableSection(Section):
-    """ ELF SUNW or GNU Version Definition table section.
-        Has an associated StringTableSection that's passed in the constructor.
-    """
-    def __init__(self, header, name, stream, elffile, stringtable):
-        super(GNUVerDefTableSection, self).__init__(header, name, stream)
-        self.elffile = elffile
-        self.elfstructs = self.elffile.structs
-        self.stringtable = stringtable
-
-    def num_versions(self):
-        """ Number of version definitions in the table
-        """
-        return self['sh_info']
-        
-    def get_version(self, index):
-        """ Get the version information located at index #n in the table
-            Return boths the verdef structure and an iterator to retrieve
-            both the version names and dependencies in the form of 
-            verdaux entries
-        """
-        for verdef, verdaux_iter in self.iter_versions():
-            if verdef['vd_ndx'] == index:
-                return verdef, verdaux_iter
-
-        return None
-
-    def _iter_version_auxiliaries(self, entry_offset, count):
-        """ Yield all auxiliary entries of a version definition
-        """
-        for _ in range(count):
-            entry = struct_parse(
-                        self.elfstructs.Elf_Verdaux,
-                        self.stream,
-                        stream_pos=entry_offset)
-
-            name = self.stringtable.get_string(entry['vda_name'])
-            vernaux = VersionAuxiliary(entry, name)
-            yield vernaux
-
-            if not entry['vda_next']:
-                break
-
-            entry_offset += entry['vda_next']
-        
-
-    def iter_versions(self):
-        """ Yield all the version definition entries in the table 
-            Each time it returns the main version definition structure
-            and an iterator to walk through its auxiliaries entries
-        """
-        entry_offset = self['sh_offset']
-        for _ in range(self.num_versions()):
-            entry = struct_parse(
-                self.elfstructs.Elf_Verdef,
-                self.stream,
-                stream_pos=entry_offset)
-
-            elf_assert(entry['vd_cnt'] > 0,
-                'Expected number of version names to be > 0'
-                'for version definition at index %i' % entry['vd_ndx'])
-
-            verdef = Version(entry)
-            aux_entries_offset = entry_offset + entry['vd_aux']
-            verdaux_iter = self._iter_version_auxiliaries(aux_entries_offset,
-                                                          entry['vd_cnt'])
-            yield verdef, verdaux_iter
-
-            if not entry['vd_next']:
-                break
-
-            entry_offset += entry['vd_next'] 
-
-
-class GNUVerSymTableSection(Section):
-    """ ELF SUNW or GNU Versym table section.
-        Has an associated SymbolTableSection that's passed in the constructor.
-    """
-    def __init__(self, header, name, stream, elffile, symboltable):
-        super(GNUVerSymTableSection, self).__init__(header, name, stream)
-        self.elffile = elffile
-        self.elfstructs = self.elffile.structs
-        self.symboltable = symboltable
-
-    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)
-            It begins at 1 and not 0 since the first entry is used to
-            store the current version of the syminfo table
-        """
-        # Grab the symbol's entry from the stream
-        entry_offset = self['sh_offset'] + n * self['sh_entsize']
-        entry = struct_parse(
-            self.elfstructs.Elf_Versym,
-            self.stream,
-            stream_pos=entry_offset)
-        # Find the symbol name in the associated symbol table
-        name = self.symboltable.get_symbol(n).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)
-