MODULE _unix; (* connect to unix host *) IMPORT SYSTEM, API; (* how to find C declarations: - gcc -E preprocess only (to stdout) (preprocessor expand) - grep -r name /usr/include/* - ldd progfile - objdump -T progfile (-t) (-x) *) CONST RTLD_LAZY = 1; BIT_DEPTH* = API.BIT_DEPTH; VAR sym, libc, libdl :INTEGER; _dlopen* :PROCEDURE [linux] (name, flags :INTEGER) :INTEGER; _dlsym* :PROCEDURE [linux] (p, name :INTEGER) :INTEGER; _dlclose* :PROCEDURE [linux] (p :INTEGER) :INTEGER; _open* :PROCEDURE [linux] (name, flags, mode :INTEGER) :INTEGER; _close* :PROCEDURE [linux] (fd :INTEGER) :INTEGER; _read* :PROCEDURE [linux] (fd, buf, sz :INTEGER): INTEGER; _write* :PROCEDURE [linux] (fd, buf, sz :INTEGER) :INTEGER; _exit* :PROCEDURE [linux] (n :INTEGER); _malloc* :PROCEDURE [linux] (sz :INTEGER) :INTEGER; _select* :PROCEDURE [linux] (cnt, readfds, writefds, exceptfds, timeout :INTEGER) :INTEGER; (* error message to stderr *) PROCEDURE writeChar (c :CHAR); VAR ri :INTEGER; BEGIN ri := _write (2, SYSTEM.ADR(c), 1); ASSERT (ri = 1) END writeChar; PROCEDURE writeString (s :ARRAY OF CHAR); VAR i :INTEGER; BEGIN i := 0; WHILE s[i] # 0X DO writeChar (s[i]); INC(i) END; END writeString; PROCEDURE nl; BEGIN writeChar (0AX) END nl; PROCEDURE getSymAdr (lib :INTEGER; name :ARRAY OF CHAR; adr :INTEGER); BEGIN sym := _dlsym (lib, SYSTEM.ADR(name[0])); IF sym = 0 THEN writeString ("error: dlsym: "); writeString (name); nl END; ASSERT (sym # 0); SYSTEM.PUT (adr, sym) END getSymAdr; PROCEDURE finish*; VAR ri :INTEGER; BEGIN IF libc # 0 THEN ri := _dlclose (libc); libc := 0 END; IF libdl # 0 THEN ri := _dlclose (libdl); libdl := 0 END; END finish; BEGIN _dlopen := API.dlopen; _dlsym := API.dlsym; libc := _dlopen (SYSTEM.SADR("libc.so.6"), RTLD_LAZY); ASSERT (libc # 0); (* getSymAdr is not used for write() to get writeString() error message going *); sym := _dlsym (libc, SYSTEM.SADR("write")); ASSERT (sym # 0); SYSTEM.PUT (SYSTEM.ADR(_write), sym); libdl := _dlopen (SYSTEM.SADR("libdl.so.2"), RTLD_LAZY); ASSERT (libdl # 0); getSymAdr (libdl, "dlclose", SYSTEM.ADR(_dlclose)); getSymAdr (libc, "open", SYSTEM.ADR(_open)); getSymAdr (libc, "close", SYSTEM.ADR(_close)); getSymAdr (libc, "read", SYSTEM.ADR(_read)); getSymAdr (libc, "exit", SYSTEM.ADR(_exit)); getSymAdr (libc, "malloc", SYSTEM.ADR(_malloc)); getSymAdr (libc, "select", SYSTEM.ADR(_select)); END _unix.