diff options
Diffstat (limited to 'build-aux/stack.c.gen')
-rwxr-xr-x | build-aux/stack.c.gen | 69 |
1 files changed, 38 insertions, 31 deletions
diff --git a/build-aux/stack.c.gen b/build-aux/stack.c.gen index 07d5cfc..858c28a 100755 --- a/build-aux/stack.c.gen +++ b/build-aux/stack.c.gen @@ -149,7 +149,7 @@ def analyze( extra_nodes: list[Node] = [], app_func_filters: dict[str, typing.Callable[[str], int]], app_location_xform: typing.Callable[[str], str], - app_indirect_callees: typing.Callable[[VCGElem], list[str]], + app_indirect_callees: typing.Callable[[VCGElem], tuple[list[str], bool]], app_skip_call: typing.Callable[[list[str], str], bool], cfg_max_call_depth: int, ) -> AnalyzeResult: @@ -221,9 +221,10 @@ def analyze( if caller not in graph: raise ValueError(f"unknown caller: {caller}") if callee == "__indirect_call": - for callee in app_indirect_callees(elem): + callees, missing_ok = app_indirect_callees(elem) + for callee in callees: if callee not in graph[caller].calls: - graph[caller].calls[callee] = True + graph[caller].calls[callee] = missing_ok else: graph[caller].calls[callee] = False case _: @@ -339,7 +340,9 @@ def main( all_nodes: list[Node] = [] hooks_is_intrhandler: list[typing.Callable[[str], bool]] = [] - hooks_indirect_callees: list[typing.Callable[[str, str], list[str] | None]] = [] + hooks_indirect_callees: list[ + typing.Callable[[str, str], tuple[list[str], bool] | None] + ] = [] hooks_skip_call: list[typing.Callable[[list[str], str], bool]] = [] # The sbc-harness codebase ####################################### @@ -394,30 +397,34 @@ def main( re_call_objcall = re.compile(r"LO_CALL\((?P<obj>[^,]+), (?P<meth>[^,)]+)[,)].*") - def sbc_indirect_callees(loc: str, line: str) -> list[str] | None: + def sbc_indirect_callees(loc: str, line: str) -> tuple[list[str], bool] | None: if "/3rd-party/" in loc: return None if m := re_call_objcall.fullmatch(line): if m.group("meth") in objcalls: - return sorted(objcalls[m.group("meth")]) - return [f"__indirect_call:{m.group('obj')}.vtable->{m.group('meth')}"] + return sorted(objcalls[m.group("meth")]), True + return [ + f"__indirect_call:{m.group('obj')}.vtable->{m.group('meth')}" + ], False if "trigger->cb(trigger->cb_arg)" in line: return [ "alarmclock_sleep_intrhandler", "w5500_tcp_alarm_handler", "w5500_udp_alarm_handler", - ] + ], True if "/chan.h:" in loc and "front->dequeue(" in line: return [ "_cr_chan_dequeue", "_cr_select_dequeue", - ] + ], True if tmessage_handlers and "/srv.c:" in loc and "tmessage_handlers[typ](" in line: - return sorted(tmessage_handlers) + # Functions for disabled protocol extensions will be missing. + return sorted(tmessage_handlers), True if lib9p_msgs and "/9p.c:" in loc: for meth in ["validate", "unmarshal", "marshal"]: if line.startswith(f"tentry.{meth}("): - return sorted(f"{meth}_{msg}" for msg in lib9p_msgs) + # Functions for disabled protocol extensions will be missing. + return sorted(f"{meth}_{msg}" for msg in lib9p_msgs), True return None hooks_indirect_callees += [sbc_indirect_callees] @@ -492,7 +499,7 @@ def main( hooks_is_intrhandler += [pico_is_intrhandler] - def pico_indirect_callees(loc: str, line: str) -> list[str] | None: + def pico_indirect_callees(loc: str, line: str) -> tuple[list[str], bool] | None: if "/3rd-party/pico-sdk/" not in loc or "/3rd-party/pico-sdk/lib/" in loc: return None m = re_call_other.fullmatch(line) @@ -500,43 +507,43 @@ def main( match call: case "connect_internal_flash_func": - return ["rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH)"] + return ["rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH)"], False case "flash_exit_xip_func": - return ["rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP)"] + return ["rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP)"], False case "flash_range_erase_func": - return ["rom_func_lookup(ROM_FUNC_FLASH_RANGE_ERASE)"] + return ["rom_func_lookup(ROM_FUNC_FLASH_RANGE_ERASE)"], False case "flash_flush_cache_func": - return ["rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE)"] + return ["rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE)"], False case "rom_table_lookup": - return ["rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET)"] + return ["rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET)"], False if "/flash.c:" in loc and "boot2_copyout" in line: - return ["_stage2_boot"] + return ["_stage2_boot"], False if "/gpio.c:" in loc and call == "callback": - return sbc_gpio_handlers + return sbc_gpio_handlers, True if "/printf.c:" in loc: if call == "out": return [ "_out_buffer", "_out_null", "_out_fct", - ] + ], False if "->fct(" in line: - return ["stdio_buffered_printer"] + return ["stdio_buffered_printer"], False if "/stdio.c:" in loc: if call == "out_func": return [ "stdio_out_chars_crlf", "stdio_out_chars_no_crlf", - ] + ], False if call and (call.startswith("d->") or call.startswith("driver->")): _, meth = call.split("->", 1) match meth: case "out_chars": - return ["stdio_uart_out_chars"] + return ["stdio_uart_out_chars"], False case "out_flush": - return ["stdio_uart_out_flush"] + return ["stdio_uart_out_flush"], False case "in_chars": - return ["stdio_uart_in_chars"] + return ["stdio_uart_in_chars"], False return None hooks_indirect_callees += [pico_indirect_callees] @@ -689,7 +696,7 @@ def main( elif " _usbd_driver[] = {" in line: in_table = True - def tud_indirect_callees(loc: str, line: str) -> list[str] | None: + def tud_indirect_callees(loc: str, line: str) -> tuple[list[str], bool] | None: if ( "/tinyusb/" not in loc or "/tinyusb/src/host/" in loc @@ -704,12 +711,12 @@ def main( # "process_test_mode_cb", "tud_vendor_control_xfer_cb", *sorted(tud_drivers["control_xfer_cb"]), - ] + ], False elif call.startswith("driver->"): - return sorted(tud_drivers[call[len("driver->") :]]) + return sorted(tud_drivers[call[len("driver->") :]]), False elif call == "event.func_call.func": # callback from usb_defer_func() - return [] + return [], False return None @@ -787,7 +794,7 @@ def main( parts[0] = "./" + os.path.relpath(parts[0], arg_base_dir) return ":".join(parts) - def indirect_callees(elem: VCGElem) -> list[str]: + def indirect_callees(elem: VCGElem) -> tuple[list[str], bool]: loc = elem.attrs.get("label", "") line = read_source(loc) @@ -800,7 +807,7 @@ def main( if m := re_call_other.fullmatch(line): placeholder += ":" + m.group("func") placeholder += " at " + location_xform(elem.attrs.get("label", "")) - return [placeholder] + return [placeholder], False def skip_call(chain: list[str], call: str) -> bool: for hook in hooks_skip_call: |