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.
This commit is contained in:
Guillaume Souchere 2022-11-09 10:46:18 +01:00
parent e92250e6a2
commit c47ea5d2bb
2 changed files with 29 additions and 4 deletions

View File

@ -12,6 +12,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}
)

View File

@ -95,6 +95,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: BinaryIO) -> None:
self.elf_file = elf_file
@ -159,7 +164,7 @@ class ElfInfo(object):
return None
def load_rtl_file(rtl_filename: str, tu_filename: str, functions: List[RtlFunction]) -> None:
def load_rtl_file(rtl_filename: str, tu_filename: str, functions: List[RtlFunction], ignore_pairs: List[IgnorePair]) -> None:
last_function: Optional[RtlFunction] = None
for line in open(rtl_filename):
# Find function definition
@ -175,6 +180,17 @@ def load_rtl_file(rtl_filename: str, tu_filename: str, functions: List[RtlFuncti
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
@ -304,12 +320,12 @@ def match_rtl_funcs_to_symbols(rtl_functions: List[RtlFunction], elfinfo: ElfInf
return symbols, refs
def get_symbols_and_refs(rtl_list: List[str], elf_file: BinaryIO) -> Tuple[List[Symbol], List[Reference]]:
def get_symbols_and_refs(rtl_list: List[str], elf_file: BinaryIO, ignore_pairs: List[IgnorePair]) -> Tuple[List[Symbol], List[Reference]]:
elfinfo = ElfInfo(elf_file)
rtl_functions: 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)
@ -361,6 +377,10 @@ def main() -> None:
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',
@ -384,7 +404,11 @@ def main() -> None:
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 []