1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
# 05 — Ghidra bridge
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
Ghidra answers *what is the code*; green-eye answers *what did it do*. The
bridge joins them in both directions: Ghidra symbols into the runtime session,
runtime hit addresses back into the Ghidra project.
## 1. Address conventions (read this first)
| Space | Meaning | Transformation |
|---|---|---|
| file vaddr | offset in the binary (`libcuda+0x…`) | base |
| Ghidra program addr | what the decompiler shows | file vaddr + image base (`0x100000` for libcuda) |
| runtime addr | live process / emulator address | file vaddr + load bias |
* Firmware linked at its load address: bias 0 (the demo, and a
relocated-to-RAM GSP image when using the probe bias).
* CUDA `libcuda` in the host oracle: runtime base from `/proc/<pid>/maps`;
`--bias` normalises it if you want runtime addresses in the DB.
* The project's `decompiled_index.tsv`/bucket TSVs carry **both** program and
file addresses; green-eye parses both and stores the program address in
`symbol.extras["program_addr"]`.
## 2. Build a symbol DB from Ghidra exports
```bash
./greeneye.sh symbols export \
--names ../../userspace/cuda/570.144/annotations/names.tsv \
--index ../../userspace/cuda/570.144/run/analysis/decompiled/decompiled_index.tsv \
--exports ../../userspace/cuda/570.144/run/analysis/elf-index/exports.tsv \
--callgraph ../../userspace/cuda/570.144/run/analysis/elf-index/callgraph.tsv \
--bias 0 -o symbols-cuda.json
```
For the GSP firmware project (`tools/ghidra/gsp-fwimage-570.144/`), first run
the existing export scripts (`ExportFunctionIndex.java`,
`DecompileFunctions.java`, …) to produce TSVs, then:
```bash
./greeneye.sh symbols export --index <export.tsv> --bias 0 -o symbols-gsp.json
```
`load_index_tsv` is column-aware: it accepts
`<program>\t<file>\t<size>\t<name>\t<bucket>\t<line>\t<status>`, the 4-column
exports form, or a plain `<addr>\t<name>` two-column form.
## 3. Runtime addresses in the session
```python
db = SymbolDB()
db.load_json("symbols-cuda.json")
db.load_names_tsv("names.tsv", bias=runtime_base - file_base)
s.symbols = db # or pass symbols= to attach()/launch()
```
`resolve()` then annotates every hit with the Ghidra name, and
`greeneye.ghidra.corpus_location(symbol, corpus_root)` returns
`<bucket>:<line>` when the index carried that information — the pointer from a
live hit to the decompiled body.
## 4. Annotate hits back into Ghidra
```bash
./greeneye.sh analyze dumps/<run> --symbols symbols-gsp.json --out run.md
python3 - <<'PY'
from greeneye.ghidra import export_hits
from greeneye.symbols import SymbolDB
db = SymbolDB(); db.load_json("symbols-gsp.json")
print(export_hits("dumps/<run>", "greeneye_hits.tsv", symbols=db))
PY
```
`greeneye_hits.tsv` is `addr<TAB>hits<TAB>symbol<TAB>annotation`. Then run the
bundled Java script in Ghidra headless:
```bash
$GHIDRA/support/analyzeHeadless <proj_dir> <project> -process <program> -noanalysis \
-scriptPath debug/risc-v-gsp-rm-vm/ghidra \
-postScript MarkGreenEyeHits.java /abs/path/greeneye_hits.tsv
```
`ExportForGreenEye.java` is the reverse helper: it walks the current program
and writes a green-eye-compatible `addr<TAB>name<TAB>size` TSV.
## 5. Breakpoints from Ghidra
Two practical routes today:
1. `greeneye decompose/decompile` → note the file vaddr → script
`s.hook("0x…")` (green-eye translates to runtime via the bias you loaded).
2. Use `symbols export` from the Ghidra index, then `s.hook("<name>")` by
name — the most robust route across recompilations.
A future Ghidra-side green-eye console (roadmap item) can call
`greeneye` through its CLI to set breakpoints directly from the tool.
## 6. Limits
* Wrapper-generated functions are re-laid-out between driver patch versions;
transfer names, never raw wrapper addresses (the CUDA playbook's lesson).
* The decompiler does not recover struct types; structure schemas for
green-eye decoding must be written or exported separately.
* `decompiled_index.tsv` buckets are large and gitignored; keep symbol JSONs
small (name/size/subsystem only) if they must be tracked.
|