mirror of
https://github.com/gentoo-mirror/gentoo.git
synced 2026-07-29 22:28:08 -07:00
dev-python/pyelftools: drop old <0.24 versions
This commit is contained in:
@@ -1,3 +1 @@
|
||||
DIST pyelftools-0.22.tar.gz 395525 SHA256 9f7dd617b8a577a3834e7dd7f34f49df21c0670e67a48b21add19abe1adffb60 SHA512 10a84d9d0e28cb609f252990fbc05747e0840c5efeeb6890e13076aa2d59780c7d1a5bd6036dee6f8b252a984796a3834183ccab1c1988473bc69646fe56867b WHIRLPOOL eac57cef3f4159deac907394995655e227aa1d034a3b4ec54728531d08ef1b4f8edee33d971a3423b32d08efba621496bb5e778ba090bc264db6d006da4f8842
|
||||
DIST pyelftools-0.23.tar.gz 401363 SHA256 fc57aadd096e8f9b9b03f1a9578f673ee645e1513a5ff0192ef439e77eab21de SHA512 47102b2b0c69f357ba1c6af8e45157cd5395a74aaaf10fcccbf5b2d584a494aa16b1f6d08599459ae036f45888cb0fe422cb3241458e6ee0f1e8e1f32b3ae5d0 WHIRLPOOL 1492b08020bb7a106b939c8691f9910949a9d36241a8379f5358832b7b79a6ac1fdac4aaa928d65cd25fe466cb96bb38ef383bd9e79ae5fe0417aad53a1387a4
|
||||
DIST pyelftools-0.24.tar.gz 411874 SHA256 e9dd97d685a5b96b88a988dabadb88e5a539b64cd7d7927fac9a7368dc4c459c SHA512 5169617f9a8446ffc21dfc44ee185a388c8945a0296bdc6752483b0756888dccb10e3ee88e529d101cf31a4595de924b5c95f5459d5ee4448f57c0c4f2c56887 WHIRLPOOL 9523129a70f76a89ca6779f00df46f975b38080a2303cf1fb3666188be0aef2602f4970d195a70325f4a44e687e6393eb779a5f7d7431400f96a8ae602a32b26
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
From b3157177bde20a2b0d0ada7b2ba44144ee5aea6f Mon Sep 17 00:00:00 2001
|
||||
From: Mike Frysinger <vapier@gentoo.org>
|
||||
Date: Sun, 9 Jun 2013 18:42:40 -0400
|
||||
Subject: [PATCH] support parsing of dynamic ELFs w/out section headers
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
At runtime, ELFs do not use the section headers at all. Instead, only
|
||||
the program segments and dynamic tags get used. This means you can
|
||||
strip the section table completely from an ELF and have it still work.
|
||||
|
||||
In practice, people rarely do this, but it's not unheard of. Make the
|
||||
Dynamic tags work even in these cases by loading the strings table the
|
||||
same way the runtime loader does:
|
||||
* parse the symtab address from DT_STRTAB
|
||||
* locate the file offset via the program segments
|
||||
|
||||
In order to avoid circular deps (parsing a dyntag requires walking parsed
|
||||
dyntags), add a set of internal funcs for returning the raw values.
|
||||
|
||||
You can see this in action:
|
||||
$ eu-strip -g --strip-sections a.out
|
||||
$ readelf -S a.out
|
||||
<nothing>
|
||||
$ lddtree.py ./a.out
|
||||
a.out (interpreter => /lib64/ld-linux-x86-64.so.2)
|
||||
libïäöëß.so => None
|
||||
libc.so.6 => /lib64/libc.so.6
|
||||
|
||||
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
|
||||
---
|
||||
elftools/elf/dynamic.py | 81 ++++++++++++++++++---
|
||||
test/test_dynamic.py | 28 ++++++-
|
||||
.../aarch64_super_stripped.elf | Bin 0 -> 4136 bytes
|
||||
3 files changed, 97 insertions(+), 12 deletions(-)
|
||||
create mode 100755 test/testfiles_for_unittests/aarch64_super_stripped.elf
|
||||
|
||||
diff --git a/elftools/elf/dynamic.py b/elftools/elf/dynamic.py
|
||||
index d9db870..ad5111f 100644
|
||||
--- a/elftools/elf/dynamic.py
|
||||
+++ b/elftools/elf/dynamic.py
|
||||
@@ -11,9 +11,22 @@ import itertools
|
||||
from .sections import Section
|
||||
from .segments import Segment
|
||||
from ..common.exceptions import ELFError
|
||||
-from ..common.utils import struct_parse
|
||||
-
|
||||
-from .enums import ENUM_D_TAG
|
||||
+from ..common.utils import struct_parse, parse_cstring_from_stream
|
||||
+
|
||||
+
|
||||
+class _DynamicStringTable(object):
|
||||
+ """ Bare string table based on values found via ELF dynamic tags and
|
||||
+ loadable segments only. Good enough for get_string() only.
|
||||
+ """
|
||||
+ def __init__(self, stream, table_offset):
|
||||
+ self._stream = stream
|
||||
+ self._table_offset = table_offset
|
||||
+
|
||||
+ def get_string(self, offset):
|
||||
+ """ Get the string stored at the given offset in this string table.
|
||||
+ """
|
||||
+ return parse_cstring_from_stream(self._stream,
|
||||
+ self._table_offset + offset)
|
||||
|
||||
|
||||
class DynamicTag(object):
|
||||
@@ -61,27 +76,71 @@ class Dynamic(object):
|
||||
self._num_tags = -1
|
||||
self._offset = position
|
||||
self._tagsize = self._elfstructs.Elf_Dyn.sizeof()
|
||||
- self._stringtable = stringtable
|
||||
+ self.__stringtable = stringtable
|
||||
|
||||
- def iter_tags(self, type=None):
|
||||
- """ Yield all tags (limit to |type| if specified)
|
||||
+ @property
|
||||
+ def _stringtable(self):
|
||||
+ """ Return a string table for looking up dynamic tag related strings.
|
||||
+
|
||||
+ This won't be a "full" string table object, but will at least support
|
||||
+ the get_string() function.
|
||||
+ """
|
||||
+ if self.__stringtable:
|
||||
+ return self.__stringtable
|
||||
+
|
||||
+ # If the ELF has stripped its section table (which is unusual, but
|
||||
+ # perfectly valid), we need to use the dynamic tags to locate the
|
||||
+ # dynamic string table.
|
||||
+ strtab = None
|
||||
+ for tag in self._iter_tags(type='DT_STRTAB'):
|
||||
+ strtab = tag['d_val']
|
||||
+ break
|
||||
+ # If we found a dynamic string table, locate the offset in the file
|
||||
+ # by using the program headers.
|
||||
+ if strtab:
|
||||
+ for segment in self._elffile.iter_segments():
|
||||
+ if (strtab >= segment['p_vaddr'] and
|
||||
+ strtab < segment['p_vaddr'] + segment['p_filesz']):
|
||||
+ self.__stringtable = _DynamicStringTable(
|
||||
+ self._stream,
|
||||
+ segment['p_offset'] + (strtab - segment['p_vaddr']))
|
||||
+ return self.__stringtable
|
||||
+
|
||||
+ # That didn't work for some reason. Let's use the section header
|
||||
+ # even though this ELF is super weird.
|
||||
+ self.__stringtable = self._elffile.get_section_by_name(b'.dynstr')
|
||||
+
|
||||
+ return self.__stringtable
|
||||
+
|
||||
+ def _iter_tags(self, type=None):
|
||||
+ """ Yield all raw tags (limit to |type| if specified)
|
||||
"""
|
||||
for n in itertools.count():
|
||||
- tag = self.get_tag(n)
|
||||
- if type is None or tag.entry.d_tag == type:
|
||||
+ tag = self._get_tag(n)
|
||||
+ if type is None or tag['d_tag'] == type:
|
||||
yield tag
|
||||
- if tag.entry.d_tag == 'DT_NULL':
|
||||
+ if tag['d_tag'] == 'DT_NULL':
|
||||
break
|
||||
|
||||
- def get_tag(self, n):
|
||||
- """ Get the tag at index #n from the file (DynamicTag object)
|
||||
+ def iter_tags(self, type=None):
|
||||
+ """ Yield all tags (limit to |type| if specified)
|
||||
+ """
|
||||
+ for tag in self._iter_tags(type=type):
|
||||
+ yield DynamicTag(tag, self._stringtable)
|
||||
+
|
||||
+ def _get_tag(self, n):
|
||||
+ """ Get the raw tag at index #n from the file
|
||||
"""
|
||||
offset = self._offset + n * self._tagsize
|
||||
- entry = struct_parse(
|
||||
+ return struct_parse(
|
||||
self._elfstructs.Elf_Dyn,
|
||||
self._stream,
|
||||
stream_pos=offset)
|
||||
- return DynamicTag(entry, self._stringtable)
|
||||
+
|
||||
+ def get_tag(self, n):
|
||||
+ """ Get the tag at index #n from the file (DynamicTag object)
|
||||
+ """
|
||||
+ return DynamicTag(self._get_tag(n), self._stringtable)
|
||||
|
||||
def num_tags(self):
|
||||
""" Number of dynamic tags in the file
|
||||
--
|
||||
2.0.0
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
From 80305ad20ebd481dde19fa7ff2d90249269aa588 Mon Sep 17 00:00:00 2001
|
||||
From: Eli Bendersky <eliben@gmail.com>
|
||||
Date: Wed, 23 Apr 2014 16:44:11 -0700
|
||||
Subject: [PATCH] Issue #29: Fail more gracefully when no string table is found
|
||||
for dynamic.
|
||||
|
||||
---
|
||||
elftools/elf/dynamic.py | 4 ++++
|
||||
test/test_dynamic.py | 25 +++++++++++++++++++++++++
|
||||
2 files changed, 29 insertions(+)
|
||||
create mode 100644 test/test_dynamic.py
|
||||
|
||||
diff --git a/elftools/elf/dynamic.py b/elftools/elf/dynamic.py
|
||||
index e36598e..6f88bf9 100644
|
||||
--- a/elftools/elf/dynamic.py
|
||||
+++ b/elftools/elf/dynamic.py
|
||||
@@ -10,6 +10,7 @@ import itertools
|
||||
|
||||
from .sections import Section
|
||||
from .segments import Segment
|
||||
+from ..common.exceptions import ELFError
|
||||
from ..common.utils import struct_parse
|
||||
|
||||
from .enums import ENUM_D_TAG
|
||||
@@ -29,6 +30,8 @@ class DynamicTag(object):
|
||||
'DT_SUNW_FILTER'])
|
||||
|
||||
def __init__(self, entry, stringtable):
|
||||
+ if stringtable is None:
|
||||
+ raise ELFError('Creating DynamicTag without string table')
|
||||
self.entry = entry
|
||||
if entry.d_tag in self._HANDLED_TAGS:
|
||||
setattr(self, entry.d_tag[3:].lower(),
|
||||
@@ -114,6 +117,7 @@ class DynamicSegment(Segment, Dynamic):
|
||||
# So we must look for the dynamic section contained in the dynamic
|
||||
# segment, we do so by searching for the dynamic section whose content
|
||||
# is located at the same offset as the dynamic segment
|
||||
+ stringtable = None
|
||||
for section in elffile.iter_sections():
|
||||
if (isinstance(section, DynamicSection) and
|
||||
section['sh_offset'] == header['p_offset']):
|
||||
diff --git a/test/test_dynamic.py b/test/test_dynamic.py
|
||||
new file mode 100644
|
||||
index 0000000..0ee9b35
|
||||
--- /dev/null
|
||||
+++ b/test/test_dynamic.py
|
||||
@@ -0,0 +1,25 @@
|
||||
+#-------------------------------------------------------------------------------
|
||||
+# elftools tests
|
||||
+#
|
||||
+# Eli Bendersky (eliben@gmail.com)
|
||||
+# This code is in the public domain
|
||||
+#-------------------------------------------------------------------------------
|
||||
+try:
|
||||
+ import unittest2 as unittest
|
||||
+except ImportError:
|
||||
+ import unittest
|
||||
+import os
|
||||
+
|
||||
+from utils import setup_syspath; setup_syspath()
|
||||
+from elftools.common.exceptions import ELFError
|
||||
+from elftools.elf.dynamic import DynamicTag
|
||||
+
|
||||
+
|
||||
+class TestDynamicTag(unittest.TestCase):
|
||||
+ def test_requires_stringtable(self):
|
||||
+ with self.assertRaises(ELFError):
|
||||
+ dt = DynamicTag('', None)
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ unittest.main()
|
||||
--
|
||||
2.0.0
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# Copyright 1999-2016 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Id$
|
||||
|
||||
EAPI="5"
|
||||
|
||||
PYTHON_COMPAT=( python{2_7,3_4} )
|
||||
inherit distutils-r1
|
||||
|
||||
DESCRIPTION="pure-Python library for analyzing ELF files and DWARF debugging information"
|
||||
HOMEPAGE="https://pypi.python.org/pypi/pyelftools https://github.com/eliben/pyelftools"
|
||||
SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.tar.gz"
|
||||
|
||||
LICENSE="public-domain"
|
||||
SLOT="0"
|
||||
KEYWORDS="alpha amd64 arm arm64 hppa ia64 m68k ~mips ppc ppc64 s390 sh sparc x86 ~amd64-fbsd ~sparc-fbsd ~x86-fbsd ~amd64-linux ~x86-linux"
|
||||
IUSE="examples"
|
||||
|
||||
PATCHES=(
|
||||
"${FILESDIR}"/${P}-grace-string-dyn.patch
|
||||
"${FILESDIR}"/${P}-dyntable.patch
|
||||
)
|
||||
|
||||
python_test() {
|
||||
# readelf_tests often fails due to host `readelf` changing output format
|
||||
local t
|
||||
for t in all_unittests examples_test ; do
|
||||
"${PYTHON}" ./test/run_${t}.py || die "Tests fail with ${EPYTHON}"
|
||||
done
|
||||
}
|
||||
|
||||
python_install_all() {
|
||||
use examples && local EXAMPLES=( examples/. )
|
||||
distutils-r1_python_install_all
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
# Copyright 1999-2016 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Id$
|
||||
|
||||
EAPI="5"
|
||||
|
||||
PYTHON_COMPAT=( python2_7 python3_{4,5} )
|
||||
inherit distutils-r1
|
||||
|
||||
DESCRIPTION="pure-Python library for analyzing ELF files and DWARF debugging information"
|
||||
HOMEPAGE="https://pypi.python.org/pypi/pyelftools https://github.com/eliben/pyelftools"
|
||||
SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.tar.gz"
|
||||
|
||||
LICENSE="public-domain"
|
||||
SLOT="0"
|
||||
KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-fbsd ~sparc-fbsd ~x86-fbsd ~amd64-linux ~x86-linux"
|
||||
IUSE="examples"
|
||||
|
||||
python_test() {
|
||||
# readelf_tests often fails due to host `readelf` changing output format
|
||||
local t
|
||||
for t in all_unittests examples_test ; do
|
||||
"${PYTHON}" ./test/run_${t}.py || die "Tests fail with ${EPYTHON}"
|
||||
done
|
||||
}
|
||||
|
||||
python_install_all() {
|
||||
use examples && local EXAMPLES=( examples/. )
|
||||
distutils-r1_python_install_all
|
||||
}
|
||||
Reference in New Issue
Block a user