Currently, after the major rewrite towards dynamic shared objects in #13, we handle the "main" compartment file and library dependencies differently. Specifically, for functions in the "main" compartment file called from library dependencies, we update the addresses at map-time, in order to not do dynamic lookups at runtime (as this would mean jumping from the compartment to the runtime loader, and basically crash, due to bounds errors, as we do not intercept this jump). However, if a library dependency calls a function that is not contained within itself, but needs to be loaded from another library [^1], this will obviously crash.
Some proposals to fix this:
Handle all so files loaded identically, performing "eager relocation binding" at map time;
Dynamically intercept PLT calls, by transitioning from the compartment to the manager (alter the branch target address at runtime for all PLT stubs), to perform runtime dynamic loading, similar to how it is done usually;
Move all libraries in their own compartment, and do something similar to intercepts, to transition between the compartments when such a function is called. This would also mean we won't have duplicate libraries across compartments (i.e., if two compartments both require libc, each compartment will have its own copy in the current design).
The proposals are in estimated implementation difficulty order. I think my personal preference would be 2 > 1 >>> 3.
[^1]: I believe the current test lua_simple does this with __assert, but I need to debug this. I also plan on adding a simpler test to showcase this, without needing huge libraries.
Currently, after the major rewrite towards dynamic shared objects in #13, we handle the "main" compartment file and library dependencies differently. Specifically, for functions in the "main" compartment file called from library dependencies, we update the addresses at map-time, in order to not do dynamic lookups at runtime (as this would mean jumping from the compartment to the runtime loader, and basically crash, due to bounds errors, as we do not intercept this jump). However, if a library dependency calls a function that is not contained within itself, but needs to be loaded from another library [^1], this will obviously crash.
Some proposals to fix this:
so
files loaded identically, performing "eager relocation binding" at map time;branch
target address at runtime for all PLT stubs), to perform runtime dynamic loading, similar to how it is done usually;libc
, each compartment will have its own copy in the current design).The proposals are in estimated implementation difficulty order. I think my personal preference would be 2 > 1 >>> 3.
[^1]: I believe the current test
lua_simple
does this with__assert
, but I need to debug this. I also plan on adding a simpler test to showcase this, without needing huge libraries.