From bf9ca16841642f7b5b0471ce6aa48ae471d4acd5 Mon Sep 17 00:00:00 2001 From: Yann Rouillard Date: Mon, 29 Apr 2013 01:38:40 +0200 Subject: [PATCH] added support for SUNW_syminfo header --- elftools/elf/constants.py | 17 +++++++++++++++++ elftools/elf/descriptions.py | 31 ++++++++++++++++++++++++++++++- elftools/elf/elffile.py | 15 ++++++++++++++- elftools/elf/enums.py | 1 + elftools/elf/sections.py | 35 +++++++++++++++++++++++++++++++++++ elftools/elf/structs.py | 8 ++++++-- 6 files changed, 103 insertions(+), 4 deletions(-) diff --git a/elftools/elf/constants.py b/elftools/elf/constants.py index df75e16..e694293 100644 --- a/elftools/elf/constants.py +++ b/elftools/elf/constants.py @@ -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 diff --git a/elftools/elf/descriptions.py b/elftools/elf/descriptions.py index df81000..df8972f 100644 --- a/elftools/elf/descriptions.py +++ b/elftools/elf/descriptions.py @@ -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 = '' @@ -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)) diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py index 1d8d6de..7e18c92 100644 --- a/elftools/elf/elffile.py +++ b/elftools/elf/elffile.py @@ -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 """ diff --git a/elftools/elf/enums.py b/elftools/elf/enums.py index aaa6c71..0a90c19 100644 --- a/elftools/elf/enums.py +++ b/elftools/elf/enums.py @@ -192,6 +192,7 @@ ENUM_SH_TYPE = dict( SHT_LOUSER=0x80000000, SHT_HIUSER=0xffffffff, SHT_AMD64_UNWIND=0x70000001, + SHT_SUNW_syminfo=0x6ffffffc, _default_=Pass, ) diff --git a/elftools/elf/sections.py b/elftools/elf/sections.py index 518c857..1446ccf 100644 --- a/elftools/elf/sections.py +++ b/elftools/elf/sections.py @@ -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) diff --git a/elftools/elf/structs.py b/elftools/elf/structs.py index 08567de..7b9365f 100644 --- a/elftools/elf/structs.py +++ b/elftools/elf/structs.py @@ -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'), + ) -- 2.30.2