aboutsummaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2019-08-09 15:26:23 -0400
committerRich Felker <dalias@aerifal.cx>2019-11-02 18:30:56 -0400
commit22daaea39f1cc5f7391f0a5cd84576ffb58c2860 (patch)
tree336711effd188b25691df5c5d21030578035ab65 /ldso
parentc0450320940c8c45f3847f2d0a22c0ebc545b291 (diff)
downloadmusl-22daaea39f1cc5f7391f0a5cd84576ffb58c2860.zip
musl-22daaea39f1cc5f7391f0a5cd84576ffb58c2860.tar.gz
musl-22daaea39f1cc5f7391f0a5cd84576ffb58c2860.tar.bz2
add time64 redirect for, and redirecting implementation of, dlsym
if symbols are being redirected to provide the new time64 ABI, dlsym must perform matching redirections; otherwise, it would poke a hole in the magic and return pointers to functions that are not safe to call from a caller using time64 types. rather than duplicating a table of redirections, use the time64 symbols present in libc's symbol table to derive the decision for whether a particular symbol needs to be redirected.
Diffstat (limited to 'ldso')
-rw-r--r--ldso/dynlink.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 7ac0bf7..7810356 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -2237,6 +2237,33 @@ hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra
return res;
}
+hidden void *__dlsym_redir_time64(void *restrict p, const char *restrict s, void *restrict ra)
+{
+#if _REDIR_TIME64
+ const char *suffix, *suffix2 = "";
+ char redir[36];
+
+ /* Map the symbol name to a time64 version of itself according to the
+ * pattern used for naming the redirected time64 symbols. */
+ size_t l = strnlen(s, sizeof redir);
+ if (l<4 || l==sizeof redir) goto no_redir;
+ if (s[l-2]=='_' && s[l-1]=='r') {
+ l -= 2;
+ suffix2 = s+l;
+ }
+ if (l<4) goto no_redir;
+ if (!strcmp(s+l-4, "time")) suffix = "64";
+ else suffix = "_time64";
+
+ /* Use the presence of the remapped symbol name in libc to determine
+ * whether it's one that requires time64 redirection; replace if so. */
+ snprintf(redir, sizeof redir, "__%.*s%s%s", (int)l, s, suffix, suffix2);
+ if (find_sym(&ldso, redir, 1).sym) s = redir;
+no_redir:
+#endif
+ return __dlsym(p, s, ra);
+}
+
int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
{
struct dso *current;