From 6b2ef0690c3e39a28ae95d4e95ccf1ed5116b5b1 Mon Sep 17 00:00:00 2001 From: opencode Date: Fri, 13 Nov 2026 09:20:18 +0000 Subject: [PATCH] docs(gui): correct XMapWindow and name 0x3FD645B0 XRaiseWindow --- dwt/gui/trace_accept.lua | 5 +++-- dwt/gui/xhello.asm | 8 +++++--- dwt/gui/xtext.asm | 12 +++++++----- dwt/notes/CROSS.md | 3 ++- dwt/notes/GUI_APPS.md | 32 ++++++++++++++++++++++++++++---- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/dwt/gui/trace_accept.lua b/dwt/gui/trace_accept.lua index a074588..e6fd48b 100644 --- a/dwt/gui/trace_accept.lua +++ b/dwt/gui/trace_accept.lua @@ -14,7 +14,8 @@ -- 3F3F4680 authorisation check -- 3F706A40 create_process -- 3FD41B90 XCreateSimpleWindow --- 3FD645B0 XMapWindow +-- 3FD645B0 XRaiseWindow (ConfigureWindow/CWStackMode; does not map) +-- 3FD64F60 XMapWindow -- 3FD9F6B0 XSync -- -- Also snapshots frames on a trigger file: " ". @@ -138,7 +139,7 @@ local function arm() cmd('bpset 3F706A40,,{ printf "TR CREATE_PROC entry entryarg=%08X nameptr=%08X proc=%08X\\n", d@(a14-32), d@(a14-64), d@0x1b3900 ; g }') -- window calls cmd('bpset 3FD41B90,,{ printf "TR CreateSimpleWindow\\n" ; g }') - cmd('bpset 3FD645B0,,{ printf "TR MapWindow\\n" ; g }') + cmd('bpset 3FD645B0,,{ printf "TR RaiseWindow\\n" ; g }') cmd('bpset 3FD9F6B0,,{ printf "TR XSync\\n" ; g }') -- xhello progress is tracked through its relocated markers (0189xxxx); -- the code offsets moved when the setf fix was inserted, so no bpsets here. diff --git a/dwt/gui/xhello.asm b/dwt/gui/xhello.asm index 3c7b6f6..ee80a01 100644 --- a/dwt/gui/xhello.asm +++ b/dwt/gui/xhello.asm @@ -23,7 +23,7 @@ ; Xlib entry points (Ghidra address -> bit address): ; 7F384AE XOpenDisplay(name) -> 3F9C2570 ; 7FA8372 XCreateSimpleWindow(...) -> 3FD41B90 -; 7FAC8B6 XMapWindow(display,window) -> 3FD645B0 +; 7FAC8B6 XRaiseWindow(display,window) -> 3FD645B0 (does NOT map) ; 7FB3ED6 XSync(display,discard) -> 3FD9F6B0 ; 7F68B1A strlen(s) -> 3FB458D0 (convention check) ; @@ -116,12 +116,14 @@ _start: movi 4, a0, L move a0, @01890140h, 1 - ; ---- XMapWindow(display, window) ------------------------------ + ; ---- XRaiseWindow(display, window) ---------------------------- + ; ConfigureWindow with CWStackMode=Above: raises an already-mapped + ; window. It does NOT map it -- XMapWindow is 3FD64F60. move a14, -*sp, 1 movi 01892000h, a14, L move a10, *a14+, 1 ; window move a11, *a14+, 1 ; display - calla 3FD645B0h ; XMapWindow + calla 3FD645B0h ; XRaiseWindow move @01890420h, sp, 1 move @01890400h, a14, 1 setf 16, 0, 0 diff --git a/dwt/gui/xtext.asm b/dwt/gui/xtext.asm index bbaa2ae..ff2bd51 100644 --- a/dwt/gui/xtext.asm +++ b/dwt/gui/xtext.asm @@ -9,7 +9,7 @@ ; XLoadFont(d,"fixed") 3FD4AE80 ; XCreateGC(d,win,mask,&values) 3F997000 ; XSetForeground(d,gc,1) 3FD99A60 -; XMapWindow(d,win) 3FD645B0 +; XRaiseWindow(d,win) 3FD645B0 (does NOT map) ; XSync(d,0) / XDrawString(...) loop 3FD9F6B0 / 3FDA0000 ; ; The GC is created with a zero value-mask, so the server fills it from the @@ -49,7 +49,7 @@ ; 01842060 window id ; 01842080 GC id returned by XCreateGC ; 018420A0 XSetForeground return -; 018420C0 XMapWindow return +; 018420C0 XRaiseWindow return ; 018420E0 last XSync return ; 01842100 first XDrawString return ; 01842120 second XDrawString return @@ -180,15 +180,17 @@ _start: movi 6, a0, L move a0, @01842000h, 1 ; stage = 6 - ; ---- XMapWindow(display, window) ----------------------------- + ; ---- XRaiseWindow(display, window) --------------------------- + ; ConfigureWindow with CWStackMode=Above: raises an already-mapped + ; window. It does NOT map it -- XMapWindow is 3FD64F60. move a14, -*sp, 1 movi 01894000h, a14, L move a10, *a14+, 1 ; window move a11, *a14+, 1 ; display - calla 3FD645B0h ; XMapWindow + calla 3FD645B0h ; XRaiseWindow setf 16, 0, 0 setf 32, 0, 1 - move a8, @018420C0h, 1 ; MARK map + move a8, @018420C0h, 1 ; MARK raise movi 7, a0, L move a0, @01842000h, 1 ; stage = 7 diff --git a/dwt/notes/CROSS.md b/dwt/notes/CROSS.md index 7b493e0..195866c 100644 --- a/dwt/notes/CROSS.md +++ b/dwt/notes/CROSS.md @@ -362,7 +362,8 @@ Facts for anyone tempted to "just create a window" (details in (`0x7EE160C` / lookup `0x7EE1B70`). TCP 6000 is a separate, user/node authorised listener. * Xlib entry points (bit addresses): `XOpenDisplay` `0x3F9C2570`, - `XCreateSimpleWindow` `0x3FD41B90`, `XMapWindow` `0x3FD645B0`, + `XCreateSimpleWindow` `0x3FD41B90`, `XMapWindow` `0x3FD64F60`, + `XRaiseWindow` `0x3FD645B0` (ConfigureWindow/CWStackMode, does not map), `XSync` `0x3FD9F6B0`, `XCreateGC` `0x3F997000`, `XDrawString` `0x3FDA0000`. * **Live result:** a 390-byte payload (poke+jump, no breakpoints) called `strlen("0::0")` successfully (returned 4) using the firmware ABI, then diff --git a/dwt/notes/GUI_APPS.md b/dwt/notes/GUI_APPS.md index 9825869..e04586d 100644 --- a/dwt/notes/GUI_APPS.md +++ b/dwt/notes/GUI_APPS.md @@ -76,8 +76,9 @@ request buffer), which is how these were named; the DB26 `XDrawString` and DB25 | `XOpenDisplay(name)` | `0x07F384AE` | `0x3F9C2570` | mallocs 0x4D8, parses the name, connects | | `XParseDisplay` / service lookup | `0x07FA7538` | `0x3FD3A9C0` | splits `host:display.screen`, resolves `"xserver"` | | `XCreateSimpleWindow(d,p,x,y,w,h,bw,border,bg)` | `0x07FA8372` | `0x3FD41B90` | opcode 1, 9 args | -| `XMapWindow(d,w)` | `0x07FAC8B6` | `0x3FD645B0` | opcode 8, 2 args | +| `XRaiseWindow(d,w)` | `0x07FAC8B6` | `0x3FD645B0` | ConfigureWindow, opcode 12, `CWStackMode` mask `0x40`, value `Above` (0) | | `XMapSubwindows(d,w)` | `0x07FAC97E` | `0x3FD64BF0` | opcode 9 | +| `XMapWindow(d,w)` | `0x07FAC9EC` | `0x3FD64F60` | opcode 8 (MapWindow), 2 args | | `XSelectInput(d,w,mask)` | `0x07FB2FAA` | `0x3FD97D50` | ChangeWindowAttributes, mask 0x800 | | `XChangeWindowAttributes` | `0x07FA70EE` | `0x3FD38770` | opcode 2 | | `XConfigureWindow` | `0x07FA74A2` | `0x3FD3A510` | opcode 12 | @@ -93,6 +94,20 @@ request buffer), which is how these were named; the DB26 `XDrawString` and DB25 | internal PolyFillRectangle fast path | `0x07F33D1E` | `0x3F99E8F0` | opcode 70; not a public entry point | | `strlen` | `0x07F68B1A` | `0x3FB458D0` | used as the ABI check | +**Drift check.** The map/raise pair was mislabelled for a long time, so pin the +names to the request byte rather than to memory. From the repo root: + +``` +tools/smart34010/dis34 -l -o -b 3FD64F60 -s 0x16C9EC vt1200_v22.bin +# expect: movk 8, a11 ; movb ... *a10 -> MapWindow, opcode 8, length 2 +tools/smart34010/dis34 -l -o -b 3FD645B0 -s 0x16C8B6 vt1200_v22.bin +# expect: movk 12, a7 ; movb ... *a10 -> ConfigureWindow, opcode 12, +# then movi 0x40 into the value-mask (CWStackMode) and value 0 (Above) +``` + +(The `-s` values are file offsets: `(bit_address >> 3) - 0x07E40000`, the ROM's +byte base.) + ### 2.3 X server internals that matter | what | Ghidra | bits | @@ -176,9 +191,17 @@ The full minimum is **4 Xlib calls**: 1. `XOpenDisplay("0::0")` — `0x3F9C2570` 2. `XCreateSimpleWindow(d, root, x, y, w, h, bw, border, background)` — `0x3FD41B90` -3. `XMapWindow(d, win)` — `0x3FD645B0` +3. `XMapWindow(d, win)` — `0x3FD64F60` 4. `XSync(d, 0)` — `0x3FD9F6B0` (flush + round trip) +`XMapWindow` is `0x3FD64F60` (MapWindow, opcode 8). `0x3FD645B0` is +**`XRaiseWindow`**, not `XMapWindow`: it sends ConfigureWindow (opcode 12) with +`CWStackMode` = `Above`, which reorders the stacking but **does not map the +window**. The shipped `dwt/gui` payloads call `XRaiseWindow`, so they never map +their window themselves; it still appears framed, so the map is issued on their +behalf (the WM frames top-level client windows). A client that wants to be sure +it is mapped should call `0x3FD64F60`. + To draw text add `XLoadFont(d,"fixed")` (`0x3FD4AE80`), `XCreateGC` (`0x3F997000`) with `GCFont=0x4000`, `XSetForeground` (`0x3FD99A60`) and `XDrawString` (`0x3FDA0000`). No event loop is needed for a static window; the @@ -194,7 +217,7 @@ Payload: `dwt/gui/xhello.asm` → `dwt/gui/build/xhello.bin` (390 B), linked at `0x01840000`, built with the TI SDK flow (`dwt/gui/build.sh`). It first calls `strlen("0::0")` as an ABI check (must return 4; if not it returns without touching Xlib), then `XOpenDisplay`, root lookup, `XCreateSimpleWindow`, -`XMapWindow`, `XSync`, storing a stage counter at bit `0x01850140` and the +`XRaiseWindow`, `XSync`, storing a stage counter at bit `0x01850140` and the display/window at `0x01850100`/`0x01850120`. Run: `VT1200_SKIP_LEVEL1=1`, private `-nvram_directory`/`-cfg_directory`, @@ -331,7 +354,8 @@ live. **Verdict: H3 holds, with one payload bug on top.** A process created by the firmware's own `create_process` connects to the `"xserver"` local service, -completes the X11 setup handshake, creates and maps a window. The final, +completes the X11 setup handshake, creates a window and raises it. It appears +framed (and mapped) on screen. The final, **breakpoint-free** run shows it at frame 2838: `dwt/gui/evidence/xhello_window_frame2838.png` (black 400x200 window at 100,100 with the WM frame/title bar, over the Terminal Manager). -- 2.47.3