Mini-posix knihovna s Win32 API

Re:Mini-posix knihovna s Win32 API
« Odpověď #15 kdy: 19. 12. 2020, 15:44:13 »
Ještě bych se zeptal - proč tak moc zavrhujete víceméně standardní přístup, kdy když už děláte multiplatformní programy, tak je psát multiplatformě už od začátku?
Navíc dnes máte dost prostředků na to to automaticky otestovat už ve chvíli commitu (já coby konzerva to dělám sice ručně, ale věci si vždycky testuju na linux i386 a x64 a raspberry pi s -Wall -Werror a když to chci i pro win tak právě na Watcomu, a až tak pracné to není) a připadá mi to jako čistší řešení než de-facto dělat vlastními silami něco jako WSL1


mhi

  • ***
  • 245
    • Zobrazit profil
Re:Mini-posix knihovna s Win32 API
« Odpověď #16 kdy: 20. 12. 2020, 15:16:58 »
Vynechal jsem tu spoustu detailu. Muj kod je obcas michan s ruznymi historickymi knihovnami nebo jednotlivymi .c soubory, ktere jsem neprogramoval a nemam zajem travit svuj cas opravou neceho co vznikalo treba v 90. letech (a obsahuje to teba kod ve stylu K&R :) ). Dale tam jsou obcas casti v assembleru, nebo prilinkovany nejaky object. Mam to tak, ze urcite veci jdou prekladat jen urcitymi verzemi gcc, nebo "jen" nefunguji. Nechtejte po mne detaily, psal bych tu romany, jsou to vsechno interni veci, ktere se zatim nevyplati lepe udrzovat, protoze jich je moc a pouzivaji se malo casto.

Ten mingw je nejblizsi tomu co potrebuju, nicmene musel bych mit verze pro ruzne gcc, no mozna to jde poskladat, preci jen mi prislo jednodussi pouzit to co je overene ze chodi a jen to na stejnem stroji prelozit znovu s jinymi headerfiles a pak prekovertovat. Vyzkousim cestu prelozit si nejakou minimalistickou crt z bcc/watcom/msvc/...

Re:Mini-posix knihovna s Win32 API
« Odpověď #17 kdy: 20. 12. 2020, 15:23:09 »
Tak takhle mi to už dává smysl. Nezávidím.  :(

Re:Mini-posix knihovna s Win32 API
« Odpověď #18 kdy: 21. 12. 2020, 22:16:54 »
Jen mě tak napadlo. Co si takovou knihovnu vyrobit právě pomocí mingw? Pro těch "pár" funkcí by to nemuselo trvat dlouho.

mhi

  • ***
  • 245
    • Zobrazit profil
Re:Mini-posix knihovna s Win32 API
« Odpověď #19 kdy: 29. 12. 2020, 15:57:14 »
Mingw je myslim tvrde zadratovane proti msvcrt, to nechci, nebude to chodit.

Tak jsem se do toho pustil. Slinkuju helloworld :). Nejvetsi problem byl tedy poslepovat z jinych projektu konvertor ELF to EXE/PE, aby to umelo spravne prehazet ELF z noveho gcc, generuji se tam nektere veci trochu jinak nez jsem byl zvykly. Navic mi IDA hazi ze import tabulku mam poskozenou, tezko rict co tam mam blbe - EXE ale normalne chodi.

Vysledek:

Kód: [Vybrat]
#include "../windefs.h"

#define STD_INPUT_HANDLE    ((DWORD)-10)
#define STD_OUTPUT_HANDLE   ((DWORD)-11)
#define STD_ERROR_HANDLE    ((DWORD)-12)

WINBASEAPI
HANDLE
WINAPI
GetStdHandle(
    _In_ DWORD nStdHandle
    );



WINBASEAPI
BOOL
WINAPI
WriteFile(
    _In_ HANDLE hFile,
    LPCVOID lpBuffer,
    _In_ DWORD nNumberOfBytesToWrite,
    _Out_opt_ LPDWORD lpNumberOfBytesWritten,
    _Inout_opt_ void *
    );

