c73a33edd8
Path A landed for R3/R4. The byte->MxStatus synthesizer in Lmx.dll is
FUN_10100ce0 (`analysis/ghidra/exports/Lmx.dll.synthesizer-helpers2-decompile.md`),
a 4-byte u32 LE -> 4-tuple MxStatus decoder used by every NMX-frame
parser in Lmx.dll. The kernel is byte-deterministic and context-free,
so it ports as a pure function -- the operation-tracking state
machine the original verdict deferred is NOT required for synthesis.
Bit layout (per FUN_10100ce0 lines 21-24):
bit 31: success (-1 if set, 0 if clear)
bits 27..24: category (4 bits)
bits 23..20: detected_by (4 bits)
bits 15..0: detail (i16 -- low 16 bits, signed)
bits 30..28, 19..16: reserved/padding
Codec changes:
- MxStatus::from_packed_u32() / ::to_packed_u32() -- the kernel +
inverse for round-trip parity.
- MxStatus::from_nmx_response_code() -- the constructed-from-response-
code switch in FUN_1010bd10:741-770 (six proven mappings: 0x01, 0x02
-> CommunicationError + RequestingNmx; 0x03 -> ConfigurationError +
RequestingNmx; 0x04 -> ConfigurationError + RespondingNmx; 0x05 ->
CommunicationError + RespondingNmx; 0x1A -> CommunicationError +
RequestingNmx).
- MxStatusCategory / MxStatusSource: from_i16/to_i16 promoted to const
fn so MxStatus::from_packed_u32 can be const.
- NmxOperationStatusMessage::try_parse_process_data_received_body() --
thin wrapper that peels the outer NmxObservedEnvelope before
delegating to try_parse_inner. Mirrors
NmxOperationStatusMessage.TryParseProcessDataReceivedBody (.NET cs:20-32).
- NmxOperationStatusMessage::promote_to_typed() -- entry point that
returns the existing Status field. Documented as a no-op pass-through
for now (the 5-byte inner-body wire shape is NOT the same field as
the 4-byte packed-u32 the kernel decodes); kept for API symmetry.
- 22 new round-trip tests covering the kernel, the response-code
switch, the proven 0x00/0x41/0xEF completion bytes, and round-trip
for every canonical sentinel.
mxaccess (Session) changes:
- New OperationKind enum (Write/WriteSecured/Read/Subscribe/
Unsubscribe/Activate/Suspend/Other).
- New OperationContext struct (correlation_id, op_kind, reference,
retry_count) -- ground for the F54 follow-on per-operation
correlation work.
- New OperationStatus event type {raw, status, context,
is_during_recovery}, mirroring MxNativeOperationStatusEvent (cs:73-78)
with the typed-MxStatus addition.
- Session::operation_status_events() -> broadcast::Receiver<Arc<
OperationStatus>> + operation_status_stream() Stream variant.
- callback_router() now tries operation-status parsing first, falling
through to subscription messages -- matches MxNativeSession
.OnCallbackReceived dispatch order (cs:574,582,590).
- recover_connection() flips a recovery_active counter (Arc<AtomicU32>
shared with the router) so OperationStatus.is_during_recovery is
populated correctly. Mirrors MxNativeSession._recoveryActive
Volatile.Read at cs:573.
- 3 new router tests covering: status-word frame dispatch + typed
promotion to WriteCompleteOk; completion-only frames stay verbatim;
is_during_recovery is stamped from the live counter.
Per-operation context tracking (correlating completion frames back to
outstanding writes/subscribes via the correlation_id) is filed as F54
in design/followups.md. The synthesizer kernel itself is byte-
deterministic, so the kernel and the correlation work are decoupled.
Ghidra evidence (the next-ring xref walk beyond FUN_10114a90):
- analysis/ghidra/exports/Lmx.dll.set-attribute-result-xrefs.md --
xrefs to OnSetAttributeResult / CancelWithStatus / OperationComplete.
- analysis/ghidra/exports/Lmx.dll.vtable-data-xrefs.md -- vtable-slot
data xrefs for the virtual-dispatch path.
- analysis/ghidra/exports/Lmx.dll.synthesizer-decompile.md --
ScanOnDemandCallback::OperationComplete/MultipleOperationComplete
(FUN_1010b990), RemotePlatformResolver::OperationComplete
(FUN_1010dc80), and the constructed-from-responseCode synthesizer
in FUN_1010bd10 (lines 698-770). FUN_1010bd10 is the wire-frame
receiver that drives the synthesis.
- analysis/ghidra/exports/Lmx.dll.synthesizer-helpers-decompile.md --
FUN_10003fc0 (the <success %d category %d ...> formatter; confirms
the 4-tuple layout), FUN_1008f150 (dispatch helper).
- analysis/ghidra/exports/Lmx.dll.synthesizer-helpers2-decompile.md --
FUN_10100ce0 (the kernel itself), FUN_10100bc0 (3xu16 reader),
FUN_1005e580 (4-byte stream reader), FUN_1010ee00 (sister NMX-frame
parser using the same kernel).
- analysis/ghidra/exports/Lmx.dll.synthesizer-callers-xrefs.md --
caller graph; confirms the kernel is called from many wire-frame
parsers but each parser shares the single 4-byte decoder.
R3/R4 verdict updated in design/70-risks-and-open-questions.md from
"settled at verbatim-preserve" to "settled per Path A". F54 filed in
design/followups.md for the per-operation correlation work.
cargo build / test / clippy -D warnings / RUSTDOCFLAGS=-D warnings doc
all clean. cargo public-api baselines regenerated for mxaccess and
mxaccess-codec.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
120 lines
4.1 KiB
Markdown
120 lines
4.1 KiB
Markdown
# Lmx.dll xrefs
|
|
|
|
## 0x1010bd10 at 1010bd10
|
|
|
|
Target function: `FUN_1010bd10`
|
|
|
|
| From | Ref type | Caller function |
|
|
| --- | --- | --- |
|
|
| `1010d89b` | `UNCONDITIONAL_CALL` | `FUN_1010d4a0` |
|
|
|
|
## 0x1010e410 at 1010e410
|
|
|
|
Target function: `FUN_1010e410`
|
|
|
|
| From | Ref type | Caller function |
|
|
| --- | --- | --- |
|
|
| `101956a8` | `DATA` | `` |
|
|
|
|
## 0x10101360 at 10101360
|
|
|
|
Target function: `FUN_10101360`
|
|
|
|
| From | Ref type | Caller function |
|
|
| --- | --- | --- |
|
|
| `10061e82` | `UNCONDITIONAL_CALL` | `FUN_10061c60` |
|
|
| `10110335` | `UNCONDITIONAL_CALL` | `` |
|
|
|
|
## 0x10100ce0 at 10100ce0
|
|
|
|
Target function: `FUN_10100ce0`
|
|
|
|
| From | Ref type | Caller function |
|
|
| --- | --- | --- |
|
|
| `1010c2ea` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c474` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c50d` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c5fb` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c8ac` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010ca5f` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010cb16` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010cd61` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010f27d` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `1010f365` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `1010fa8d` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `1010facf` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
|
|
## 0x10100bc0 at 10100bc0
|
|
|
|
Target function: `FUN_10100bc0`
|
|
|
|
| From | Ref type | Caller function |
|
|
| --- | --- | --- |
|
|
| `1010c47e` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c605` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010ca69` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010cb20` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
|
|
## 0x1005e580 at 1005e580
|
|
|
|
Target function: `FUN_1005e580`
|
|
|
|
| From | Ref type | Caller function |
|
|
| --- | --- | --- |
|
|
| `1010c612` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010ca76` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010f51a` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `1010f8bb` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `1010fa76` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `1010fab8` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `10110415` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `10110440` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `10110513` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `101116fc` | `UNCONDITIONAL_CALL` | `` |
|
|
| `10111ab6` | `UNCONDITIONAL_CALL` | `` |
|
|
| `10111d51` | `UNCONDITIONAL_CALL` | `` |
|
|
| `10111884` | `UNCONDITIONAL_CALL` | `` |
|
|
| `101118d2` | `UNCONDITIONAL_CALL` | `` |
|
|
| `10111b52` | `UNCONDITIONAL_CALL` | `` |
|
|
| `10110be2` | `UNCONDITIONAL_CALL` | `FUN_10110986` |
|
|
| `10110c03` | `UNCONDITIONAL_CALL` | `FUN_10110986` |
|
|
|
|
## 0x10067aa0 at 10067aa0
|
|
|
|
Target function: `FUN_10067aa0`
|
|
|
|
| From | Ref type | Caller function |
|
|
| --- | --- | --- |
|
|
| `1006afb2` | `UNCONDITIONAL_CALL` | `FUN_10069c30` |
|
|
| `101044a9` | `UNCONDITIONAL_CALL` | `Catch@10104467` |
|
|
| `100fd351` | `UNCONDITIONAL_CALL` | `FUN_100fd200` |
|
|
| `10067d89` | `UNCONDITIONAL_CALL` | `FUN_10067d30` |
|
|
| `100fd560` | `UNCONDITIONAL_CALL` | `FUN_100fd400` |
|
|
| `100ffe3a` | `UNCONDITIONAL_CALL` | `FUN_100ffc90` |
|
|
| `1010951d` | `UNCONDITIONAL_CALL` | `FUN_10107880` |
|
|
| `1010bfcc` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c250` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c2bb` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c7a4` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010d27a` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010f497` | `UNCONDITIONAL_CALL` | `FUN_1010ee00` |
|
|
| `10070743` | `UNCONDITIONAL_CALL` | `FUN_10070360` |
|
|
| `10070869` | `UNCONDITIONAL_CALL` | `FUN_10070360` |
|
|
| `10070a01` | `UNCONDITIONAL_CALL` | `FUN_10070360` |
|
|
|
|
## 0x100860c0 at 100860c0
|
|
|
|
Target function: `FUN_100860c0`
|
|
|
|
| From | Ref type | Caller function |
|
|
| --- | --- | --- |
|
|
| `10069f19` | `UNCONDITIONAL_CALL` | `FUN_10069c30` |
|
|
| `1006a588` | `UNCONDITIONAL_CALL` | `FUN_10069c30` |
|
|
| `10138a4b` | `UNCONDITIONAL_CALL` | `FUN_101389c0` |
|
|
| `1010c158` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c206` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010c5ba` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010d0b4` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
| `1010d167` | `UNCONDITIONAL_CALL` | `FUN_1010bd10` |
|
|
|