34 pontos por xguru 2022-10-25 | 11 comentários | Compartilhar no WhatsApp
  • O Wine é uma camada de compatibilidade que permite executar programas do Windows em sistemas operacionais compatíveis com POSIX (Linux, macOS, BSD)
    • O Steam Deck da Valve também usa uma solução baseada em Wine

WINE = Wine Is Not an Emulator

  • A abordagem de emulação é lenta e, na prática, Linux/macOS conseguem executar binários do Windows nativamente (com uma pequena ajuda)
  • Explica em detalhes, com um depurador, como binários de Linux/Windows funcionam

Hello, Wine!

  • Basicamente, o Wine é um "dynamic loader" para executáveis do Windows
  • É um binário Linux nativo e sabe como processar EXE e DLL
  • O Wine carrega o executável do Windows na memória, faz o parsing, identifica dependências e salta para o código que deve ser executado
  • Só isso já permite executar binários do Windows, mas há exceções

System Calls

  • As chamadas de sistema, chamadas de syscalls, são o que torna o Wine complexo
  • syscalls são implementadas pelo sistema operacional, não ficam dentro do executável ou da biblioteca
  • As syscalls fornecidas pelo SO são a API do sistema operacional
    • Linux: read, write, open, brk, getpid,..
    • Windows: NtReadFile, NtCreateProcess, NtCreateMutant,..
    Publicidade
  • Chamadas de sistema são diferentes de chamadas normais de função no código. Por exemplo, abrir um arquivo precisa ser tratado pelo kernel porque ele acompanha o File Descriptor
  • Portanto, o código da aplicação precisa de uma forma de se "interromper" e entregar o controle ao kernel ("context switch")
  • O conjunto de funções fornecido pelo SO e a forma de chamá-las variam entre sistemas operacionais
    • No Linux, ao chamar a função read(), é preciso colocar o descritor de arquivo no registrador %rdi, o ponteiro do buffer em %rsi e a quantidade de bytes a ler em %rdx
    • Já no Windows, a função read() não existe no kernel
  • Se executarmos o mesmo código que imprime "Hello World!" em Linux/Windows
    • No Linux, ele chama puts de libc.so; no Windows, chama printf de ucrtbase.dll
    • Hoje em dia, no Linux, é comum fazer link estático e incluir a implementação de puts dentro do binário, então libc.so nem é usado em tempo de execução
  • No Windows, pelo menos até recentemente, "só malware usava chamadas de sistema diretamente"
    • Aplicações comuns sempre dependem de kernel32.dll/kernelbase.dll/ntdll.dll para não se comunicar diretamente com o kernel
Publicidade

Runtime translation of Syscalls

  • E se interceptarmos as syscalls?
    E se, quando a aplicação chamar NtWriteFile(), entrarmos no meio, chamarmos write() e depois retornarmos no formato de resultado que o binário espera?
  • Isso seria possível se fornecêssemos uma versão customizada de ucrtbase.dll, mas surgem problemas complexos
  • Em vez disso, modifica-se a ntdll.dll, que fica entre o binário e o kernel
  • Versões recentes do Wine são compostas por ntdll.dll (binário PE) e ntdll.so (binário ELF)
    • A DLL é uma camada fina que apenas redireciona a chamada para o lado ELF
    • O ELF tem uma função especial chamada __wine_syscall_dispatcher, que faz a mágica de converter a pilha atual de Windows para Linux, ou vice-versa
  • Esse syscall dispatcher é a ponte que liga o mundo Windows ao mundo Linux
    • Ele lida com convenções de chamada, aloca espaço de pilha, move registradores e faz outras tarefas do tipo
    • Quando a execução chega em ntdll.so e passa para o binário Linux, passamos a poder usar todas as APIs do Linux

É só isso?

  • Parece muito simples, mas...
    • A API do Windows é enorme, mal documentada, tem bugs conhecidos e desconhecidos, e eles precisam ser preservados exatamente como são. A maior parte do código do Wine é a implementação de várias DLLs do Windows
    • Existem várias formas de fazer chamadas de sistema e, tecnicamente, não há como impedir que aplicações chamem syscalls diretamente
      (Lembre-se: jogos de Windows fazem todo tipo de loucura)
      O kernel do Linux tem mecanismos especiais para lidar com isso e, claro, isso aumenta ainda mais a complexidade
    • O problema de 32 bits vs 64 bits também é um absurdo. Existem inúmeros jogos de 32 bits, e eles não vão ser relançados em 64 bits. Como o Wine suporta os dois, isso também aumenta a complexidade
    • Nem chegamos a falar do wine-server. É um processo separado criado pelo Wine, que mantém o "estado" do kernel (descritores de arquivo, mutexes etc.)
    • Quer executar jogos? Aí é preciso lidar com DirectX, PulseAudio, dispositivos de entrada e muito mais, então o trabalho cresce enormemente
  • O Wine vem sendo desenvolvido há muito tempo e percorreu um longo caminho. Hoje, já consegue rodar jogos modernos como Cyberpunk 2077 e Elden Ring sem problemas
    Às vezes, o Wine chega até a apresentar desempenho melhor que o Windows

