diff options
Diffstat (limited to 'build-aux/measurestack/app_plugins.py')
-rw-r--r-- | build-aux/measurestack/app_plugins.py | 215 |
1 files changed, 28 insertions, 187 deletions
diff --git a/build-aux/measurestack/app_plugins.py b/build-aux/measurestack/app_plugins.py index e365f82..6fc81ec 100644 --- a/build-aux/measurestack/app_plugins.py +++ b/build-aux/measurestack/app_plugins.py @@ -19,7 +19,6 @@ __all__ = [ "LibCRIPCPlugin", "Lib9PPlugin", "LibMiscPlugin", - "PicoFmtPlugin", "PicoSDKPlugin", "TinyUSBDevicePlugin", "NewlibPlugin", @@ -129,20 +128,7 @@ class LibMiscPlugin: return None def skipmodels(self) -> dict[BaseName, analyze.SkipModel]: - return { - BaseName("__assert_msg_fail"): analyze.SkipModel( - {BaseName("__assert_msg_fail")}, self._skipmodel___assert_msg_fail - ), - } - - def _skipmodel___assert_msg_fail( - self, chain: typing.Sequence[QName], node: Node, call: QName - ) -> bool: - if call.base() in [BaseName("__lm_printf"), BaseName("__lm_light_printf")]: - return any( - c.base() == BaseName("__assert_msg_fail") for c in reversed(chain) - ) - return False + return {} class LibHWPlugin: @@ -268,35 +254,17 @@ class LibCRIPCPlugin: class Lib9PPlugin: - re_tmessage_handler = re.compile( - r"^\s*\[LIB9P_TYP_T[^]]+\]\s*=\s*\(tmessage_handler\)\s*(?P<handler>\S+),\s*$" - ) - re_lib9p_msg_entry = re.compile(r"^\s*_MSG_(?:[A-Z]+)\((?P<typ>\S+)\),$") - re_lib9p_caller = re.compile( - r"^lib9p_(?P<grp>[TR])msg_(?P<meth>validate|unmarshal|marshal)$" - ) - re_lib9p_callee = re.compile( - r"^(?P<meth>validate|unmarshal|marshal)_(?P<msg>(?P<grp>[TR]).*)$" - ) + re_lib9p_msg_entry = re.compile(r"^\s*_MSG\((?P<typ>\S+)\),$") - tmessage_handlers: set[QName] | None lib9p_msgs: set[str] _CONFIG_9P_MAX_CONNS: int | None _CONFIG_9P_MAX_REQS: int | None - formatters: typing.Collection[BaseName] def __init__( self, arg_base_dir: str, arg_c_fnames: typing.Collection[str], - libmisc_plugin: LibMiscPlugin, ) -> None: - self.formatters = { - x.base() - for x in libmisc_plugin.objcalls["format"] - if str(x.base()).startswith("lib9p_") - } - # Find filenames ####################################################### def _is_config_h(fname: str) -> bool: @@ -314,7 +282,7 @@ class Lib9PPlugin: ) lib9p_generated_c_fname = util.get_zero_or_one( - lambda fname: fname.endswith("lib9p/_core_generated.c"), arg_c_fnames + lambda fname: fname.endswith("lib9p/core_generated.c"), arg_c_fnames ) # Read config ########################################################## @@ -336,16 +304,6 @@ class Lib9PPlugin: # Read sources ######################################################### - tmessage_handlers: set[QName] | None = None - if lib9p_srv_c_fname: - tmessage_handlers = set() - with open(lib9p_srv_c_fname, "r", encoding="utf-8") as fh: - for line in fh: - line = line.rstrip() - if m := self.re_tmessage_handler.fullmatch(line): - tmessage_handlers.add(QName(m.group("handler"))) - self.tmessage_handlers = tmessage_handlers - lib9p_msgs: set[str] = set() if lib9p_generated_c_fname: with open(lib9p_generated_c_fname, "r", encoding="utf-8") as fh: @@ -377,153 +335,37 @@ class Lib9PPlugin: def extra_nodes(self) -> typing.Collection[Node]: return [] - def indirect_callees( - self, loc: str, line: str - ) -> tuple[typing.Collection[QName], bool] | None: - if "/3rd-party/" in loc: - return None - if ( - self.tmessage_handlers - and "/srv.c:" in loc - and "tmessage_handlers[typ](" in line - ): - # Functions for disabled protocol extensions will be missing. - return self.tmessage_handlers, True - if self.lib9p_msgs and "/9p.c:" in loc: - for meth in ["validate", "unmarshal", "marshal"]: - if line.startswith(f"tentry.{meth}("): - # Functions for disabled protocol extensions will be missing. - return [QName(f"{meth}_{msg}") for msg in self.lib9p_msgs], True - return None - - def skipmodels(self) -> dict[BaseName, analyze.SkipModel]: - ret: dict[BaseName, analyze.SkipModel] = { - BaseName("_lib9p_validate"): analyze.SkipModel( - 1, - self._skipmodel__lib9p_validate_unmarshal_marshal, - ), - BaseName("_lib9p_unmarshal"): analyze.SkipModel( - 1, - self._skipmodel__lib9p_validate_unmarshal_marshal, - ), - BaseName("_lib9p_marshal"): analyze.SkipModel( - 1, - self._skipmodel__lib9p_validate_unmarshal_marshal, - ), - } - return ret - - def _skipmodel__lib9p_validate_unmarshal_marshal( - self, chain: typing.Sequence[QName], node: Node, call: QName - ) -> bool: - m_caller = self.re_lib9p_caller.fullmatch(str(chain[-1].base())) - assert m_caller - - m_callee = self.re_lib9p_callee.fullmatch(str(call.base())) - if not m_callee: - return False - return m_caller.group("grp") != m_callee.group("grp") - - -class PicoFmtPlugin: - known_fct: dict[BaseName, BaseName] - wont_call_v: typing.Collection[BaseName] - - def __init__( - self, arg_pico_platform: str, wont_call_v: typing.Collection[BaseName] - ) -> None: - self.known_fct = { - # pico_fmt - BaseName("fmt_vsnprintf"): BaseName("_out_buffer"), - } - match arg_pico_platform: - case "rp2040": - self.known_fct.update( - { - # pico_stdio - BaseName("__wrap_vprintf"): BaseName("stdio_buffered_printer"), - BaseName("stdio_vprintf"): BaseName("stdio_buffered_printer"), - # libfmt - BaseName("__lm_light_printf"): BaseName("libfmt_light_fct"), - } - ) - case "host": - self.known_fct.update( - { - # libfmt - BaseName("__lm_printf"): BaseName("libfmt_libc_fct"), - BaseName("__lm_light_printf"): BaseName("libfmt_libc_fct"), - } - ) - self.wont_call_v = set([*self.known_fct.values(), *wont_call_v]) - - def is_intrhandler(self, name: QName) -> bool: - return False - - def init_array(self) -> typing.Collection[QName]: - return [] - - def extra_includes(self) -> typing.Collection[BaseName]: - return [] - - def extra_nodes(self) -> typing.Collection[Node]: - return [] + re_table_call = re.compile( + r"\s*_lib9p_(?P<meth>validate|unmarshal|marshal)\(.*(?P<grp>[RT])msg.*\);\s*" + ) + re_print_call = re.compile(r".*lib9p_table_msg.*\.print\(.*") def indirect_callees( self, loc: str, line: str ) -> tuple[typing.Collection[QName], bool] | None: - if "/3rd-party/pico-fmt/" not in loc: + if "/3rd-party/" in loc: return None - if "/printf.c:" in loc: - m = util.re_call_other.fullmatch(line) - call: str | None = m.group("func") if m else None - if "->fct" in line: - return [x.as_qname() for x in self.known_fct.values()], False - if "specifier_table" in line: + if self.lib9p_msgs and "lib9p/core.c:" in loc: + if m := self.re_table_call.fullmatch(line): + meth = m.group("meth") + grp = m.group("grp") + # Functions for disabled protocol extensions will be missing. return [ - # pico-fmt - QName("conv_sint"), - QName("conv_uint"), - # QName("conv_double"), - QName("conv_char"), - QName("conv_str"), - QName("conv_ptr"), - QName("conv_pct"), - # libfmt - QName("libfmt_conv_formatter"), - QName("libfmt_conv_quote"), - ], False + QName(f"{meth}_{msg}") + for msg in self.lib9p_msgs + if msg.startswith(grp) + ], True + if self.re_print_call.fullmatch(line): + # Functions for disabled protocol extensions will be missing. + return [QName(f"fmt_print_{msg}") for msg in self.lib9p_msgs], True + if "lib9p/srv.c:" in loc: + if "srv->msglog(" in line: + # Actual ROMs shouldn't set this, and so will be missing on rp2040 builds. + return [QName("log_msg")], True return None def skipmodels(self) -> dict[BaseName, analyze.SkipModel]: - ret: dict[BaseName, analyze.SkipModel] = { - BaseName("fmt_state_putchar"): analyze.SkipModel( - self.known_fct.keys(), self._skipmodel_fmt_state_putchar - ), - BaseName("_vfctprintf"): analyze.SkipModel( - self.wont_call_v, self._skipmodel__vfctprintf - ), - } - return ret - - def _skipmodel_fmt_state_putchar( - self, chain: typing.Sequence[QName], node: Node, call: QName - ) -> bool: - if call.base() in self.known_fct.values(): - fct: BaseName | None = None - for pcall in reversed(chain): - if pcall.base() in self.known_fct: - fct = self.known_fct[pcall.base()] - return call.base() != fct - return True - return False - - def _skipmodel__vfctprintf( - self, chain: typing.Sequence[QName], node: Node, call: QName - ) -> bool: - if call.base() == BaseName("libfmt_conv_formatter"): - return any(c.base() in self.wont_call_v for c in chain) - return False + return {} class PicoSDKPlugin: @@ -604,6 +446,8 @@ class PicoSDKPlugin: return [QName("rom_func_lookup(ROM_FUNC_FLASH_RANGE_ERASE)")], False case "flash_flush_cache_func": return [QName("rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE)")], False + case "flash_range_program_func": + return [QName("rom_func_lookup(ROM_FUNC_FLASH_RANGE_PROGRAM)")], False case "rom_table_lookup": return [QName("rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET)")], False if "/flash.c:" in loc and "boot2_copyout" in line: @@ -941,10 +785,7 @@ class LibGCCPlugin: return False def init_array(self) -> typing.Collection[QName]: - return [ - QName("libfmt_install_formatter"), - QName("libfmt_install_quote"), - ] + return [] def extra_includes(self) -> typing.Collection[BaseName]: return [] |