summaryrefslogtreecommitdiff
path: root/build-aux/measurestack/app_plugins.py
diff options
context:
space:
mode:
Diffstat (limited to 'build-aux/measurestack/app_plugins.py')
-rw-r--r--build-aux/measurestack/app_plugins.py158
1 files changed, 108 insertions, 50 deletions
diff --git a/build-aux/measurestack/app_plugins.py b/build-aux/measurestack/app_plugins.py
index 7eb7706..519e6b8 100644
--- a/build-aux/measurestack/app_plugins.py
+++ b/build-aux/measurestack/app_plugins.py
@@ -6,7 +6,7 @@
import re
import typing
-from . import util
+from . import analyze, util
from .analyze import BaseName, Node, QName
from .util import synthetic_node
@@ -51,8 +51,8 @@ class CmdPlugin:
return [QName("get_root")], False
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- return False
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ return {}
re_comment = re.compile(r"/\*.*?\*/")
@@ -130,8 +130,8 @@ class LibObjPlugin:
], False
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- return False
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ return {}
class LibHWPlugin:
@@ -199,8 +199,8 @@ class LibHWPlugin:
], False
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- return False
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ return {}
class LibCRPlugin:
@@ -223,8 +223,8 @@ class LibCRPlugin:
) -> tuple[typing.Collection[QName], bool] | None:
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- return False
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ return {}
class LibCRIPCPlugin:
@@ -252,8 +252,8 @@ class LibCRIPCPlugin:
], False
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- return False
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ return {}
re_tmessage_handler = re.compile(
@@ -263,6 +263,9 @@ 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]).*)$"
+)
class Lib9PPlugin:
@@ -372,21 +375,48 @@ class Lib9PPlugin:
return [QName(f"{meth}_{msg}") for msg in self.lib9p_msgs], True
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- if "lib9p/srv.c:srv_util_pathfree" in str(call):
- assert isinstance(self.CONFIG_9P_SRV_MAX_DEPTH, int)
- if len(chain) >= self.CONFIG_9P_SRV_MAX_DEPTH and all(
- ("lib9p/srv.c:srv_util_pathfree" in str(c))
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ ret: dict[BaseName, analyze.SkipModel] = {
+ BaseName("_lib9p_validate"): analyze.SkipModel(
+ 2,
+ self._skipmodel__lib9p_validate_unmarshal_marshal,
+ ),
+ BaseName("_lib9p_unmarshal"): analyze.SkipModel(
+ 2,
+ self._skipmodel__lib9p_validate_unmarshal_marshal,
+ ),
+ BaseName("_lib9p_marshal"): analyze.SkipModel(
+ 2,
+ self._skipmodel__lib9p_validate_unmarshal_marshal,
+ ),
+ }
+ if isinstance(self.CONFIG_9P_SRV_MAX_DEPTH, int):
+ ret[BaseName("srv_util_pathfree")] = analyze.SkipModel(
+ self.CONFIG_9P_SRV_MAX_DEPTH,
+ self._skipmodel_srv_util_pathfree,
+ )
+ return ret
+
+ def _skipmodel__lib9p_validate_unmarshal_marshal(
+ self, chain: typing.Sequence[QName], call: QName
+ ) -> bool:
+ m_caller = re_lib9p_caller.fullmatch(str(chain[-2].base()))
+ assert m_caller
+
+ m_callee = re_lib9p_callee.fullmatch(str(call.base()))
+ if not m_callee:
+ return False
+ return m_caller.group("grp") != m_callee.group("grp")
+
+ def _skipmodel_srv_util_pathfree(
+ self, chain: typing.Sequence[QName], call: QName
+ ) -> bool:
+ assert isinstance(self.CONFIG_9P_SRV_MAX_DEPTH, int)
+ if call.base() == BaseName("srv_util_pathfree"):
+ return len(chain) >= self.CONFIG_9P_SRV_MAX_DEPTH and all(
+ c.base() == BaseName("srv_util_pathfree")
for c in chain[-self.CONFIG_9P_SRV_MAX_DEPTH :]
- ):
- return True
- wrapper = next((c for c in chain if re_lib9p_caller.match(str(c))), None)
- if wrapper:
- m = re_lib9p_caller.match(str(wrapper))
- assert m
- deny = m.group("meth") + "_" + ("R" if m.group("grp") == "T" else "T")
- if str(call.base()).startswith(deny):
- return True
+ )
return False
@@ -408,14 +438,20 @@ class LibMiscPlugin:
) -> tuple[typing.Collection[QName], bool] | None:
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- if (
- len(chain) > 1
- and chain[-1].base() == BaseName("__assert_msg_fail")
- and call.base() == BaseName("__lm_printf")
- and any(c.base() == BaseName("__assert_msg_fail") for c in chain[:-1])
- ):
- return True
+ 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], call: QName
+ ) -> bool:
+ if call.base() in [BaseName("__lm_printf")]:
+ return any(
+ c.base() == BaseName("__assert_msg_fail") for c in reversed(chain[:-1])
+ )
return False
@@ -462,23 +498,45 @@ class PicoFmtPlugin:
return [x.as_qname() for x in self.known_fct.values()], False
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ ret: dict[BaseName, analyze.SkipModel] = {
+ BaseName("_out_rev"): analyze.SkipModel(
+ self.known_out.keys(), self._skipmodel_outcaller
+ ),
+ BaseName("_etoa"): analyze.SkipModel(
+ self.known_out.keys(), self._skipmodel_outcaller
+ ),
+ BaseName("_vsnprintf"): analyze.SkipModel(
+ self.known_out.keys(), self._skipmodel_outcaller
+ ),
+ BaseName("_out_fct"): analyze.SkipModel(
+ self.known_fct.keys(), self._skipmodel__out_fct
+ ),
+ }
+ return ret
+
+ def _skipmodel_outcaller(self, chain: typing.Sequence[QName], call: QName) -> bool:
if call.base() in self.known_out.values():
out: BaseName | None = None
- for pcall in chain:
+ for pcall in reversed(chain):
if pcall.base() in self.known_out:
out = self.known_out[pcall.base()]
- if out == BaseName("_out_buffer") and call.base() == BaseName(
- "_out_null"
- ): # XXX: Gross hack
- out = BaseName("_out_null")
- return call.base() != out
+ if out == BaseName("_out_buffer") and call.base() == BaseName(
+ "_out_null"
+ ): # XXX: Gross hack
+ out = BaseName("_out_null")
+ return call.base() != out
+ return True
+ return False
+
+ def _skipmodel__out_fct(self, chain: typing.Sequence[QName], call: QName) -> bool:
if call.base() in self.known_fct.values():
fct: BaseName | None = None
- for pcall in chain:
+ for pcall in reversed(chain):
if pcall.base() in self.known_fct:
fct = self.known_fct[pcall.base()]
- return call.base() != fct
+ return call.base() != fct
+ return True
return False
@@ -588,8 +646,8 @@ class PicoSDKPlugin:
return self.app_preinit_array, False
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- return False
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ return {}
def extra_nodes(self) -> typing.Collection[Node]:
ret = []
@@ -820,8 +878,8 @@ class TinyUSBDevicePlugin:
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- return False
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ return {}
class NewlibPlugin:
@@ -887,8 +945,8 @@ class NewlibPlugin:
) -> tuple[typing.Collection[QName], bool] | None:
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- return False
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ return {}
class LibGCCPlugin:
@@ -917,5 +975,5 @@ class LibGCCPlugin:
) -> tuple[typing.Collection[QName], bool] | None:
return None
- def skip_call(self, chain: typing.Sequence[QName], call: QName) -> bool:
- return False
+ def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
+ return {}