-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Use an .init_array
function to capture argc/argv on Linux.
#78854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Per the ELF specification, the `.init_array` section contains a list of functions that need to be called before `main()` to initialize a library (i.e. libSwiftCore.so). The functions in this section take the initial values of `argc`, `argv`, and `environ` as arguments. This gives us an opportunity to capture/copy these values before `main()` is called in a way that may be more reliable than the current "inspect the stack" mechanism used on Linux (and derived platforms such as Android.)
@swift-ci test |
cc @al45tair |
Sadly, that is not true. Musl doesn't pass |
Well, for the sake of documenting the implementation if it ever becomes viable… here ya go. |
Huh. This actually passed on Linux. I wasn't expecting that… @al45tair does this mean we don't have test coverage of the edge cases you mentioned? |
Indeed, we don't. We could do with more testing of the Static SDK for Linux; there was some talk at one point of building programs from the compatibility test suite, and I think @justice-adams-apple did a little bit of work on that, but we don't have a regular job doing that (as far as I know) and we don't have anything during PR testing either. |
Do we know at the point this file is compiled whether we're using Glibc or Musl? If not, we could set it up so it tries this first, but if the args are empty, we fall back to the existing code path. Or perhaps this is sufficient to cover those other cases, and we really just need this and the older "read from /proc" as a fallback? |
@al45tair ping :) |
We do, yes.
This isn't sufficient because of the combination of the Rosetta bug and Musl. That's why I picked the admittedly baroque scheme that is in there now — which only fails when someone changes the environment from a constructor function. The only place I know of where someone was doing that has now been fixed, FWIW (they also thought doing that was crazy but were unable to do anything else because of a problem with an Intel driver). The right fix for all of this is to capture the arguments when entering the main function, as that's the only place you can guarantee that they are valid. That would require changing the compiler's codegen to emit something suitable at the entry point. |
Per the ELF specification, the
.init_array
section contains a list of functions that need to be called beforemain()
to initialize a library (i.e. libSwiftCore.so). The functions in this section take the initial values ofargc
,argv
, andenviron
as arguments. This gives us an opportunity to capture/copy these values beforemain()
is called in a way that may be more reliable than the current "inspect the stack" mechanism used on Linux (and derived platforms such as Android.)