WINBASEAPI
DECLSPEC_NORETURN
VOID
WINAPI
ExitProcess(
    _In_ UINT uExitCode
    );

typedef int ssize_t;
typedef int size_t;
[b]
static inline ssize_t write(int fd, const void *buf, size_t count) __attribute__((always_inline));

static inline void exit(int status) __attribute__((always_inline));[/b]

int main()
{
    const char *hellostr = "Hello world\n";

   write( GetStdHandle(STD_OUTPUT_HANDLE), hellostr, lstrlenA(hellostr));

   exit(0);
}


void exit(int status) {ExitProcess(status);}


ssize_t write(int fd, const void *buf, size_t count)
{
  DWORD bw;
  WriteFile(fd, buf, count, &bw, NULL);
  return bw;
}

V disassembleru z toho vypadne:

Kód: [Vybrat]
.text:00401000 _text           segment para public 'CODE' use32
.text:00401000                 assume cs:_text
.text:00401000                 ;org 401000h
.text:00401000                 assume es:nothing, ss:nothing, ds:_text, fs:nothing, gs:nothing
.text:00401000                 public start
.text:00401000 start           dd 0FB1E0FF3h           ; toto je endbr32 :)
.text:00401004 ; ---------------------------------------------------------------------------
.text:00401004                 lea     ecx, [esp+4]
.text:00401008                 and     esp, 0FFFFFFF0h
.text:0040100B                 push    dword ptr [ecx-4]
.text:0040100E                 push    ebp
.text:0040100F                 mov     ebp, esp
.text:00401011                 push    ebx
.text:00401012                 push    ecx
.text:00401013                 sub     esp, 1Ch
.text:00401016                 push    offset aHelloWorld ; "Hello world\n"
.text:0040101B                 call    lstrlenA
.text:00401020                 mov     dword ptr [esp], 0FFFFFFF5h
.text:00401027                 mov     ebx, eax
.text:00401029                 call    GetStdHandle
.text:0040102E                 lea     edx, [ebp-0Ch]
.text:00401031                 push    0
.text:00401033                 push    edx
.text:00401034                 push    ebx
.text:00401035                 push    offset aHelloWorld ; "Hello world\n"
.text:0040103A                 push    eax
.text:0040103B                 call    WriteFile
.text:00401040                 push    0
.text:00401042                 call    ExitProcess
.text:00401047 ; ---------------------------------------------------------------------------
.text:00401047                 lea     esp, [ebp-8]
.text:0040104A                 xor     eax, eax
.text:0040104C                 pop     ecx
.text:0040104D                 pop     ebx
.text:0040104E                 pop     ebp
.text:0040104F                 lea     esp, [ecx-4]
.text:00401052                 retn


Pres ty inline pujde vyresit spousta veci relativne efektivne, napr. KERNEL32.dll:lstrlenA() budu aliasovat na strlen stejne jako to delam u exitu -> KERNEL32:ExitProcess().  Takhle asi udelam 2 verze knihovny, jedna ktera se bude snazit o maximalni kompatibilitu (tam nebude zadny inline-pro pouziti s dalsimi knihovnami/bloby/atd. ktere budou ocekavat existenci vsech symbolu) a druha ktera nageneruje z prvni knihovny ty inlines (a tim se to rovnou bude preklapet na Windows API).

Tusite jak primet gcc k tomu aby negeneroval ten bordel s endbr/stackem/frameptr ? Moje cmdline + verze:
gcc -m32 -c hello.c -Os -fno-PIC -fno-stack-protector -fomit-frame-pointer   # gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)


Pro rypaly: ten kod je proof of concept!


Re:Mini-posix knihovna s Win32 API
« Odpověď #20 kdy: 29. 12. 2020, 16:10:02 »
Přiznávám se, že jsem vlákno pořádně nečetl, ale něco v tom stylu může mít za cíl midipix: https://midipix.org/ . Vypadá to ale, že se jedná o pre-alpha verzi :(

mhi

  • ***
  • 245
    • Zobrazit profil
