Skip to content

Commit 0fe20aa

Browse files
[libc] support PIE relocations (#78993)
For some reasons, we are using `-fpie` (libc/cmake/modules/LLVMLibCObjectRules.cmake:31) without supporting it. According to @lntue, some of the hermetic tests are broken without proper PIE support. This patch implements basic relocations support for PIE.
1 parent 02f95b7 commit 0fe20aa

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

libc/startup/linux/do_start.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ extern uintptr_t __init_array_start[];
2929
extern uintptr_t __init_array_end[];
3030
extern uintptr_t __fini_array_start[];
3131
extern uintptr_t __fini_array_end[];
32+
// https://refspecs.linuxbase.org/elf/gabi4+/ch5.dynamic.html#dynamic_section
33+
// This symbol is provided by the dynamic linker. It can be undefined depending
34+
// on how the program is loaded exactly.
35+
[[gnu::weak,
36+
gnu::visibility("hidden")]] extern const Elf64_Dyn _DYNAMIC[]; // NOLINT
3237
}
3338

3439
namespace LIBC_NAMESPACE {
@@ -94,18 +99,26 @@ static ThreadAttributes main_thread_attrib;
9499
}
95100
}
96101

102+
ptrdiff_t base = 0;
97103
app.tls.size = 0;
104+
Elf64_Phdr *tls_phdr = nullptr;
105+
98106
for (uintptr_t i = 0; i < program_hdr_count; ++i) {
99-
Elf64_Phdr *phdr = program_hdr_table + i;
100-
if (phdr->p_type != PT_TLS)
101-
continue;
102-
// TODO: p_vaddr value has to be adjusted for static-pie executables.
103-
app.tls.address = phdr->p_vaddr;
104-
app.tls.size = phdr->p_memsz;
105-
app.tls.init_size = phdr->p_filesz;
106-
app.tls.align = phdr->p_align;
107+
Elf64_Phdr &phdr = program_hdr_table[i];
108+
if (phdr.p_type == PT_PHDR)
109+
base = reinterpret_cast<ptrdiff_t>(program_hdr_table) - phdr.p_vaddr;
110+
if (phdr.p_type == PT_DYNAMIC && _DYNAMIC)
111+
base = reinterpret_cast<ptrdiff_t>(_DYNAMIC) - phdr.p_vaddr;
112+
if (phdr.p_type == PT_TLS)
113+
tls_phdr = &phdr;
114+
// TODO: adjust PT_GNU_STACK
107115
}
108116

117+
app.tls.address = tls_phdr->p_vaddr + base;
118+
app.tls.size = tls_phdr->p_memsz;
119+
app.tls.init_size = tls_phdr->p_filesz;
120+
app.tls.align = tls_phdr->p_align;
121+
109122
// This descriptor has to be static since its cleanup function cannot
110123
// capture the context.
111124
static TLSDescriptor tls;

0 commit comments

Comments
 (0)