gen_addresses: per-lane fragment dir; duplicate names are a hard error
This commit is contained in:
parent
0d84eb2d4c
commit
9834b3d175
2 changed files with 33 additions and 1 deletions
18
ghidra/addresses.d/README.md
Normal file
18
ghidra/addresses.d/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Per-lane address fragments
|
||||
|
||||
`addresses.json` is a single shared file. When several lanes run concurrently they edit the
|
||||
same lines, and three times on 2026-09-08 one lane's `git add` swept another's in-flight
|
||||
entries into the wrong commit. Nothing was lost, but authorship and atomicity were.
|
||||
|
||||
A lane may instead drop its own file here:
|
||||
|
||||
```json
|
||||
{ "entries": [ { "name": "...", "addr": "0x...", "convention": "...",
|
||||
"prototype": "...", "status": "verified", "source": "findings/..." } ] }
|
||||
```
|
||||
|
||||
Name it after the lane (`lane-d.json`). `tools/gen_addresses.py` merges every fragment in
|
||||
sorted order after `addresses.json`. A **duplicate name across files is a hard error**, not
|
||||
last-wins — two lanes disagreeing about an address is exactly the thing we must not paper over.
|
||||
|
||||
The integrator folds fragments back into `addresses.json` once the lane's work is merged.
|
||||
|
|
@ -1,10 +1,24 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Emit include/generated/sots_addresses.h for sots-engine from ghidra/addresses.json.
|
||||
Only facts (name, RVA, convention, prototype, status) — never decompiler text."""
|
||||
import json, os, subprocess, sys, datetime
|
||||
import glob, json, os, subprocess, sys, datetime
|
||||
root = os.path.join(os.path.dirname(__file__), "..")
|
||||
j = json.load(open(os.path.join(root, "ghidra", "addresses.json")))
|
||||
base = int(j["image_base"], 16)
|
||||
|
||||
# Per-lane fragments. addresses.json is a single shared file, so concurrent lanes kept
|
||||
# sweeping each other's in-flight entries into the wrong commit. A lane may instead write
|
||||
# ghidra/addresses.d/<lane>.json ({"entries": [...]}) — its own file, no shared-line edits.
|
||||
# Fragments are merged here in sorted order; a duplicate name is an error, not a silent
|
||||
# last-wins, because two lanes disagreeing about an address is exactly what we must not paper over.
|
||||
seen = {e["name"]: "addresses.json" for e in j["entries"]}
|
||||
for frag_path in sorted(glob.glob(os.path.join(root, "ghidra", "addresses.d", "*.json"))):
|
||||
frag_name = os.path.basename(frag_path)
|
||||
for e in json.load(open(frag_path))["entries"]:
|
||||
if e["name"] in seen:
|
||||
sys.exit(f"duplicate address entry {e['name']!r}: in {seen[e['name']]} and {frag_name}")
|
||||
seen[e["name"]] = frag_name
|
||||
j["entries"].append(e)
|
||||
try: rev = subprocess.check_output(["git","-C",root,"rev-parse","--short","HEAD"]).decode().strip()
|
||||
except Exception: rev = "unknown"
|
||||
out = [ "// GENERATED — do not edit. Facts about Sword of the Stars.exe (GOG 1.8.1).",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue