summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2013-01-02 18:27:04 +0000
committerMike Frysinger <vapier@gentoo.org>2013-01-02 18:27:04 +0000
commit72d4e9a4e96947d73b7f48a2d99e085b46f0e943 (patch)
tree1e1a8f0edc6a78e4c4a7f930d494e954937d6e6d /dev-python/pyelftools
parentVersion bump to latest. Drop older. (diff)
downloadgentoo-2-72d4e9a4e96947d73b7f48a2d99e085b46f0e943.tar.gz
gentoo-2-72d4e9a4e96947d73b7f48a2d99e085b46f0e943.tar.bz2
gentoo-2-72d4e9a4e96947d73b7f48a2d99e085b46f0e943.zip
Add dynamic tag support as pax-utils/lddtree uses it.
(Portage version: 2.2.0_alpha144/cvs/Linux x86_64, signed Manifest commit with key FB7C4156)
Diffstat (limited to 'dev-python/pyelftools')
-rw-r--r--dev-python/pyelftools/ChangeLog11
-rw-r--r--dev-python/pyelftools/files/pyelftools-0.20-dyntags-1.patch266
-rw-r--r--dev-python/pyelftools/files/pyelftools-0.20-dyntags-2.patch94
-rw-r--r--dev-python/pyelftools/pyelftools-0.20-r1.ebuild31
4 files changed, 400 insertions, 2 deletions
diff --git a/dev-python/pyelftools/ChangeLog b/dev-python/pyelftools/ChangeLog
index 548d8019426b..adf7cef03c58 100644
--- a/dev-python/pyelftools/ChangeLog
+++ b/dev-python/pyelftools/ChangeLog
@@ -1,3 +1,10 @@
# ChangeLog for dev-python/pyelftools
-# Copyright 1999-2012 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/dev-python/pyelftools/ChangeLog,v 1.1 2012/11/01 05:44:11 vapier Exp $
+# Copyright 1999-2013 Gentoo Foundation; Distributed under the GPL v2
+# $Header: /var/cvsroot/gentoo-x86/dev-python/pyelftools/ChangeLog,v 1.2 2013/01/02 18:27:04 vapier Exp $
+*pyelftools-0.20-r1 (02 Jan 2013)
+
+ 02 Jan 2013; Mike Frysinger <vapier@gentoo.org>
+ +files/pyelftools-0.20-dyntags-1.patch,
+ +files/pyelftools-0.20-dyntags-2.patch, +pyelftools-0.20-r1.ebuild:
+ Add dynamic tag support as pax-utils/lddtree uses it.
+
diff --git a/dev-python/pyelftools/files/pyelftools-0.20-dyntags-1.patch b/dev-python/pyelftools/files/pyelftools-0.20-dyntags-1.patch
new file mode 100644
index 000000000000..b86720ae3db7
--- /dev/null
+++ b/dev-python/pyelftools/files/pyelftools-0.20-dyntags-1.patch
@@ -0,0 +1,266 @@
+# 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']
diff --git a/dev-python/pyelftools/files/pyelftools-0.20-dyntags-2.patch b/dev-python/pyelftools/files/pyelftools-0.20-dyntags-2.patch
new file mode 100644
index 000000000000..02528a907df0
--- /dev/null
+++ b/dev-python/pyelftools/files/pyelftools-0.20-dyntags-2.patch
@@ -0,0 +1,94 @@
+# HG changeset patch
+# User Mike Frysinger <vapier@gentoo.org>
+# Date 1354166686 18000
+# Node ID 94901c23fe58ca227aacadcdc5d7ad3045171b24
+# Parent a9c9b2f9ec964e6750dd6f9a96767fe2e9201d85
+rework dynamic tag walking to avoid doing it twice on the first call to iter_tags
+
+Based on suggestions from David James
+
+diff -r a9c9b2f9ec96 -r 94901c23fe58 elftools/elf/dynamic.py
+--- a/elftools/elf/dynamic.py Mon Nov 12 16:27:19 2012 -0500
++++ b/elftools/elf/dynamic.py Thu Nov 29 00:24:46 2012 -0500
+@@ -6,6 +6,8 @@
+ # Mike Frysinger (vapier@gentoo.org)
+ # This code is in the public domain
+ #-------------------------------------------------------------------------------
++import itertools
++
+ from .sections import Section
+ from .segments import Segment
+ from ..common.utils import struct_parse
+@@ -20,11 +22,12 @@
+ Similarly to Section objects, allows dictionary-like access to the
+ dynamic tag.
+ """
++
++ _HANDLED_TAGS = frozenset(['DT_NEEDED', 'DT_RPATH', 'DT_RUNPATH'])
++
+ 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':
++ if entry.d_tag in self._HANDLED_TAGS:
+ dynstr = elffile.get_section_by_name('.dynstr')
+ setattr(self, entry.d_tag[3:].lower(), dynstr.get_string(self.entry.d_val))
+
+@@ -37,9 +40,7 @@
+ 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':
++ if self.entry.d_tag in self._HANDLED_TAGS:
+ s = '"%s"' % getattr(self, self.entry.d_tag[3:].lower())
+ else:
+ s = '%#x' % self.entry.d_ptr
+@@ -58,16 +59,12 @@
+ 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)
++ for n in itertools.count():
++ tag = self.get_tag(n)
++ if type is None or tag.entry.d_tag == type:
++ yield tag
++ if tag.entry.d_tag == 'DT_NULL':
++ break
+
+ def get_tag(self, n):
+ """ Get the tag at index #n from the file (DynamicTag object)
+@@ -86,17 +83,11 @@
+ 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
++ for n in itertools.count():
++ tag = self.get_tag(n)
++ if tag.entry.d_tag == 'DT_NULL':
++ self._num_tags = n
++ return n
+
+
+ class DynamicSection(Section, Dynamic):
diff --git a/dev-python/pyelftools/pyelftools-0.20-r1.ebuild b/dev-python/pyelftools/pyelftools-0.20-r1.ebuild
new file mode 100644
index 000000000000..e629c7edff22
--- /dev/null
+++ b/dev-python/pyelftools/pyelftools-0.20-r1.ebuild
@@ -0,0 +1,31 @@
+# Copyright 1999-2013 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/dev-python/pyelftools/pyelftools-0.20-r1.ebuild,v 1.1 2013/01/02 18:27:04 vapier Exp $
+
+EAPI="4"
+
+SUPPORT_PYTHON_ABIS="1"
+
+inherit distutils eutils
+
+DESCRIPTION="pure-Python library for parsing and analyzing ELF files and DWARF debugging information"
+HOMEPAGE="http://pypi.python.org/pypi/pyelftools https://bitbucket.org/eliben/pyelftools"
+SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.tar.gz"
+
+LICENSE="public-domain"
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-fbsd ~sparc-fbsd ~x86-fbsd"
+IUSE=""
+
+src_prepare() {
+ epatch "${FILESDIR}"/${P}-dyntags-{1,2}.patch
+ distutils_src_prepare
+}
+
+src_test() {
+ local t
+ # readelf_tests fails
+ for t in all_unittests examples_test ; do
+ ./test/run_${t}.py || die
+ done
+}