ci: validate untouched ECX fastcall path
This commit is contained in:
@@ -77,18 +77,27 @@ jobs:
|
||||
if not re.search(r"mov\s+esi,\s*ecx", collector):
|
||||
raise SystemExit("ABI validation failed: collector callback does not consume L from ECX")
|
||||
|
||||
# lua_close is much smaller in B2 because fragment reconstruction is gone.
|
||||
# Zig may preserve ECX in any callee-saved register or a stack slot; do
|
||||
# not require the B1-specific ESI allocation.
|
||||
# B2 lua_close has no helper call before callOriginal: Zig can legally
|
||||
# leave the incoming fastcall ECX untouched and call the trampoline
|
||||
# directly. Accept either explicit preservation or verified no write
|
||||
# to ECX before the first call instruction.
|
||||
close = callback_snippet("6f6ef0", 800)
|
||||
ecx_preserved = re.search(
|
||||
first_call = re.search(r"\bcall\b", close)
|
||||
if not first_call:
|
||||
raise SystemExit("ABI validation failed: lua_close trampoline call missing")
|
||||
before_call = close[:first_call.start()]
|
||||
ecx_saved = re.search(
|
||||
r"(?:mov\s+(?:esi|edi|ebx|ebp|eax|edx),\s*ecx|push\s+ecx|mov\s+(?:dword ptr\s*)?\[[^\]]+\],\s*ecx)",
|
||||
close,
|
||||
before_call,
|
||||
)
|
||||
if not ecx_preserved:
|
||||
ecx_written = re.search(
|
||||
r"\b(?:mov|lea|xor|and|or|add|sub|imul|inc|dec|pop)\s+ecx\b",
|
||||
before_call,
|
||||
)
|
||||
if not ecx_saved and ecx_written:
|
||||
print("lua_close callback snippet:")
|
||||
print(close)
|
||||
raise SystemExit("ABI validation failed: lua_close callback does not preserve L from ECX")
|
||||
raise SystemExit("ABI validation failed: lua_close clobbers incoming ECX before trampoline")
|
||||
|
||||
# Native helper ABI observed directly in WoW 5875:
|
||||
# lua_gc_remove_objects: ECX=L, EDX=&list, stack arg all=0.
|
||||
|
||||
Reference in New Issue
Block a user