diff options
author | Nick Desaulniers (paternity leave) <nickdesaulniers@users.noreply.github.com> | 2024-06-25 09:04:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-25 09:04:19 -0700 |
commit | dca49d739de07b1755ad65aa26dacd2e2c22af20 (patch) | |
tree | 8f1d99804f454be310c45ce46fcdbd84d82e5a25 | |
parent | e951bd0f51f8b077296f09d9c60ddf150048042f (diff) | |
download | llvm-dca49d739de07b1755ad65aa26dacd2e2c22af20.zip llvm-dca49d739de07b1755ad65aa26dacd2e2c22af20.tar.gz llvm-dca49d739de07b1755ad65aa26dacd2e2c22af20.tar.bz2 |
[libc][arm32] define argc type and stack alignment (#96367)
https://github.com/ARM-software/abi-aa/blob/main/aapcs32/aapcs32.rst#6212stack-constraints-at-a-public-interface
mentions that the stack on ARM32 is double word aligned.
Remove confused comments around ArgcType. argc is always an int, passed on the
stack, so we need to store a pointer to it (regardless of ILP32 or LP64).
-rw-r--r-- | libc/config/linux/app.h | 24 | ||||
-rw-r--r-- | libc/src/__support/threads/thread.h | 3 | ||||
-rw-r--r-- | libc/startup/linux/do_start.cpp | 4 |
3 files changed, 8 insertions, 23 deletions
diff --git a/libc/config/linux/app.h b/libc/config/linux/app.h index 766cd49..2a3b156 100644 --- a/libc/config/linux/app.h +++ b/libc/config/linux/app.h @@ -35,24 +35,6 @@ struct TLSImage { uintptr_t align; }; -#if defined(LIBC_TARGET_ARCH_IS_X86_64) || \ - defined(LIBC_TARGET_ARCH_IS_AARCH64) || \ - defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) -// At the language level, argc is an int. But we use uint64_t as the x86_64 -// 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 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 uintptr_t ArgVEntryType; - -typedef uintptr_t EnvironType; -#else -#error "argc and argv types are not defined for the target platform." -#endif - // Linux manpage on `proc(5)` says that the aux vector is an array of // unsigned long pairs. // (see: https://man7.org/linux/man-pages/man5/proc.5.html) @@ -65,7 +47,7 @@ struct AuxEntry { }; struct Args { - ArgcType argc; + uintptr_t argc; // A flexible length array would be more suitable here, but C++ doesn't have // flexible arrays: P1039 proposes to fix this. So, for now we just fake it. @@ -73,7 +55,7 @@ struct Args { // (ISO C 5.1.2.2.1) so one is fine. Also, length of 1 is not really wrong as // |argc| is guaranteed to be atleast 1, and there is an 8-byte null entry at // the end of the argv array. - ArgVEntryType argv[1]; + uintptr_t argv[1]; }; // Data structure which captures properties of a linux application. @@ -87,7 +69,7 @@ struct AppProperties { TLSImage tls; // Environment data. - EnvironType *env_ptr; + uintptr_t *env_ptr; // Auxiliary vector data. AuxEntry *auxv_ptr; diff --git a/libc/src/__support/threads/thread.h b/libc/src/__support/threads/thread.h index acfe338..f89c687 100644 --- a/libc/src/__support/threads/thread.h +++ b/libc/src/__support/threads/thread.h @@ -43,6 +43,9 @@ union ThreadReturnValue { defined(LIBC_TARGET_ARCH_IS_X86_64) || \ defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)) constexpr unsigned int STACK_ALIGNMENT = 16; +#elif defined(LIBC_TARGET_ARCH_IS_ARM) +// See Section 6.2.1.2 Stack constraints at a public interface of AAPCS32. +constexpr unsigned int STACK_ALIGNMENT = 8; #endif // TODO: Provide stack alignment requirements for other architectures. diff --git a/libc/startup/linux/do_start.cpp b/libc/startup/linux/do_start.cpp index 3d7d32a..30ab1f0 100644 --- a/libc/startup/linux/do_start.cpp +++ b/libc/startup/linux/do_start.cpp @@ -69,8 +69,8 @@ static ThreadAttributes main_thread_attrib; // 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. - ArgVEntryType *env_ptr = app.args->argv + app.args->argc + 1; - ArgVEntryType *env_end_marker = env_ptr; + uintptr_t *env_ptr = app.args->argv + app.args->argc + 1; + uintptr_t *env_end_marker = env_ptr; app.env_ptr = env_ptr; while (*env_end_marker) ++env_end_marker; |