Skip to content

Commit

Permalink
Merge pull request #13 from vsoch/try/update-again
Browse files Browse the repository at this point in the history
updating elf.py with upstream master
  • Loading branch information
vsoch committed Jun 20, 2022
2 parents 1db0697 + e324e1a commit 0e7d07a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 16 deletions.
37 changes: 21 additions & 16 deletions cle/backends/elf/elf.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import elftools
from elftools.elf import elffile, sections, dynamic, enums
from elftools.dwarf import callframe
from elftools.common.exceptions import ELFError, DWARFError
from elftools.common.exceptions import ELFError, DWARFError, ELFParseError
from elftools.dwarf.dwarf_expr import DWARFExprParser
from elftools.dwarf.descriptions import describe_form_class, describe_attr_value, set_global_machine_arch
from elftools.dwarf.dwarfinfo import DWARFInfo
Expand Down Expand Up @@ -616,8 +616,11 @@ def _load_line_info(self, dwarf):
"""
for cu in dwarf.iter_CUs():
comp_dir = '.'
die = cu.get_top_DIE()

try:
die = cu.get_top_DIE()
except KeyError:
# pyelftools is not very resilient
continue
if 'DW_AT_comp_dir' in die.attributes:
comp_dir = die.attributes['DW_AT_comp_dir'].value.decode()

Expand All @@ -626,16 +629,14 @@ def _load_line_info(self, dwarf):
if "DW_AT_stmt_list" in die.attributes:
del die.attributes["DW_AT_stmt_list"]

# Added because this fails sometimes, along with lineprog.get_entries()
try:
lineprog = dwarf.line_program_for_CU(cu)
if lineprog is None:
continue
entries = lineprog.get_entries()
except Exception as e:
except ELFParseError:
continue
if lineprog is None:
continue
file_cache = {}
for line in entries:
for line in lineprog.get_entries():
if line.state is None:
continue
if line.state.file in file_cache:
Expand Down Expand Up @@ -721,13 +722,17 @@ def parse_die_types(die):
for cu in dwarf.iter_CUs():
expr_parser = DWARFExprParser(cu.structs)

# scan the whole die tree for DW_TAG_base_type and DW_TAG_typedef
for die in cu.iter_DIEs():
if die.tag == "DW_TAG_base_type":
var_type = VariableType.read_from_die(die)
if var_type is not None:
type_list[die.offset] = var_type
parse_die_types(die)
# scan the whole die tree for DW_TAG_base_type
try:
for die in cu.iter_DIEs():
if die.tag == "DW_TAG_base_type":
var_type = VariableType.read_from_die(die)
if var_type is not None:
type_list[die.offset] = var_type
parse_die_types(die)
except KeyError:
# pyelftools is not very resilient - we need to catch KeyErrors here
continue

# Provide type information to the corpus
self.corpus.type_die_lookup = type_die_lookup
Expand Down
2 changes: 2 additions & 0 deletions cle/backends/elf/elfcore.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ def __init__(self, *args, executable=None, remote_file_mapping=None, remote_file

self.__reload_children()

self._remote_file_mapper = None

@staticmethod
def is_compatible(stream):
stream.seek(0)
Expand Down
18 changes: 18 additions & 0 deletions tests/test_dwarf_resiliency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# pylint:disable=no-self-use,missing-class-docstring
import os
from unittest import TestCase, main

import cle


TESTS_BASE = os.path.join(os.path.dirname(os.path.realpath(__file__)),
os.path.join('..', '..', 'binaries', 'tests'))

class TestDwarfResiliency(TestCase):
def test_dwarf_pyelftools_keyerrors(self):
binary_path = os.path.join(TESTS_BASE, "i386", "dwarf_resiliency_0")
_ = cle.Loader(binary_path, auto_load_libs=False, load_debug_info=True)


if __name__ == "__main__":
main()

0 comments on commit 0e7d07a

Please sign in to comment.