Recent submissions

Comment · 12 days ago
> And one of the great things of having a Wine port is that It just works.|

Todd Howard probably

Comment · 12 days ago
I would've checked it, if their Office 365... sorry... COPILOT OFFICE... wasn't such a problem to install and test. Notepad++ is enough.
Comment · 12 days ago
Against my better judgement and my personal sanity, I decided to keep issues there, at least for now
Comment · 12 days ago
There are some basic OpenBSD-isms like ucontext, stack mapping, mmap, fix trap context so rest of the %gs patching logic even knows where to work.

Rest is basically ~~two~~ three main issues 1. %gs/gsbase - we trap on %gs instructions because %gs=0 gsbase=0 so all of them illegally point at page zero. So we take the instruction, decode, turn it into %gs-less instruction, and stow it somewhere else. To do conversion we need a scratch register (now two, thanks MINGW32-GCC, you c*nt), we replace whatever gsbase should've been with our TEB pointer, and gogogo (with restore of the scratch register state {or two}). Old instruction (if wide enough) becomes jmp rel32 (I picked it because it is 5 bytes, and short jump branches are too... short). If it isn't, we are just constantly trap on that so we just create a hash between trap location and stub location. Those cases are thankfully rare.

Just this one patch gives us Notepad, Notepad++, Factorio, and many many other games

2. SIGUSR1. Basically Windows lets threads chat thru their thread API, and Electron apps (I really wanted Eve Online to work) and Chromium apps constantly chat and interrogate each other with that thread API. Wine decided to emulate some of the APIs with unix signals. Now the main issue here is that OpenBSD, does not allow one process to signal a thread in another process. So we catch it with the currently active thread, and reemit it now inside of the process as SIGUSR2. Read on SuspendThread, GetThreadContext, ReadProcessMemory, and why Mojo/Crashpad works how they work, very fun! Makes you really enjoy the security OpenBSD gives you. Another dev is making this code better and handle other SIGnals.

3. ReadProcessMemory / WriteProcessMemory (NtReadVirtualMemory / NtWriteVirtualMemory) - this is also for Electron/Chromium but mostly Steam. We only needed it majorly when we started pushing towards steam working. Steamwebhelper, steam overlay, and steam watching you play and tracking your game time, are completely against OpenBSD's security model. Wine processes are not descendants of wineserver, so wineserver cannot ptrace them unless you enable kern.global_ptrace=1. We were trying to keep kernel as stock as possible so...

2 and 3 are very much together and if you ever seen on windows how chrome looks in the Task Manager and how many chrome processes there are, well now you know my pain, haha

Comment · 12 days ago
I was (and partially probably still am) hoping that it will go upstream in some shape or form so I kept the original name.
Comment · 12 days ago
At that time, that LLM built solution was like 3+ weeks old if not more. It's just me and Fabien for now though. Rest are working on helping us turn it into a nice Port Wine
Comment · 12 days ago
Soon like with Speedrun submissions, we will have to show ourselves livestream coding to avoid any AI usage suspicions
Comment · 12 days ago
I never hid the fact that I iterated with AI. It's pretty hard to commit to an approach if you don't even know if it will succeed. And boy oh boy this was a shot in the dark.

I also respect Wine and OpenBSD and their rules to not have any LLM code in the repo/ports. So my approach was to iterate over solutions, find approach that works, ask AI to "just see if my idea even works", learn what/how/why of that approach, generate some supporting manuals for myself (for example how to decode %gs instructions and how to reencode them) and then write my own code based just on decoding tables (and not LLM code).

I did not know how to work with REX/SIB/ModRM, how to detect prefixes, how to parse every single instruction that contains %gs, how offsets work, how to encode jmp rels, why I want to use JMP *0(%RIP) instead of JMP 32rel on return, why I want to leave stub on SIGUSR (or any other signal). But I do know now.

I was incredibly lucky that patching just these %gs instructions were enough to launch Factorio and play, with broken sound, but anyways! Holy molly this was and is so much FUN!

The approach still feels like cheating, and if it feels the same for you, I perfectly understand.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton