diff options
author | Mike Frysinger <vapier@gentoo.org> | 2013-01-02 18:27:04 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2013-01-02 18:27:04 +0000 |
commit | 72d4e9a4e96947d73b7f48a2d99e085b46f0e943 (patch) | |
tree | 1e1a8f0edc6a78e4c4a7f930d494e954937d6e6d /dev-python/pyelftools | |
parent | Version bump to latest. Drop older. (diff) | |
download | gentoo-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/ChangeLog | 11 | ||||
-rw-r--r-- | dev-python/pyelftools/files/pyelftools-0.20-dyntags-1.patch | 266 | ||||
-rw-r--r-- | dev-python/pyelftools/files/pyelftools-0.20-dyntags-2.patch | 94 | ||||
-rw-r--r-- | dev-python/pyelftools/pyelftools-0.20-r1.ebuild | 31 |
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 +} |