11 comentários

 
roxie 2022-10-29

Mais do que o conteúdo em si, a qualidade do resumo é realmente impressionante. Obrigado.

 
minho2da 2022-10-25

Estou usando o yes24 e a Kyobo Bookstore, que oferecem serviços de leitura por assinatura.

Depois de mudar o ambiente do PC de casa para Ubuntu, tentei executar o YES24 e a Kyobo Bookstore usando o Wine.

Os dois usam DRM próprio, então eu fiquei em dúvida se iriam rodar, mas o YES24, que acredito ter sido feito com Qt, funcionou bem, enquanto o ebook da Kyobo Bookstore não funcionou. (a interface abre, mas o DRM não roda)

Eu sabia que os dois tinham DRM, então fiquei pensando no que fazia um funcionar e o outro não, mas vendo o texto acima acho que dá para entender mais ou menos (aquele meme do "entendi tudo perfeitamente" mais ou menos).

 
bbulbum 2022-10-25

Fico feliz que, desde o Wine 5.0, o KakaoTalk rode sem nenhuma configuração. (independentemente de eu querer usar o KakaoTalk ou não..) Há alguns problemas na exibição de certas telas, mas recursos como envio de imagens pela área de transferência funcionam de forma integrada. No geral, parece que o Wine está mais focado em rodar jogos, mas é ótimo ver que ele também consegue executar bem vários aplicativos. Mesmo quando se fala em adotar Linux em órgãos públicos, nem sequer cogitarem uma versão Linux do KakaoTalk é algo meio... bem ruim.. Já a versão para Mac eles fizeram rapidinho..

 
bbulbum 2022-10-25

Eu tinha uma noção geral, mas é incrível ver o Wine explicado com tanto detalhe assim... rs

 
kayws426 2022-10-25

Como o Wine geralmente consegue executar bem programas do Windows, será que também daria para pensar em criar aplicativos multiplataforma usando o Wine? (limitado a desktop)

 
ganadist 2022-10-26

Há muito tempo, pelo que eu sei, até o HWP da Hancom chegou a ser portado e lançado para Linux com base no Wine. (O R4 tinha uma camada separada de biblioteca de compatibilidade win32, e se foi o R5 ou o 2002 que usou Wine eu já não lembro direito.)
Por isso, por um tempo, existia até a piada de que, graças ao Wine, o win32 era a API multiplataforma mais popular e bem-sucedida.
Mas agora é a era do electron/wasm ;;;

 
jinseokim 2022-10-25

Uma história um pouco diferente, mas, se você pretende fazer isso — como a licença do Wine é LGPL, dependendo de como o código for escrito, talvez seja necessário divulgar parte ou a totalidade do código-fonte.

 
kunggom 2022-10-25

Como também é explicado no texto original, o motivo de o Wine não ser um emulador é que ele usa as instruções da CPU diretamente. Isso significa que, basicamente, o software que pode ser executado com o Wine é software para Windows que roda em CPUs x86 ou x86-64.

Num momento em que a Apple já migrou toda a linha Mac para a arquitetura ARM, e a própria MS também está lançando kits de desenvolvimento baseados em ARM, talvez seja um pouco forçado chamar de “suporte multiplataforma” um software que só funciona em CPUs baseadas em x86(-64).

 
kayws426 2022-10-27

Sim. Como você disse... acho que acabei limitando isso, sem perceber, a máquinas da família x86.

 
jjpark78 2022-10-25

Com a existência de Electron e Tauri, se fosse preciso criar algo multiplataforma do zero, parece que não seria uma boa escolha. Se houver alguma limitação específica que impeça o uso de tecnologias baseadas em navegador web, o uso de uma biblioteca como Qt, que oferece bom suporte a cross-compiling, talvez seja melhor..

 
iceflower01 2022-10-25

222