diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-03-01 14:53:58 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-03-01 17:25:04 -0700 |
commit | 6fedfe71cfab86aecf4168ecf35961bf88ce0438 (patch) | |
tree | 0c1d961f46881a8fb1bf46b23fdb2c927624309a /build-aux | |
parent | 902a7661cfed71b1f50aa95bac9345883cb435cc (diff) |
lint-bin: (dry-run) lint that list of functions matches stack.c.gen
Diffstat (limited to 'build-aux')
-rwxr-xr-x | build-aux/lint-bin | 40 | ||||
-rwxr-xr-x | build-aux/stack.c.gen | 13 |
2 files changed, 52 insertions, 1 deletions
diff --git a/build-aux/lint-bin b/build-aux/lint-bin index ffc2a12..0b955de 100755 --- a/build-aux/lint-bin +++ b/build-aux/lint-bin @@ -18,6 +18,15 @@ shopt -s extglob # Textual info: # - ${elf%.elf}.dis : `objdump --section-headers ${elf}; objdump --disassemble ${elf}; picotool coprodis --quiet ${elf}` # - ${elf}.map : `ld --print-map` info +# - ${elf%.elf}_stack.c : `stack.c.gen` + +RED=$(tput setaf 1) +RESET=$(tput sgr0) + +err() { + printf "${RED}%s${RESET}: %s\n" "$1" "$2" >&2 + #r=1 +} # Input is `ld --print-map` format. # @@ -27,6 +36,14 @@ objdump_globals() { sed -E -n '/^ \.t?(data|bss)\./{ / 0x/{ p; D; }; N; s/\n/ /; p; }' <"$1" } +readelf_funcs() { + local in_elffile + in_elffile=$1 + + readelf --syms --wide -- "$in_elffile" | + awk '$4 == "FUNC" { print $8 }' +} + lint_globals() { local in_mapfile in_mapfile=$1 @@ -72,14 +89,37 @@ lint_globals() { } | column -t } +lint_stack() { + local in_elffile + in_elffile=$1 + + IFS='' + while read -r line; do + func=${line#$'\t'} + if [[ $line == $'\t'* ]]; then + err "$in_elffile" "function in binary but not _stack.c: ${func}" + else + err "$in_elffile" "function in _stack.c but not binary: ${func}" + fi + done < <( + comm -3 \ + <(sed -En 's/^included: (.*:)?//p' "${in_elffile%.elf}_stack.c" | sort -u) \ + <(readelf_funcs "$in_elffile" | sed 's/\.part\.[0-9]*$//' | sort -u)) +} + main() { + r=0 + local elf for elf in "$@"; do { echo 'Global variables:' lint_globals "${elf}.map" | sed 's/^/ /' } > "${elf%.elf}.lint.globals" + lint_stack "$elf" &> "${elf%.elf}.lint.stack" done + + return $r } main "$@" diff --git a/build-aux/stack.c.gen b/build-aux/stack.c.gen index f851afe..2965c00 100755 --- a/build-aux/stack.c.gen +++ b/build-aux/stack.c.gen @@ -142,6 +142,8 @@ class AnalyzeResult(typing.NamedTuple): missing: set[str] dynamic: set[str] + included_funcs: set[str] + class Application(typing.Protocol): def extra_nodes(self) -> typing.Collection[Node]: ... @@ -246,6 +248,7 @@ def analyze( missing: set[str] = set() dynamic: set[str] = set() + included_funcs: set[str] = set() dbg = False @@ -288,6 +291,7 @@ def analyze( print(f"//dbg: {funcname}\t{node.nstatic}") if node.usage_kind == "dynamic" or node.ndynamic > 0: dynamic.add(app.location_xform(funcname)) + included_funcs.add(funcname) return node.nstatic + max( [ 0, @@ -312,7 +316,9 @@ def analyze( nsum += cnt * n groups[grp_name] = AnalyzeResultGroup(rows=rows, nmax=nmax, nsum=nsum) - return AnalyzeResult(groups=groups, missing=missing, dynamic=dynamic) + return AnalyzeResult( + groups=groups, missing=missing, dynamic=dynamic, included_funcs=included_funcs + ) ################################################################################ @@ -1094,6 +1100,11 @@ def main( print(f"warning: dynamic-stack-usage: {funcname}") print("*/") + print("") + print("/*") + for funcname in sorted(result.included_funcs): + print(f"included: {funcname}") + print("*/") if __name__ == "__main__": |