Beispiel #1
0
        private static InstructionBuilder CreateFunctionAndGetBuilder(BitcodeModule module, DebugBasicType doubleType, string name, string section, uint line)
        {
            DIFile file = module.DIBuilder.CreateFile(TestSrcFileName);

            DebugFunctionType signature = module.Context.CreateFunctionType(module.DIBuilder, doubleType, doubleType, doubleType);
            var func = module.CreateFunction(module.DICompileUnit !, name, name, file, line, signature, true, true, line + 1, DebugInfoFlags.None, false);

            func.Section = section;
            var entry = func.AppendBasicBlock("entry");

            return(new InstructionBuilder(entry));
        }
Beispiel #2
0
        /// <summary>Creates a Function definition with Debug information</summary>
        /// <param name="scope">Containing scope for the function</param>
        /// <param name="name">Name of the function in source language form</param>
        /// <param name="linkageName">Mangled linker visible name of the function (may be same as <paramref name="name"/> if mangling not required by source language</param>
        /// <param name="file">File containing the function definition</param>
        /// <param name="line">Line number of the function definition</param>
        /// <param name="signature">LLVM Function type for the signature of the function</param>
        /// <param name="isLocalToUnit">Flag to indicate if this function is local to the compilation unit</param>
        /// <param name="isDefinition">Flag to indicate if this is a definition</param>
        /// <param name="scopeLine">First line of the function's outermost scope, this may not be the same as the first line of the function definition due to source formatting</param>
        /// <param name="debugFlags">Additional flags describing this function</param>
        /// <param name="isOptimized">Flag to indicate if this function is optimized</param>
        /// <param name="tParam">Parameter Metadata node</param>
        /// <param name="decl">Declaration Metadata node</param>
        /// <returns>Function described by the arguments</returns>
        public Function CreateFunction(DIScope scope
                                       , string name
                                       , string linkageName
                                       , DIFile file
                                       , uint line
                                       , DebugFunctionType signature
                                       , bool isLocalToUnit
                                       , bool isDefinition
                                       , uint scopeLine
                                       , DebugInfoFlags debugFlags
                                       , bool isOptimized
                                       , [CanBeNull] MDNode tParam = null
                                       , [CanBeNull] MDNode decl   = null
                                       )
        {
            ValidateHandle( );
            scope.ValidateNotNull(nameof(scope));
            name.ValidateNotNullOrWhiteSpace(nameof(name));
            signature.ValidateNotNull(nameof(signature));
            if (signature.DIType == null)
            {
                throw new ArgumentException("Signature requires debug type information", nameof(signature));
            }

            var func        = AddFunction(linkageName ?? name, signature);
            var diSignature = signature.DIType;
            var diFunc      = DIBuilder.CreateFunction(scope: scope
                                                       , name: name
                                                       , mangledName: linkageName
                                                       , file: file
                                                       , line: line
                                                       , signatureType: diSignature
                                                       , isLocalToUnit: isLocalToUnit
                                                       , isDefinition: isDefinition
                                                       , scopeLine: scopeLine
                                                       , debugFlags: debugFlags
                                                       , isOptimized: isOptimized
                                                       , function: func
                                                       , typeParameter: tParam
                                                       , declaration: decl
                                                       );

            Debug.Assert(diFunc.Describes(func), "Expected to get a debug function that describes the provided function");
            func.DISubProgram = diFunc;
            return(func);
        }
Beispiel #3
0
        private static Function DeclareDoCopyFunc(BitcodeModule module, DIFile diFile, IDebugType <ITypeRef, DIType> voidType)
        {
            var doCopySig = module.Context.CreateFunctionType(module.DIBuilder, voidType);

            var doCopyFunc = module.CreateFunction(scope: diFile
                                                   , name: "DoCopy"
                                                   , linkageName: null
                                                   , file: diFile
                                                   , line: 23
                                                   , signature: doCopySig
                                                   , isLocalToUnit: false
                                                   , isDefinition: true
                                                   , scopeLine: 24
                                                   , debugFlags: DebugInfoFlags.None
                                                   , isOptimized: false
                                                   ).AddAttributes(FunctionAttributeIndex.Function, AttributeKind.NoInline, AttributeKind.NoUnwind, AttributeKind.OptimizeNone)
                             .AddAttributes(FunctionAttributeIndex.Function, TargetDependentAttributes);

            return(doCopyFunc);
        }
