Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6938a6a
Fixed abstract origin address with form ref_addr (in contrast with th…
Jul 7, 2025
16128ba
Code now loads parameter information from DWARF
Jul 7, 2025
7ef5052
Changes to DWARF types: added encoding field to BaseType if available…
Jul 8, 2025
1924547
Added support for enumeration and subroutine DWARF types
Jul 9, 2025
26be21d
EnumerationType now stores its underlying type
Jul 9, 2025
23530d9
Added VariantType
Jul 14, 2025
d789bfb
Moved DWARF reference resolving code to a more abstract function that…
Jul 14, 2025
19fa304
Merge branch 'bug_fix_ref_addr' into function_parameters
Jul 14, 2025
5592852
Removed resolve_reference in favor of using die.get_DIE_from_attribut…
Jul 16, 2025
914d878
Merge branch 'bug_fix_ref_addr' into function_parameters
Jul 16, 2025
50dda2e
Renamed VariantValue to VariantCaseType. Renamed uses of discr to tag…
Jul 18, 2025
b65d5ca
Renamed tag to tag_value in VariantCaseType. Added some documentation…
Jul 28, 2025
e2eecaa
Added support for getting alginment information from DWARF info
Jul 29, 2025
6e6f52f
Bug fixes for getting SubprogramType working. Started adding stuff fo…
Nov 19, 2025
571e1c6
Fixed namespace generation for DWARF DIEs
Nov 20, 2025
3570f33
Added support for DWARF const types to CLE. StructType is more resili…
Dec 1, 2025
030a84c
Merge branch 'master' into function_parameters
Dec 1, 2025
235b0e2
Merge branch 'angr:master' into function_parameters
calebh Dec 1, 2025
77589be
Added support for DWARF atomic, immutable, packed, reference, restric…
Dec 2, 2025
94e7e46
Merge branch 'function_parameters' of https://github.com/draperlabora…
Dec 2, 2025
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
12 changes: 8 additions & 4 deletions cle/backends/elf/elf.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from .subprogram import LexicalBlock, Subprogram
from .symbol import ELFSymbol, Symbol, SymbolType
from .variable import Variable
from .variable_type import VariableType
from .variable_type import VariableType, SubprogramType

try:
import pypcode
Expand Down Expand Up @@ -761,7 +761,7 @@ def _load_dies(self, dwarf: DWARFInfo):
if VariableType.supported_die(die):
var_type = VariableType.read_from_die(die, self)
if var_type is not None:
type_list[die.offset] = var_type
type_list[cu.cu_offset + die.offset] = var_type
except KeyError:
# pyelftools is not very resilient - we need to catch KeyErrors here
continue
Expand Down Expand Up @@ -863,16 +863,20 @@ def _load_die_lex_block(
return None

if subprogram is None:
subprogram = block = Subprogram(name, low_pc, high_pc, ranges)
subprogram = block = Subprogram.from_die(die, self, name, low_pc, high_pc, ranges)
else:
block = LexicalBlock(low_pc, high_pc, ranges)

for sub_die in cu.iter_DIE_children(die):
if sub_die.tag in ["DW_TAG_variable", "DW_TAG_formal_parameter"]:
is_variable = sub_die.tag == "DW_TAG_variable"
is_formal_parameter = sub_die.tag == "DW_TAG_formal_parameter"
if is_variable or is_formal_parameter:
# load local variable
var = Variable.from_die(sub_die, expr_parser, self, block)
var.decl_file = file_path
subprogram.local_variables.append(var)
if is_formal_parameter:
subprogram.parameters.append(var)
elif sub_die.tag == "DW_TAG_lexical_block":
sub_block = self._load_die_lex_block(
sub_die, dwarf, aranges, expr_parser, type_list, cu, file_path, subprogram, namespace
Expand Down
35 changes: 34 additions & 1 deletion cle/backends/elf/subprogram.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from elftools.dwarf.die import DIE

from cle.backends.inlined_function import InlinedFunction

from .variable import Variable

from .variable_type import VariableType

if TYPE_CHECKING:
from .elf import ELF

class LexicalBlock:
"""
Expand Down Expand Up @@ -41,6 +49,7 @@ class Subprogram(LexicalBlock):
DW_TAG_subprogram for DWARF. The behavior is mostly inherited from
LexicalBlock to avoid redundancy.

:param elf_object: The ELF object containing the subprogram
:param name: The name of the function/program
:param low_pc: The relative start address of the subprogram
:param high_pc: The relative end address of the subprogram
Expand All @@ -52,11 +61,35 @@ class Subprogram(LexicalBlock):
"""

def __init__(
self, name: str | None, low_pc: int | None, high_pc: int | None, ranges: list[tuple[int, int]] | None = None
self, elf_object: ELF, name: str | None, linkage_name: str | None, low_pc: int | None, high_pc: int | None,
ranges: list[tuple[int, int]] | None = None,
) -> None:
self._elf_object = elf_object
# pass self as the super_block of this subprogram
self.subprogram = self
super().__init__(low_pc, high_pc, ranges)
self.name = name
self.linkage_name = linkage_name
self.parameters: list[Variable] = []
self.local_variables: list[Variable] = []
self.inlined_functions: list[InlinedFunction] = []
self._return_type_offset = None

@staticmethod
def from_die(die: DIE, elf_object: ELF, name: str | None, low_pc: int | None, high_pc: int | None, ranges: list[tuple[int, int]] | None = None):
linkage_name_attr = die.attributes.get("DW_AT_linkage_name", None)
linkage_name = None if linkage_name_attr is None else linkage_name_attr.value.decode()

sub_prg = Subprogram(elf_object, name, linkage_name, low_pc, high_pc, ranges=ranges)
if "DW_AT_type" in die.attributes:
sub_prg._return_type_offset = die.attributes["DW_AT_type"].value + die.cu.cu_offset
return sub_prg

@property
def return_type(self) -> VariableType | None:
# Note that in DWARF an omitted return type typically means a void return type
try:
return self._elf_object.type_list[self._return_type_offset]
except KeyError:
return None

Loading
Loading