如何使用Marshall LLVMSharp功能

时间:2018-05-02 05:29:20

标签: c# delegates llvm marshalling

因此,使用ANTLR4& amp; LLVMSharp。尝试使用marshal函数添加2个双精度,并且应用程序仅在调试模式下崩溃(可能的堆栈损坏?)IR为以下示例生成。编组整数作为参数时没有问题。

define double @main(double %x, double %y) #0 {
entry:
  %tmp = fadd double %x, %y
  ret double %tmp
}

错误如下所示。

Managed Debugging Assistant 'FatalExecutionEngineError' 
The runtime has encountered a fatal error. The address of the error was at 0x737e17cf, on thread 0x299c. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshalling errors for COM-interop or PInvoke, which may corrupt the stack.

编组代码如下所示

LLVMBool success = new LLVMBool(0);
LLVMModuleRef module = LLVM.ModuleCreateWithName("LLVMSharpIntro");
LLVMTypeRef[] param_types = { LLVM.DoubleType(), LLVM.DoubleType() };
LLVMTypeRef ret_type = LLVM.FunctionType(LLVM.DoubleType(), param_types, false);
LLVMValueRef sum = LLVM.AddFunction(module, "main", ret_type);

LLVMBasicBlockRef entry = LLVM.AppendBasicBlock(sum, "entry");
LLVMBuilderRef builder = LLVM.CreateBuilder();
LLVM.PositionBuilderAtEnd(builder, entry);

LLVMValueRef tmp = LLVM.BuildFAdd(builder, LLVM.GetParam(sum, 0), LLVM.GetParam(sum, 1), "tmp");
LLVM.BuildRet(builder, tmp);

if(LLVM.VerifyModule(module,LLVMVerifierFailureAction.LLVMPrintMessageAction, out var error) != success)
{
    Console.WriteLine($"Error: {error}");
}

LLVM.LinkInMCJIT();
LLVM.InitializeX86TargetMC();
LLVM.InitializeX86Target();
LLVM.InitializeX86TargetInfo();
LLVM.InitializeX86AsmParser();
LLVM.InitializeX86AsmPrinter();

LLVMMCJITCompilerOptions options = new LLVMMCJITCompilerOptions { NoFramePointerElim = 1 };
LLVM.InitializeMCJITCompilerOptions(options);
if (LLVM.CreateExecutionEngineForModule(out var engine, module, out error) != success)
{
    Console.WriteLine($"Error: {error}");
}
LLVM.DumpModule(module);
var addMethod = Marshal.GetDelegateForFunctionPointer<FloatingPoint>(LLVM.GetPointerToGlobal(engine, sum));
GC.KeepAlive(addMethod);

Console.WriteLine(addMethod(6.0, 2.0));

编辑:找到解决方案,你必须在x64 cpu目标中运行C#项目,即使它是针对x86的。显然,调试器会以其他方式翻转。不要认为代码本身实际上有任何不正确的地方,在这些情况下调试器似乎无法很好地处理非托管函数。

0 个答案:

没有答案