Init no longer changes the default scheme to initfs at any point in
time. And for sandboxing you would be switching scheme namespace, not
default scheme.
It should be possible to mix and match relibc version from before and
after this change without breaking exec, though I haven't tested it.
Calculating it earlier is a micro-optimization that doesn't seem like it
matters at all compared to all other costs of spawning a process. But at
the same time it makes things more fragile. And in fact bootstrap
actually passed the wrong value. It passed the
total_args_envs_auxvpointee_size that it computed rather than the
total_args_envs_size. While over-approximation doesn't cause UB, it
unnecessarily increases the amount of memory used after exec.
In addition pass &[&[u8]] rather than iterators for args and envs to
enable precomputing the total arg and env size. This also prevents you
from forgetting to pass a reversed iterator.
As we know, vectors amortize the cost of adding new elements by reserving
space for multiple elements when full. This is useful but may lead to
allocating more memory than necessary.
`relibc` generally avoids over allocations by reserving the exact amount
of space when possible. I fixed a few areas that still over allocated or
reallocated unnecessarily by leveraging iterators that are more likely
to know sizes.
With this change, gcc can now successfully compile a tiny program that
printfs an integer returned from a function, from a dynamically linked
library that it compiled as well.
Rustc however, is orders of magnitude more complex, and the next step is
to fix constructors which require access to `environ`, in ld.so