added support for SUNW_syminfo header
authorYann Rouillard <yann@pleiades.fr.eu.org>
Sun, 28 Apr 2013 23:38:40 +0000 (01:38 +0200)
committerYann Rouillard <yann@pleiades.fr.eu.org>
Sun, 28 Apr 2013 23:38:40 +0000 (01:38 +0200)
elftools/elf/constants.py
elftools/elf/descriptions.py
elftools/elf/elffile.py
elftools/elf/enums.py
elftools/elf/sections.py
elftools/elf/structs.py

index df75e16fe0e0b41195a0b1fb04a52ffede62316e..e694293a553a40defd8d4d1ecc902ed254061754 100644 (file)
@@ -45,3 +45,20 @@ class P_FLAGS(object):
     PF_MASKOS=0x00FF0000
     PF_MASKPROC=0xFF000000
 
+
+# symbol info flags for entries
+# in the .SUNW_syminfo section
+class SYMINF0_FLAGS(object):
+    """ Flags for the si_flags field of entries
+        in the .SUNW_syminfo section
+    """
+    SYMINFO_FLG_DIRECT=0x1
+    SYMINFO_FLG_FILTER=0x2
+    SYMINFO_FLG_COPY=0x4
+    SYMINFO_FLG_LAZYLOAD=0x8
+    SYMINFO_FLG_DIRECTBIND=0x10
+    SYMINFO_FLG_NOEXTDIRECT=0x20
+    SYMINFO_FLG_AUXILIARY=0x40
+    SYMINFO_FLG_INTERPOSE=0x80
+    SYMINFO_FLG_CAP=0x100
+    SYMINFO_FLG_DEFERRED=0x200
index df8100015c4dd293e31f7cb664af7b8e33da9aa3..df8972fc017bb44694784b43f03b64cbde5b1be4 100644 (file)
@@ -9,7 +9,7 @@
 from .enums import (
     ENUM_D_TAG, ENUM_E_VERSION, ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64
     )
-from .constants import P_FLAGS, SH_FLAGS
+from .constants import P_FLAGS, SH_FLAGS, SYMINF0_FLAGS
 from ..common.py3compat import iteritems
 
 
@@ -84,6 +84,22 @@ def describe_dyn_tag(x):
     return _DESCR_D_TAG.get(x, _unknown)
 
 
+def describe_syminfo_flags(x):
+    s = ''
+    for flag in (
+            SYMINF0_FLAGS.SYMINFO_FLG_DIRECT,
+            SYMINF0_FLAGS.SYMINFO_FLG_DIRECTBIND,
+            SYMINF0_FLAGS.SYMINFO_FLG_COPY,
+            SYMINF0_FLAGS.SYMINFO_FLG_LAZYLOAD,
+            SYMINF0_FLAGS.SYMINFO_FLG_NOEXTDIRECT,
+            SYMINF0_FLAGS.SYMINFO_FLG_AUXILIARY,
+            SYMINF0_FLAGS.SYMINFO_FLG_FILTER,
+            SYMINF0_FLAGS.SYMINFO_FLG_INTERPOSE,
+            SYMINF0_FLAGS.SYMINFO_FLG_CAP,
+            SYMINF0_FLAGS.SYMINFO_FLG_DEFERRED):
+        s += _DESCR_SYMINFO_FLAGS[flag] if (x & flag) else ''
+    return s
+
 #-------------------------------------------------------------------------------
 _unknown = '<unknown>'
 
@@ -236,6 +252,19 @@ _DESCR_ST_SHNDX = dict(
     SHN_COMMON='COM',
 )
 
+_DESCR_SYMINFO_FLAGS = {
+    SYMINF0_FLAGS.SYMINFO_FLG_DIRECT: 'D',
+    SYMINF0_FLAGS.SYMINFO_FLG_DIRECTBIND: 'B',
+    SYMINF0_FLAGS.SYMINFO_FLG_COPY: 'C',
+    SYMINF0_FLAGS.SYMINFO_FLG_LAZYLOAD: 'L',
+    SYMINF0_FLAGS.SYMINFO_FLG_NOEXTDIRECT: 'N',
+    SYMINF0_FLAGS.SYMINFO_FLG_AUXILIARY: 'A',
+    SYMINF0_FLAGS.SYMINFO_FLG_FILTER: 'F',
+    SYMINF0_FLAGS.SYMINFO_FLG_INTERPOSE: 'I',
+    SYMINF0_FLAGS.SYMINFO_FLG_CAP: 'S',
+    SYMINF0_FLAGS.SYMINFO_FLG_DEFERRED: 'P',
+}
+
 _DESCR_RELOC_TYPE_i386 = dict(
         (v, k) for k, v in iteritems(ENUM_RELOC_TYPE_i386))
 