Beispiel #4
0
        private static Function DeclareCopyFunc(BitcodeModule module
                                                , DIFile diFile
                                                , IDebugType <ITypeRef, DIType> voidType
                                                , DIDerivedType constFoo
                                                , DebugPointerType fooPtr
                                                )
        {
            // Since the first parameter is passed by value
            // using the pointer + alloca + memcopy pattern, the actual
            // source, and therefore debug, signature is NOT a pointer.
            // However, that usage would create a signature with two
            // pointers as the arguments, which doesn't match the source
            // To get the correct debug info signature this inserts an
            // explicit DebugType<> that overrides the default behavior
            // to pair the LLVM pointer type with the original source type.
            var copySig = module.Context.CreateFunctionType(module.DIBuilder
                                                            , voidType
                                                            , DebugType.Create(fooPtr, constFoo)
                                                            , fooPtr
                                                            );

            var copyFunc = module.CreateFunction(scope: diFile
                                                 , name: "copy"
                                                 , linkageName: null
                                                 , file: diFile
                                                 , line: 11
                                                 , signature: copySig
                                                 , isLocalToUnit: true
                                                 , isDefinition: true
                                                 , scopeLine: 14
                                                 , debugFlags: DebugInfoFlags.Prototyped
                                                 , isOptimized: false
                                                 ).Linkage(Linkage.Internal)  // static function
                           .AddAttributes(FunctionAttributeIndex.Function, AttributeKind.NoUnwind, AttributeKind.NoInline, AttributeKind.OptimizeNone)
                           .AddAttributes(FunctionAttributeIndex.Function, TargetDependentAttributes);

            TargetDetails.AddABIAttributesForByValueStructure(copyFunc, 0);
            return(copyFunc);
        }
Beispiel #5
0
        private static void CreateCopyFunctionBody(BitcodeModule module
                                                   , DataLayout layout
                                                   , Function copyFunc
                                                   , DIFile diFile
                                                   , ITypeRef foo
                                                   , DebugPointerType fooPtr
                                                   , DIType constFooType
                                                   )
        {
            var diBuilder = module.DIBuilder;

            copyFunc.Parameters[0].Name = "src";
            copyFunc.Parameters[1].Name = "pDst";

            // create block for the function body, only need one for this simple sample
            var blk = copyFunc.AppendBasicBlock("entry");

            // create instruction builder to build the body
            var instBuilder = new InstructionBuilder(blk);

            // create debug info locals for the arguments
            // NOTE: Debug parameter indices are 1 based!
            var paramSrc = diBuilder.CreateArgument(copyFunc.DISubProgram, "src", diFile, 11, constFooType, false, 0, 1);
            var paramDst = diBuilder.CreateArgument(copyFunc.DISubProgram, "pDst", diFile, 12, fooPtr.DIType, false, 0, 2);

            uint ptrAlign = layout.CallFrameAlignmentOf(fooPtr);

            // create Locals
            // NOTE: There's no debug location attached to these instructions.
            //       The debug info will come from the declare intrinsic below.
            var dstAddr = instBuilder.Alloca(fooPtr)
                          .RegisterName("pDst.addr")
                          .Alignment(ptrAlign);

            bool param0ByVal = copyFunc.Attributes[FunctionAttributeIndex.Parameter0].Contains(AttributeKind.ByVal);

            if (param0ByVal)
            {
                diBuilder.InsertDeclare(copyFunc.Parameters[0]
                                        , paramSrc
                                        , new DILocation(module.Context, 11, 43, copyFunc.DISubProgram)
                                        , blk
                                        );
            }

            instBuilder.Store(copyFunc.Parameters[1], dstAddr)
            .Alignment(ptrAlign);

            // insert declare pseudo instruction to attach debug info to the local declarations
            diBuilder.InsertDeclare(dstAddr, paramDst, new DILocation(module.Context, 12, 38, copyFunc.DISubProgram), blk);

            if (!param0ByVal)
            {
                // since the function's LLVM signature uses a pointer, which is copied locally
                // inform the debugger to treat it as the value by dereferencing the pointer
                diBuilder.InsertDeclare(copyFunc.Parameters[0]
                                        , paramSrc
                                        , diBuilder.CreateExpression(ExpressionOp.deref)
                                        , new DILocation(module.Context, 11, 43, copyFunc.DISubProgram)
                                        , blk
                                        );
            }

            var loadedDst = instBuilder.Load(dstAddr)
                            .Alignment(ptrAlign)
                            .SetDebugLocation(15, 6, copyFunc.DISubProgram);

            var dstPtr = instBuilder.BitCast(loadedDst, module.Context.Int8Type.CreatePointerType( ))
                         .SetDebugLocation(15, 13, copyFunc.DISubProgram);

            var srcPtr = instBuilder.BitCast(copyFunc.Parameters[0], module.Context.Int8Type.CreatePointerType( ))
                         .SetDebugLocation(15, 13, copyFunc.DISubProgram);

            uint pointerSize = layout.IntPtrType(module.Context).IntegerBitWidth;

            instBuilder.MemCpy(module
                               , dstPtr
                               , srcPtr
                               , module.Context.CreateConstant(pointerSize, layout.ByteSizeOf(foo), false)
                               , ( int )layout.AbiAlignmentOf(foo)
                               , false
                               ).SetDebugLocation(15, 13, copyFunc.DISubProgram);

            instBuilder.Return( )
            .SetDebugLocation(16, 1, copyFunc.DISubProgram);
        }