Skip to content

Commit

Permalink
i#1973: musl: Support late injection (#7254)
Browse files Browse the repository at this point in the history
Musl supplies no argument to constructors in .init section, thus it's
hard to retrieve environment variables without libc functions. Let's
depend on "environ" variable for now, which is relatively fine in
libdrpreload.so.

This fixes tests requiring late injection on musl, including common.fib,
common.nativeexec and common.nativeexec_{exe,bindnow}*.

Issue: #1973
  • Loading branch information
ziyao233 authored Feb 8, 2025
1 parent 40ed75f commit a13ca48
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions core/unix/preload.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,26 @@ take_over(const char *pname)
}

INITIALIZER_ATTRIBUTES int
#if INIT_BEFORE_LIBC
/* i#1973: Unlike glibc, musl calls constructors without any arguments, thus
* it's hard to retrieve envp without depending on any libc symbols.
* Retrieve it from stable ABI envrion, which is a simple bare pointer on musl.
* XXX: find a more portable way to retrieve environment variables, or detect
* libc type and choose the proper method at runtime.
*/
#ifdef MUSL
_init(void)
{
extern char **environ;
char **envp = environ;
#else
# if INIT_BEFORE_LIBC
_init(int argc, char *arg0, ...)
{
char **argv = &arg0, **envp = &argv[argc + 1];
#else
# else
_init(int argc, char **argv, char **envp)
{
# endif
#endif
const char *name;
#if VERBOSE_INIT_FINI
Expand All @@ -157,9 +170,11 @@ _init(int argc, char **argv, char **envp)

#if VERBOSE
{
# ifndef MUSL
int i;
for (i = 0; i < argc; i++)
fprintf(stderr, "\targ %d = %s\n", i, argv[i]);
# endif
fprintf(stderr, "env 0 is %s\n", envp[0]);
fprintf(stderr, "env 1 is %s\n", envp[1]);
fprintf(stderr, "env 2 is %s\n", envp[2]);
Expand Down

0 comments on commit a13ca48

Please sign in to comment.