From 01621ab86337104aafebc7eaf1ed7c7f5c16d1f7 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Tue, 16 Aug 2022 06:38:15 -0700 Subject: [PATCH] Finish refactoring out py3compat and delete the file Fixes #415 --- elftools/common/py3compat.py | 26 -------------------------- elftools/common/utils.py | 3 +++ elftools/dwarf/datatype_cpp.py | 16 ++++++++-------- elftools/dwarf/descriptions.py | 3 +-- elftools/dwarf/die.py | 3 +-- elftools/elf/notes.py | 3 +-- examples/dwarf_decode_address.py | 2 +- examples/dwarf_pubnames_types.py | 2 +- scripts/dwarfdump.py | 2 +- scripts/readelf.py | 4 +--- test/test_dwarf_cu_and_die_cache.py | 2 +- test/utils.py | 3 +-- 12 files changed, 20 insertions(+), 49 deletions(-) delete mode 100644 elftools/common/py3compat.py diff --git a/elftools/common/py3compat.py b/elftools/common/py3compat.py deleted file mode 100644 index 7894896..0000000 --- a/elftools/common/py3compat.py +++ /dev/null @@ -1,26 +0,0 @@ -#------------------------------------------------------------------------------- -# elftools: common/py3compat.py -# -# Python 2/3 compatibility code -# -# Eli Bendersky (eliben@gmail.com) -# This code is in the public domain -#------------------------------------------------------------------------------- -import sys -PY3 = sys.version_info[0] == 3 -assert PY3, '''\ -Python 2 is no longer supported by pyelftools; if you need to use Python 2, -please download an older pyelftools version (such as version 0.29). -''' - - -if PY3: - # Functions for acting on bytestrings and strings. In Python 2 and 3, - # strings and bytes are the same and chr/ord can be used to convert between - # numeric byte values and their string representations. In Python 3, bytes - # and strings are different types and bytes hold numeric values when - # iterated over. - - - def bytes2str(b): return b.decode('latin-1') - def str2bytes(s): return s.encode('latin-1') diff --git a/elftools/common/utils.py b/elftools/common/utils.py index 2355ed4..b4bc1e7 100644 --- a/elftools/common/utils.py +++ b/elftools/common/utils.py @@ -19,6 +19,9 @@ def merge_dicts(*dicts): result.update(d) return result +def bytes2str(b): + """Decode a bytes object into a string.""" + return b.decode('latin-1') def bytelist2string(bytelist): """ Convert a list of byte values (e.g. [0x10 0x20 0x00]) to a bytes object diff --git a/elftools/dwarf/datatype_cpp.py b/elftools/dwarf/datatype_cpp.py index 0986a38..45b23bb 100644 --- a/elftools/dwarf/datatype_cpp.py +++ b/elftools/dwarf/datatype_cpp.py @@ -7,7 +7,7 @@ # Eli Bendersky (eliben@gmail.com) # This code is in the public domain #------------------------------------------------------------------------------- -from ..common.py3compat import bytes2str +from ..common.utils import bytes2str cpp_symbols = dict( pointer = "*", @@ -20,7 +20,7 @@ def describe_cpp_datatype(var_die): def parse_cpp_datatype(var_die): """Given a DIE that describes a variable, a parameter, or a member with DW_AT_type in it, tries to return the C++ datatype as a string - + Returns a TypeDesc. Does not follow typedefs, doesn't resolve array element types @@ -48,7 +48,7 @@ def parse_cpp_datatype(var_die): # From this point on, type_die doesn't change t.tag = _strip_type_tag(type_die) t.modifiers = tuple(mods) - + if t.tag in ('ptr_to_member', 'subroutine'): if t.tag == 'ptr_to_member': ptr_prefix = DIE_name(type_die.get_DIE_from_attribute('DW_AT_containing_type')) + "::" @@ -103,8 +103,8 @@ def parse_cpp_datatype(var_die): # If unnamed scope, fall back to scope type - like "structure " parent = parent.get_parent() t.scopes = tuple(scopes) - - return t + + return t #-------------------------------------------------- @@ -133,7 +133,7 @@ class TypeDesc(object): self.name = None self.modifiers = () # Reads left to right self.scopes = () # Reads left to right - self.tag = None + self.tag = None self.dimensions = None def __str__(self): @@ -191,7 +191,7 @@ def get_class_spec_if_member(func_spec, the_func): class_spec = ClassDesc() class_spec.scopes = this_type.scopes + (this_type.name,) class_spec.const_member = any(("const", "pointer") == this_type.modifiers[i:i+2] - for i in range(len(this_type.modifiers))) # const -> pointer -> const for this arg of const + for i in range(len(this_type.modifiers))) # const -> pointer -> const for this arg of const return class_spec # Check the parent element chain - could be a class @@ -225,7 +225,7 @@ def DIE_is_ptr_to_member_struct(type_die): if type_die.tag == 'DW_TAG_structure_type': members = tuple(die for die in type_die.iter_children() if die.tag == "DW_TAG_member") return len(members) == 2 and safe_DIE_name(members[0]) == "__pfn" and safe_DIE_name(members[1]) == "__delta" - return False + return False def _strip_type_tag(die): """Given a DIE with DW_TAG_foo_type, returns foo""" diff --git a/elftools/dwarf/descriptions.py b/elftools/dwarf/descriptions.py index 7861180..90cbaa1 100644 --- a/elftools/dwarf/descriptions.py +++ b/elftools/dwarf/descriptions.py @@ -11,8 +11,7 @@ from collections import defaultdict from .constants import * from .dwarf_expr import DWARFExprParser from .die import DIE -from ..common.utils import preserve_stream_pos, dwarf_assert -from ..common.py3compat import bytes2str +from ..common.utils import preserve_stream_pos, dwarf_assert, bytes2str from .callframe import instruction_name, CIE, FDE diff --git a/elftools/dwarf/die.py b/elftools/dwarf/die.py index 6d9a764..ef6d908 100755 --- a/elftools/dwarf/die.py +++ b/elftools/dwarf/die.py @@ -10,8 +10,7 @@ from collections import namedtuple, OrderedDict import os from ..common.exceptions import DWARFError -from ..common.py3compat import bytes2str -from ..common.utils import struct_parse, preserve_stream_pos +from ..common.utils import bytes2str, struct_parse, preserve_stream_pos from .enums import DW_FORM_raw2name from .dwarf_util import _resolve_via_offset_table, _get_base_offset diff --git a/elftools/elf/notes.py b/elftools/elf/notes.py index 60648c6..c708cbf 100644 --- a/elftools/elf/notes.py +++ b/elftools/elf/notes.py @@ -6,8 +6,7 @@ # Eli Bendersky (eliben@gmail.com) # This code is in the public domain #------------------------------------------------------------------------------- -from ..common.py3compat import bytes2str -from ..common.utils import struct_parse, bytes2hex, roundup +from ..common.utils import struct_parse, bytes2hex, roundup, bytes2str from ..construct import CString diff --git a/examples/dwarf_decode_address.py b/examples/dwarf_decode_address.py index 007ba08..e335d0b 100644 --- a/examples/dwarf_decode_address.py +++ b/examples/dwarf_decode_address.py @@ -14,7 +14,7 @@ import sys # examples/ dir of the source distribution. sys.path[0:0] = ['.', '..'] -from elftools.common.py3compat import bytes2str +from elftools.common.utils import bytes2str from elftools.dwarf.descriptions import describe_form_class from elftools.elf.elffile import ELFFile diff --git a/examples/dwarf_pubnames_types.py b/examples/dwarf_pubnames_types.py index d9daaff..708706f 100644 --- a/examples/dwarf_pubnames_types.py +++ b/examples/dwarf_pubnames_types.py @@ -17,7 +17,7 @@ import sys sys.path[0:0] = ['.', '..'] from elftools.elf.elffile import ELFFile -from elftools.common.py3compat import bytes2str +from elftools.common.utils import bytes2str def process_file(filename): print('Processing file:', filename) diff --git a/scripts/dwarfdump.py b/scripts/dwarfdump.py index ca6bac3..e593f1c 100644 --- a/scripts/dwarfdump.py +++ b/scripts/dwarfdump.py @@ -23,7 +23,7 @@ sys.path.insert(0, '.') from elftools import __version__ from elftools.common.exceptions import DWARFError, ELFError -from elftools.common.py3compat import bytes2str +from elftools.common.utils import bytes2str from elftools.elf.elffile import ELFFile from elftools.dwarf.locationlists import LocationParser, LocationEntry, LocationExpr, LocationViewPair, BaseAddressEntry as LocBaseAddressEntry from elftools.dwarf.ranges import RangeEntry # ranges.BaseAddressEntry collides with the one above diff --git a/scripts/readelf.py b/scripts/readelf.py index cd9d384..8a44282 100755 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -26,9 +26,7 @@ sys.path.insert(0, '.') from elftools import __version__ from elftools.common.exceptions import ELFError -from elftools.common.py3compat import ( - bytes2str, str2bytes) -from elftools.common.utils import iterbytes +from elftools.common.utils import bytes2str, iterbytes from elftools.elf.elffile import ELFFile from elftools.elf.dynamic import DynamicSection, DynamicSegment from elftools.elf.enums import ENUM_D_TAG diff --git a/test/test_dwarf_cu_and_die_cache.py b/test/test_dwarf_cu_and_die_cache.py index bf7f4d7..5180e12 100644 --- a/test/test_dwarf_cu_and_die_cache.py +++ b/test/test_dwarf_cu_and_die_cache.py @@ -8,7 +8,7 @@ import os import unittest from elftools.elf.elffile import ELFFile -from elftools.common.py3compat import bytes2str +from elftools.common.utils import bytes2str class TestCacheLUTandDIEref(unittest.TestCase): def dprint(self, list): diff --git a/test/utils.py b/test/utils.py index 4669cf8..f90f653 100644 --- a/test/utils.py +++ b/test/utils.py @@ -22,8 +22,7 @@ def run_exe(exe_path, args=[], echo=False): print('[cmd]', ' '.join(popen_cmd)) proc = subprocess.Popen(popen_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc_stdout = proc.communicate()[0] - from elftools.common.py3compat import bytes2str - return proc.returncode, bytes2str(proc_stdout) + return proc.returncode, proc_stdout.decode('latin-1') def is_in_rootdir(): -- 2.30.2