Skip to content

Commit

Permalink
[libc] Fix start up crash on 32 bit systems (#66210)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mikhailramalho committed Sep 14, 2023
1 parent 4f63252 commit 72e6f06
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 10 deletions.
9 changes: 6 additions & 3 deletions libc/config/linux/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@ struct TLSImage {
// ABI specifies it as an 8 byte value. Likewise, in the ARM64 ABI, arguments
// are usually passed in registers. x0 is a doubleword register, so this is
// 64 bit for aarch64 as well.
typedef uint64_t ArgcType;
typedef uintptr_t ArgcType;

// At the language level, argv is a char** value. However, we use uint64_t as
// ABIs specify the argv vector be an |argc| long array of 8-byte values.
typedef uint64_t ArgVEntryType;
typedef uintptr_t ArgVEntryType;

typedef uintptr_t EnvironType;
typedef uintptr_t AuxEntryType;
#else
#error "argc and argv types are not defined for the target platform."
#endif
Expand Down Expand Up @@ -74,7 +77,7 @@ struct AppProperties {
TLSImage tls;

// Environment data.
uint64_t *envPtr;
EnvironType *envPtr;
};

extern AppProperties app;
Expand Down
24 changes: 17 additions & 7 deletions libc/startup/linux/riscv64/start.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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.
Expand Down

0 comments on commit 72e6f06

Please sign in to comment.