commit 622a7ad267120de5326656b4aa68096d41d5c28d
parent 85d6377d5d28913567bfb2226ab1c319717ca399
Author: Jared Tobin <jared@jtobin.io>
Date: Fri, 13 Feb 2026 20:09:57 +0400
fix: make --callers work with --scan-nct --symbol
Previously --callers only affected --list-symbols mode. Now it also
works with NCT scanning to analyze all symbols that can reach the
target rather than all symbols the target can reach.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat:
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/app/Main.hs b/app/Main.hs
@@ -6,14 +6,14 @@ import Audit.AArch64
( AuditResult(..), Violation(..), ViolationReason(..)
, TaintConfig(..)
, NctReason(..), NctFinding(..), nctLine, nctInstr, nctReason
- , LineMap, isGhcRuntimeFinding
- , SymbolScanResult(..)
+ , LineMap, buildLineMap, isGhcRuntimeFinding
+ , SymbolScanResult(..), scanNct
, buildCallGraph, allSymbols, reachableSymbols, reachingSymbols
, symbolExists
, auditFile, auditFileInterProc
, auditFileWithConfig, auditFileInterProcWithConfig
, parseFile, regName, loadTaintConfig
- , scanNctFile, scanNctFileForSymbol
+ , scanNctFile
)
import Audit.AArch64.Parser (parseAsm)
import Audit.AArch64.Types (Instr)
@@ -144,7 +144,7 @@ main = do
else if optScanNct opts
then case optSymbol opts of
Just sym -> do
- result <- scanNctFileForSymbol sym (optInput opts)
+ result <- scanNctForSymbol opts sym
case result of
Left err -> do
TIO.putStrLn $ "Error: " <> err
@@ -264,6 +264,34 @@ listSymbols opts = do
else TIO.putStrLn $ "\n" <> T.pack (show (length filtered))
<> " symbols"
+-- | NCT scan for a symbol (callees or callers based on options).
+scanNctForSymbol :: Options -> Text -> IO (Either Text SymbolScanResult)
+scanNctForSymbol opts rootSym = do
+ bs <- BS.readFile (optInput opts)
+ case decodeUtf8' bs of
+ Left err -> pure (Left (T.pack (show err)))
+ Right src ->
+ case parseAsm src of
+ Left _ -> pure (Left "parse failed")
+ Right lns -> do
+ let cg = buildCallGraph lns
+ if not (symbolExists rootSym cg)
+ then pure (Left ("symbol not found: " <> rootSym))
+ else do
+ let syms = if optCallers opts
+ then reachingSymbols rootSym cg
+ else reachableSymbols rootSym cg
+ lineMap = buildLineMap lns
+ allFindings = scanNct lns
+ filtered = Map.filterWithKey
+ (\sym _ -> Set.member sym syms) allFindings
+ pure $ Right $ SymbolScanResult
+ { ssrRootSymbol = rootSym
+ , ssrReachable = Set.size syms
+ , ssrLineMap = lineMap
+ , ssrFindings = filtered
+ }
+
-- | Output NCT scan results for a specific symbol and its callees.
outputNctSymbol :: Options -> SymbolScanResult -> IO ()
outputNctSymbol opts ssr = do