Skip to content

Commit dca49d7

Browse files
[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).
1 parent e951bd0 commit dca49d7

File tree

3 files changed

+8
-23
lines changed

3 files changed

+8
-23
lines changed

libc/config/linux/app.h

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,6 @@ struct TLSImage {
3535
uintptr_t align;
3636
};
3737

38-
#if defined(LIBC_TARGET_ARCH_IS_X86_64) || \
39-
defined(LIBC_TARGET_ARCH_IS_AARCH64) || \
40-
defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
41-
// At the language level, argc is an int. But we use uint64_t as the x86_64
42-
// ABI specifies it as an 8 byte value. Likewise, in the ARM64 ABI, arguments
43-
// are usually passed in registers. x0 is a doubleword register, so this is
44-
// 64 bit for aarch64 as well.
45-
typedef uintptr_t ArgcType;
46-
47-
// At the language level, argv is a char** value. However, we use uint64_t as
48-
// ABIs specify the argv vector be an |argc| long array of 8-byte values.
49-
typedef uintptr_t ArgVEntryType;
50-
51-
typedef uintptr_t EnvironType;
52-
#else
53-
#error "argc and argv types are not defined for the target platform."
54-
#endif
55-
5638
// Linux manpage on `proc(5)` says that the aux vector is an array of
5739
// unsigned long pairs.
5840
// (see: https://man7.org/linux/man-pages/man5/proc.5.html)
@@ -65,15 +47,15 @@ struct AuxEntry {
6547
};
6648

6749
struct Args {
68-
ArgcType argc;
50+
uintptr_t argc;
6951

7052
// A flexible length array would be more suitable here, but C++ doesn't have
7153
// flexible arrays: P1039 proposes to fix this. So, for now we just fake it.
7254
// Even if argc is zero, "argv[argc] shall be a null pointer"
7355
// (ISO C 5.1.2.2.1) so one is fine. Also, length of 1 is not really wrong as
7456
// |argc| is guaranteed to be atleast 1, and there is an 8-byte null entry at
7557
// the end of the argv array.
76-
ArgVEntryType argv[1];
58+
uintptr_t argv[1];
7759
};
7860

7961
// Data structure which captures properties of a linux application.
@@ -87,7 +69,7 @@ struct AppProperties {
8769
TLSImage tls;
8870

8971
// Environment data.
90-
EnvironType *env_ptr;
72+
uintptr_t *env_ptr;
9173

9274
// Auxiliary vector data.
9375
AuxEntry *auxv_ptr;

libc/src/__support/threads/thread.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ union ThreadReturnValue {
4343
defined(LIBC_TARGET_ARCH_IS_X86_64) || \
4444
defined(LIBC_TARGET_ARCH_IS_ANY_RISCV))
4545
constexpr unsigned int STACK_ALIGNMENT = 16;
46+
#elif defined(LIBC_TARGET_ARCH_IS_ARM)
47+
// See Section 6.2.1.2 Stack constraints at a public interface of AAPCS32.
48+
constexpr unsigned int STACK_ALIGNMENT = 8;
4649
#endif
4750
// TODO: Provide stack alignment requirements for other architectures.
4851

libc/startup/linux/do_start.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ static ThreadAttributes main_thread_attrib;
6969
// After the argv array, is a 8-byte long NULL value before the array of env
7070
// values. The end of the env values is marked by another 8-byte long NULL
7171
// value. We step over it (the "+ 1" below) to get to the env values.
72-
ArgVEntryType *env_ptr = app.args->argv + app.args->argc + 1;
73-
ArgVEntryType *env_end_marker = env_ptr;
72+
uintptr_t *env_ptr = app.args->argv + app.args->argc + 1;
73+
uintptr_t *env_end_marker = env_ptr;
7474
app.env_ptr = env_ptr;
7575
while (*env_end_marker)
7676
++env_end_marker;

0 commit comments

Comments
 (0)