Re:Mini-posix knihovna s Win32 API
« Odpověď #21 kdy: 29. 12. 2020, 17:50:19 »
Diky za tip, povedlo se vam to nekomu stahnout? Nejak se nemuzu dopidit jak se dostat k privatnimu githubu se zdrojaky (mam access denied).

Kazdopadne mi to prijde jako tezky overkill, oni tam resi sice podobny problem, ale knihovna se patla treba v prekladu unicode na utf8, pochybuju navic ze takovou vec prelozim nejakym starym gcc. Ja chci naopak minimalismus.

Uvazuju o 4 vecech:
- asi by bylo dobre pomoci inline fci nejak wrapnout unicode/ansi verze (misto #define CreateFile CreateFileA), aby to nezborilo pres define stejne se jmenujici fce v programu, netusite MS pouziva #define misto always_inline fce ?

- muzu pouzit spoustu fci z ntdll.dll, skoda ze nejde pouzit jejich fce xxxprintf, ledaze bych na to pouzil nejaky intermediate string buffer a pak tisknul pres nejaky snprintf, ale to se mi moc nelibi

- A pak bych rad vyresil chytre ty inline wrappery nad Win32 API jako je exit(n), stejne tak v mych programech neni problem udelat ze (file) HANDLE je to same co file deskriptor a ve wrapperu open()->CreateFileA jen poresit STDIN/OUT/ERR aby to zavolalo GetStdHandle(); dalsi problem je errno, nevim jestli si muzu dovolit udelat #define   ENOENT ERROR_FILE_NOT_FOUND (tady to zrovna sedi, oboji jsou 2, ale urcite se to jinde rozpadne).

- pokud by doslo k tomu, ze cast projektu bude prelozena s tim ze HANDLE == filedescriptor (tzn. ty inline fce) a cast ocekavajici translaci pres knihovni fce, mate nekdo tip jak zamezit vzajemnemu slinkovani takovych vzajemne nekompatibilnich obj files ?

RDa

  • *****
  • 1 191
    • Zobrazit profil
    • E-mail
Re:Mini-posix knihovna s Win32 API
« Odpověď #22 kdy: 29. 12. 2020, 18:07:12 »
Nebylo by snazsi zkompilovat qemu-user pro win, a pak tomu predhazovat tvoje linux binarky?

mhi

  • ***
  • 245
    • Zobrazit profil
Re:Mini-posix knihovna s Win32 API
« Odpověď #23 kdy: 29. 12. 2020, 19:46:08 »
Podle me qemu-user neresi ABI, ale mozna se pletu.A jestli to bylo mysleno tak ze si mam to ABI do toho nejak zadratovat sam, tak to je jednodussi udelat tu libc.

Narazil jsem ale na zajimavy problem a to je TLS, gcc v Linuxu totiz na takove promenne pristupuje jak se mu zachce via gs:xxx (R_386_TLS_LE) , ve Windows to je ale potreba pres TlsIndex a pak fs:[0x2C]. x86_64-w64-mingw32-gcc na to ma zadratovany hack a pomaha si pres ___emutls_get_address. MSVC to prelozi ze si rovnou vytahne z fs:[0x2c] co potrebuje a pres globalni tlsindex leze kam potrebuje. Jak toto vyresim nevim.

nula

Re:Mini-posix knihovna s Win32 API
« Odpověď #24 kdy: 29. 12. 2020, 21:59:39 »
Mam jeste dotaz, o wsl se uz tady zminovalo, ale uplne jste neodpovedel - proc vlastne nemuzete tyhle utilitky na widlich spoustet pres wsl? Pripadne pres docker (for windows/desktop) ?

RDa

  • *****
  • 1 191
    • Zobrazit profil
    • E-mail
Re:Mini-posix knihovna s Win32 API
« Odpověď #25 kdy: 30. 12. 2020, 00:21:24 »
Mam jeste dotaz, o wsl se uz tady zminovalo, ale uplne jste neodpovedel - proc vlastne nemuzete tyhle utilitky na widlich spoustet pres wsl? Pripadne pres docker (for windows/desktop) ?

imho to je problem verzovani napr. GLIBC, kdy prislusne exporty tam bud jeste nejsou, nebo uz nejsou. Stejny problem potkavam pri spousteni binarek skrze ruzne linuxy.. pritom to je nekdy fakt takova prkotina, kdyz se podivate, ze v cem se lisi 2.25 a 2.32 :-)

