From f874d709e5a45d63c8ee9ab6b0300195aa5d20a5 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 23 Sep 2026 12:11:04 -0400 Subject: userspace/cuda: add CUDA userspace driver analysis, tooling and name maps Add the analysis of the NVIDIA CUDA userspace driver used by Open-IOV VMs: * docs/01-08: architecture (layers, object model, threads, sync, memory, channels, launch), build and execution model, the driver/kernel/GPU interface contract, virtualization approaches, the 570.144 decompilation map with the corrected libcuda crash path and the current engine-topology blocker, tooling, and a version-upgrade playbook. * tools/: version-agnostic toolchain - stdlib ELF/interface toolkit (exports, unwind-table function map, wrapper resolution, version delta, crash address decode), callgraph walker, corpus annotator, and Ghidra analysis/decompilation/name-map scripts with resumable parallel drivers. * 570.144/annotations/: our name map (exports + resolved wrappers + verified internals) and subsystem index, tracked so naming work accumulates. * READ-ME-FIRST.md: reading guide with the fast lookup recipes. The full decompiled corpus and annotated corpus stay untracked (vendor- derived, gitignored under the version run/ tree). --- userspace/cuda/tools/ghidra_batch_decompile.sh | 83 ++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 userspace/cuda/tools/ghidra_batch_decompile.sh (limited to 'userspace/cuda/tools/ghidra_batch_decompile.sh') diff --git a/userspace/cuda/tools/ghidra_batch_decompile.sh b/userspace/cuda/tools/ghidra_batch_decompile.sh new file mode 100755 index 0000000..bce8cb9 --- /dev/null +++ b/userspace/cuda/tools/ghidra_batch_decompile.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# SPDX-License-Identifier: BSD-3-Clause +# +# ghidra_batch_decompile.sh - decompile the whole code range of an analyzed +# CUDA program in parallel. Chunks already present are skipped, so the command +# is safe to re-run and to interrupt. +# +# Ghidra takes an exclusive project lock even in -readOnly mode, so a single +# project cannot be opened by several processes. To parallelize, this script +# makes one copy of the analyzed project per worker under /wk/ and +# round-robins the chunks across the copies. Copies are kept (they make +# resuming cheap) and can be removed with: rm -rf /wk +# +# Usage: +# ghidra_batch_decompile.sh \ +# [chunk_size_hex] [jobs] [timeout_s] +# +# Defaults: chunk 0x100000, jobs 5, timeout 120. +# env: GHIDRA_HOME, GHIDRA_HEADLESS_MAXMEM (default 4G for batch jobs), MAX_CPU +# +# After it completes, merge per-chunk indexes with: +# ghidra_index_merge.sh +set -euo pipefail + +HERE="$(cd "$(dirname "$0")" && pwd)" +GHIDRA_HOME="${GHIDRA_HOME:-/snap/ghidra/current/ghidra}" +ANALYZE="$GHIDRA_HOME/support/analyzeHeadless" +export GHIDRA_HEADLESS_MAXMEM="${GHIDRA_HEADLESS_MAXMEM:-4G}" + +PROJECT_DIR="${1:?usage: $0 [chunk_hex] [jobs] [timeout_s]}" +PROJECT_NAME="${2:?}" +PROGRAM="${3:?}" +OUTDIR="${4:?}" +START="${5:?}" +END="${6:?}" +CHUNK="${7:-0x100000}" +JOBS="${8:-5}" +TIMEOUT="${9:-120}" + +mkdir -p "$OUTDIR/buckets" "$OUTDIR/index" "$OUTDIR/logs" "$OUTDIR/wk" + +START_D=$((START)); END_D=$((END)); CHUNK_D=$((CHUNK)) + +# Build the chunk list first: every chunk gets its OWN project copy, so two +# concurrent jobs can never race on the same Ghidra project lock. +ranges="" +n=0 +for ((a=START_D; a "$log" 2>&1 || { echo "[FAIL] $a-$b (see $log)"; exit 1; } + tail -1 "$log" +' _ + +echo "[ok] batch decompilation done -> $OUTDIR/buckets" +echo " merge indexes: $HERE/ghidra_index_merge.sh $OUTDIR" -- cgit v1.2.3