Skip to content

Commit

Permalink
[mono] Fix SwiftError variable offset calculation (#103043)
Browse files Browse the repository at this point in the history
* Avoid var allocation when SwiftError is passed via the stack

* Refactor Security.Cryptography tests to pass SwiftError at the end of the signature
  • Loading branch information
kotlarmilos authored Jun 17, 2024
1 parent d85716e commit 193b826
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ internal static unsafe void ChaCha20Poly1305Encrypt(
fixed (byte* aadPtr = &GetSwiftRef(aad))
{
AppleCryptoNative_ChaCha20Poly1305Encrypt(
out SwiftError error,
new UnsafeBufferPointer<byte>(keyPtr, key.Length),
new UnsafeBufferPointer<byte>(noncePtr, nonce.Length),
new UnsafeBufferPointer<byte>(plaintextPtr, plaintext.Length),
new UnsafeMutableBufferPointer<byte>(ciphertextPtr, ciphertext.Length),
new UnsafeMutableBufferPointer<byte>(tagPtr, tag.Length),
new UnsafeBufferPointer<byte>(aadPtr, aad.Length));
new UnsafeBufferPointer<byte>(aadPtr, aad.Length),
out SwiftError error);

if (error.Value != null)
{
Expand All @@ -76,13 +76,13 @@ internal static unsafe void ChaCha20Poly1305Decrypt(
fixed (byte* aadPtr = &GetSwiftRef(aad))
{
AppleCryptoNative_ChaCha20Poly1305Decrypt(
out SwiftError error,
new UnsafeBufferPointer<byte>(keyPtr, key.Length),
new UnsafeBufferPointer<byte>(noncePtr, nonce.Length),
new UnsafeBufferPointer<byte>(ciphertextPtr, ciphertext.Length),
new UnsafeBufferPointer<byte>(tagPtr, tag.Length),
new UnsafeMutableBufferPointer<byte>(plaintextPtr, plaintext.Length),
new UnsafeBufferPointer<byte>(aadPtr, aad.Length));
new UnsafeBufferPointer<byte>(aadPtr, aad.Length),
out SwiftError error);

if (error.Value != null)
{
Expand Down Expand Up @@ -116,13 +116,13 @@ internal static unsafe void AesGcmEncrypt(
fixed (byte* aadPtr = &GetSwiftRef(aad))
{
AppleCryptoNative_AesGcmEncrypt(
out SwiftError error,
new UnsafeBufferPointer<byte>(keyPtr, key.Length),
new UnsafeBufferPointer<byte>(noncePtr, nonce.Length),
new UnsafeBufferPointer<byte>(plaintextPtr, plaintext.Length),
new UnsafeMutableBufferPointer<byte>(ciphertextPtr, ciphertext.Length),
new UnsafeMutableBufferPointer<byte>(tagPtr, tag.Length),
new UnsafeBufferPointer<byte>(aadPtr, aad.Length));
new UnsafeBufferPointer<byte>(aadPtr, aad.Length),
out SwiftError error);

if (error.Value != null)
{
Expand All @@ -149,13 +149,13 @@ internal static unsafe void AesGcmDecrypt(
fixed (byte* aadPtr = &GetSwiftRef(aad))
{
AppleCryptoNative_AesGcmDecrypt(
out SwiftError error,
new UnsafeBufferPointer<byte>(keyPtr, key.Length),
new UnsafeBufferPointer<byte>(noncePtr, nonce.Length),
new UnsafeBufferPointer<byte>(ciphertextPtr, ciphertext.Length),
new UnsafeBufferPointer<byte>(tagPtr, tag.Length),
new UnsafeMutableBufferPointer<byte>(plaintextPtr, plaintext.Length),
new UnsafeBufferPointer<byte>(aadPtr, aad.Length));
new UnsafeBufferPointer<byte>(aadPtr, aad.Length),
out SwiftError error);

if (error.Value != null)
{
Expand All @@ -176,46 +176,46 @@ internal static unsafe void AesGcmDecrypt(
[LibraryImport(Libraries.AppleCryptoNative)]
[UnmanagedCallConv(CallConvs = [ typeof(CallConvSwift) ])]
private static unsafe partial void AppleCryptoNative_ChaCha20Poly1305Encrypt(
out SwiftError error,
UnsafeBufferPointer<byte> key,
UnsafeBufferPointer<byte> nonce,
UnsafeBufferPointer<byte> plaintext,
UnsafeMutableBufferPointer<byte> ciphertext,
UnsafeMutableBufferPointer<byte> tag,
UnsafeBufferPointer<byte> aad);
UnsafeBufferPointer<byte> aad,
out SwiftError error);

[LibraryImport(Libraries.AppleCryptoNative)]
[UnmanagedCallConv(CallConvs = [ typeof(CallConvSwift) ])]
private static unsafe partial void AppleCryptoNative_ChaCha20Poly1305Decrypt(
out SwiftError error,
UnsafeBufferPointer<byte> key,
UnsafeBufferPointer<byte> nonce,
UnsafeBufferPointer<byte> ciphertext,
UnsafeBufferPointer<byte> tag,
UnsafeMutableBufferPointer<byte> plaintext,
UnsafeBufferPointer<byte> aad);
UnsafeBufferPointer<byte> aad,
out SwiftError error);

[LibraryImport(Libraries.AppleCryptoNative)]
[UnmanagedCallConv(CallConvs = [ typeof(CallConvSwift) ])]
private static unsafe partial void AppleCryptoNative_AesGcmEncrypt(
out SwiftError error,
UnsafeBufferPointer<byte> key,
UnsafeBufferPointer<byte> nonce,
UnsafeBufferPointer<byte> plaintext,
UnsafeMutableBufferPointer<byte> ciphertext,
UnsafeMutableBufferPointer<byte> tag,
UnsafeBufferPointer<byte> aad);
UnsafeBufferPointer<byte> aad,
out SwiftError error);

[LibraryImport(Libraries.AppleCryptoNative)]
[UnmanagedCallConv(CallConvs = [ typeof(CallConvSwift) ])]
private static unsafe partial void AppleCryptoNative_AesGcmDecrypt(
out SwiftError error,
UnsafeBufferPointer<byte> key,
UnsafeBufferPointer<byte> nonce,
UnsafeBufferPointer<byte> ciphertext,
UnsafeBufferPointer<byte> tag,
UnsafeMutableBufferPointer<byte> plaintext,
UnsafeBufferPointer<byte> aad);
UnsafeBufferPointer<byte> aad,
out SwiftError error);

[LibraryImport(Libraries.AppleCryptoNative)]
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvSwift) })]
Expand Down
31 changes: 16 additions & 15 deletions src/mono/mono/mini/mini-amd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1989,26 +1989,30 @@ mono_arch_allocate_vars (MonoCompile *cfg)
break;
}
case ArgSwiftError: {
inreg = FALSE;
if (ainfo->offset)
{
ins->opcode = OP_REGOFFSET;
offset = ALIGN_TO (offset, sizeof (target_mgreg_t));
ins->inst_basereg = cfg->frame_reg;
ins->inst_offset = offset;
offset += sizeof (target_mgreg_t);
ins->inst_offset = ainfo->offset + ARGS_OFFSET;
inreg = TRUE;
}

cfg->arch.swift_error_var = ins;
cfg->arch.swift_error_var = ins;

/* In the n2m case, the error register functions as an extra return register
* and is thus is not treated as callee-saved.
*/
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
cfg->used_int_regs |= (size_t)(1 << AMD64_R12);

/* In the n2m case, the error register functions as an extra return register
* and is thus is not treated as callee-saved.
*/
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
cfg->used_int_regs |= (size_t)(1 << AMD64_R12);
}
break;
}
default:
NOT_IMPLEMENTED;
}

