From e0c92b3e0499059b4bb882c6980ca12b2482bdf7 Mon Sep 17 00:00:00 2001 From: Guillaume Souchere Date: Wed, 9 Nov 2022 10:46:18 +0100 Subject: [PATCH] tools: update list of references to not include symbold used by __assert_func calls On xtensa architecture, the call to __assert_func uses a reference to __func__ that can sometimes be placed in flash. Since the __asert_func can be called from functions in IRAM the check_callgraph script can report an error when checking for invalid calls from IRAM to flash sections. However, the __asert_func prevents this scenario at runtime so the check_callgraph script reports a 'flas positive' situation. For this reasson, all references to __func__$x found prior to a call to __assert_func are droped in the parsing of the rtl files. --- components/heap/test/CMakeLists.txt | 1 + tools/ci/check_callgraph.py | 32 +++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/components/heap/test/CMakeLists.txt b/components/heap/test/CMakeLists.txt index 3496205c22..ec980b5b75 100644 --- a/components/heap/test/CMakeLists.txt +++ b/components/heap/test/CMakeLists.txt @@ -11,6 +11,7 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) find-refs --from-sections=.iram0.text --to-sections=.flash.text,.flash.rodata + --ignore-symbols=__func__/__assert_func,__func__/heap_caps_alloc_failed --exit-code DEPENDS ${elf_file_name} ) diff --git a/tools/ci/check_callgraph.py b/tools/ci/check_callgraph.py index 700d5e6bad..175718df7e 100755 --- a/tools/ci/check_callgraph.py +++ b/tools/ci/check_callgraph.py @@ -110,6 +110,11 @@ class Reference(object): ) +class IgnorePair(): + def __init__(self, pair: str) -> None: + self.symbol, self.function_call = pair.split('/') + + class ElfInfo(object): def __init__(self, elf_file): # type: (BinaryIO) -> None self.elf_file = elf_file @@ -174,7 +179,7 @@ class ElfInfo(object): return None -def load_rtl_file(rtl_filename, tu_filename, functions): # type: (str, str, List[RtlFunction]) -> None +def load_rtl_file(rtl_filename, tu_filename, functions, ignore_pairs): # type: (str, str, List[RtlFunction], List[IgnorePair]) -> None last_function = None # type: Optional[RtlFunction] for line in open(rtl_filename): # Find function definition @@ -190,6 +195,17 @@ def load_rtl_file(rtl_filename, tu_filename, functions): # type: (str, str, Lis match = re.match(CALL_REGEX, line) if match: target = match.group('target') + + # if target matches on of the IgnorePair function_call attributes, remove + # the last occurrence of the associated symbol from the last_function.refs list. + call_matching_pairs = [pair for pair in ignore_pairs if pair.function_call == target] + if call_matching_pairs and last_function and last_function.refs: + for pair in call_matching_pairs: + ignored_symbols = [ref for ref in last_function.refs if pair.symbol in ref] + if ignored_symbols: + last_ref = ignored_symbols.pop() + last_function.refs = [ref for ref in last_function.refs if last_ref != ref] + if target not in last_function.calls: last_function.calls.append(target) continue @@ -319,12 +335,12 @@ def match_rtl_funcs_to_symbols(rtl_functions, elfinfo): # type: (List[RtlFuncti return symbols, refs -def get_symbols_and_refs(rtl_list, elf_file): # type: (List[str], BinaryIO) -> Tuple[List[Symbol], List[Reference]] +def get_symbols_and_refs(rtl_list, elf_file, ignore_pairs): # type: (List[str], BinaryIO, List[IgnorePair]) -> Tuple[List[Symbol], List[Reference]] elfinfo = ElfInfo(elf_file) rtl_functions = [] # type: List[RtlFunction] for file_name in rtl_list: - load_rtl_file(file_name, file_name, rtl_functions) + load_rtl_file(file_name, file_name, rtl_functions, ignore_pairs) return match_rtl_funcs_to_symbols(rtl_functions, elfinfo) @@ -376,6 +392,10 @@ def main(): find_refs_parser.add_argument( '--to-sections', help='comma-separated list of target sections' ) + find_refs_parser.add_argument( + '--ignore-symbols', help='comma-separated list of symbol/function_name pairs. \ + This will force the parser to ignore the symbol preceding the call to function_name' + ) find_refs_parser.add_argument( '--exit-code', action='store_true', @@ -399,7 +419,11 @@ def main(): if not rtl_list: raise RuntimeError('No RTL files specified') - _, refs = get_symbols_and_refs(rtl_list, args.elf_file) + ignore_pairs = [] + for pair in args.ignore_symbols.split(',') if args.ignore_symbols else []: + ignore_pairs.append(IgnorePair(pair)) + + _, refs = get_symbols_and_refs(rtl_list, args.elf_file, ignore_pairs) if args.action == 'find-refs': from_sections = args.from_sections.split(',') if args.from_sections else []