Create a version of (BSD-licensed!)
ld.sothat will execute the program in a separate address space from its libraries. So the "procedure call" will call the stub in the BSD licensed
ld.sowhich will just "pass a message" to the real shared library and return a result code to the application.
There are at least two interesting problems to be addressed:
- passing pointers, and
- implementing functions that manipulate the whole process state (e.g. setuid, execve, fork, etc.)
More interesting problem is passing of code pointers. Excluding self-modifying code, the dynamic linker does not make code segments of the dynamic library available to the executable or vice-versa. Dynamic library and the executable share code only with the dynamic linker, not mutually. First time when a callback is called in the "other" module, SIGSEGV is received. Special handler can then "patch" the pointer to point into some trampoline code within the dynamic linker, and then that trampoline code forwards the call to its real destination.
The second class of problems could be solved partly within the kernel and partly within the dynamic loader. E.g. by making the dynamic linker, the executable and dynamic libraries share the same process-structure except for memory maps.
Beware! This is just a wild idea. It may or may not be feasible in practice and it may or may not circumvent GPL. Nevertheless, it is an interesting technical problem.
This scheme may or may not have found a loophole in the GPL. Quoting Werner Koch:
Just for the record: Linking is only one indication that the whole is a derived work. There is no one to one relation ship and in particular even two separate processes might make up a derived work.IMHO, this statement just illustrates the problem with GPL: there is no clear definition of derived work.