From 82fea4635cdf6716ad70d47f704df686086ced06 Mon Sep 17 00:00:00 2001 From: liubo Date: Thu, 9 Nov 2023 14:44:41 +0800 Subject: [PATCH] ELFFile: allow filtering of sections by type in iter_sections Signed-off-by: liubo --- ...of-sections-by-type-in-iter_sections.patch | 101 ++++++++++++++++++ pyelftools.spec | 7 +- 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 0001-ELFFile-allow-filtering-of-sections-by-type-in-iter_sections.patch diff --git a/0001-ELFFile-allow-filtering-of-sections-by-type-in-iter_sections.patch b/0001-ELFFile-allow-filtering-of-sections-by-type-in-iter_sections.patch new file mode 100644 index 0000000..526684f --- /dev/null +++ b/0001-ELFFile-allow-filtering-of-sections-by-type-in-iter_sections.patch @@ -0,0 +1,101 @@ +From d71faebcd58ef26ce973044f2a822a494c42a3c1 Mon Sep 17 00:00:00 2001 +From: Andreas Ziegler +Date: Tue, 12 Jan 2021 01:27:24 +0100 +Subject: [PATCH] ELFFile: allow filtering of sections by type in iter_sections + (#345) + +As stated in the corresponding issue, we can already filter +the output of Dynamic.iter_tags() by the type of the tag +we're looking for. + +Let's adapt the iteration over the sections of the ELF file +so that it only yields sections of a certain type if the +optional type parameter is passed to iter_sections(). + +By doing this we can also simplify two call sites inside +the ELFFile class. + +Fixes: #344 +--- + elftools/elf/elffile.py | 19 ++++++++++++------- + test/test_elffile.py | 11 +++++++++++ + 2 files changed, 23 insertions(+), 7 deletions(-) + +diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py +index 0b44b29..779ae3b 100644 +--- a/elftools/elf/elffile.py ++++ b/elftools/elf/elffile.py +@@ -135,11 +135,17 @@ class ELFFile(object): + self._make_section_name_map() + return self._section_name_map.get(section_name, None) + +- def iter_sections(self): +- """ Yield all the sections in the file ++ def iter_sections(self, type=None): ++ """ Yield all the sections in the file. If the optional |type| ++ parameter is passed, this method will only yield sections of the ++ given type. The parameter value must be a string containing the ++ name of the type as defined in the ELF specification, e.g. ++ 'SHT_SYMTAB'. + """ + for i in range(self.num_sections()): +- yield self.get_section(i) ++ section = self.get_section(i) ++ if type is None or section['sh_type'] == type: ++ yield section + + def num_segments(self): + """ Number of segments in the file +@@ -254,7 +260,7 @@ class ELFFile(object): + def has_ehabi_info(self): + """ Check whether this file appears to have arm exception handler index table. + """ +- return any(s['sh_type'] == 'SHT_ARM_EXIDX' for s in self.iter_sections()) ++ return any(self.iter_sections(type='SHT_ARM_EXIDX')) + + def get_ehabi_infos(self): + """ Generally, shared library and executable contain 1 .ARM.exidx section. +@@ -265,9 +271,8 @@ class ELFFile(object): + if self['e_type'] == 'ET_REL': + # TODO: support relocatable file + assert False, "Current version of pyelftools doesn't support relocatable file." +- for section in self.iter_sections(): +- if section['sh_type'] == 'SHT_ARM_EXIDX': +- _ret.append(EHABIInfo(section, self.little_endian)) ++ for section in self.iter_sections(type='SHT_ARM_EXIDX'): ++ _ret.append(EHABIInfo(section, self.little_endian)) + return _ret if len(_ret) > 0 else None + + def get_machine_arch(self): +diff --git a/test/test_elffile.py b/test/test_elffile.py +index 654b202..1edba94 100644 +--- a/test/test_elffile.py ++++ b/test/test_elffile.py +@@ -5,6 +5,7 @@ + # This code is in the public domain + #------------------------------------------------------------------------------- + import unittest ++import os + + from elftools.elf.elffile import ELFFile + +@@ -43,6 +44,16 @@ class TestMap(unittest.TestCase): + self.assertEqual(tuple(elf.address_offsets(0x103FE, 4)), ()) + self.assertEqual(tuple(elf.address_offsets(0x10400, 4)), ()) + ++class TestSectionFilter(unittest.TestCase): ++ ++ def test_section_filter(self): ++ with open(os.path.join('test', 'testfiles_for_unittests', ++ 'arm_exidx_test.so'), 'rb') as f: ++ elf = ELFFile(f) ++ self.assertEqual(len(list(elf.iter_sections())), 26) ++ self.assertEqual(len(list(elf.iter_sections('SHT_REL'))), 2) ++ self.assertEqual(len(list(elf.iter_sections('SHT_ARM_EXIDX'))), 1) ++ self.assertTrue(elf.has_ehabi_info()) + + if __name__ == '__main__': + unittest.main() +-- +2.42.0.windows.2 + diff --git a/pyelftools.spec b/pyelftools.spec index 70a74b0..913e408 100644 --- a/pyelftools.spec +++ b/pyelftools.spec @@ -2,12 +2,14 @@ Name: pyelftools Version: 0.27 -Release: 1 +Release: 2 License: Public Domain Summary: Pure-Python library for parsing and analyzing ELF files URL: https://github.com/eliben/pyelftools Source0: https://github.com/eliben/pyelftools/archive/v%{version}/%{name}-%{version}.tar.gz +Patch0001: 0001-ELFFile-allow-filtering-of-sections-by-type-in-iter_sections.patch + %description This package provides a python library for parsing and analyzing ELF files and DWARF debugging information. @@ -46,6 +48,9 @@ mv %{buildroot}/usr/bin/readelf.py %{buildroot}/usr/bin/pyreadelf %changelog +* Thu Nov 9 2023 liubo - 0.27-2 +- ELFFile: allow filtering of sections by type in iter_sections + * Thu Oct 13 2022 wulei - 0.27-1 - upgrade version to 0.27 -- Gitee