index 1d8d6de21245f7764abd1c1aaf583cce7f140a6f..7e18c92b408e54b38ef6c77c1e6ff174bf75b830 100644 (file)
@@ -12,7 +12,8 @@ from ..common.utils import struct_parse, elf_assert
 from ..construct import ConstructError
 from .structs import ELFStructs
 from .sections import (
-        Section, StringTableSection, SymbolTableSection, NullSection)
+        Section, StringTableSection, SymbolTableSection,
+        SUNWSyminfoTableSection, NullSection)
 from .dynamic import DynamicSection, DynamicSegment
 from .relocation import RelocationSection, RelocationHandler
 from .segments import Segment, InterpSegment
@@ -243,6 +244,8 @@ class ELFFile(object):
             return NullSection(section_header, name, self.stream)
         elif sectype in ('SHT_SYMTAB', 'SHT_DYNSYM'):
             return self._make_symbol_table_section(section_header, name)
+        elif sectype == 'SHT_SUNW_syminfo':
+            return self._make_sunwsyminfo_table_section(section_header, name)
         elif sectype in ('SHT_REL', 'SHT_RELA'):
             return RelocationSection(
                 section_header, name, self.stream, self)
@@ -261,6 +264,16 @@ class ELFFile(object):
             elffile=self,
             stringtable=strtab_section)
 
+    def _make_sunwsyminfo_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 SUNWSyminfoTableSection(
+            section_header, name, self.stream,
+            elffile=self,
+            symboltable=strtab_section)
+
     def _get_segment_header(self, n):
         """ Find the header of segment #n, parse it and return the struct
         """
index aaa6c710e3404ef9d68b3b1a2d855ede8851dd82..0a90c19b5abeae01304edbb45494ff0aecd3b245 100644 (file)
@@ -192,6 +192,7 @@ ENUM_SH_TYPE = dict(
     SHT_LOUSER=0x80000000,
     SHT_HIUSER=0xffffffff,
     SHT_AMD64_UNWIND=0x70000001,
+    SHT_SUNW_syminfo=0x6ffffffc,
     _default_=Pass,
 )
 
index 518c857aa92c28bdd5fdc7aab457426a5fc8efaf..1446ccf9d114eddebea2e34f9f3f9f7071a4fcbb 100644 (file)
@@ -123,3 +123,38 @@ class Symbol(object):
         return self.entry[name]
 
 
+class SUNWSyminfoTableSection(Section):
+    """ ELF .SUNW Syminfo table section.
+        Has an associated SymbolTableSection that's passed in the constructor.
+    """
+    def __init__(self, header, name, stream, elffile, symboltable):
+        super(SUNWSyminfoTableSection, 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'] - 1
+
+    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_Syminfo,
+            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(1, self.num_symbols() + 1):
+            yield self.get_symbol(i)
index 08567de4fbe4c86b2f417d07f06f34b1dace8d12..7b9365fcfb4118be3183ea77f4d9ed2ae4870ee6 100644 (file)
@@ -73,6 +73,7 @@ class ELFStructs(object):
         self._create_sym()
         self._create_rel()
         self._create_dyn()
+        self._create_syminfo()
     
     def _create_ehdr(self):
         self.Elf_Ehdr = Struct('Elf_Ehdr',
@@ -203,5 +204,8 @@ class ELFStructs(object):
                 self.Elf_xword('st_size'),
             )
 
-
-
+    def _create_syminfo(self):
+        self.Elf_Syminfo = Struct('Elf_Syminfo',
+            self.Elf_half('si_boundto'),
+            self.Elf_half('si_flags'),
+        )