a6af8b3cd2
Phase 6 chose match targets by eye from the boundary inventory. tools/sf3_triage now ranks every eligible candidate by (tier, size, address) from tracked inputs alone and records why everything else was excluded. Eligibility: an exact or fallthrough extent, a non-degenerate body, not already registered, not the header entry, not named by --exclude. indirect, escape, outside, runaway, contained and standalone are excluded and counted. Tiers: 0 duplicate-group representative (one match, several addresses), 1 exact leaf (no cross-references, so no symbol rows), 2 exact non-leaf, 3 fallthrough. Result: 1916 listed (tier 0: 9, tier 1: 509, tier 2: 1394, tier 3: 4), with 252 degenerate bodies, 88 low-confidence grades, 12 registered, 1 header entry and 2 named near-misses excluded. The nine tier-0 entries are the real duplicate groups: matching those nine bodies registers 22 function addresses. The two deferred near-misses are excluded by name in the Makefile so the exclusion stays visible rather than buried in the tool. 160 synthetic tests pass.
139 lines
4.8 KiB
Makefile
139 lines
4.8 KiB
Makefile
# Phase 3 all-assembly baseline orchestration.
|
|
# All original and generated ROM-derived inputs/outputs remain ignored.
|
|
|
|
SHELL := /usr/bin/bash
|
|
|
|
EXE := extracted/SCUS_946.40;1
|
|
MANIFEST := extracted/MANIFEST.tsv
|
|
SPLAT := tools/splat/.venv/bin/splat
|
|
AS := tools/mipsel-none-elf-binutils/prefix/usr/bin/mipsel-none-elf-as
|
|
LD := tools/mipsel-none-elf-binutils/prefix/usr/bin/mipsel-none-elf-ld
|
|
OBJCOPY := tools/mipsel-none-elf-binutils/prefix/usr/bin/mipsel-none-elf-objcopy
|
|
|
|
ASM_ROOT := asm
|
|
SPLAT_CONFIG := $(ASM_ROOT)/scus_946_40.yaml
|
|
SPLAT_OUTPUT := $(ASM_ROOT)/generated
|
|
LINKER_SCRIPT := $(ASM_ROOT)/scus_946_40.ld
|
|
BUILD := build
|
|
ELF := $(BUILD)/scus_946_40.elf
|
|
REBUILT := $(BUILD)/scus_946_40.rebuilt
|
|
INPUT_REPORT := .run/p3-exe-info.tsv
|
|
|
|
# Phase 5 ordered code build: C regions listed in the tracked registry are
|
|
# compiled with the identified toolchain and linked in address order between
|
|
# data fallbacks taken from the original executable. An empty registry
|
|
# reproduces the all-payload data baseline exactly.
|
|
REGIONS := config/regions.tsv
|
|
SYMBOLS := config/symbols.tsv
|
|
INVENTORY := config/function_inventory.tsv
|
|
EXTENTS := config/function_extents.tsv
|
|
DUPES := config/duplicate_bodies.tsv
|
|
WORKLIST := config/match_worklist.tsv
|
|
MATCH := tools/sf3_match
|
|
EXTENTS_TOOL := tools/sf3_extents
|
|
DUPES_TOOL := tools/sf3_dupes
|
|
TRIAGE_TOOL := tools/sf3_triage
|
|
CODE_OUT := build/code
|
|
EXPECTED_SHA1 := e173426c157384ebf1b6caf8c6fea18a85a14af9
|
|
|
|
.PHONY: all validate split assemble link binary code gate extents extents-verify dupes worklist test check clean
|
|
|
|
all: binary
|
|
|
|
validate:
|
|
@test -f "$(EXE)"
|
|
@test -f "$(MANIFEST)"
|
|
@mkdir -p .run
|
|
@./tools/sf3_extract psx-exe-info "$(EXE)" "$(MANIFEST)" > "$(INPUT_REPORT)"
|
|
|
|
split: validate
|
|
@test -f "$(SPLAT)"
|
|
@test -f "$(SPLAT_CONFIG)"
|
|
@cd "$(ASM_ROOT)" && ../"$(SPLAT)" split "$$(basename "$(SPLAT_CONFIG)")" --disassemble-all
|
|
|
|
assemble: split
|
|
@test -d "$(SPLAT_OUTPUT)" && test ! -L "$(SPLAT_OUTPUT)"
|
|
@test -f "$(AS)"
|
|
@test ! -L "$(BUILD)"
|
|
@mkdir -p "$(BUILD)"
|
|
@while IFS= read -r source; do \
|
|
rel="$${source#$(ASM_ROOT)/}"; \
|
|
object="$(BUILD)/$${rel}.o"; \
|
|
mkdir -p "$$(dirname "$$object")"; \
|
|
"$(AS)" -march=r3000 -G0 -I "$(ASM_ROOT)/include" -o "$$object" "$$source"; \
|
|
done < <(find "$(SPLAT_OUTPUT)" -type f -name '*.s' -print | sort)
|
|
|
|
link: assemble
|
|
@test -f "$(LINKER_SCRIPT)"
|
|
@test -f "$(LD)"
|
|
@rm -f "$(ELF)"
|
|
@"$(LD)" -T "$(LINKER_SCRIPT)" -o "$(ELF)"
|
|
|
|
binary: link
|
|
@test -f "$(OBJCOPY)"
|
|
@rm -f "$(REBUILT)"
|
|
@"$(OBJCOPY)" -O binary "$(ELF)" "$(REBUILT)"
|
|
|
|
# Ordered code build and full-binary gate (Phase 5). `code` builds only;
|
|
# `gate` builds and then requires the whole executable to be byte-identical.
|
|
code: validate
|
|
@test -f "$(MATCH)"
|
|
@test -f "$(REGIONS)"
|
|
@test -f "$(SYMBOLS)"
|
|
@rm -rf "$(CODE_OUT)"
|
|
@"$(MATCH)" build --exe "$(EXE)" --regions "$(REGIONS)" --symbols "$(SYMBOLS)" --out "$(CODE_OUT)"
|
|
|
|
gate: validate
|
|
@test -f "$(MATCH)"
|
|
@test -f "$(REGIONS)"
|
|
@test -f "$(SYMBOLS)"
|
|
@rm -rf "$(CODE_OUT)"
|
|
@"$(MATCH)" gate --exe "$(EXE)" --regions "$(REGIONS)" --symbols "$(SYMBOLS)" --out "$(CODE_OUT)" \
|
|
--expect-sha1 "$(EXPECTED_SHA1)"
|
|
|
|
# Function extents (Phase 7). `extents` regenerates the tracked table from the
|
|
# inventory; `extents-verify` re-derives it and requires every registered region
|
|
# to agree, so a region can never silently disagree with the derived extent.
|
|
extents: validate
|
|
@test -f "$(EXTENTS_TOOL)"
|
|
@test -f "$(INVENTORY)"
|
|
@"$(EXTENTS_TOOL)" scan --exe "$(EXE)" --inventory "$(INVENTORY)" --out "$(EXTENTS)" --force
|
|
|
|
extents-verify: validate
|
|
@test -f "$(EXTENTS_TOOL)"
|
|
@test -f "$(INVENTORY)"
|
|
@test -f "$(EXTENTS)"
|
|
@"$(EXTENTS_TOOL)" verify --exe "$(EXE)" --inventory "$(INVENTORY)" \
|
|
--extents "$(EXTENTS)" --regions "$(REGIONS)"
|
|
|
|
# Duplicate-body census (Phase 7): groups byte-identical bodies so a shared body
|
|
# is matched once and registered once per address.
|
|
dupes: validate
|
|
@test -f "$(DUPES_TOOL)"
|
|
@test -f "$(EXTENTS)"
|
|
@"$(DUPES_TOOL)" census --exe "$(EXE)" --extents "$(EXTENTS)" --out "$(DUPES)" --force
|
|
|
|
# Ranked match worklist (Phase 7). The two --exclude addresses are the recorded
|
|
# near-misses deferred by developer direction in Phase 7; naming them here keeps
|
|
# the exclusion visible instead of burying it in the tool.
|
|
worklist: validate
|
|
@test -f "$(TRIAGE_TOOL)"
|
|
@test -f "$(EXTENTS)"
|
|
@test -f "$(DUPES)"
|
|
@"$(TRIAGE_TOOL)" plan --exe "$(EXE)" --extents "$(EXTENTS)" --inventory "$(INVENTORY)" \
|
|
--census "$(DUPES)" --regions "$(REGIONS)" \
|
|
--exclude 0x8005DEF8 --exclude 0x800F3160 --out "$(WORKLIST)" --force
|
|
|
|
# Verification gates. `test` is synthetic-only and needs no game input;
|
|
# `check` adds the extents check and the full-binary byte gate (which do).
|
|
test:
|
|
@PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tools/tests
|
|
|
|
check: test extents-verify gate
|
|
|
|
clean:
|
|
@if test -e "$(BUILD)"; then \
|
|
test -d "$(BUILD)" && test ! -L "$(BUILD)"; \
|
|
rm -rf "$(BUILD)"; \
|
|
fi
|