You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gentoo-overlay/dev-python/pyelftools/files/pyelftools-0.20-dyntags-1.p...

267 lines
8.4 KiB

# HG changeset patch
# User Mike Frysinger <vapier@gentoo.org>
# Date 1352755639 18000
# Node ID a9c9b2f9ec964e6750dd6f9a96767fe2e9201d85
# Parent f3408c7b954910aa3a58e88196efba4954c0cc55
add support for parsing of the dynamic section/segment and its tags
diff -r f3408c7b9549 -r a9c9b2f9ec96 elftools/elf/dynamic.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/elftools/elf/dynamic.py Mon Nov 12 16:27:19 2012 -0500
@@ -0,0 +1,115 @@
+#-------------------------------------------------------------------------------
+# elftools: elf/dynamic.py
+#
+# ELF Dynamic Tags
+#
+# Mike Frysinger (vapier@gentoo.org)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+from .sections import Section
+from .segments import Segment
+from ..common.utils import struct_parse
+
+from .enums import ENUM_D_TAG
+
+
+class DynamicTag(object):
+ """ Dynamic Tag object - representing a single dynamic tag entry from a
+ dynamic section.
+
+ Similarly to Section objects, allows dictionary-like access to the
+ dynamic tag.
+ """
+ def __init__(self, entry, elffile):
+ self.entry = entry
+ if entry.d_tag == 'DT_NEEDED' or \
+ entry.d_tag == 'DT_RPATH' or \
+ entry.d_tag == 'DT_RUNPATH':
+ dynstr = elffile.get_section_by_name('.dynstr')
+ setattr(self, entry.d_tag[3:].lower(), dynstr.get_string(self.entry.d_val))
+
+ def __getitem__(self, name):
+ """ Implement dict-like access to entries
+ """
+ return self.entry[name]
+
+ def __repr__(self):
+ return '<DynamicTag (%s): %r>' % (self.entry.d_tag, self.entry)
+
+ def __str__(self):
+ if self.entry.d_tag == 'DT_NEEDED' or \
+ self.entry.d_tag == 'DT_RPATH' or \
+ self.entry.d_tag == 'DT_RUNPATH':
+ s = '"%s"' % getattr(self, self.entry.d_tag[3:].lower())
+ else:
+ s = '%#x' % self.entry.d_ptr
+ return '<DynamicTag (%s) %s>' % (self.entry.d_tag, s)
+
+
+class Dynamic(object):
+ def __init__(self, stream, elffile, position):
+ self._stream = stream
+ self._elffile = elffile
+ self._elfstructs = elffile.structs
+ self._num_tags = -1;
+ self._offset = position
+ self._tagsize = self._elfstructs.Elf_Dyn.sizeof()
+
+ def iter_tags(self, type=None):
+ """ Yield all tags (limit to |type| if specified)
+ """
+ offset = self._offset - self._tagsize
+ for i in range(self.num_tags):
+ offset += self._tagsize
+ entry = struct_parse(
+ self._elfstructs.Elf_Dyn,
+ self._stream,
+ stream_pos=offset)
+ if type is not None and entry.d_tag != type:
+ continue
+ yield DynamicTag(entry, self._elffile)
+
+ def get_tag(self, n):
+ """ Get the tag at index #n from the file (DynamicTag object)
+ """
+ offset = self._offset + n * self._tagsize
+ entry = struct_parse(
+ self._elfstructs.Elf_Dyn,
+ self._stream,
+ stream_pos=offset)
+ return DynamicTag(entry, self._elffile)
+
+ @property
+ def num_tags(self):
+ """ Number of dynamic tags in the file
+ """
+ if self._num_tags != -1:
+ return self._num_tags
+
+ offset = self._offset
+ while True:
+ entry = struct_parse(
+ self._elfstructs.Elf_Dyn,
+ self._stream,
+ stream_pos=offset)
+ if entry.d_tag == 'DT_NULL':
+ self._num_tags = ((offset - self._offset) // self._tagsize) + 1
+ break
+ offset += self._tagsize
+ return self._num_tags
+
+
+class DynamicSection(Section, Dynamic):
+ """ ELF dynamic table section. Knows how to process the list of tags.
+ """
+ def __init__(self, header, name, stream, elffile):
+ Section.__init__(self, header, name, stream)
+ Dynamic.__init__(self, stream, elffile, self['sh_offset'])
+
+
+class DynamicSegment(Segment, Dynamic):
+ """ ELF dynamic table segment. Knows how to process the list of tags.
+ """
+ def __init__(self, header, stream, elffile):
+ Segment.__init__(self, header, stream)
+ Dynamic.__init__(self, stream, elffile, self['p_offset'])
diff -r f3408c7b9549 -r a9c9b2f9ec96 elftools/elf/elffile.py
--- a/elftools/elf/elffile.py Thu Jul 05 06:32:09 2012 +0300
+++ b/elftools/elf/elffile.py Mon Nov 12 16:27:19 2012 -0500
@@ -13,6 +13,7 @@
from .structs import ELFStructs
from .sections import (
Section, StringTableSection, SymbolTableSection, NullSection)
+from .dynamic import DynamicSection, DynamicSegment
from .relocation import RelocationSection, RelocationHandler
from .segments import Segment, InterpSegment
from .enums import ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64
@@ -208,6 +209,8 @@
segtype = segment_header['p_type']
if segtype == 'PT_INTERP':
return InterpSegment(segment_header, self.stream)
+ elif segtype == 'PT_DYNAMIC':
+ return DynamicSegment(segment_header, self.stream, self)
else:
return Segment(segment_header, self.stream)
@@ -241,6 +244,8 @@
elif sectype in ('SHT_REL', 'SHT_RELA'):
return RelocationSection(
section_header, name, self.stream, self)
+ elif sectype == 'SHT_DYNAMIC':
+ return DynamicSection(section_header, name, self.stream, self)
else:
return Section(section_header, name, self.stream)
diff -r f3408c7b9549 -r a9c9b2f9ec96 elftools/elf/enums.py
--- a/elftools/elf/enums.py Thu Jul 05 06:32:09 2012 +0300
+++ b/elftools/elf/enums.py Mon Nov 12 16:27:19 2012 -0500
@@ -186,6 +186,82 @@
_default_=Pass,
)
+# d_tag
+ENUM_D_TAG = dict(
+ DT_NULL=0,
+ DT_NEEDED=1,
+ DT_PLTRELSZ=2,
+ DT_PLTGOT=3,
+ DT_HASH=4,
+ DT_STRTAB=5,
+ DT_SYMTAB=6,
+ DT_RELA=7,
+ DT_RELASZ=8,
+ DT_RELAENT=9,
+ DT_STRSZ=10,
+ DT_SYMENT=11,
+ DT_INIT=12,
+ DT_FINI=13,
+ DT_SONAME=14,
+ DT_RPATH=15,
+ DT_SYMBOLIC=16,
+ DT_REL=17,
+ DT_RELSZ=18,
+ DT_RELENT=19,
+ DT_PLTREL=20,
+ DT_DEBUG=21,
+ DT_TEXTREL=22,
+ DT_JMPREL=23,
+ DT_BIND_NOW=24,
+ DT_INIT_ARRAY=25,
+ DT_FINI_ARRAY=26,
+ DT_INIT_ARRAYSZ=27,
+ DT_FINI_ARRAYSZ=28,
+ DT_RUNPATH=29,
+ DT_FLAGS=30,
+ DT_ENCODING=32,
+ DT_PREINIT_ARRAY=32,
+ DT_PREINIT_ARRAYSZ=33,
+ DT_NUM=34,
+ DT_LOOS=0x6000000d,
+ DT_HIOS=0x6ffff000,
+ DT_LOPROC=0x70000000,
+ DT_HIPROC=0x7fffffff,
+ DT_PROCNUM=0x35,
+ DT_VALRNGLO=0x6ffffd00,
+ DT_GNU_PRELINKED=0x6ffffdf5,
+ DT_GNU_CONFLICTSZ=0x6ffffdf6,
+ DT_GNU_LIBLISTSZ=0x6ffffdf7,
+ DT_CHECKSUM=0x6ffffdf8,
+ DT_PLTPADSZ=0x6ffffdf9,
+ DT_MOVEENT=0x6ffffdfa,
+ DT_MOVESZ=0x6ffffdfb,
+ DT_SYMINSZ=0x6ffffdfe,
+ DT_SYMINENT=0x6ffffdff,
+ DT_GNU_HASH=0x6ffffef5,
+ DT_TLSDESC_PLT=0x6ffffef6,
+ DT_TLSDESC_GOT=0x6ffffef7,
+ DT_GNU_CONFLICT=0x6ffffef8,
+ DT_GNU_LIBLIST=0x6ffffef9,
+ DT_CONFIG=0x6ffffefa,
+ DT_DEPAUDIT=0x6ffffefb,
+ DT_AUDIT=0x6ffffefc,
+ DT_PLTPAD=0x6ffffefd,
+ DT_MOVETAB=0x6ffffefe,
+ DT_SYMINFO=0x6ffffeff,
+ DT_VERSYM=0x6ffffff0,
+ DT_RELACOUNT=0x6ffffff9,
+ DT_RELCOUNT=0x6ffffffa,
+ DT_FLAGS_1=0x6ffffffb,
+ DT_VERDEF=0x6ffffffc,
+ DT_VERDEFNUM=0x6ffffffd,
+ DT_VERNEED=0x6ffffffe,
+ DT_VERNEEDNUM=0x6fffffff,
+ DT_AUXILIARY=0x7ffffffd,
+ DT_FILTER=0x7fffffff,
+ _default_=Pass,
+)
+
ENUM_RELOC_TYPE_i386 = dict(
R_386_NONE=0,
R_386_32=1,
diff -r f3408c7b9549 -r a9c9b2f9ec96 elftools/elf/structs.py
--- a/elftools/elf/structs.py Thu Jul 05 06:32:09 2012 +0300
+++ b/elftools/elf/structs.py Mon Nov 12 16:27:19 2012 -0500
@@ -72,6 +72,7 @@
self._create_shdr()
self._create_sym()
self._create_rel()
+ self._create_dyn()
def _create_ehdr(self):
self.Elf_Ehdr = Struct('Elf_Ehdr',
@@ -165,6 +166,13 @@
self.Elf_sxword('r_addend'),
)
+ def _create_dyn(self):
+ self.Elf_Dyn = Struct('Elf_Dyn',
+ Enum(self.Elf_sxword('d_tag'), **ENUM_D_TAG),
+ self.Elf_xword('d_val'),
+ Value('d_ptr', lambda ctx: ctx['d_val']),
+ )
+
def _create_sym(self):
# st_info is hierarchical. To access the type, use
# container['st_info']['type']