diff options
| author | Laytan Laats <laytanlaats@hotmail.com> | 2024-03-23 23:17:01 +0100 |
|---|---|---|
| committer | Laytan Laats <laytanlaats@hotmail.com> | 2024-03-23 23:17:01 +0100 |
| commit | 07a9969a41ef32b8063ba574332c231f8b76ef1e (patch) | |
| tree | f30f946857f44208f0d793af3d2660e02c3380ed /src | |
| parent | 517d7ae0b0fd400ceb6a213e7d644c19b8088bfd (diff) | |
darwin: arm64 abi fixes
Since commit b4fe9677a1f69acde12e7cf296269f0c4d98362f some core tests
segfault during build, upon investigation it is because some arg types
were of size 0 and you can't have a 0 sized int.
It also applies the earlier fix for parameters to the return types, this
fixes #3223
Thought I would put this PR up, but I am in no way an expert in abi so
feel free to close for a better fix if there is one.
I am able to run the entire core test suite with `-sanitize:address`
with these changes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/llvm_abi.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 375235752..f976d99b3 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1146,11 +1146,26 @@ namespace lbAbiArm64 { if (size <= 16) { LLVMTypeRef cast_type = nullptr; + GB_ASSERT(size > 0); if (size <= 8) { cast_type = LLVMIntTypeInContext(c, cast(unsigned)(size*8)); } else { unsigned count = cast(unsigned)((size+7)/8); - cast_type = llvm_array_type(LLVMInt64TypeInContext(c), count); + + LLVMTypeRef llvm_i64 = LLVMIntTypeInContext(c, 64); + LLVMTypeRef *types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, count); + + i64 size_copy = size; + for (unsigned i = 0; i < count; i++) { + if (size_copy >= 8) { + types[i] = llvm_i64; + } else { + types[i] = LLVMIntTypeInContext(c, 8*cast(unsigned)size_copy); + } + size_copy -= 8; + } + GB_ASSERT(size_copy <= 0); + cast_type = LLVMStructTypeInContext(c, types, count, true); } return lb_arg_type_direct(return_type, cast_type, nullptr, nullptr); } else { @@ -1183,7 +1198,9 @@ namespace lbAbiArm64 { i64 size = lb_sizeof(type); if (size <= 16) { LLVMTypeRef cast_type = nullptr; - if (size <= 8) { + if (size == 0) { + cast_type = LLVMStructTypeInContext(c, nullptr, 0, false); + } else if (size <= 8) { cast_type = LLVMIntTypeInContext(c, cast(unsigned)(size*8)); } else { unsigned count = cast(unsigned)((size+7)/8); |