Esempio n. 1
0
        private void EmitNativeMain(LLVMContextRef context)
        {
            LLVMValueRef shadowStackTop = Module.GetNamedGlobal("t_pShadowStackTop");

            LLVMBuilderRef builder        = context.CreateBuilder();
            var            mainSignature  = LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32, new LLVMTypeRef[] { LLVMTypeRef.Int32, LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0) }, false);
            var            mainFunc       = Module.AddFunction("__managed__Main", mainSignature);
            var            mainEntryBlock = mainFunc.AppendBasicBlock("entry");

            builder.PositionAtEnd(mainEntryBlock);
            LLVMValueRef managedMain = Module.GetNamedFunction("StartupCodeMain");

            if (managedMain.Handle == IntPtr.Zero)
            {
                throw new Exception("Main not found");
            }

            LLVMTypeRef  reversePInvokeFrameType = LLVMTypeRef.CreateStruct(new LLVMTypeRef[] { LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0) }, false);
            LLVMValueRef reversePinvokeFrame     = builder.BuildAlloca(reversePInvokeFrameType, "ReversePInvokeFrame");
            LLVMValueRef RhpReversePInvoke2      = Module.GetNamedFunction("RhpReversePInvoke2");

            if (RhpReversePInvoke2.Handle == IntPtr.Zero)
            {
                RhpReversePInvoke2 = Module.AddFunction("RhpReversePInvoke2", LLVMTypeRef.CreateFunction(LLVMTypeRef.Void, new LLVMTypeRef[] { LLVMTypeRef.CreatePointer(reversePInvokeFrameType, 0) }, false));
            }

            builder.BuildCall(RhpReversePInvoke2, new LLVMValueRef[] { reversePinvokeFrame }, "");

            var shadowStack     = builder.BuildMalloc(LLVMTypeRef.CreateArray(LLVMTypeRef.Int8, 1000000), String.Empty);
            var castShadowStack = builder.BuildPointerCast(shadowStack, LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), String.Empty);

            builder.BuildStore(castShadowStack, shadowStackTop);

            var shadowStackBottom = Module.AddGlobal(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), "t_pShadowStackBottom");

            shadowStackBottom.Linkage         = LLVMLinkage.LLVMExternalLinkage;
            shadowStackBottom.Initializer     = LLVMValueRef.CreateConstPointerNull(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0));
            shadowStackBottom.ThreadLocalMode = LLVMThreadLocalMode.LLVMLocalDynamicTLSModel;
            builder.BuildStore(castShadowStack, shadowStackBottom);

            // Pass on main arguments
            LLVMValueRef argc = mainFunc.GetParam(0);
            LLVMValueRef argv = mainFunc.GetParam(1);

            LLVMValueRef mainReturn = builder.BuildCall(managedMain, new LLVMValueRef[]
            {
                castShadowStack,
                argc,
                argv,
            },
                                                        "returnValue");

            builder.BuildRet(mainReturn);
            mainFunc.Linkage = LLVMLinkage.LLVMExternalLinkage;
        }
        static void BuildFilterFunclet(LLVMModuleRef module, LLVMTypeRef[] funcletArgTypes)
        {
            LlvmFilterFunclet = module.AddFunction("LlvmFilterFunclet", LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32, funcletArgTypes, false));
            var            block          = LlvmFilterFunclet.AppendBasicBlock("Filter");
            LLVMBuilderRef funcletBuilder = Context.CreateBuilder();

            funcletBuilder.PositionAtEnd(block);

            LLVMValueRef filterResult = funcletBuilder.BuildCall(LlvmFilterFunclet.GetParam(0), new LLVMValueRef[] { LlvmFilterFunclet.GetParam(1) }, "callFilter");

            funcletBuilder.BuildRet(filterResult);
            funcletBuilder.Dispose();
        }
Esempio n. 3
0
        static void BuildCatchFunclet(LLVMModuleRef module, string funcletName, LLVMTypeRef[] funcletArgTypes, bool passGenericContext = false)
        {
            LlvmCatchFunclet = module.AddFunction(funcletName, LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32,
                                                                                          funcletArgTypes, false));
            var            block          = LlvmCatchFunclet.AppendBasicBlock("Catch");
            LLVMBuilderRef funcletBuilder = Context.CreateBuilder();

            funcletBuilder.PositionAtEnd(block);

            List <LLVMValueRef> llvmArgs = new List <LLVMValueRef>();

            llvmArgs.Add(LlvmCatchFunclet.GetParam(2));
            if (passGenericContext)
            {
                llvmArgs.Add(LlvmCatchFunclet.GetParam(3));
            }
            LLVMValueRef leaveToILOffset = funcletBuilder.BuildCall(LlvmCatchFunclet.GetParam(1), llvmArgs.ToArray(), string.Empty);

            funcletBuilder.BuildRet(leaveToILOffset);
            funcletBuilder.Dispose();
        }
