[libc-commits] [libc] [libc] support PIE relocations (PR #78993)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Mon Jan 22 08:33:07 PST 2024


https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/78993

>From c017a96cd0fb07ce69e0ecb077d843f0fcab0574 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Mon, 22 Jan 2024 10:22:39 -0500
Subject: [PATCH 1/2] [libc] support PIE relocations

---
 libc/startup/linux/do_start.cpp | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/libc/startup/linux/do_start.cpp b/libc/startup/linux/do_start.cpp
index 05dbd4488f5882..36f065e4f829a2 100644
--- a/libc/startup/linux/do_start.cpp
+++ b/libc/startup/linux/do_start.cpp
@@ -29,6 +29,9 @@ extern uintptr_t __init_array_start[];
 extern uintptr_t __init_array_end[];
 extern uintptr_t __fini_array_start[];
 extern uintptr_t __fini_array_end[];
+// https://refspecs.linuxbase.org/elf/gabi4+/ch5.dynamic.html#dynamic_section
+[[gnu::weak,
+  gnu::visibility("hidden")]] extern const Elf64_Dyn _DYNAMIC[]; // NOLINT
 }
 
 namespace LIBC_NAMESPACE {
@@ -94,18 +97,26 @@ static ThreadAttributes main_thread_attrib;
     }
   }
 
+  ptrdiff_t base = 0;
   app.tls.size = 0;
+  Elf64_Phdr *tls_phdr = nullptr;
+
   for (uintptr_t i = 0; i < program_hdr_count; ++i) {
-    Elf64_Phdr *phdr = program_hdr_table + i;
-    if (phdr->p_type != PT_TLS)
-      continue;
-    // TODO: p_vaddr value has to be adjusted for static-pie executables.
-    app.tls.address = phdr->p_vaddr;
-    app.tls.size = phdr->p_memsz;
-    app.tls.init_size = phdr->p_filesz;
-    app.tls.align = phdr->p_align;
+    auto &phdr = program_hdr_table[i];
+    if (phdr.p_type == PT_PHDR)
+      base = reinterpret_cast<ptrdiff_t>(program_hdr_table) - phdr.p_vaddr;
+    if (phdr.p_type == PT_DYNAMIC && _DYNAMIC)
+      base = reinterpret_cast<ptrdiff_t>(_DYNAMIC) - phdr.p_vaddr;
+    if (phdr.p_type == PT_TLS)
+      tls_phdr = &phdr;
+    // TODO: adjust PT_GNU_STACK
   }
 
+  app.tls.address = tls_phdr->p_vaddr + base;
+  app.tls.size = tls_phdr->p_memsz;
+  app.tls.init_size = tls_phdr->p_filesz;
+  app.tls.align = tls_phdr->p_align;
+
   // This descriptor has to be static since its cleanup function cannot
   // capture the context.
   static TLSDescriptor tls;

>From b686a337e279a57c3918b5145135ce1ba462db05 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Mon, 22 Jan 2024 11:32:54 -0500
Subject: [PATCH 2/2] address CR

---
 libc/startup/linux/do_start.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libc/startup/linux/do_start.cpp b/libc/startup/linux/do_start.cpp
index 36f065e4f829a2..10b215cdc27b7e 100644
--- a/libc/startup/linux/do_start.cpp
+++ b/libc/startup/linux/do_start.cpp
@@ -30,6 +30,8 @@ extern uintptr_t __init_array_end[];
 extern uintptr_t __fini_array_start[];
 extern uintptr_t __fini_array_end[];
 // https://refspecs.linuxbase.org/elf/gabi4+/ch5.dynamic.html#dynamic_section
+// This symbol is provided by the dynamic linker. It can be undefined depending
+// on how the program is loaded exactly.
 [[gnu::weak,
   gnu::visibility("hidden")]] extern const Elf64_Dyn _DYNAMIC[]; // NOLINT
 }
@@ -102,7 +104,7 @@ static ThreadAttributes main_thread_attrib;
   Elf64_Phdr *tls_phdr = nullptr;
 
   for (uintptr_t i = 0; i < program_hdr_count; ++i) {
-    auto &phdr = program_hdr_table[i];
+    Elf64_Phdr &phdr = program_hdr_table[i];
     if (phdr.p_type == PT_PHDR)
       base = reinterpret_cast<ptrdiff_t>(program_hdr_table) - phdr.p_vaddr;
     if (phdr.p_type == PT_DYNAMIC && _DYNAMIC)



More information about the libc-commits mailing list