diff --git a/src/stm8dce/__main__.py b/src/stm8dce/__main__.py index fc7c483..b04580c 100755 --- a/src/stm8dce/__main__.py +++ b/src/stm8dce/__main__.py @@ -183,7 +183,7 @@ def run( for function in functions: function.resolve_constants(constants) - # Resolve constants accessed by initializers + # Resolve functions and constants accessed by initializers debug.pdbg() debug.pdbg("Resolving functions and constants accessed by initializers") debug.pseperator() @@ -213,7 +213,7 @@ def run( debug.pdbg() debug.pdbg(f"Traversing entry function: {entry_label}") debug.pseperator() - keep_functions += [entry_function] + asm_analysis.traverse_calls( + keep_functions += [entry_function] + asm_analysis.traverse_functions( functions, entry_function ) elif modules: @@ -242,25 +242,12 @@ def run( f"Traversing function {function.name} referenced by module {entry_module.name}" ) debug.pseperator() - keep_functions += [function] + asm_analysis.traverse_calls( + keep_functions += [function] + asm_analysis.traverse_functions( functions, function ) else: raise ValueError(f"Error: Entry label not found: {entry_label}") - # Keep functions assigned to a function pointer - for func in functions: - for function_pointer in func.fptrs: - if function_pointer not in keep_functions: - debug.pdbg() - debug.pdbg( - f"Traversing function assigned to function pointer: {function_pointer.name}" - ) - debug.pseperator() - keep_functions += [function_pointer] + asm_analysis.traverse_calls( - functions, function_pointer - ) - # Keep interrupt handlers and all of their traversed calls # but exclude unused IRQ handlers if opted by the user interrupt_handlers = asm_analysis.interrupt_handlers(functions) @@ -270,7 +257,9 @@ def run( debug.pdbg() debug.pdbg(f"Traversing IRQ handler: {handler.name}") debug.pseperator() - keep_functions += [handler] + asm_analysis.traverse_calls(functions, handler) + keep_functions += [handler] + asm_analysis.traverse_functions( + functions, handler + ) # Keep functions accessed by initializers for initializer in initializers: @@ -284,7 +273,7 @@ def run( f"Traversing function {function_pointer.name} accessed by initializer" ) debug.pseperator() - keep_functions += [function_pointer] + asm_analysis.traverse_calls( + keep_functions += [function_pointer] + asm_analysis.traverse_functions( functions, function_pointer ) @@ -313,7 +302,7 @@ def run( debug.pdbg() debug.pdbg(f"Traversing excluded function: {name}") debug.pseperator() - keep_functions += [excluded_function] + asm_analysis.traverse_calls( + keep_functions += [excluded_function] + asm_analysis.traverse_functions( functions, excluded_function ) @@ -333,7 +322,9 @@ def run( f"Traversing function {ref.name} referenced by module {module.name}" ) debug.pseperator() - keep_functions += [ref] + asm_analysis.traverse_calls(functions, ref) + keep_functions += [ref] + asm_analysis.traverse_functions( + functions, ref + ) elif isinstance(ref, asm_analysis.Constant) and ref not in keep_constants: keep_constants.append(ref) diff --git a/src/stm8dce/asm_analysis.py b/src/stm8dce/asm_analysis.py index 4b87205..94c7118 100644 --- a/src/stm8dce/asm_analysis.py +++ b/src/stm8dce/asm_analysis.py @@ -96,12 +96,11 @@ class Function: long_read_labels_str (list): List of long read labels. Generated Attributes: - calls (list): List of resolved functions called by the function (See resolve_calls). + function_references (list): List of functions referenced by the function (See resolve_calls & resolve_fptrs). external_calls (list): List of external functions (in rel & lib files) called by the function. constants (list): List of resolved constants read by the function (See resolve_constants). external_constants (list): List of external constants (in rel & lib files) read by the function. global_defs (list): List of resolved global definitions used by the function (See resolve_globals). - fptrs (list): List of resolved function pointers assigned by the function (See resolve_fptrs). isr_def (IntDef): Resolved interrupt definition associated with the function (See resolve_isr). empty (bool): Indicates if the function is empty. @@ -117,12 +116,11 @@ def __init__(self, path, start_line_number, name): self.calls_str = [] self.long_read_labels_str = [] - self.calls = [] + self.function_references = [] self.external_calls = [] self.constants = [] self.external_constants = [] self.global_defs = [] - self.fptrs = [] self.isr_def = None self.empty = True @@ -140,14 +138,15 @@ def print(self): print(f"End line: {self.end_line_number}") print(f"Calls: {self.calls_str}") print(f"Long read labels: {self.long_read_labels_str}") - print(f"Resolved calls: {[call.name for call in self.calls]}") + print( + f"Resolved function references: {[call.name for call in self.function_references]}" + ) print(f"External calls: {self.external_calls}") print(f"Resolved constants: {[const.name for const in self.constants]}") print(f"External constants: {self.external_constants}") print( f"Resolved global definitions: {[glob.name for glob in self.global_defs]}" ) - print(f"Resolved function pointers: {[fptr.name for fptr in self.fptrs]}") print(f"IRQ Handler: {self.isr_def}") print(f"Empty: {self.empty}") @@ -209,7 +208,7 @@ def resolve_calls(self, functions): for func in funcs: print(f"In file {func.path}:{func.start_line_number}") exit(1) - self.calls.append(funcs[0]) + self.function_references.append(funcs[0]) debug.pdbg( f"Function {self.name} in {self.path}:{self.start_line_number} calls function {funcs[0].name} in {funcs[0].path}:{funcs[0].start_line_number}" ) @@ -222,7 +221,7 @@ def resolve_calls(self, functions): f"Error: Multiple static definitions for function {func} in {func.path}" ) exit(1) - self.calls.append(func) + self.function_references.append(func) debug.pdbg( f"Function {self.name} in {self.path}:{self.start_line_number} calls static function {func.name} in {func.path}:{func.start_line_number}" ) @@ -238,7 +237,7 @@ def resolve_fptrs(self, functions): for long_read_label in self.long_read_labels_str: for func in functions: if func.name == long_read_label: - self.fptrs.append(func) + self.function_references.append(func) debug.pdbg( f"Function {self.name} in {self.path}:{self.start_line_number} assigns function pointer to {func.name} in {func.path}:{func.start_line_number}" ) @@ -568,9 +567,9 @@ def constant_by_filename_name(constants, filename, name): return ret -def traverse_calls(functions, top): +def traverse_functions(functions, top): """ - Traverse all calls made by a function and return a list of all traversed functions. + Traverse all functions referenced by a function and return a list of all traversed functions. Args: functions (list): List of Function objects. @@ -583,11 +582,11 @@ def traverse_calls(functions, top): ret = [] - for call in top.calls: - if call == top: + for function in top.function_references: + if function == top: continue - ret += [call] + traverse_calls(functions, call) + ret += [function] + traverse_functions(functions, function) debug.pdbg(f"Traversing out {top.name} in {top.path}:{top.start_line_number}")