git: e6c769620316 - main - rtld: Fix i386/amd64 TP offset when p_vaddr % p_align != 0
Konstantin Belousov
kib at FreeBSD.org
Mon Aug 16 10:56:15 UTC 2021
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=e6c76962031625d51fe4225ecfa15c85155eb13a
commit e6c76962031625d51fe4225ecfa15c85155eb13a
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-16 10:55:34 +0000
rtld: Fix i386/amd64 TP offset when p_vaddr % p_align != 0
For a Variant II architecture, the TP offset of a TLS symbol is st_value -
tlsoffset + r_addend. tlsoffset is computed by either calculate_tls_offset
or calculate_first_tls_offset.
The return value of calculate_first_tls_offset is the smallest integer
satisfying res >= size and (-res) % p_align = p_vaddr % p_align
(= p_offset % p_align). (The formula is a bit contrived. The basic idea
is to subtract the minimum integer from size + align - 1 so that the result
ihas the expected remainder.)
Reviewed by: kib
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D31538
Differential revision: https://reviews.freebsd.org/D31541
---
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-main
mailing list