[docs]classVariable:""" Variable for DWARF from a DW_TAG_variable or DW_TAG_formal_parameter :ivar str name: The name of the variable :ivar relative_addr: The relative addr (base addr depends on the type) :ivar lexical_block: For a local variable, the lexical block where the variable is declared """
[docs]def__init__(self,elf_object:"ELF"):self._elf_object=elf_object# all other optional params can be set afterwardsself.relative_addr=Noneself.name=Noneself._type_offset=Noneself.decl_line=Noneself.decl_file=Noneself.lexical_block=Noneself.external=Falseself.declaration_only=False
[docs]@staticmethoddeffrom_die(die:DIE,expr_parser,elf_object:"ELF",lexical_block:Optional["LexicalBlock"]=None):# first the addressif"DW_AT_location"indie.attributesanddie.attributes["DW_AT_location"].form=="DW_FORM_exprloc":parsed_exprs=expr_parser.parse_expr(die.attributes["DW_AT_location"].value)iflen(parsed_exprs)==1andparsed_exprs[0].op_name=="DW_OP_addr":addr=parsed_exprs[0].args[0]var=MemoryVariable(elf_object,addr)eliflen(parsed_exprs)==1andparsed_exprs[0].op_name=="DW_OP_fbreg":addr=parsed_exprs[0].args[0]var=StackVariable(elf_object,addr)eliflen(parsed_exprs)==1andparsed_exprs[0].op_name.startswith("DW_OP_reg"):addr=parsed_exprs[0].op-0x50# 0x50 == DW_OP_reg0var=RegisterVariable(elf_object,addr)else:var=Variable(elf_object)else:var=Variable(elf_object)if"DW_AT_name"indie.attributes:var.name=die.attributes["DW_AT_name"].value.decode("utf-8")if"DW_AT_type"indie.attributes:var._type_offset=die.attributes["DW_AT_type"].value+die.cu.cu_offsetif"DW_AT_decl_line"indie.attributes:var.decl_line=die.attributes["DW_AT_decl_line"].valueif"DW_AT_external"indie.attributes:var.external=Trueif"DW_AT_declaration"indie.attributes:var.declaration_only=Truevar.lexical_block=lexical_blockreturnvar
# overwritten for stack variables
[docs]defrebased_addr_from_cfa(self,cfa:int):""" The address of this variable in the global memory. :param cfa: The canonical frame address as described by the DWARF standard. """returnself.rebased_addr
@propertydefrebased_addr(self):returnNone@propertydefaddr(self):""" Please use 'relative_addr' or 'rebased_addr' instead. """returnself.relative_addr@propertydeftype(self)->VariableType:try:returnself._elf_object.type_list[self._type_offset]exceptKeyError:returnNone@propertydefsort(self)->str:# sort = 'stack' | 'register' | 'global'return"unknown"
[docs]classMemoryVariable(Variable):""" This includes all variables that are not on the stack and not in a register. So all global variables, and also local static variables in C! """
[docs]classRegisterVariable(Variable):""" Register Variable from DWARF. """
[docs]def__init__(self,elf_object:"ELF",register_addr):super().__init__(elf_object)# FIXME should this really go into relative addr?self.relative_addr=register_addr