summaryrefslogtreecommitdiff
path: root/build-aux/stack.c.gen
diff options
context:
space:
mode:
Diffstat (limited to 'build-aux/stack.c.gen')
-rwxr-xr-xbuild-aux/stack.c.gen81
1 files changed, 51 insertions, 30 deletions
diff --git a/build-aux/stack.c.gen b/build-aux/stack.c.gen
index e327298..af5d740 100755
--- a/build-aux/stack.c.gen
+++ b/build-aux/stack.c.gen
@@ -135,7 +135,7 @@ def analyze(
*,
ci_fnames: list[str],
extra_nodes: list[Node] = [],
- app_func_filters: dict[str, typing.Callable[[str], bool]],
+ 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_skip_call: typing.Callable[[list[str], str], bool],
@@ -289,12 +289,12 @@ def analyze(
nsum = 0
rows: dict[str, int] = {}
for funcname in graph:
- if grp_filter(funcname):
+ if cnt := grp_filter(funcname):
n = nstatic(funcname)
rows[app_location_xform(funcname)] = n
if n > nmax:
nmax = n
- nsum += n
+ nsum += cnt * n
# Figure sizes.
namelen = max([len(k) for k in rows.keys()] + [len(grp_name) + 4])
@@ -314,7 +314,7 @@ def analyze(
for funcname in sorted(missing):
print(f"warning: missing: {funcname}")
for funcname in sorted(dynamic):
- print(f"warning: dynamic: {funcname}")
+ print(f"warning: dynamic-stack-usage: {funcname}")
print("*/")
@@ -431,9 +431,14 @@ def main(
hooks_indirect_callees += [sbc_indirect_callees]
- def sbc_is_thread(name: str) -> bool:
+ def sbc_is_thread(name: str) -> int:
if name.endswith("_cr") and name != "lib9p_srv_read_cr":
- return True
+ if "9p" in name:
+ if "read" in name:
+ return 8
+ elif "write" in name:
+ return 16
+ return 1
if name == "main":
return True
return False
@@ -721,51 +726,67 @@ def main(
# newlib #########################################################
if arg_pico_platform == "rp2040":
+ # This is accurate to
+ # /usr/arm-none-eabi/lib/thumb/v6-m/nofp/libg.a as of
+ # Parabola's arm-none-eabi-newlib 4.5.0.20241231-1.
all_nodes += [
# malloc
- synthetic_node("free", 0), # TODO
- synthetic_node("malloc", 0), # TODO
- synthetic_node("realloc", 0), # TODO
- synthetic_node("aligned_alloc", 0), # TODO
- synthetic_node("reallocarray", 0), # TODO
+ synthetic_node("free", 8, {"_free_r"}),
+ synthetic_node("malloc", 8, {"_malloc_r"}),
+ synthetic_node("realloc", 8, {"_realloc_r"}),
+ synthetic_node("aligned_alloc", 8, {"_memalign_r"}),
+ synthetic_node("reallocarray", 24, {"realloc", "__errno"}),
+ synthetic_node("_free_r", 0), # TODO
+ synthetic_node("_malloc_r", 0), # TODO
+ synthetic_node("_realloc_r", 0), # TODO
+ synthetic_node("_memalign_r", 0), # TODO
# execution
- synthetic_node("abort", 0), # TODO
- synthetic_node("longjmp", 0), # TODO
- synthetic_node("setjmp", 0), # TODO
+ synthetic_node("raise", 16, {"_getpid_r"}),
+ synthetic_node("abort", 8, {"raise", "_exit"}),
+ synthetic_node("longjmp", 0),
+ synthetic_node("setjmp", 0),
# <strings.h>
- synthetic_node("memcmp", 0), # TODO
- synthetic_node("memcpy", 0), # TODO
- synthetic_node("memset", 0), # TODO
- synthetic_node("strcmp", 0), # TODO
- synthetic_node("strlen", 0), # TODO
- synthetic_node("strncpy", 0), # TODO
- synthetic_node("strnlen", 0), # TODO
+ synthetic_node("memcmp", 12),
+ synthetic_node("memcpy", 28),
+ synthetic_node("memset", 20),
+ synthetic_node("strcmp", 16),
+ synthetic_node("strlen", 8),
+ synthetic_node("strncpy", 16),
+ synthetic_node("strnlen", 8),
# other
- synthetic_node("random", 0), # TODO
+ synthetic_node("__errno", 0),
+ synthetic_node("_getpid_r", 8, {"_getpid"}),
+ synthetic_node("random", 8),
]
# libgcc #########################################################
if arg_pico_platform == "rp2040":
+ # This is accurate to
+ # /usr/lib/gcc/arm-none-eabi/14.2.0/thumb/v6-m/nofp/libgcc.a
+ # as of Parabola's arm-none-eabi-gcc 14.2.0-1.
all_nodes += [
- synthetic_node("__aeabi_idiv0", 0), # TODO
- synthetic_node("__aeabi_ldiv0", 0), # TODO
+ synthetic_node("__aeabi_idiv0", 0),
+ synthetic_node("__aeabi_ldiv0", 0),
+ synthetic_node("__aeabi_llsr", 0),
]
# Tie it all together ############################################
- def thread_filter(name: str) -> bool:
+ def thread_filter(name: str) -> int:
return sbc_is_thread(name)
- def intrhandler_filter(name: str) -> bool:
+ def intrhandler_filter(name: str) -> int:
name = name.rsplit(":", 1)[-1]
for hook in hooks_is_intrhandler:
if hook(name):
- return True
- return False
+ return 1
+ return 0
- def misc_filter(name: str) -> bool:
- return name.endswith(":__lm_printf") or name == "__assert_msg_fail"
+ def misc_filter(name: str) -> int:
+ if name.endswith(":__lm_printf") or name == "__assert_msg_fail":
+ return 1
+ return 0
def location_xform(loc: str) -> str:
if not loc.startswith("/"):