git: a3c0eaa3c286 - stable/13 - rtld: Fix i386/amd64 TP offset when p_vaddr % p_align != 0

Konstantin Belousov kib at FreeBSD.org
Mon Aug 23 09:21:51 UTC 2021


The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=a3c0eaa3c286b8d29247c65463b73d35f7795a86

commit a3c0eaa3c286b8d29247c65463b73d35f7795a86
Author:     Fangrui Song <i at maskray.me>
AuthorDate: 2021-08-14 16:56:58 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-08-23 09:20:56 +0000

    rtld: Fix i386/amd64 TP offset when p_vaddr % p_align != 0
    
    (cherry picked from commit e6c76962031625d51fe4225ecfa15c85155eb13a)
---
 libexec/rtld-elf/amd64/reloc.c | 27 ++++++++++++---------------
 libexec/rtld-elf/i386/reloc.c  | 27 ++++++++++++---------------
 2 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/libexec/rtld-elf/amd64/reloc.c b/libexec/rtld-elf/amd64/reloc.c
index 689b0d8635d4..508ae04a7448 100644
--- a/libexec/rtld-elf/amd64/reloc.c
+++ b/libexec/rtld-elf/amd64/reloc.c
@@ -548,29 +548,26 @@ __tls_get_addr(tls_index *ti)
 }
 
 size_t
-calculate_first_tls_offset(size_t size, size_t align, size_t offset)
+calculate_tls_offset(size_t prev_offset, size_t prev_size __unused,
+    size_t size, size_t align, size_t offset)
 {
 	size_t res;
 
-	res = roundup(size, align);
-	offset &= align - 1;
-	if (offset != 0)
-		res += align - offset;
-	return (res);
+        /*
+	 * res is the smallest integer satisfying res - prev_offset >= size
+         * and (-res) % p_align = p_vaddr % p_align (= p_offset % p_align).
+	 */
+        res = prev_offset + size + align - 1;
+        res -= (res + offset) & (align - 1);
+        return (res);
 }
 
 size_t
-calculate_tls_offset(size_t prev_offset, size_t prev_size __unused, size_t size,
-    size_t align, size_t offset)
+calculate_first_tls_offset(size_t size, size_t align, size_t offset)
 {
-	size_t res;
-
-	res = roundup(prev_offset + size, align);
-	offset &= align - 1;
-	if (offset != 0)
-		res += align - offset;
-	return (res);
+	return (calculate_tls_offset(0, 0, size, align, offset));
 }
+
 size_t
 calculate_tls_end(size_t off, size_t size __unused)
 {
diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c
index cab163b35e6a..69da93347bbb 100644
--- a/libexec/rtld-elf/i386/reloc.c
+++ b/libexec/rtld-elf/i386/reloc.c
@@ -539,29 +539,26 @@ __tls_get_addr(tls_index *ti)
 }
 
 size_t
-calculate_first_tls_offset(size_t size, size_t align, size_t offset)
+calculate_tls_offset(size_t prev_offset, size_t prev_size __unused,
+    size_t size, size_t align, size_t offset)
 {
 	size_t res;
 
-	res = roundup(size, align);
-	offset &= align - 1;
-	if (offset != 0)
-		res += align - offset;
-	return (res);
+        /*
+	 * res is the smallest integer satisfying res - prev_offset >= size
+         * and (-res) % p_align = p_vaddr % p_align (= p_offset % p_align).
+	 */
+        res = prev_offset + size + align - 1;
+        res -= (res + offset) & (align - 1);
+        return (res);
 }
 
 size_t
-calculate_tls_offset(size_t prev_offset, size_t prev_size __unused, size_t size,
-    size_t align, size_t offset)
+calculate_first_tls_offset(size_t size, size_t align, size_t offset)
 {
-	size_t res;
-
-	res = roundup(prev_offset + size, align);
-	offset &= align - 1;
-	if (offset != 0)
-		res += align - offset;
-	return (res);
+	return (calculate_tls_offset(0, 0, size, align, offset));
 }
+
 size_t
 calculate_tls_end(size_t off, size_t size __unused)
 {


More information about the dev-commits-src-branches mailing list