From 8aaf5d60aa0b3ddb05e117f52c0e30ec246b7aad Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 17 Jan 2025 10:39:49 +0100 Subject: tools/syz-declextract: support function scopes Extract info about function scopes formed by switch'es on function arguments. For example if we have: void foo(..., int cmd, ...) { ... switch (cmd) { case FOO: ... block 1 ... case BAR: ... block 2 ... } ... } We record that any data flow within block 1 is only relevant when foo's arg cmd has value FOO, similarly for block 2 and BAR. This allows to do 3 things: 1. Locate ioctl commands that are switched on within transitively called functions. 2. Infer return value for each ioctl command. 3. Infer argument type when it's not specified in _IO macro. This will also allow to infer other multiplexed syscalls. Descriptions generated on Linux commit c4b9570cfb63501. --- pkg/declextract/interface.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'pkg/declextract/interface.go') diff --git a/pkg/declextract/interface.go b/pkg/declextract/interface.go index b5c8ea5ac..d891b4899 100644 --- a/pkg/declextract/interface.go +++ b/pkg/declextract/interface.go @@ -59,15 +59,16 @@ func (ctx *context) processFunctions() { } nocallers := 0 for _, fn := range ctx.Functions { - for _, callee := range fn.Calls { - called := ctx.findFunc(callee, fn.File) - if called == nil || called == fn { - continue + for _, scope := range fn.Scopes { + for _, callee := range scope.Calls { + called := ctx.findFunc(callee, fn.File) + if called == nil || called == fn { + continue + } + fn.calls = append(fn.calls, called) + called.callers++ } - fn.calls = append(fn.calls, called) - called.callers++ } - fn.Calls = nil if len(fn.calls) == 0 { nocallers++ } @@ -84,7 +85,9 @@ func (ctx *context) reachableLOC(name, file string) int { ctx.collectRachable(fn, reachable) loc := 0 for fn := range reachable { - loc += fn.LOC + for _, scope := range fn.Scopes { + loc += scope.LOC + } } return loc } -- cgit mrf-deployment