Skip to content

v0.0.189

Choose a tag to compare

@github-actions github-actions released this 18 Sep 16:04
· 72 commits to main since this release

rePIU v0.0.189

이전 릴리스 v0.0.188 이후의 변경입니다. Linux x64에서 pumpit2a가 텍스처가 입혀진
화면을 그리게 됐고, 선택 옵션을 켜면 게임 시계가 흐르며 장면이 진행합니다.
Windows
동작은 그대로입니다(두 곳의 공용 수정은 아래에 따로 적었습니다).

Linux x64: 어디까지 왔나

v0.0.188 v0.0.189
Glide 초기화 → 렌더 루프 도달 도달
텍스처 업로드 건너뜀 Win32와 같은 gate 96개
부동소수점 signal 복귀 뒤 전부 NaN 정상
렌더 단계 게임 시계 멈춤 기본값: 멈춤 / 옵션 켜면 흐름
옵션 켠 90초 실행 — 폴트 0, 3,913프레임, 장면 진행

렌더 단계 시계를 살리는 옵션은 REPIU_LINUX_X64_SAFE_POINT_INJECTION입니다. 값과 관계없이
변수가 있으면 켜집니다
(=0도 켜짐). 다음 릴리스에서 기본값으로 켤 예정입니다.

고친 것

실행 재진입과 인터럽트 (Tasks 702–705)

  • Glide gate와 타이머 체인 경계 뒤 AOT 코드로 다시 들어갑니다. 전에는 경계 뒤 PUSH·
    CALL이 host 스택에서 실행돼 게스트 스택에서 사라졌습니다.
  • INT 8 주입 frame에 게스트 선택자를 넣고, ISR의 IRETD를 HLE로 처리합니다.
  • 아무것도 바꾸지 않은 스레드 인터럽트가 host R15(게스트 ESP)를 32비트 값으로 덮던
    문제를 고쳤습니다.

CPU 상태와 코드 방출 (Tasks 707, 710, 713, 716)

  • x87 tag word — signal 복귀마다 모든 FPU 레지스터가 "비어 있지 않음"이 되어 이후
    연산이 전부 NaN이었습니다.
  • 상위 바이트 lowering — mov dh,[esp] 같은 명령의 첫 바이트가 DL을 저장하는 대신
    덮어써 EDX가 깨졌고, 그 결과 glEnable(GL_TEXTURE_2D)가 실패해 텍스처가 통째로
    생략됐습니다.
  • long-mode 경로에 timer safe point(1,067곳)를 심습니다.
  • CS: override 데이터 접근(mov al, cs:[edx+table])을 복사로 방출합니다. 전에는 x64에
    처리기가 없는 HLE boundary였습니다.

세그먼트 fold (Tasks 711, 712, 717)

  • loader의 초기 스택 선택자(0x0034)와 데이터 선택자(0x0024)를 명시적으로 쓰는
    override는 어느 세그먼트 레지스터에서든 base 0으로 계산합니다. 게스트의 암묵적
    접근은 원래 flat이기 때문입니다.
    • SS: Watcom lseek가 스택 밖에 써서 PIU.BIN을 110만 번 읽던 문제
    • ES: sprintf("%d")가 텍스처 픽셀을 숫자로 복사해 스택과 힙을 덮던 문제

Glide LFB (Task 708) — LFB 버퍼 주소를 host 포인터에서 32비트로 잘라 넘기던 것을,
게스트가 가리킬 수 있는 4GiB 아래 공용 예약(ReserveLowAddressMemory)으로 옮겼습니다.

Windows에도 적용되는 공용 수정

  • SS fold(Task 712) — Windows에서도 PIU.BIN을 처음으로 바르게 읽게 됐습니다.
  • 데이터 선택자 fold(Task 717) — 30초 실행의 시계·safe point·세그먼트 수치가 잡음
    범위 안이었습니다.
  • Windows x86 빌드가 Linux 전용 telemetry 소스를 더 이상 컴파일하지 않습니다(Task 706).

새 진단 (설정하지 않으면 동작 없음)

변수 / 출력 내용
REPIU_LIVE_GUEST_PEEK=<offset>[,n] 매초 게스트 dword 최대 16개 기록
REPIU_LIVE_GUEST_SCAN=<offset>,<bytes>,<dword> 범위 안 dword 개수와 연속 구간
REPIU_LINUX_X64_DATA_WATCH=<address> Linux 하드웨어 쓰기 감시점(기록 후 계속 실행)
[repiu-fault-stack] Linux 처리되지 않은 폴트 뒤 게스트 스택 64 dword
최종 실행 보고 회수가 거절된 종료 경로에서도 요약 출력(Task 709)

