Skip to content

Commit 72e6f06

Browse files
[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.
1 parent 4f63252 commit 72e6f06

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

libc/config/linux/app.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@ struct TLSImage {
4242
// ABI specifies it as an 8 byte value. Likewise, in the ARM64 ABI, arguments
4343
// are usually passed in registers. x0 is a doubleword register, so this is
4444
// 64 bit for aarch64 as well.
45-
typedef uint64_t ArgcType;
45+
typedef uintptr_t ArgcType;
4646

4747
// At the language level, argv is a char** value. However, we use uint64_t as
4848
// ABIs specify the argv vector be an |argc| long array of 8-byte values.
49-
typedef uint64_t ArgVEntryType;
49+
typedef uintptr_t ArgVEntryType;
50+
51+
typedef uintptr_t EnvironType;
52+
typedef uintptr_t AuxEntryType;
5053
#else
5154
#error "argc and argv types are not defined for the target platform."
5255
#endif
@@ -74,7 +77,7 @@ struct AppProperties {
7477
TLSImage tls;
7578

7679
// Environment data.
77-
uint64_t *envPtr;
80+
EnvironType *envPtr;
7881
};
7982

8083
extern AppProperties app;

libc/startup/linux/riscv64/start.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,20 @@ using __llvm_libc::app;
118118

119119
// TODO: Would be nice to use the aux entry structure from elf.h when available.
120120
struct AuxEntry {
121-
uint64_t type;
122-
uint64_t value;
121+
__llvm_libc::AuxEntryType type;
122+
__llvm_libc::AuxEntryType value;
123123
};
124124

125+
#if defined(LIBC_TARGET_ARCH_IS_X86_64) || \
126+
defined(LIBC_TARGET_ARCH_IS_AARCH64) || \
127+
defined(LIBC_TARGET_ARCH_IS_RISCV64)
128+
typedef Elf64_Phdr PgrHdrTableType;
129+
#elif defined(LIBC_TARGET_ARCH_IS_RISCV32)
130+
typedef Elf32_Phdr PgrHdrTableType;
131+
#else
132+
#error "Program header table type is not defined for the target platform."
133+
#endif
134+
125135
__attribute__((noinline)) static void do_start() {
126136
LIBC_INLINE_ASM(".option push\n\t"
127137
".option norelax\n\t"
@@ -135,8 +145,8 @@ __attribute__((noinline)) static void do_start() {
135145
// After the argv array, is a 8-byte long NULL value before the array of env
136146
// values. The end of the env values is marked by another 8-byte long NULL
137147
// value. We step over it (the "+ 1" below) to get to the env values.
138-
uint64_t *env_ptr = app.args->argv + app.args->argc + 1;
139-
uint64_t *env_end_marker = env_ptr;
148+
__llvm_libc::ArgVEntryType *env_ptr = app.args->argv + app.args->argc + 1;
149+
__llvm_libc::ArgVEntryType *env_end_marker = env_ptr;
140150
app.envPtr = env_ptr;
141151
while (*env_end_marker)
142152
++env_end_marker;
@@ -146,13 +156,13 @@ __attribute__((noinline)) static void do_start() {
146156

147157
// After the env array, is the aux-vector. The end of the aux-vector is
148158
// denoted by an AT_NULL entry.
149-
Elf64_Phdr *programHdrTable = nullptr;
159+
PgrHdrTableType *programHdrTable = nullptr;
150160
uintptr_t programHdrCount;
151161
for (AuxEntry *aux_entry = reinterpret_cast<AuxEntry *>(env_end_marker + 1);
152162
aux_entry->type != AT_NULL; ++aux_entry) {
153163
switch (aux_entry->type) {
154164
case AT_PHDR:
155-
programHdrTable = reinterpret_cast<Elf64_Phdr *>(aux_entry->value);
165+
programHdrTable = reinterpret_cast<PgrHdrTableType *>(aux_entry->value);
156166
break;
157167
case AT_PHNUM:
158168
programHdrCount = aux_entry->value;
@@ -167,7 +177,7 @@ __attribute__((noinline)) static void do_start() {
167177

168178
app.tls.size = 0;
169179
for (uintptr_t i = 0; i < programHdrCount; ++i) {
170-
Elf64_Phdr *phdr = programHdrTable + i;
180+
PgrHdrTableType *phdr = programHdrTable + i;
171181
if (phdr->p_type != PT_TLS)
172182
continue;
173183
// TODO: p_vaddr value has to be adjusted for static-pie executables.

0 commit comments

Comments
 (0)