aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2021-04-05 03:05:44 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2021-04-06 00:23:08 +0000
commitd36d6816151705907393889d661cbfd25c630ca8 (patch)
tree7d105ce0cfee5f3754f917743d4cf7de209070e2
parent843d16436d3388c1b46d37fca4e86885612d0e64 (diff)
downloadsrc-d36d6816151705907393889d661cbfd25c630ca8.tar.gz
src-d36d6816151705907393889d661cbfd25c630ca8.zip
rtld dl_iterate_phdr(): dlpi_tls_data is wrong
dl_iterate_phdr() dlpi_tls_data should provide the TLS module segment address, and not the TLS init segment address as it does now. Reported by: emacsray@gmail.com PR: 254774 Sponsored by: The FreeBSD Foundation MFC after: 1 week
-rw-r--r--lib/libc/gen/dl_iterate_phdr.37
-rw-r--r--libexec/rtld-elf/Symbol.map1
-rw-r--r--libexec/rtld-elf/rtld.17
-rw-r--r--libexec/rtld-elf/rtld.c8
-rw-r--r--sys/sys/param.h2
5 files changed, 21 insertions, 4 deletions
diff --git a/lib/libc/gen/dl_iterate_phdr.3 b/lib/libc/gen/dl_iterate_phdr.3
index 6e952dc13b57..fe4face9eeb7 100644
--- a/lib/libc/gen/dl_iterate_phdr.3
+++ b/lib/libc/gen/dl_iterate_phdr.3
@@ -15,7 +15,7 @@
.\"
.\" $OpenBSD: dl_iterate_phdr.3,v 1.3 2007/05/31 19:19:48 jmc Exp $
.\" $FreeBSD$
-.Dd October 9, 2014
+.Dd April 5, 2021
.Dt DL_ITERATE_PHDR 3
.Os
.Sh NAME
@@ -80,7 +80,10 @@ The counter of the object unloads performed by the dynamic linker.
.It Fa dlpi_tls_modid
The TLS index of the object.
.It Fa dlpi_tls_data
-A pointer to the initialization data for the object TLS segment.
+A pointer to the calling thread' TLS data segment for this module,
+if it was allocated,
+.Dv NULL
+otherwise.
.El
.Pp
Future versions of
diff --git a/libexec/rtld-elf/Symbol.map b/libexec/rtld-elf/Symbol.map
index 13068c5626dc..0a9eac82cf05 100644
--- a/libexec/rtld-elf/Symbol.map
+++ b/libexec/rtld-elf/Symbol.map
@@ -34,4 +34,5 @@ FBSDprivate_1.0 {
_r_debug_postinit;
_rtld_version__FreeBSD_version;
_rtld_version_laddr_offset;
+ _rtld_version_dlpi_tls_data;
};
diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index 589b9a92aa77..7f633ce0b486 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -424,6 +424,13 @@ See
Also it indicates the presence of
.Va l_refname
member of the structure.
+.It Dv _rtld_version_dlpi_tls_data
+The
+.Va dlpi_tls_data
+member of the structure
+.Vt dl_phdr_info
+contains the address of the module TLS segment for the calling thread,
+and not the address of the initialization segment.
.El
.Sh FILES
.Bl -tag -width ".Pa /var/run/ld-elf32.so.hints" -compact
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 733c3c80b70f..19027518d3c2 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -3909,13 +3909,16 @@ dlinfo(void *handle, int request, void *p)
static void
rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info)
{
+ tls_index ti;
phdr_info->dlpi_addr = (Elf_Addr)obj->relocbase;
phdr_info->dlpi_name = obj->path;
phdr_info->dlpi_phdr = obj->phdr;
phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]);
phdr_info->dlpi_tls_modid = obj->tlsindex;
- phdr_info->dlpi_tls_data = obj->tlsinit;
+ ti.ti_module = obj->tlsindex;
+ ti.ti_offset = 0;
+ phdr_info->dlpi_tls_data = __tls_get_addr(&ti);
phdr_info->dlpi_adds = obj_loads;
phdr_info->dlpi_subs = obj_loads - obj_count;
}
@@ -5914,3 +5917,6 @@ int _rtld_version__FreeBSD_version = __FreeBSD_version;
extern char _rtld_version_laddr_offset __exported;
char _rtld_version_laddr_offset;
+
+extern char _rtld_version_dlpi_tls_data __exported;
+char _rtld_version_dlpi_tls_data;
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 5176dd1e9732..e3230de27bb1 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -60,7 +60,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1400006 /* Master, propagated to newvers */
+#define __FreeBSD_version 1400007 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,