diff --git a/libc/config/linux/app.h b/libc/config/linux/app.h index ffd0e01f7b5a45..40a45078f6c8f3 100644 --- a/libc/config/linux/app.h +++ b/libc/config/linux/app.h @@ -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 @@ -74,7 +77,7 @@ struct AppProperties { TLSImage tls; // Environment data. - uint64_t *envPtr; + EnvironType *envPtr; }; extern AppProperties app; diff --git a/libc/startup/linux/riscv64/start.cpp b/libc/startup/linux/riscv64/start.cpp index d68cc9219ecce7..1bf05b94ad5acf 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(env_end_marker + 1); aux_entry->type != AT_NULL; ++aux_entry) { switch (aux_entry->type) { case AT_PHDR: - programHdrTable = reinterpret_cast(aux_entry->value); + programHdrTable = reinterpret_cast(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.