Esempio n. 4
0
        static void BuildFilterFunclet(LLVMModuleRef module, string funcletName, LLVMTypeRef[] funcletArgTypes, bool passGenericContext = false)
        {
            LlvmFilterFunclet = module.AddFunction(funcletName, LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32,
                                                                                           funcletArgTypes, false));
            var            block          = LlvmFilterFunclet.AppendBasicBlock("Filter");
            LLVMBuilderRef funcletBuilder = Context.CreateBuilder();

            funcletBuilder.PositionAtEnd(block);

            List <LLVMValueRef> llvmArgs = new List <LLVMValueRef>();

            llvmArgs.Add(LlvmFilterFunclet.GetParam(2)); //shadow stack
            llvmArgs.Add(LlvmFilterFunclet.GetParam(0)); // exception object
            if (passGenericContext)
            {
                llvmArgs.Add(LlvmFilterFunclet.GetParam(3));
            }
            LLVMValueRef filterResult = funcletBuilder.BuildCall(LlvmFilterFunclet.GetParam(1), llvmArgs.ToArray(), string.Empty);

            funcletBuilder.BuildRet(filterResult);
            funcletBuilder.Dispose();
        }
Esempio n. 5
0
        static void BuildFinallyFunclet(LLVMModuleRef module)
        {
            LlvmFinallyFunclet = module.AddFunction("LlvmFinallyFunclet", LLVMTypeRef.CreateFunction(LLVMTypeRef.Void,
                                                                                                     new LLVMTypeRef[]
            {
                LLVMTypeRef.CreatePointer(LLVMTypeRef.CreateFunction(LLVMTypeRef.Void, new LLVMTypeRef[] { LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0) }, false), 0), // finallyHandler
                LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0),                                                                                                          // shadow stack
            }, false));
            var            block          = LlvmFinallyFunclet.AppendBasicBlock("GenericFinally");
            LLVMBuilderRef funcletBuilder = Context.CreateBuilder();

            funcletBuilder.PositionAtEnd(block);

            var finallyFunclet  = LlvmFinallyFunclet.GetParam(0);
            var castShadowStack = LlvmFinallyFunclet.GetParam(1);

            List <LLVMValueRef> llvmArgs = new List <LLVMValueRef>();

            llvmArgs.Add(castShadowStack);

            funcletBuilder.BuildCall(finallyFunclet, llvmArgs.ToArray(), string.Empty);
            funcletBuilder.BuildRetVoid();
            funcletBuilder.Dispose();
        }
Esempio n. 6
0
        private SNode Visit(SNode node)
        {
            LLVMTypeRef[] paramType = { };
            var           funcType  = LLVMTypeRef.CreateFunction(LLVMTypeRef.Void, paramType);

            func  = mod.AddFunction("main", funcType);
            entry = func.AppendBasicBlock("entry");
            var body = func.AppendBasicBlock("body");

            blockStack.Add(entry);
            blockStack.Add(body);
            symbolTables.Add(new LLVMSymbolTable(symbolTables.Last()));
            builder.PositionAtEnd(body);
            Visit(node.CompoundStatement);
            builder.BuildRetVoid();
            builder.PositionAtEnd(entry);
            builder.BuildBr(body);
            return(node);
        }
