Skip to content

Commit

Permalink
Fixed calling into native libgit2 on osx-arm64 (git_libgit2_opts vari…
Browse files Browse the repository at this point in the history
…adic parameters)
  • Loading branch information
frindler committed Apr 2, 2022
1 parent 0ff4838 commit 5e78b82
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 10 deletions.
36 changes: 36 additions & 0 deletions LibGit2Sharp/Core/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,42 @@ internal static extern int git_libgit2_opts(int option,
internal static extern int git_libgit2_opts(int option, out GitStrArray extensions);
#endregion

#region git_libgit2_opts_osxarm64

// For RID osx-arm64 the calling convention is different: we need to pad out to 8 arguments before varargs
// (see discussion at https://github.com/dotnet/runtime/issues/48796)

// git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, int level, git_buf *buf)
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")]
internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, uint level, GitBuf buf);

// git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")]
internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, uint level,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string path);

// git_libgit2_opts(GIT_OPT_ENABLE_*, int enabled)
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")]
internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, int enabled);

// git_libgit2_opts(GIT_OPT_SET_USER_AGENT, const char *path)
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")]
internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string path);

// git_libgit2_opts(GIT_OPT_GET_USER_AGENT, git_buf *buf)
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")]
internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, GitBuf buf);

// git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, const char **extensions, size_t len)
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")]
internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, IntPtr extensions, UIntPtr len);

// git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, git_strarray *out)
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")]
internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, out GitStrArray extensions);
#endregion

[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_graph_ahead_behind(out UIntPtr ahead, out UIntPtr behind, git_repository* repo, ref GitOid one, ref GitOid two);

Expand Down
62 changes: 52 additions & 10 deletions LibGit2Sharp/Core/Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ namespace LibGit2Sharp.Core
{
internal class Proxy
{
internal static readonly bool isOSXArm64 = RuntimeInformation.ProcessArchitecture == Architecture.Arm64
&& RuntimeInformation.IsOSPlatform(OSPlatform.OSX);

#region git_blame_

public static unsafe BlameHandle git_blame_file(
Expand Down Expand Up @@ -3408,7 +3411,11 @@ public static string git_libgit2_opts_get_search_path(ConfigurationLevel level)

using (var buf = new GitBuf())
{
var res = NativeMethods.git_libgit2_opts((int)LibGit2Option.GetSearchPath, (uint)level, buf);
int res;
if (isOSXArm64)
res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.GetSearchPath, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)level, buf);
else
res = NativeMethods.git_libgit2_opts((int)LibGit2Option.GetSearchPath, (uint)level, buf);
Ensure.ZeroResult(res);

path = LaxUtf8Marshaler.FromNative(buf.ptr) ?? string.Empty;
Expand All @@ -3419,7 +3426,10 @@ public static string git_libgit2_opts_get_search_path(ConfigurationLevel level)

public static void git_libgit2_opts_enable_strict_hash_verification(bool enabled)
{
NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableStrictHashVerification, enabled ? 1 : 0);
if (isOSXArm64)
NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableStrictHashVerification, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0);
else
NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableStrictHashVerification, enabled ? 1 : 0);
}

/// <summary>
Expand All @@ -3432,7 +3442,11 @@ public static void git_libgit2_opts_enable_strict_hash_verification(bool enabled
/// </param>
public static void git_libgit2_opts_set_search_path(ConfigurationLevel level, string path)
{
var res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetSearchPath, (uint)level, path);
int res;
if (isOSXArm64)
res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.SetSearchPath, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)level, path);
else
res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetSearchPath, (uint)level, path);
Ensure.ZeroResult(res);
}

Expand All @@ -3443,7 +3457,11 @@ public static void git_libgit2_opts_set_search_path(ConfigurationLevel level, st
public static void git_libgit2_opts_set_enable_caching(bool enabled)
{
// libgit2 expects non-zero value for true
var res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableCaching, enabled ? 1 : 0);
int res;
if (isOSXArm64)
res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableCaching, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0);
else
res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableCaching, enabled ? 1 : 0);
Ensure.ZeroResult(res);
}

Expand All @@ -3454,7 +3472,11 @@ public static void git_libgit2_opts_set_enable_caching(bool enabled)
public static void git_libgit2_opts_set_enable_ofsdelta(bool enabled)
{
// libgit2 expects non-zero value for true
var res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableOfsDelta, enabled ? 1 : 0);
int res;
if (isOSXArm64)
res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableOfsDelta, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0);
else
res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableOfsDelta, enabled ? 1 : 0);
Ensure.ZeroResult(res);
}

Expand All @@ -3465,7 +3487,11 @@ public static void git_libgit2_opts_set_enable_ofsdelta(bool enabled)
public static void git_libgit2_opts_set_enable_strictobjectcreation(bool enabled)
{
// libgit2 expects non-zero value for true
var res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableStrictObjectCreation, enabled ? 1 : 0);
int res;
if (isOSXArm64)
res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.EnableStrictObjectCreation, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0);
else
res = NativeMethods.git_libgit2_opts((int)LibGit2Option.EnableStrictObjectCreation, enabled ? 1 : 0);
Ensure.ZeroResult(res);
}

Expand All @@ -3476,7 +3502,11 @@ public static void git_libgit2_opts_set_enable_strictobjectcreation(bool enabled
/// <param name="userAgent">The user-agent string to use</param>
public static void git_libgit2_opts_set_user_agent(string userAgent)
{
var res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetUserAgent, userAgent);
int res;
if (isOSXArm64)
res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.SetUserAgent, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, userAgent);
else
res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetUserAgent, userAgent);
Ensure.ZeroResult(res);
}

Expand All @@ -3492,7 +3522,11 @@ public static string git_libgit2_opts_get_user_agent()

using (var buf = new GitBuf())
{
var res = NativeMethods.git_libgit2_opts((int)LibGit2Option.GetUserAgent, buf);
int res;
if (isOSXArm64)
res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.GetUserAgent, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, buf);
else
res = NativeMethods.git_libgit2_opts((int)LibGit2Option.GetUserAgent, buf);
Ensure.ZeroResult(res);

userAgent = LaxUtf8Marshaler.FromNative(buf.ptr) ?? string.Empty;
Expand All @@ -3505,7 +3539,11 @@ public static void git_libgit2_opts_set_extensions(string[] extensions)
{
using (var array = GitStrArrayManaged.BuildFrom(extensions))
{
var res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetExtensions, array.Array.Strings, array.Array.Count);
int res;
if (isOSXArm64)
res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.SetExtensions, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, array.Array.Strings, array.Array.Count);
else
res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetExtensions, array.Array.Strings, array.Array.Count);
Ensure.ZeroResult(res);
}
}
Expand All @@ -3516,7 +3554,11 @@ public static string[] git_libgit2_opts_get_extensions()

try
{
var res = NativeMethods.git_libgit2_opts((int)LibGit2Option.GetExtensions, out array.Array);
int res;
if (isOSXArm64)
res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.GetExtensions, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out array.Array);
else
res = NativeMethods.git_libgit2_opts((int)LibGit2Option.GetExtensions, out array.Array);
Ensure.ZeroResult(res);

return array.ReadStrings();
Expand Down

0 comments on commit 5e78b82

Please sign in to comment.