summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2022-07-19 19:00:53 -0400
committerRich Felker <dalias@aerifal.cx>2022-07-19 19:00:53 -0400
commitd16d7b10997e6f1c224c3de01b43868f0ce2cc3d (patch)
tree5965ae45c5154b9ad86034dcefd25dcbecdafb71 /ldso
parent63c67053a3e42e9dff788de432f82ff07d4d772a (diff)
downloadmusl-d16d7b10997e6f1c224c3de01b43868f0ce2cc3d.tar.gz
early stage ldso: remove symbolic references via error handling function
while the error handling function should not be reached in stage 2 (assuming ldso itself was linked correctly), this was not statically determinate from the compiler's perspective, and in theory a compiler performing LTO could lift the TLS references (errno and other things) out of the printf-family functions called in a stage where TLS is not yet initialized. instead, perform the call via a static-storage, internal-linkage function pointer which will be set to a no-op function until the stage where the real error handling function should be reachable. inspired by commit 63c67053a3e42e9dff788de432f82ff07d4d772a.
Diffstat (limited to 'ldso')
-rw-r--r--ldso/dynlink.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 14fdd29e..cc677952 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -29,7 +29,9 @@
#define realloc __libc_realloc
#define free __libc_free
-static void error(const char *, ...);
+static void error_impl(const char *, ...);
+static void error_noop(const char *, ...);
+static void (*error)(const char *, ...) = error_noop;
#define MAXP2(a,b) (-(-(a)&-(b)))
#define ALIGN(x,y) ((x)+(y)-1 & -(y))
@@ -1758,6 +1760,9 @@ void __dls3(size_t *sp, size_t *auxv)
env_preload = getenv("LD_PRELOAD");
}
+ /* Activate error handler function */
+ error = error_impl;
+
/* If the main program was already loaded by the kernel,
* AT_PHDR will point to some location other than the dynamic
* linker's program headers. */
@@ -2347,7 +2352,7 @@ int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void
return ret;
}
-static void error(const char *fmt, ...)
+static void error_impl(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -2361,3 +2366,7 @@ static void error(const char *fmt, ...)
__dl_vseterr(fmt, ap);
va_end(ap);
}
+
+static void error_noop(const char *fmt, ...)
+{
+}