1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-10 01:50:53 +09:00

Automatically export '__managed__Main' when needed (#105353)

* Automatically export '__managed__Main' if needed

* Add unit test for stub .exe configuration

* Move '__managed__Main' export to shared .targets

* Use 'LoadLibrary' and 'GetProcAddress' instead

* Update 'CMakeLists.txt' from 'SharedLibrary'

* Fix .cs filename in .csproj file

* Port scripts from shared library test
This commit is contained in:
Sergio Pedri 2024-07-31 20:58:10 -07:00 committed by GitHub
parent 1dffab5ceb
commit 3577d44a77
Signed by: github
GPG key ID: B5690EEEBB952194
5 changed files with 150 additions and 0 deletions

View file

@ -291,6 +291,9 @@ The .NET Foundation licenses this file to you under the MIT license.
<!-- The managed debugging support in libraries is unused - trim it -->
<IlcArg Condition="'$(DebuggerSupport)' != 'true'" Include="--feature:System.Diagnostics.Debugger.IsSupported=false" />
<!-- Export the managed entry point if building a native library in custom main mode -->
<IlcArg Condition="'$(NativeLib)' == 'Shared' and '$(CustomNativeMain)' == 'true'" Include="--export-dynamic-symbol:__managed__Main" />
</ItemGroup>
<MakeDir Directories="$(NativeIntermediateOutputPath)" />

View file

@ -0,0 +1,16 @@
project (CustomMainWithStubExeNative)
include_directories(${INC_PLATFORM_DIR})
add_executable (CustomMainWithStubExeNative CustomMainWithStubExeNative.cpp)
if (CLR_CMAKE_TARGET_UNIX)
target_link_libraries (CustomMainWithStubExeNative PRIVATE ${CMAKE_DL_LIBS})
endif()
# add the install targets
install (TARGETS CustomMainWithStubExeNative DESTINATION bin)
# If there's a dynamic ASAN runtime, then copy it to project output.
if (NOT "${ASAN_RUNTIME}" STREQUAL "")
file(COPY "${ASAN_RUNTIME}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endif()

View file

@ -0,0 +1,40 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
class Program
{
// Each of the module initializer, class constructor, and IncrementExitCode
// should be executed exactly once, causing this to each 100 by program exit.
static int s_exitCode;
[ModuleInitializer]
internal static void InitializeModule()
{
s_exitCode += 8;
}
static Program()
{
s_exitCode += 31;
// A side-effecting operation to prevent this cctor from being pre-inited at compile time.
Console.WriteLine("hello from static constructor");
}
[UnmanagedCallersOnly(EntryPoint = "IncrementExitCode")]
static void IncrementExitCode(int amount)
{
s_exitCode += amount;
}
int ExitCode;
static int Main(string[] args)
{
Console.WriteLine("hello from managed main");
return s_exitCode;
}
}

View file

@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<CustomNativeMain>true</CustomNativeMain>
<NativeLib>Shared</NativeLib>
</PropertyGroup>
<PropertyGroup>
<CLRTestBatchPreCommands><![CDATA[
$(CLRTestBatchPreCommands)
mkdir native 2>nul
copy /y clang_rt.* native\
copy /y CustomMainWithStubExeNative.exe native\CustomMainWithStubExe.exe
]]></CLRTestBatchPreCommands>
<CLRTestBashPreCommands><![CDATA[
$(CLRTestBashPreCommands)
mkdir -p native
cp libclang_rt.* native/
cp CustomMainWithStubExeNative native/CustomMainWithStubExe
]]></CLRTestBashPreCommands>
</PropertyGroup>
<ItemGroup>
<Compile Include="CustomMainWithStubExe.cs" />
</ItemGroup>
<ItemGroup>
<CMakeProjectReference Include="CMakeLists.txt" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,60 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#ifdef TARGET_WINDOWS
#include "windows.h"
#else
#include "dlfcn.h"
#endif
#include "stdio.h"
#include <stdint.h>
#include "string.h"
#ifndef TARGET_WINDOWS
#define __stdcall
#endif
// typedef for shared lib exported methods
#if defined(_WIN32)
typedef int(__stdcall *f___managed__Main)(int argc, wchar_t* argv[]);
#else
typedef int(__stdcall *f___managed__Main)(int argc, char* argv[]);
#endif
typedef void(__stdcall *f_IncrementExitCode)(int32_t amount);
#if defined(_WIN32)
int __cdecl wmain(int argc, wchar_t* argv[])
#else
int main(int argc, char* argv[])
#endif
{
#ifdef TARGET_WINDOWS
HINSTANCE handle = LoadLibrary("CustomMainWithStubExe.dll");
#elif __APPLE__
void *handle = dlopen(strcat(argv[0], ".dylib"), RTLD_LAZY);
#else
void *handle = dlopen(strcat(argv[0], ".so"), RTLD_LAZY);
#endif
if (!handle)
return 1;
#ifdef TARGET_WINDOWS
f___managed__Main __managed__MainFunc = (f___managed__Main)GetProcAddress(handle, "__managed__Main");
f_IncrementExitCode IncrementExitCodeFunc = (f_IncrementExitCode)GetProcAddress(handle, "IncrementExitCode");
#else
f___managed__Main __managed__MainFunc = (f___managed__Main)dlsym(handle, "__managed__Main");
f_IncrementExitCode IncrementExitCodeFunc = (f_IncrementExitCode)dlsym(handle, "IncrementExitCode");
#endif
puts("hello from native main");
IncrementExitCodeFunc(61);
return __managed__MainFunc(argc, argv);
}
extern "C" const char* __stdcall __asan_default_options()
{
// NativeAOT is not designed to be unloadable, so we'll leak a few allocations from the shared library.
// Disable leak detection as we don't care about these leaks as of now.
return "detect_leaks=0 use_sigaltstack=0";
}