if (!inreg && (ainfo->storage != ArgOnStack) && (ainfo->storage != ArgValuetypeAddrInIReg) && (ainfo->storage != ArgValuetypeAddrOnStack) && (ainfo->storage != ArgGSharedVtOnStack) && (ainfo->storage != ArgSwiftError)) {
if (!inreg && (ainfo->storage != ArgOnStack) && (ainfo->storage != ArgValuetypeAddrInIReg) && (ainfo->storage != ArgValuetypeAddrOnStack) && (ainfo->storage != ArgGSharedVtOnStack)) {
ins->opcode = OP_REGOFFSET;
ins->inst_basereg = cfg->frame_reg;
/* These arguments are saved to the stack in the prolog */
Expand Down Expand Up @@ -8259,10 +8263,7 @@ MONO_RESTORE_WARNING
break;
case ArgSwiftError:
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
if (ainfo->offset) {
amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, ARGS_OFFSET + ainfo->offset, 8);
amd64_mov_membase_reg (code, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset, AMD64_R11, sizeof (target_mgreg_t));
} else {
if (ainfo->offset == 0) {
amd64_mov_membase_reg (code, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset, ainfo->reg, sizeof (target_mgreg_t));
}
} else if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
Expand Down
20 changes: 9 additions & 11 deletions src/mono/mono/mini/mini-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -2877,14 +2877,15 @@ mono_arch_allocate_vars (MonoCompile *cfg)
}
case ArgSwiftError: {
ins->flags |= MONO_INST_VOLATILE;
size = 8;
align = 8;
offset += align - 1;
offset &= ~(align - 1);
ins->opcode = OP_REGOFFSET;
ins->inst_basereg = cfg->frame_reg;
ins->inst_offset = offset;
offset += size;
if (ainfo->offset) {
g_assert (cfg->arch.args_reg);
ins->inst_basereg = cfg->arch.args_reg;
ins->inst_offset = ainfo->offset;
} else {
ins->inst_offset = offset;
offset += 8;
}

cfg->arch.swift_error_var = ins;

Expand Down Expand Up @@ -5955,10 +5956,7 @@ emit_move_args (MonoCompile *cfg, guint8 *code)
break;
case ArgSwiftError:
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
if (ainfo->offset) {
code = emit_ldrx (code, ARMREG_IP0, cfg->arch.args_reg, ainfo->offset);
code = emit_strx (code, ARMREG_IP0, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
} else {
if (ainfo->offset == 0) {
code = emit_strx (code, ainfo->reg, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
}
} else if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
Expand Down

0 comments on commit 193b826

Please sign in to comment.