Skip to content

Commit 7299391

Browse files
committed
VaListX64 vs. VaListArm64
1 parent 9ffb490 commit 7299391

File tree

1 file changed

+40
-14
lines changed

1 file changed

+40
-14
lines changed

src/Sentry/Platforms/Native/CFunctions.cs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ internal static void SetValueIfNotNull(sentry_value_t obj, string key, double? v
8282
public static bool Init(SentryOptions options)
8383
{
8484
_isWindows = System.OperatingSystem.IsWindows();
85+
_isArm64 = RuntimeInformation.OSArchitecture == Architecture.Arm64;
86+
8587
var cOptions = sentry_options_new();
8688

8789
// Note: DSN is not null because options.IsValid() must have returned true for this to be called.
@@ -442,6 +444,7 @@ private static void nativeTransportFree(IntPtr state)
442444
// The logger we should forward native messages to. This is referenced by nativeLog() which in turn for.
443445
private static IDiagnosticLogger? _logger;
444446
private static bool _isWindows = false;
447+
private static bool _isArm64 = false;
445448

446449
// This method is called from the C library and forwards incoming messages to the currently set _logger.
447450
// [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })] // error CS3016: Arrays as attribute arguments is not CLS-complian
@@ -495,21 +498,14 @@ private static void nativeLogImpl(int cLevel, IntPtr format, IntPtr args, IntPtr
495498
message = Marshal.PtrToStringAnsi(buffer);
496499
});
497500
}
501+
// For Linux/macOS, we must make a copy of the VaList to be able to pass it back...
502+
else if (_isArm64)
503+
{
504+
message = FormatWithVaList<VaListArm64>(format, args);
505+
}
498506
else
499507
{
500-
// For Linux/macOS, we must make a copy of the VaList to be able to pass it back...
501-
var argsStruct = Marshal.PtrToStructure<VaListLinux64>(args);
502-
var formattedLength = 0;
503-
WithMarshalledStruct(argsStruct, argsPtr =>
504-
formattedLength = 1 + vsnprintf_linux(IntPtr.Zero, UIntPtr.Zero, format, argsPtr)
505-
);
506-
507-
WithAllocatedPtr(formattedLength, buffer =>
508-
WithMarshalledStruct(argsStruct, argsPtr =>
509-
{
510-
vsnprintf_linux(buffer, (UIntPtr)formattedLength, format, argsPtr);
511-
message = Marshal.PtrToStringAnsi(buffer);
512-
}));
508+
message = FormatWithVaList<VaListX64>(format, args);
513509
}
514510
}
515511
catch (Exception err)
@@ -534,14 +530,25 @@ private static void nativeLogImpl(int cLevel, IntPtr format, IntPtr args, IntPtr
534530

535531
// https://stackoverflow.com/a/4958507/2386130
536532
[StructLayout(LayoutKind.Sequential, Pack = 4)]
537-
private struct VaListLinux64
533+
private struct VaListX64
538534
{
539535
private uint _gp_offset;
540536
private uint _fp_offset;
541537
private IntPtr _overflow_arg_area;
542538
private IntPtr _reg_save_area;
543539
}
544540

541+
// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#definition-of-va-list
542+
[StructLayout(LayoutKind.Sequential)]
543+
private struct VaListArm64
544+
{
545+
private IntPtr __stack;
546+
private IntPtr __gr_top;
547+
private IntPtr __vr_top;
548+
private int __gr_offs;
549+
private int __vr_offs;
550+
}
551+
545552
private static void WithAllocatedPtr(int size, Action<IntPtr> action)
546553
{
547554
var ptr = IntPtr.Zero;
@@ -562,4 +569,23 @@ private static void WithMarshalledStruct<T>(T structure, Action<IntPtr> action)
562569
Marshal.StructureToPtr(structure, ptr, false);
563570
action(ptr);
564571
});
572+
573+
private static string? FormatWithVaList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(IntPtr format, IntPtr args) where T : struct
574+
{
575+
string? message = null;
576+
var argsStruct = Marshal.PtrToStructure<T>(args);
577+
var formattedLength = 0;
578+
WithMarshalledStruct(argsStruct, argsPtr =>
579+
formattedLength = 1 + vsnprintf_linux(IntPtr.Zero, UIntPtr.Zero, format, argsPtr)
580+
);
581+
582+
WithAllocatedPtr(formattedLength, buffer =>
583+
WithMarshalledStruct(argsStruct, argsPtr =>
584+
{
585+
vsnprintf_linux(buffer, (UIntPtr)formattedLength, format, argsPtr);
586+
message = Marshal.PtrToStringAnsi(buffer);
587+
}));
588+
589+
return message;
590+
}
565591
}

0 commit comments

Comments
 (0)