diff options
author | Rich Felker <dalias@aerifal.cx> | 2021-03-26 13:35:41 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2021-03-26 13:35:41 -0400 |
commit | 521b4d27a00b12b238b3d4284a2c490daf851ab1 (patch) | |
tree | 4df62c4e0082782e61396226741cd4108f3a0f19 | |
parent | 122002f0ddf267977282f05066a0794e31661501 (diff) | |
download | musl-521b4d27a00b12b238b3d4284a2c490daf851ab1.tar.gz musl-521b4d27a00b12b238b3d4284a2c490daf851ab1.tar.bz2 musl-521b4d27a00b12b238b3d4284a2c490daf851ab1.tar.xz musl-521b4d27a00b12b238b3d4284a2c490daf851ab1.zip |
fix dl_iterate_phdr dlpi_tls_data reporting to match spec
dl_iterate_phdr was wrongly reporting the address of the DSO's PT_TLS
image rather than the calling thread's instance of the TLS. the man
page, which is essentially normative for a nonstandard function of
this sort, clearly specifies the latter. it does not clarify where
exactly within/relative-to the image the pointer should point, but the
reasonable thing to do is match the ABI's DTP offset, and this seems
to be what other implementations do.
-rw-r--r-- | ldso/dynlink.c | 2 | ||||
-rw-r--r-- | src/ldso/dl_iterate_phdr.c | 3 |
2 files changed, 3 insertions, 2 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c index aaadcce0..b66ad537 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -2331,7 +2331,7 @@ int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void info.dlpi_adds = gencnt; info.dlpi_subs = 0; info.dlpi_tls_modid = current->tls_id; - info.dlpi_tls_data = current->tls.image; + info.dlpi_tls_data = __tls_get_addr((tls_mod_off_t[]){current->tls_id,0}); ret = (callback)(&info, sizeof (info), data); diff --git a/src/ldso/dl_iterate_phdr.c b/src/ldso/dl_iterate_phdr.c index 86c87ef8..9546dd36 100644 --- a/src/ldso/dl_iterate_phdr.c +++ b/src/ldso/dl_iterate_phdr.c @@ -1,5 +1,6 @@ #include <elf.h> #include <link.h> +#include "pthread_impl.h" #include "libc.h" #define AUX_CNT 38 @@ -35,7 +36,7 @@ static int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size info.dlpi_subs = 0; if (tls_phdr) { info.dlpi_tls_modid = 1; - info.dlpi_tls_data = (void *)(base + tls_phdr->p_vaddr); + info.dlpi_tls_data = __tls_get_addr((tls_mod_off_t[]){1,0}); } else { info.dlpi_tls_modid = 0; info.dlpi_tls_data = 0; |