Esempio n. 7
0
        private void GetCodeForReadyToRunGenericHelper(WebAssemblyCodegenCompilation compilation, ReadyToRunGenericHelperNode node, NodeFactory factory)
        {
            LLVMBuilderRef builder      = compilation.Module.Context.CreateBuilder();
            var            args         = new List <LLVMTypeRef>();
            MethodDesc     delegateCtor = null;

            if (node.Id == ReadyToRunHelperId.DelegateCtor)
            {
                DelegateCreationInfo target = (DelegateCreationInfo)node.Target;
                delegateCtor = target.Constructor.Method;
                bool isStatic = delegateCtor.Signature.IsStatic;
                int  argCount = delegateCtor.Signature.Length;
                if (!isStatic)
                {
                    argCount++;
                }
                for (int i = 0; i < argCount; i++)
                {
                    TypeDesc argType;
                    if (i == 0 && !isStatic)
                    {
                        argType = delegateCtor.OwningType;
                    }
                    else
                    {
                        argType = delegateCtor.Signature[i - (isStatic ? 0 : 1)];
                    }
                    args.Add(ILImporter.GetLLVMTypeForTypeDesc(argType));
                }
            }

            LLVMValueRef helperFunc = Module.GetNamedFunction(node.GetMangledName(factory.NameMangler));

            if (helperFunc.Handle == IntPtr.Zero)
            {
                throw new Exception("if the function is requested here, it should have been created earlier");
            }
            var helperBlock = helperFunc.AppendBasicBlock("genericHelper");

            builder.PositionAtEnd(helperBlock);
            var          importer = new ILImporter(builder, compilation, Module, helperFunc, delegateCtor);
            LLVMValueRef ctx;
            string       gepName;

            if (node is ReadyToRunGenericLookupFromTypeNode)
            {
                // Locate the VTable slot that points to the dictionary
                int vtableSlot = VirtualMethodSlotHelper.GetGenericDictionarySlot(factory, (TypeDesc)node.DictionaryOwner);

                int pointerSize = factory.Target.PointerSize;
                // Load the dictionary pointer from the VTable
                int slotOffset    = EETypeNode.GetVTableOffset(pointerSize) + (vtableSlot * pointerSize);
                var slotGep       = builder.BuildGEP(helperFunc.GetParam(1), new[] { LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, (ulong)slotOffset, false) }, "slotGep");
                var slotGepPtrPtr = builder.BuildPointerCast(slotGep,
                                                             LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), 0), "slotGepPtrPtr");
                ctx     = builder.BuildLoad(slotGepPtrPtr, "dictGep");
                gepName = "typeNodeGep";
            }
            else
            {
                ctx     = helperFunc.GetParam(1);
                gepName = "paramGep";
            }

            LLVMValueRef resVar = OutputCodeForDictionaryLookup(builder, factory, node, node.LookupSignature, ctx, gepName);

            switch (node.Id)
            {
            case ReadyToRunHelperId.GetNonGCStaticBase:
            {
                MetadataType target = (MetadataType)node.Target;

                if (compilation.TypeSystemContext.HasLazyStaticConstructor(target))
                {
                    importer.OutputCodeForTriggerCctor(target, resVar);
                }
            }
            break;

            case ReadyToRunHelperId.GetGCStaticBase:
            {
                MetadataType target = (MetadataType)node.Target;

                var ptrPtrPtr = builder.BuildBitCast(resVar, LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), 0), 0), "ptrPtrPtr");

                resVar = builder.BuildLoad(builder.BuildLoad(ptrPtrPtr, "ind1"), "ind2");

                if (compilation.TypeSystemContext.HasLazyStaticConstructor(target))
                {
                    GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(target);
                    var nonGcStaticsBase = OutputCodeForDictionaryLookup(builder, factory, node, nonGcRegionLookup, ctx, "lazyGep");
                    importer.OutputCodeForTriggerCctor(target, nonGcStaticsBase);
                }
            }
            break;

            case ReadyToRunHelperId.GetThreadStaticBase:
            {
                MetadataType target = (MetadataType)node.Target;

                if (compilation.TypeSystemContext.HasLazyStaticConstructor(target))
                {
                    GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(target);
                    var threadStaticBase = OutputCodeForDictionaryLookup(builder, factory, node, nonGcRegionLookup, ctx, "tsGep");
                    importer.OutputCodeForTriggerCctor(target, threadStaticBase);
                }
                resVar = importer.OutputCodeForGetThreadStaticBaseForType(resVar).ValueAsType(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), builder);
            }
            break;

            case ReadyToRunHelperId.DelegateCtor:
            {
                DelegateCreationInfo target      = (DelegateCreationInfo)node.Target;
                MethodDesc           constructor = target.Constructor.Method;
                var fatPtr = ILImporter.MakeFatPointer(builder, resVar, compilation);
                importer.OutputCodeForDelegateCtorInit(builder, helperFunc, constructor, fatPtr);
            }
            break;

            // These are all simple: just get the thing from the dictionary and we're done
            case ReadyToRunHelperId.TypeHandle:
            case ReadyToRunHelperId.MethodHandle:
            case ReadyToRunHelperId.FieldHandle:
            case ReadyToRunHelperId.MethodDictionary:
            case ReadyToRunHelperId.MethodEntry:
            case ReadyToRunHelperId.VirtualDispatchCell:
            case ReadyToRunHelperId.DefaultConstructor:
                break;

            default:
                throw new NotImplementedException();
            }

            if (node.Id != ReadyToRunHelperId.DelegateCtor)
            {
                builder.BuildRet(resVar);
            }
            else
            {
                builder.BuildRetVoid();
            }
        }
Esempio n. 8
0
 public void PositionBuilderAtEnd(LLVMBuilderRef builder) => builder.PositionAtEnd(Block);