I am working on the binary utilities for ForwardCom, and I have got an idea of a new concept for function libraries.
The well-known method for static linking is used. An option to the linker specifies that certain object files or library files should be re-linkable. The necessary symbol and relocation records are then preserved in the executable file so that the library functions can later be replaced by repeating the link process.
This concept has many advantages:
The executable file is ready to run without any external dependencies. You will never have problems with a missing DLL or a wrong version of a shared object.
An important advantage of static linking is that you don't have to load a large dynamic library containing hundreds of functions when you only need a few of these functions. The re-linking feature combines this advantage with the ability to update or replace a library later or to use a third-party library, which traditionally requires dynamic linking.
If you update a DLL in Windows, you are affecting all programs that use this DLL, even if some programs work better with the old version. With re-linkable libraries, you can update a library in each program separately.
You can update or modify a program without access to the original source code.
The rarely used symbol interposition feature in shared objects is very inefficient because all accesses to public symbols go through global offset tables (GOT) and procedure linkage tables (PLT). These inefficient table lookups are not needed with the relink method
You can have different versions of your functions for different platforms. For example, the same program can have different graphical user interfaces for different environments. The appropriate version can conveniently be linked to the executable program as part of the installation procedure.
You can have specific versions of a critical piece of code optimized for different microprocessor models.
You can reconfigure a program at any time if you update the hardware or operating system.
You are not wasting time on loading and linking dynamic libraries every time a program is loaded.
Modifying or updating an executable program requires administrator privileges, for security reasons.
While this concept is intended for ForwardCom, it can also be implemented in existing systems. The only thing this requires is a new linker. Run-time loading of this kind of library is only possible in ForwardCom, though.
I have previously proposed a feature to link in libraries when a program is loaded, where the choice of library can depend on environment variables, or whatever. Do we still need this feature if we have relinking at install time? I think it is safer to relink when a program is installed than when it is loaded, because a hacker might insert a tampered-with library to be linked at load time.
If relinking requires administrator privileges then it is more convenient to do it when the program is installed. In the rare cases where a choice between different versions needs to be done at load time, it would be safer (and faster) to store different ready-made versions of the executable file.
Interesting. You'd still probably need some kind of dynamic linking for plugins (since a same set of interface functions can lead to multiple different plugins loaded at the same time... maybe you could do it with some kind of OS-supplied dispatcher), but it would probably cut the usage of dynamic linking a lot, yes.
You'd still probably need some kind of dynamic linking for plugins.
You are right. A plugin could in principle be statically linked into the executable, but you would probably prefer third party plugins to be loaded at runtime.
Maybe we need to mark functions and data in the executable as public or private, where only public symbols can be accessed by plugins. But a plugin, whether statically or dynamically linked, is still able to access everything that it can find the address of. This might be a security problem. Even if there is no malicious intent, a poorly behaved plugin that messes with things it shouldn't touch might cause compatibility problems.
This is also a problem in existing systems, of course, but I would like ForwardCom to be safer. Maybe we need a system where each plugin is running as a separate thread or process where we can control its access rights?
Maybe we need a system where each plugin is
running as a separate thread or process where we can
control its access rights?
I think that class of problem tend to be already solvable using IPC (inter process communication)... And it wouldn't address some of the use cases I've seen:
- Java-C++ interfacing is done with DLLs on windows, and presumably programs do tons of small function calls back and forth, and do stuff like sharing large arrays in memory. The first generation of Android apps have a ton of this stuff going on (to interface between C++ code and Android's Java APIs), and getting the thread-to-thread overhead every time you read a button or something like that would've been a problem.
- Some script languages also use dynamic linking to interface with C++ (like, I think Python does this), and they will do tons and tons of small function calls.
- Audio processing plugins need to run in the same thread as the caller because they use tiny buffers (like, 1ms tiny - which means that the whole processing of a block of audio must take less than 0.001s before sending to the audio hardware every single time). If the OS's scheduler gets involved in any way you'll have dropouts for sure.
- Some game engines allow for plugins to extend features, which might require sharing access to very large data structures like level data in memory.
In a way, this reminds me of the whole micro-kernel thing, which had the same issue but between the applications and system modules (applications don't want to wait after the scheduler to call system module functions!).
I think the optimal solution for Java, C#, and script languages is just-in-time compiling. Actually, I don't understand why there are so many slow applications out there that don't use JIT compiling :-)
The code only has to be compiled the first time it is run. Or - why not distribute it in compiled form for ForwardCom? The compiled code is guaranteed to be forward compatible with future ForwardCom processors.
The compiled code can easily be linked to C/C++ code in the JIT process. The calling conventions of ForwardCom are standardized to work across different programming languages.
You are probably right that interprocess communication is a good solution for plug ins if you don't want the plug in to have access to mess with everything in the mother program.
I think the optimal solution
for Java, C#, and script languages is just-in-time
compiling. Actually, I don't understand why there are
so many slow applications out there that don't use JIT
The code only has to be compiled the
first time it is run. Or - why not distribute it in
compiled form for ForwardCom? The compiled code is
guaranteed to be forward compatible with future
The compiled code can easily
be linked to C/C++ code in the JIT process. The
calling conventions of ForwardCom are standardized to
work across different programming languages.
are probably right that interprocess communication is
a good solution for plug ins if you don't want the
plug in to have access to mess with everything in the
To load in C++ objects, the Java code calls System.loadLibrary("name"), which on windows loads "name.dll" and on posix loads "libname.so", so you still need either dynamic linking or arbitrary on-the-fly recompilation phases on already running apps, because your Java code is already running when you learn that you have to load this library. Another similar mechanism in Java is ClassLoader, which dynamically loads in more Java code into an already running app from arbitrary jar files on the disk (it's basically the Java equivalent of loading DLLs).