알려진 것

  • 주입이 꺼진 기본값에서는 렌더 단계부터 게임 시계가 멈춥니다(17초 무렵).
  • 게스트가 세그먼트 레지스터를 읽을 때 두 host가 다른 값을 돌려줍니다(Windows 0x2B,
    Linux 0x0024). fold에서는 같게 취급하지만 값 자체는 다릅니다.
  • Linux 측정은 WSLg에서 했습니다. 실제 ext4 Ubuntu 검증은 하지 않았습니다.

검증: Linux x64 core probe 30/30, Windows x86 core probe 28/28, 두 host의 30초 실행 비교,
Linux 90초 실행.


rePIU v0.0.189

Changes since v0.0.188. On Linux x64, pumpit2a now draws textured frames, and with an
opt-in setting the game clock runs and the scenes advance.
Windows behaviour is unchanged
apart from two shared fixes listed separately below.

Where Linux x64 stands

v0.0.188 v0.0.189
Glide init → render loop reached reached
Texture upload skipped the same 96 gates as Win32
Floating point all NaN after a signal return correct
Game clock in the render phase stops default: stops / opt-in: runs
90-second run, opt-in on — no faults, 3,913 frames, scenes advance

The setting that keeps the clock running is REPIU_LINUX_X64_SAFE_POINT_INJECTION. It is on
whenever the variable exists, whatever its value
(=0 turns it on). The next release is
expected to make it the default.

Fixed

Re-entry and interrupts (Tasks 702–705)

  • Execution re-enters AOT code after Glide gates and timer-chain boundaries. Before, a PUSH or
    CALL after the boundary ran on the host stack and vanished from the guest's.
  • INT 8 injection frames carry the guest selector, and the ISR's IRETD is handled by HLE.
  • A thread interrupt that changed nothing no longer overwrites host R15 (guest ESP) with a
    32-bit value.

CPU state and emission (Tasks 707, 710, 713, 716)

  • x87 tag word: every signal return marked all FPU registers non-empty, so everything after
    it was NaN.
  • High-byte lowering: the first byte of the lowering for mov dh,[esp] and the like
    overwrote DL instead of saving it, corrupting EDX; glEnable(GL_TEXTURE_2D) then failed and
    textures were skipped altogether.
  • Timer safe points (1,067 sites) are planted on the long-mode path.
  • CS: override data accesses (mov al, cs:[edx+table]) are emitted as copies; before, they
    were HLE boundaries nothing on x64 handled.

Segment folds (Tasks 711, 712, 717)

  • An override naming the loader's initial stack selector (0x0034) or data selector (0x0024)
    now folds base 0 in any segment register, because the guest's implicit accesses are flat.
    • SS: Watcom lseek wrote outside the stack and PIU.BIN was read 1.1 million times.
    • ES: sprintf("%d") copied texture pixels as a number and overwrote the stack and heap.

Glide LFB (Task 708): the LFB buffer address was a host pointer truncated to 32 bits; the
buffer now sits in the shared below-4 GiB reservation (ReserveLowAddressMemory) where the guest
can address it.

Shared fixes that also apply to Windows

  • SS fold (Task 712): Windows now reads PIU.BIN correctly for the first time.
  • Data selector fold (Task 717): clock, safe-point and segment figures of a 30-second run
    stayed within noise.
  • The Windows x86 build no longer compiles the Linux-only telemetry source (Task 706).

New diagnostics (inert when unset)

Variable / output What it does
REPIU_LIVE_GUEST_PEEK=<offset>[,n] logs up to 16 guest dwords each second
REPIU_LIVE_GUEST_SCAN=<offset>,<bytes>,<dword> counts a dword in a range and lists its runs
REPIU_LINUX_X64_DATA_WATCH=<address> Linux hardware write watchpoint, logged and resumed
[repiu-fault-stack] 64 guest stack dwords after an unhandled Linux fault
Final execution report printed on the refused-recovery exit path as well (Task 709)

Known

  • With injection off (the default) the game clock stops once rendering starts, around 17 s.
  • The two hosts return different values when the guest reads a segment register (Windows
    0x2B, Linux 0x0024). The folds treat them alike; the values still differ.
  • Linux figures were measured under WSLg, not on a native ext4 Ubuntu install.

Verified by Linux x64 core probe 30/30, Windows x86 core probe 28/28, 30-second runs compared on
both hosts, and a 90-second Linux run.