Re:Mini-posix knihovna s Win32 API
« Odpověď #26 kdy: 30. 12. 2020, 11:50:22 »
Nekdy mrknu do nejakych starsich prekladacu typu Borland nebo Watcom na zdrojaky CRT, treba to pujde pouzit, myslel jsem ze existuje nejake free+opensource reseni.

Tiny C znate?

mhi

  • ***
  • 245
    • Zobrazit profil
Re:Mini-posix knihovna s Win32 API
« Odpověď #27 kdy: 30. 12. 2020, 12:19:16 »
ad wsl: duvodu je vice, jednak potrebuju aby to chodilo kde WSL neni (predstavte si, ze je 3rd party SW ktery nechodi na W10), za druhe nechci 'sebou' tahat hromadu blbosti a resit ruzne kompatibility apod.

ad tcc: nevim o tom, ze by mela vlastni libc, pouziva nejakou systemovou, nebo se pletu? Ale to neni reseni, predstavte si, ze mate 20 projektu, ktere v sobe obsahuji nejake zavislosti na konkretnim prekladaci (typicky treba nejaky inlinovany assembler AT&T stylu ... nebo naopak ten MS-to je dalsi vec nad ramec tohoto tematu kterou chci nekdy vyresit, abych msvc COFF/objectfile mohl pouzit v Linuxu). Najednou se stane jednodussi vyresit nejake 'hloupe' libc nez  koukat jak zmena prekladace vyvola nekonecny seznam chyb, ktere clovek musi tupe opravovat.

No ale zajimaly by mne tipy na ruzne male libc, muj favorit je openbsd, inspirovat se chci ale i u prekladacu z Win sveta (msvc, bcc), dale uclibc, musl libc, dobrym zdrojem jsou nejake opravdu historicke libc typu https://github.com/wuzhouhui/c_standard_lib ; naopak treba Watcom je plny DOS/OS2/Win3x legacy kodu

nula

Re:Mini-posix knihovna s Win32 API
« Odpověď #28 kdy: 01. 01. 2021, 09:47:47 »
S tim wsl to chapu (zhledem k predchozim zpravam), ze resis kompatibilitu glibc? K tomu chci rict, pokud samotny kompilator a glibc neni kompatibilni - tak mi prijde celkem utopicke ocekavat, ze bude spolehlive funkcni nejaky automaticky "preklad" pro win32api.

Javim, moc tady nejsem konstruktivni, za to se omlouvam.

mhi

  • ***
  • 245
    • Zobrazit profil
Re:Mini-posix knihovna s Win32 API
« Odpověď #29 kdy: 01. 01. 2021, 12:39:58 »
Je rozdil mezi 'zdrojakem vs libc' a 'executable vs libc'. Privedl jste mne ale na jednu myslenku, co povazuju za mor dnesniho IT sveta, a to je jak moc na pocatku chybi nejaka vize (+zkusenosti) toho co ma urcita knihovna umet, jak ma byt strukturovana, schopnost navrhnout dobre nejake API apod. Dneska se kod spis lepi a pak to vypada tak, ze prave glibc je neuveritelny moloch. To same msvcrt, apod. Je potrebna nejaka zmena? Udelame dalsi fci, pridame dalsi parametr, apod., zvedneme cislo v nazvu .so. a je hotovo. V horsim pripade se jen zmeni API a na zbytek se kasle. A to pak vede k tomu, ze se musi delat narovnavaky na ohybaky.

Moc casu tomu nemuzu venovat, ale uz jsem par malinkatych veci prelozil - pomoci opravdu nanolibc napatlane primo na ucel techto miniaplikaci a fascinuje mne jak ty .exe muzou byt male, svet je opet v poradku :-). Muj linker+nanolibc - 4kB. MSVC 2003 60kB; MSVC z 2019 - 180kB.