Source code for cle.backends.elf.subprogram

from __future__ import annotations

from cle.backends.inlined_function import InlinedFunction

from .variable import Variable


[docs] class LexicalBlock: """ A lexical block is a sequence of source statements, e.g. a while/for loop or an if statement or some bracketed block. Corresponds to a DW_TAG_LexicalBlock in DWARF. :param super_block: The lexical block which contains this block :param low_pc: The relative start address of the block :param high_pc: The relative end address of the block :ivar low_pc: The relative start address of the subprogram :ivar high_pc: The relative end address of the subprogram :ivar child_blocks: Lexical blocks inside this block (only direct childs) :type child_blocks: List[LexicalBlock] """
[docs] def __init__( self, low_pc: int | None, high_pc: int | None, ranges: list[tuple[int, int]] | None = None, source_file: str | None = None, source_line: int | None = None, ) -> None: self.source_file = source_file self.source_line = source_line if low_pc is None and high_pc is None: if ranges is not None: low_pc = min(x for x, _ in ranges) high_pc = max(x for _, x in ranges) if low_pc is None or high_pc is None: raise ValueError("Must provide low_pc/high_pc or ranges") if ranges is None: ranges = [(low_pc, high_pc)] self.ranges = ranges self.low_pc = low_pc self.high_pc = high_pc self.child_blocks: list[LexicalBlock] = []
[docs] def rebase(self, delta: int): self.low_pc += delta self.high_pc += delta self.ranges = [(lo + delta, hi + delta) for lo, hi in self.ranges] for blk in self.child_blocks: blk.rebase(delta)
[docs] class Subprogram(LexicalBlock): """ DW_TAG_subprogram for DWARF. The behavior is mostly inherited from LexicalBlock to avoid redundancy. :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 :ivar name: The name of the function/program :type name: str :ivar local_variables: All local variables in a Subprogram (they may reside in serveral child blocks) :type local_variables: List[Variables] """
[docs] def __init__( self, name: str | None, low_pc: int | None, high_pc: int | None, ranges: list[tuple[int, int]] | None = None, source_file: str | None = None, source_line: int | None = None, ) -> None: # pass self as the super_block of this subprogram self.subprogram = self super().__init__(low_pc, high_pc, ranges, source_file, source_line) self.name = name self.local_variables: list[Variable] = [] self.inlined_functions: list[InlinedFunction] = []
[docs] def rebase(self, delta: int): super().rebase(delta) for inl in self.inlined_functions: inl.rebase(delta)