diff options
author | Mikhail R. Gadelha <mikhail@igalia.com> | 2023-09-14 10:02:35 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-14 09:02:35 -0400 |
commit | 72e6f06119a10babeb259c42c1ffcc71253e9081 (patch) | |
tree | 08fb5eec558dce91063095b38de1512c735e2791 /libc/startup | |
parent | 4f63252d5d0acfc32633a36e18fff469a606e6ce (diff) | |
download | llvm-72e6f06119a10babeb259c42c1ffcc71253e9081.zip llvm-72e6f06119a10babeb259c42c1ffcc71253e9081.tar.gz llvm-72e6f06119a10babeb259c42c1ffcc71253e9081.tar.bz2 |
[libc] Fix start up crash on 32 bit systems (#66210)
This patch changes the default types of argc/argv so it's no longer a
uint64_t in all systems, instead, it's now a uintptr_t, which fixes
crashes in 32-bit systems that expect 32-bit types. This patch also adds
two uintptr_t types (EnvironType and AuxEntryType) for the same reason.
The patch also adds a PgrHdrTableType type behind an ifdef that's
Elf64_Phdr in 64-bit systems and Elf32_Phdr in 32-bit systems.
Diffstat (limited to 'libc/startup')
-rw-r--r-- | libc/startup/linux/riscv64/start.cpp | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/libc/startup/linux/riscv64/start.cpp b/libc/startup/linux/riscv64/start.cpp index d68cc92..1bf05b9 100644 --- a/libc/startup/linux/riscv64/start.cpp +++ b/libc/startup/linux/riscv64/start.cpp @@ -118,10 +118,20 @@ using __llvm_libc::app; // TODO: Would be nice to use the aux entry structure from elf.h when available. struct AuxEntry { - uint64_t type; - uint64_t value; + __llvm_libc::AuxEntryType type; + __llvm_libc::AuxEntryType value; }; +#if defined(LIBC_TARGET_ARCH_IS_X86_64) || \ + defined(LIBC_TARGET_ARCH_IS_AARCH64) || \ + defined(LIBC_TARGET_ARCH_IS_RISCV64) +typedef Elf64_Phdr PgrHdrTableType; +#elif defined(LIBC_TARGET_ARCH_IS_RISCV32) +typedef Elf32_Phdr PgrHdrTableType; +#else +#error "Program header table type is not defined for the target platform." +#endif + __attribute__((noinline)) static void do_start() { LIBC_INLINE_ASM(".option push\n\t" ".option norelax\n\t" @@ -135,8 +145,8 @@ __attribute__((noinline)) static void do_start() { // After the argv array, is a 8-byte long NULL value before the array of env // values. The end of the env values is marked by another 8-byte long NULL // value. We step over it (the "+ 1" below) to get to the env values. - uint64_t *env_ptr = app.args->argv + app.args->argc + 1; - uint64_t *env_end_marker = env_ptr; + __llvm_libc::ArgVEntryType *env_ptr = app.args->argv + app.args->argc + 1; + __llvm_libc::ArgVEntryType *env_end_marker = env_ptr; app.envPtr = env_ptr; while (*env_end_marker) ++env_end_marker; @@ -146,13 +156,13 @@ __attribute__((noinline)) static void do_start() { // After the env array, is the aux-vector. The end of the aux-vector is // denoted by an AT_NULL entry. - Elf64_Phdr *programHdrTable = nullptr; + PgrHdrTableType *programHdrTable = nullptr; uintptr_t programHdrCount; for (AuxEntry *aux_entry = reinterpret_cast<AuxEntry *>(env_end_marker + 1); aux_entry->type != AT_NULL; ++aux_entry) { switch (aux_entry->type) { case AT_PHDR: - programHdrTable = reinterpret_cast<Elf64_Phdr *>(aux_entry->value); + programHdrTable = reinterpret_cast<PgrHdrTableType *>(aux_entry->value); break; case AT_PHNUM: programHdrCount = aux_entry->value; @@ -167,7 +177,7 @@ __attribute__((noinline)) static void do_start() { app.tls.size = 0; for (uintptr_t i = 0; i < programHdrCount; ++i) { - Elf64_Phdr *phdr = programHdrTable + i; + PgrHdrTableType *phdr = programHdrTable + i; if (phdr->p_type != PT_TLS) continue; // TODO: p_vaddr value has to be adjusted for static-pie executables. |