Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions elftools/dwarf/callframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ def _decode_CFI_table(self):
# line that serves as the base (first) line in the FDE's table.
cie = self.cie
cie_decoded_table = cie.get_decoded()
if len(cie_decoded_table.table) > 0:
if cie_decoded_table.table:
last_line_in_CIE = copy.copy(cie_decoded_table.table[-1])
cur_line = copy.copy(last_line_in_CIE)
else:
Expand Down Expand Up @@ -725,7 +725,8 @@ def __repr__(self):
# This dictionary is filled by automatically scanning the constants module
# for DW_CFA_* instructions, and mapping their values to names. Since all
# names were imported from constants with `import *`, we look in globals()
_OPCODE_NAME_MAP = {}
for name in list(globals().keys()):
if name.startswith('DW_CFA'):
_OPCODE_NAME_MAP[globals()[name]] = name
_OPCODE_NAME_MAP = {
value: name
for name, value in globals().items()
if name.startswith('DW_CFA')
}
7 changes: 3 additions & 4 deletions elftools/dwarf/compileunit.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def get_top_DIE(self):

# Note that a top DIE always has minimal offset and is therefore
# at the beginning of our lists, so no bisect is required.
if len(self._diemap) > 0:
if self._diemap:
return self._dielist[0]

top = DIE(
Expand All @@ -105,7 +105,7 @@ def has_top_DIE(self):
""" Returns whether the top DIE in this CU has already been parsed and cached.
No parsing on demand!
"""
return len(self._diemap) > 0
return bool(self._diemap)

@property
def size(self):
Expand Down Expand Up @@ -205,8 +205,7 @@ def _iter_DIE_subtree(self, die):
yield die
if die.has_children:
for c in die.iter_children():
for d in die.cu._iter_DIE_subtree(c):
yield d
yield from die.cu._iter_DIE_subtree(c)
yield die._terminator

def _get_cached_DIE(self, offset):
Expand Down
8 changes: 4 additions & 4 deletions elftools/dwarf/datatype_cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def parse_cpp_datatype(var_die):
else:
retval_type = "void "

if len(mods) and mods[-1] == 'pointer':
if mods and mods[-1] == 'pointer':
mods.pop()
t.modifiers = tuple(mods)
t.name = "%s(%s*)(%s)" % (retval_type, ptr_prefix, params)
Expand Down Expand Up @@ -147,7 +147,7 @@ def __str__(self):

parts = []
# Initial const/volatile applies to the var ifself, other consts apply to the pointee
if len(mods) and mods[0] in ('const', 'volatile'):
if mods and mods[0] in ('const', 'volatile'):
parts.append(mods[0])
mods = mods[1:]

Expand All @@ -160,7 +160,7 @@ def __str__(self):
name = '::'.join(self.scopes)+'::' + name
parts.append(name)

if len(mods):
if mods:
parts.append("".join(cpp_symbols[mod] for mod in mods))

if self.dimensions:
Expand Down Expand Up @@ -190,7 +190,7 @@ def get_class_spec_if_member(func_spec, the_func):
this_param = the_func.get_DIE_from_attribute('DW_AT_object_pointer')
this_type = parse_cpp_datatype(this_param)
class_spec = ClassDesc()
class_spec.scopes = this_type.scopes + (this_type.name,)
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
return class_spec
Expand Down
10 changes: 5 additions & 5 deletions elftools/dwarf/descriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,10 +603,10 @@ def dump_expr(self, expr, cu_offset=None):
Returns a string representing the expression.
"""
parsed = self.expr_parser.parse_expr(expr)
s = []
for deo in parsed:
s.append(self._dump_to_string(deo.op, deo.op_name, deo.args, cu_offset))
return '; '.join(s)
return '; '.join(
self._dump_to_string(deo.op, deo.op_name, deo.args, cu_offset)
for deo in parsed
)

def _init_lookups(self):
self._ops_with_decimal_arg = set([
Expand All @@ -632,7 +632,7 @@ def _dump_to_string(self, opcode, opcode_name, args, cu_offset=None):
if cu_offset is None:
cu_offset = 0

if len(args) == 0:
if not args:
if opcode_name.startswith('DW_OP_reg'):
regnum = int(opcode_name[9:])
return '%s (%s)' % (
Expand Down
2 changes: 1 addition & 1 deletion elftools/dwarf/dwarf_expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def parse_expr(self, expr):
# stream, we're done.
offset = stream.tell()
byte = stream.read(1)
if len(byte) == 0:
if not byte:
break

# Decode the opcode and its name.
Expand Down
2 changes: 1 addition & 1 deletion elftools/dwarf/dwarf_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def _file_crc32(file):
"""
d = file.read(4096)
checksum = 0
while len(d):
while d:
checksum = binascii.crc32(d, checksum)
d = file.read(4096)
return checksum
18 changes: 11 additions & 7 deletions elftools/dwarf/lineprogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,17 @@ def __init__(self, default_is_stmt):
self.discriminator = 0

def __repr__(self):
a = ['<LineState %x:' % id(self)]
a.append(' address = 0x%x' % self.address)
for attr in ('file', 'line', 'column', 'is_stmt', 'basic_block',
'end_sequence', 'prologue_end', 'epilogue_begin', 'isa',
'discriminator'):
a.append(' %s = %s' % (attr, getattr(self, attr)))
return '\n'.join(a) + '>\n'
return '\n'.join((
'<LineState %x:' % id(self),
' address = 0x%x' % self.address,
*(
' %s = %s' % (attr, getattr(self, attr))
for attr in ('file', 'line', 'column', 'is_stmt', 'basic_block',
'end_sequence', 'prologue_end', 'epilogue_begin', 'isa',
'discriminator')
),
'>',
))


class LineProgram(object):
Expand Down
4 changes: 2 additions & 2 deletions elftools/dwarf/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ def _create_lineprog_header(self):
# past it. Therefore an If is used.
self.Dwarf_lineprog_file_entry = Struct('file_entry',
CString('name'),
If(lambda ctx: len(ctx.name) != 0,
If(lambda ctx: bool(ctx.name),
Embed(Struct('',
self.Dwarf_uleb128('dir_index'),
self.Dwarf_uleb128('mtime'),
Expand Down Expand Up @@ -452,7 +452,7 @@ def _parse(self, stream, context):
CString('include_directory'))),
If(lambda ctx: ctx.version < 5,
RepeatUntilExcluding(
lambda obj, ctx: len(obj.name) == 0,
lambda obj, ctx: not obj.name,
self.Dwarf_lineprog_file_entry)) # array name is file_entry
)

Expand Down
7 changes: 3 additions & 4 deletions elftools/dwarf/typeunit.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def get_top_DIE(self):

# Note that a top DIE always has minimal offset and is therefore
# at the beginning of our lists, so no bisect is required.
if len(self._diemap) > 0:
if self._diemap:
return self._dielist[0]

top = DIE(
Expand All @@ -121,7 +121,7 @@ def has_top_DIE(self):
""" Returns whether the top DIE in this TU has already been parsed and cached.
No parsing on demand!
"""
return len(self._diemap) > 0
return bool(self._diemap)

@property
def size(self):
Expand Down Expand Up @@ -219,8 +219,7 @@ def _iter_DIE_subtree(self, die):
yield die
if die.has_children:
for c in die.iter_children():
for d in die.cu._iter_DIE_subtree(c):
yield d
yield from die.cu._iter_DIE_subtree(c)
yield die._terminator

def _get_cached_DIE(self, offset):
Expand Down
9 changes: 5 additions & 4 deletions elftools/elf/elffile.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,13 +398,14 @@ def get_ehabi_infos(self):
Object file contains many .ARM.exidx sections.
So we must traverse every section and filter sections whose type is SHT_ARM_EXIDX.
"""
_ret = []
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(type='SHT_ARM_EXIDX'):
_ret.append(EHABIInfo(section, self.little_endian))
return _ret if len(_ret) > 0 else None
_ret = [
EHABIInfo(section, self.little_endian)
for section in self.iter_sections(type='SHT_ARM_EXIDX')
]
return _ret if _ret else None

def get_machine_arch(self):
""" Return the machine architecture, as detected from the ELF header.
Expand Down
2 changes: 1 addition & 1 deletion elftools/elf/sections.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ def num_attributes(self):
def attributes(self):
""" List of all attributes in the subsubsection.
"""
return [self.header] + list(self.iter_attributes())
return [self.header, *(self.iter_attributes())]

def _make_attributes(self):
""" Create all attributes for this subsubsection except the first one
Expand Down
2 changes: 1 addition & 1 deletion elftools/elf/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def _create_rel(self):
self.Elf_addr('r_offset'),
*fields)

fields_and_addend = fields + [self.Elf_sxword('r_addend')]
fields_and_addend = [*fields, self.Elf_sxword('r_addend')]
self.Elf_Rela = Struct('Elf_Rela',
self.Elf_addr('r_offset'),
*fields_and_addend
Expand Down
4 changes: 2 additions & 2 deletions scripts/dwarfdump.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,10 @@ def _desc_operationarg(s, cu):
elif isinstance(s, int):
return hex(s)
elif isinstance(s, list): # Could be a blob (list of ints), could be a subexpression
if len(s) > 0 and isinstance(s[0], DWARFExprOp): # Subexpression
if s and isinstance(s[0], DWARFExprOp): # Subexpression
return '(' + '; '.join(_desc_operation(op.op, op.op_name, op.args, cu) for op in s) + ')'
else:
return " ".join((hex(len(s)),) + tuple("0x%02x" % b for b in s))
return " ".join((hex(len(s)), *("0x%02x" % b for b in s)))

def _arch(cu):
return cu.dwarfinfo.config.machine_arch
Expand Down
18 changes: 9 additions & 9 deletions scripts/readelf.py
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,7 @@ def _dump_debug_line_programs(self):
ver5 = lineprogram.header.version >= 5

cu_filename = bytes2str(lineprogram['file_entry'][0].name)
if len(lineprogram['include_directory']) > 0:
if lineprogram['include_directory']:
# GNU readelf 2.38 only outputs directory in wide mode
self._emitline('%s:' % cu_filename)
else:
Expand Down Expand Up @@ -1394,7 +1394,7 @@ def _dump_debug_namelut(self, what):
section = self._dwarfinfo.debug_pubtypes_sec

# readelf prints nothing if the section is not present.
if namelut is None or len(namelut) == 0:
if not namelut:
return

self._emitline('Contents of the %s section:' % section.name)
Expand Down Expand Up @@ -1428,7 +1428,7 @@ def _dump_debug_aranges(self):
# dumps them, so we should too.
unordered_entries = aranges_table._get_entries(need_empty=True)

if len(unordered_entries) == 0:
if not unordered_entries:
self._emitline()
self._emitline("Section '.debug_aranges' has no debugging data.")
return
Expand Down Expand Up @@ -1505,7 +1505,7 @@ def _dump_frames_interp_info(self, section, cfi_entries):

# Decode the table.
decoded_table = entry.get_decoded()
if len(decoded_table.table) == 0:
if not decoded_table.table:
continue

# Print the heading row for the decoded table
Expand All @@ -1521,7 +1521,7 @@ def _dump_frames_interp_info(self, section, cfi_entries):
# DWARF register number is not greater than other GPRs.)
decoded_table = entry.get_decoded()
reg_order = sorted(decoded_table.reg_order)
if len(decoded_table.reg_order):
if decoded_table.reg_order:
# Headings for the registers
for regnum in reg_order:
if regnum == ra_regnum:
Expand Down Expand Up @@ -1602,7 +1602,7 @@ def _dump_debug_locsection(self, di, loc_lists_sec):
line_template = " %%08x %%0%dx %%0%dx %%s%%s" % (addr_width, addr_width)

loc_lists = list(loc_lists_sec.iter_location_lists())
if len(loc_lists) == 0:
if not loc_lists:
# Present but empty locations section - readelf outputs a message
self._emitline("\nSection '%s' has no debugging data." % (section_name,))
return
Expand Down Expand Up @@ -1703,7 +1703,7 @@ def _dump_debug_loclists_CU_header(self, cu):
self._emitline(' Address size: %d' % cu.address_size)
self._emitline(' Segment size: %d' % cu.segment_selector_size)
self._emitline(' Offset entries: %d\n' % cu.offset_count)
if cu.offsets and len(cu.offsets):
if cu.offsets:
self._emitline(' Offsets starting at 0x%x:' % cu.offset_table_offset)
for i_offset in enumerate(cu.offsets):
self._emitline(' [%6d] 0x%x' % i_offset)
Expand All @@ -1728,7 +1728,7 @@ def _dump_debug_rnglists_CU_header(self, cu):
self._emitline(' Address size: %d' % cu.address_size)
self._emitline(' Segment size: %d' % cu.segment_selector_size)
self._emitline(' Offset entries: %d\n' % cu.offset_count)
if cu.offsets and len(cu.offsets):
if cu.offsets:
self._emitline(' Offsets starting at 0x%x:' % cu.offset_table_offset)
for i_offset in enumerate(cu.offsets):
self._emitline(' [%6d] 0x%x' % i_offset)
Expand All @@ -1755,7 +1755,7 @@ def _dump_debug_rangesection(self, di, range_lists_sec):
next_rcu_offset = 0

range_lists = list(range_lists_sec.iter_range_lists())
if len(range_lists) == 0:
if not range_lists:
# Present but empty ranges section - readelf outputs a message
self._emitline("\nSection '%s' has no debugging data." % section_name)
return
Expand Down
2 changes: 1 addition & 1 deletion test/all_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from utils import is_in_rootdir

def run_test_script(path, *args):
cmd = [sys.executable, path] + list(args)
cmd = [sys.executable, path, *args]
print("Running '%s'" % ' '.join(cmd))
subprocess.check_call(cmd)

Expand Down
4 changes: 2 additions & 2 deletions test/run_dwarfdump_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def compare_output(s1, s2):
s1 = s1.replace('(0x0000000000000000 ".text")', '(0x0000000000000000)')

def prepare_lines(s):
return [line for line in s.lower().splitlines() if line.strip() != '']
return [line for line in s.lower().splitlines() if line.strip()]

lines1 = prepare_lines(s1)
lines2 = prepare_lines(s2)
Expand Down Expand Up @@ -169,7 +169,7 @@ def main():

# If file names are given as command-line arguments, only these files
# are taken as inputs. Otherwise, autodiscovery is performed.
if len(args.files) > 0:
if args.files:
filenames = args.files
else:
filenames = sorted(discover_testfiles('test/testfiles_for_dwarfdump'))
Expand Down
4 changes: 2 additions & 2 deletions test/run_readelf_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def compare_output(s1, s2):
to replicate. Read the documentation for more details.
"""
def prepare_lines(s):
return [line for line in s.lower().splitlines() if line.strip() != '']
return [line for line in s.lower().splitlines() if line.strip()]

lines1 = prepare_lines(s1)
lines2 = prepare_lines(s2)
Expand Down Expand Up @@ -299,7 +299,7 @@ def main():

# If file names are given as command-line arguments, only these files
# are taken as inputs. Otherwise, autodiscovery is performed.
if len(args.files) > 0:
if args.files:
filenames = args.files
else:
filenames = sorted(discover_testfiles('test/testfiles_for_readelf'))
Expand Down
15 changes: 7 additions & 8 deletions test/test_dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,16 @@ class TestDynamic(unittest.TestCase):
def test_missing_sections(self):
"""Verify we can get dynamic strings w/out section headers"""

libs = []
with open(os.path.join('test', 'testfiles_for_unittests',
'aarch64_super_stripped.elf'), 'rb') as f:
elf = ELFFile(f)
for segment in elf.iter_segments():
if segment.header.p_type != 'PT_DYNAMIC':
continue

for t in segment.iter_tags():
if t.entry.d_tag == 'DT_NEEDED':
libs.append(t.needed)
libs = [
t.needed
for segment in elf.iter_segments()
if segment.header.p_type == 'PT_DYNAMIC'
for t in segment.iter_tags()
if t.entry.d_tag == 'DT_NEEDED'
]

exp = ['libc.so.6']
self.assertEqual(libs, exp)
Expand Down
Loading